Tarantool development patches archive
 help / color / mirror / Atom feed
From: Chris Sosnin <k.sosnin@tarantool.org>
To: tarantool-patches@dev.tarantool.org, sergepetrenko@tarantool.org,
	v.shpilevoy@tarantool.org
Subject: [Tarantool-patches] [PATCH 1/2] Allow leading and trailing whitespaces in FromString
Date: Fri,  5 Jun 2020 18:41:12 +0300	[thread overview]
Message-ID: <401a596ba9864ddf4ffc687f4313a60dbc664a28.1591371404.git.k.sosnin@tarantool.org> (raw)
In-Reply-To: <cover.1591371404.git.k.sosnin@tarantool.org>

This is needed for SQL, since these whitespaces are allowed in
conversions from string.

Needed for tarantool/tarantool#4415
---
 decNumber.c | 44 +++++++++++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 15 deletions(-)

diff --git a/decNumber.c b/decNumber.c
index 85deb13..7c53bc3 100644
--- a/decNumber.c
+++ b/decNumber.c
@@ -555,9 +555,9 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
   Unit  *allocres=NULL;            // -> allocated result, iff allocated
   Int   d=0;                       // count of digits found in decimal part
   const char *dotchar=NULL;        // where dot was found
-  const char *cfirst=chars;        // -> first character of decimal part
+  const char *cfirst=NULL;         // -> first character of decimal part
   const char *last=NULL;           // -> last digit of decimal part
-  const char *c;                   // work
+  const char *c, *p;               // work
   Unit  *up;                       // ..
   #if DECDPUN>1
   Int   cut, out;                  // ..
@@ -571,6 +571,9 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
   #endif
 
   do {                             // status & malloc protection
+    for (; *chars==' '; ++chars);  // skip leading whitespaces
+    cfirst=chars;
+
     for (c=chars;; c++) {          // -> input character
       if (*c>='0' && *c<='9') {    // test for Arabic digit
         last=c;
@@ -590,13 +593,14 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
           cfirst++;
           continue;}
         }
+      for (p=c; *p==' '; ++p);
       // *c is not a digit, or a valid +, -, or '.'
       break;
       } // c
 
     if (last==NULL) {              // no digits yet
       status=DEC_Conversion_syntax;// assume the worst
-      if (*c=='\0') break;         // and no more to come...
+      if (*p=='\0') break;         // and no more to come...
       #if DECSUBSET
       // if subset then infinities and NaNs are not allowed
       if (!set->extended) break;   // hopeless
@@ -626,7 +630,8 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
       // now either nothing, or nnnn payload, expected
       // -> start of integer and skip leading 0s [including plain 0]
       for (cfirst=c; *cfirst=='0';) cfirst++;
-      if (*cfirst=='\0') {         // "NaN" or "sNaN", maybe with all 0s
+      for (p=cfirst; *p==' '; ++p);
+      if (*p=='\0') {              // "NaN" or "sNaN", maybe with all 0s
         status=0;                  // it's good
         break;                     // ..
         }
@@ -635,7 +640,8 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
         if (*c<'0' || *c>'9') break; // test for Arabic digit
         last=c;
         }
-      if (*c!='\0') break;         // not all digits
+      for (p=c; *p==' '; ++p);
+      if (*p!='\0') break;         // not all digits
       if (d>set->digits-1) {
         // [NB: payload in a decNumber can be full length unless
         // clamped, in which case can only be digits-1]
@@ -647,7 +653,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
       bits=dn->bits;               // for copy-back
       } // last==NULL
 
-     else if (*c!='\0') {          // more to process...
+     else if (p==c && *p!='\0') {  // more to process...
       // had some digits; exponent is only valid sequence now
       Flag nege;                   // 1=negative exponent
       const char *firstexp;        // -> first significant exponent digit
@@ -659,16 +665,18 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
       c++;                         // to (possible) sign
       if (*c=='-') {nege=1; c++;}
        else if (*c=='+') c++;
-      if (*c=='\0') break;
-
-      for (; *c=='0' && *(c+1)!='\0';) c++;  // strip insignificant zeros
+      for (p=c; *p==' '; ++p);
+      if (*p=='\0') break;
+      // strip insignificant zeros
+      for (; *c=='0' && *(c+1)!='\0' && *(c+1)!=' ';) c++;
       firstexp=c;                            // save exponent digit place
       for (; ;c++) {
         if (*c<'0' || *c>'9') break;         // not a digit
         exponent=X10(exponent)+(Int)*c-(Int)'0';
         } // c
       // if not now on a '\0', *c must not be a digit
-      if (*c!='\0') break;
+      for (p=c; *p==' '; ++p);
+      if (*p!='\0') break;
 
       // (this next test must be after the syntax checks)
       // if it was too long the exponent may have wrapped, so check
@@ -681,6 +689,11 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[],
       status=0;                         // is OK
       } // stuff after digits
 
+     else if (*p!='\0') {    // whitespaces in the middle
+       status=DEC_Conversion_syntax;
+       break;
+     }
+
     // Here when whole string has been inspected; syntax is good
     // cfirst->first digit (never dot), last->last digit (ditto)
 
@@ -7739,12 +7752,13 @@ static decNumber *decDecap(decNumber *dn, Int drop) {
 /*   if (decBiStr(test, "mike", "MIKE")) ...                          */
 /* ------------------------------------------------------------------ */
 static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
-  for (;;targ++, str1++, str2++) {
+  const char *end=strchr(targ, ' ');
+  if (end==NULL)
+    end=targ+strlen(targ);
+  for (;targ<end; targ++, str1++, str2++) {
     if (*targ!=*str1 && *targ!=*str2) return 0;
-    // *targ has a match in one (or both, if terminator)
-    if (*targ=='\0') break;
-    } // forever
-  return 1;
+    } // for
+  return *str1=='\0';
   } // decBiStr
 
 /* ------------------------------------------------------------------ */
-- 
2.21.1 (Apple Git-122.3)

  reply	other threads:[~2020-06-05 15:41 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-05 15:41 [Tarantool-patches] [PATCH 0/2] update decNumber for SQL Chris Sosnin
2020-06-05 15:41 ` Chris Sosnin [this message]
2020-06-06 13:48   ` [Tarantool-patches] [PATCH 1/2] Allow leading and trailing whitespaces in FromString Serge Petrenko
2020-06-07 12:38     ` Chris Sosnin
2020-06-11 17:06   ` Vladislav Shpilevoy
2020-06-11 20:14     ` Chris Sosnin
2020-06-05 15:41 ` [Tarantool-patches] [PATCH 2/2] Add IsWhole method for checking the fractional part of a number Chris Sosnin
2020-06-06 14:17   ` Serge Petrenko
2020-06-07 12:40     ` Chris Sosnin
2020-06-08  8:59       ` Serge Petrenko
2020-06-11 17:06   ` Vladislav Shpilevoy
2020-06-11 20:30     ` Chris Sosnin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=401a596ba9864ddf4ffc687f4313a60dbc664a28.1591371404.git.k.sosnin@tarantool.org \
    --to=k.sosnin@tarantool.org \
    --cc=sergepetrenko@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH 1/2] Allow leading and trailing whitespaces in FromString' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox