www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2013/06/22/14:10:05

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX1+uFHkDz3KutOhzPEfZDAHO6DKmasvKhtn/DwA1Nx
6NLMJk6m0cZ9MA
Message-ID: <51C5E568.7060005@gmx.de>
Date: Sat, 22 Jun 2013 19:56:56 +0200
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121025 Thunderbird/16.0.2
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Some strto[d|f|ld] issues.
X-Y-GMX-Trusted: 0
Reply-To: djgpp-workers AT delorie DOT com

While I was trying to port the latest Lua, I have found the
following issues:
        s       endptr  value
1)   ....       ...      0     numeric values is correct but
                                endptr points to the second non
                                numeric char. Should point to
                                first dot.
2) +1eNNN       NNN      1     numeric values is correct but
                                endptr points to first 'N'.
                                Should point to 'e'.
3) +0xa.aP+NNN  NNN    10.625  numeric values is correct but
                                endptr points to first 'N'.
                                Should point to 'P'.
4)     ' '               0     numeric values is correct but
                                endptr points to end of white
                                space string.  Should point to
                                first white space char.

This issue concerns only the repository versions of strto[d|f|ld]
not the ones in djdev204.zip available in the /beta directory.
The patch below will fix all these issues.

Regards,
Juan M. Guerrero



Logging in to :pserver:anonymous AT cvs DOT delorie DOT com:2401/cvs/djgpp
Index: djgpp/src/libc/ansi/stdlib/strtod.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdlib/strtod.c,v
retrieving revision 1.12
diff -p -U 5 -r1.12 strtod.c
--- djgpp/src/libc/ansi/stdlib/strtod.c    19 Jun 2013 19:38:02 -0000   
  1.12
+++ djgpp/src/libc/ansi/stdlib/strtod.c    22 Jun 2013 15:30:27 -0000
@@ -33,19 +33,25 @@ strtod(const char *s, char **sret)
  {
    long double r = 0;            /* result */
    int e = 0;                    /* exponent */
    long double d;                /* scale */
    int sign = 1;                 /* +- 1.0 */
-  int esign = 1;
+  int esign = 0;                /* 0: no valid exponent after [eEpP] */
    int i;
    int flags = 0;
    char decimal_point = localeconv()->decimal_point[0];


+  if (sret)
+    *sret = unconst(s, char *);
+
    while (isspace((unsigned char) *s))
      s++;

+  if (!*s)
+    return 0.0;
+
    /* Handle leading sign. */
    if (*s == '+')
      s++;
    else if (*s == '-')
    {
@@ -62,11 +68,11 @@ strtod(const char *s, char **sret)
          *sret = unconst((&s[8]), char *);
        else
          *sret = unconst((&s[3]), char *);
      }

-    return (0 > sign) ? -INFINITY : INFINITY;
+    return (sign < 0) ? -INFINITY : INFINITY;
    }

    /* Handle NAN and NAN(<whatever>). */
    if (!strnicmp("NAN", s, 3))
    {
@@ -179,14 +185,18 @@ strtod(const char *s, char **sret)
          for (bit <<= (digits * HEX_DIGIT_SIZE + bin_exponent); 
!(mantissa & bit); bin_exponent--)
            bit >>= 1;
        }
      }

-    if (!flags)
+    if (flags == 0)
      {
        if (sret)
+      {
+        if (!r)
+          s--;  /*  A dot without leading numbers.  */
          *sret = unconst(s, char *);
+      }
        errno = EINVAL;  /*  No valid mantissa, no convertion could be 
performed.  */
        return 0.0L;
      }

      if (mantissa)
@@ -217,26 +227,40 @@ strtod(const char *s, char **sret)
      if (IS_EXPONENT(s))
      {
        long int exponent = 0.0;
        s++;
        if (*s == '+')
+      {
+        esign = +1;
          s++;
+      }
        else if (*s == '-')
        {
          esign = -1;
          s++;
        }

-      while ((esign * exponent + bin_exponent) < (MAX_BIN_EXPONENT + 1) 
&& IS_DEC_DIGIT(*s))
+      if (!*s)
        {
-        exponent *= 10;
-        exponent += *s - '0';
-        s++;
+        /*  Mantissa followed by [pP] with/out
+            a sign but without exponent.  */
+        s--;
+        if (esign)
+          s--;
+      }
+      else
+      {
+        while ((esign * exponent + bin_exponent) < (MAX_BIN_EXPONENT + 
1) && IS_DEC_DIGIT(*s))
+        {
+          exponent *= 10;
+          exponent += *s - '0';
+          s++;
+        }
+        bin_exponent += esign * exponent;  /*  2**bin_exponent.  */
+        while (IS_DEC_DIGIT(*s))
+          s++;  /*  Discart rest of exponent.  */
        }
-      bin_exponent += esign * exponent;  /*  2**bin_exponent.  */
-      while (IS_DEC_DIGIT(*s))
-        s++;  /*  Discart rest of exponent.  */
      }


      if (sret)
        *sret = unconst(s, char *);
@@ -285,29 +309,49 @@ strtod(const char *s, char **sret)
      }
    }
    if (flags == 0)
    {
      if (sret)
+    {
+      if (!r)
+        s--;  /*  A dot without leading numbers.  */
        *sret = unconst(s, char *);
+    }
+    errno = EINVAL;  /*  No valid mantissa, no convertion could be 
performed.  */
      return 0.0;
    }

    if ((*s == 'e') || (*s == 'E'))
    {
      s++;
      if (*s == '+')
+    {
+      esign = +1;
        s++;
+    }
      else if (*s == '-')
      {
-      s++;
        esign = -1;
+      s++;
      }
-    while (IS_DEC_DIGIT(*s))
+
+    if (!*s)
      {
-      e *= 10;
-      e += *s - '0';
-      s++;
+      /*  Mantissa followed by [eE] with/out
+          a sign but without exponent.  */
+      s--;
+      if (esign)
+        s--;
+    }
+    else
+    {
+      while (IS_DEC_DIGIT(*s))
+      {
+        e *= 10;
+        e += *s - '0';
+        s++;
+      }
      }
    }

    /* Detect overflow.  */
    if (e < 0)
@@ -346,7 +390,8 @@ strtod(const char *s, char **sret)
      }
    }

    if (sret)
      *sret = unconst(s, char *);
+
    return r * sign;
  }
Index: djgpp/src/libc/ansi/stdlib/strtold.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdlib/strtold.c,v
retrieving revision 1.12
diff -p -U 5 -r1.12 strtold.c
--- djgpp/src/libc/ansi/stdlib/strtold.c    19 Jun 2013 19:38:05 -0000   
  1.12
+++ djgpp/src/libc/ansi/stdlib/strtold.c    22 Jun 2013 15:30:28 -0000
@@ -35,19 +35,26 @@ long double
  strtold(const char *s, char **sret)
  {
    long double r = 0.0L;         /* result */
    int e = 0, ne = 0;            /* exponent */
    int sign = 1;                 /* +- 1.0 */
-  int esign = 1;
+  int esign = 0;                /* 0: no valid exponent after [eEpP] */
    int flags = 0;
    int l2powm1;
    char decimal_point = localeconv()->decimal_point[0];


+  if (sret)
+    *sret = unconst(s, char *);
+
    while(*s && isspace((unsigned char)*s))
      s++;

+  if (!*s)
+    return 0.0;
+
+  /* Handle leading sign. */
    if (*s == '+')
      s++;
    else if (*s == '-')
    {
      sign = -1;
@@ -63,11 +70,11 @@ strtold(const char *s, char **sret)
          *sret = unconst((&s[8]), char *);
        else
          *sret = unconst((&s[3]), char *);
      }

-    return (0 > sign) ? -INFINITY : INFINITY;
+    return (sign < 0) ? -INFINITY : INFINITY;
    }

    /* Handle NAN and NAN(<whatever>). */
    if (!strnicmp("NAN", s, 3))
    {
@@ -185,14 +192,18 @@ strtold(const char *s, char **sret)
          for (bit <<= (digits * HEX_DIGIT_SIZE + bin_exponent); 
!(mantissa & bit); bin_exponent--)
            bit >>= 1;
        }
      }

-    if (!flags)
+    if (flags == 0)
      {
        if (sret)
+      {
+        if (!r)
+          s--;  /*  A dot without leading numbers.  */
          *sret = unconst(s, char *);
+      }
        errno = EINVAL;  /*  No valid mantissa, no convertion could be 
performed.  */
        return 0.0L;
      }

      if (mantissa)
@@ -243,26 +254,40 @@ strtold(const char *s, char **sret)
      if (IS_EXPONENT(s))
      {
        long long int exponent = 0.0L;
        s++;
        if (*s == '+')
+      {
+        esign = +1;
          s++;
+      }
        else if (*s == '-')
        {
          esign = -1;
          s++;
        }

-      while ((esign * exponent + bin_exponent) < (MAX_BIN_EXPONENT + 1) 
&& IS_DEC_DIGIT(*s))
+      if (!*s)
        {
-        exponent *= 10;
-        exponent += *s - '0';
-        s++;
+        /*  Mantissa followed by [pP] with/out
+            a sign but without exponent.  */
+        s--;
+        if (esign)
+          s--;
+      }
+      else
+      {
+        while ((esign * exponent + bin_exponent) < (MAX_BIN_EXPONENT + 
1) && IS_DEC_DIGIT(*s))
+        {
+          exponent *= 10;
+          exponent += *s - '0';
+          s++;
+        }
+        bin_exponent += esign * exponent;  /*  2**bin_exponent.  */
+        while (IS_DEC_DIGIT(*s))
+         s++;  /*  Discart rest of exponent.  */
        }
-      bin_exponent += esign * exponent;  /*  2**bin_exponent.  */
-      while (IS_DEC_DIGIT(*s))
-        s++;  /*  Discart rest of exponent.  */
      }

      if (sret)
        *sret = unconst(s, char *);
      if (mantissa)
@@ -310,30 +335,49 @@ strtold(const char *s, char **sret)
      }
    }
    if (flags == 0)
    {
      if (sret)
+    {
+      if (!r)
+        s--;  /*  A dot without leading numbers.  */
        *sret = unconst(s, char *);
+    }
      errno = EINVAL;  /*  No valid mantissa, no convertion could be 
performed.  */
      return 0.0L;
    }

    if ((*s == 'e') || (*s == 'E'))
    {
      s++;
      if (*s == '+')
+    {
+      esign = +1;
        s++;
+    }
      else if (*s == '-')
      {
-      s++;
        esign = -1;
+      s++;
      }
-    while (IS_DEC_DIGIT(*s))
+
+    if (!*s)
      {
-      e *= 10;
-      e += *s - '0';
-      s++;
+      /*  Mantissa followed by [eE] with/out
+          a sign but without exponent.  */
+      s--;
+      if (esign)
+        s--;
+    }
+    else
+    {
+      while (IS_DEC_DIGIT(*s))
+      {
+        e *= 10;
+        e += *s - '0';
+        s++;
+      }
      }
    }
    if (esign < 0)
    {
      esign = -esign;
@@ -367,9 +411,11 @@ strtold(const char *s, char **sret)
      if (esign > 0)
        r *= d;
      else
        r /= d;
    }
+
    if (sret)
      *sret = unconst(s, char *);
+
    return r * sign;
  }
Index: djgpp/src/libc/c99/stdlib/strtof.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/c99/stdlib/strtof.c,v
retrieving revision 1.10
diff -p -U 5 -r1.10 strtof.c
--- djgpp/src/libc/c99/stdlib/strtof.c    19 Jun 2013 19:38:03 -0000    1.10
+++ djgpp/src/libc/c99/stdlib/strtof.c    22 Jun 2013 15:30:28 -0000
@@ -35,20 +35,27 @@ strtof(const char *s, char **sret)
  {
    long double r = 0;            /* result */
    int e = 0;                    /* exponent */
    long double d;                /* scale */
    int sign = 1;                 /* +- 1.0 */
-  int esign = 1;
+  int esign = 0;                /* 0: no valid exponent after [eEpP] */
    int i;
    int flags = 0;
    int overflow = 0;
    char decimal_point = localeconv()->decimal_point[0];


+  if (sret)
+    *sret = unconst(s, char *);
+
    while (isspace((unsigned char) *s))
      s++;

+  if (!*s)
+    return 0.0;
+
+  /* Handle leading sign. */
    if (*s == '+')
      s++;
    else if (*s == '-')
    {
      sign = -1;
@@ -64,11 +71,11 @@ strtof(const char *s, char **sret)
          *sret = unconst((&s[8]), char *);
        else
          *sret = unconst((&s[3]), char *);
      }

-    return (0 > sign) ? -INFINITY : INFINITY;
+    return (sign < 0) ? -INFINITY : INFINITY;
    }

    /* Handle NAN and NAN(<hex-number>). */
    if (!strnicmp("NAN", s, 3))
    {
@@ -179,14 +186,18 @@ strtof(const char *s, char **sret)
          for (bit <<= (digits * HEX_DIGIT_SIZE + bin_exponent); 
!(mantissa & bit); bin_exponent--)
            bit >>= 1;
        }
      }

-    if (!flags)
+    if (flags == 0)
      {
        if (sret)
+      {
+        if (!r)
+          s--;  /*  A dot without leading numbers.  */
          *sret = unconst(s, char *);
+      }
        errno = EINVAL;  /*  No valid mantissa, no convertion could be 
performed.  */
        return 0.0;
      }

      if (mantissa)
@@ -217,26 +228,40 @@ strtof(const char *s, char **sret)
      if (IS_EXPONENT(s))
      {
        int exponent = 0.0;
        s++;
        if (*s == '+')
+      {
+        esign = +1;
          s++;
+      }
        else if (*s == '-')
        {
          esign = -1;
          s++;
        }

-      while ((esign * exponent + bin_exponent) < (MAX_BIN_EXPONENT + 1) 
&& IS_DEC_DIGIT(*s))
+      if (!*s)
        {
-        exponent *= 10;
-        exponent += *s - '0';
-        s++;
+        /*  Mantissa followed by [pP] with/out
+            a sign but without exponent.  */
+        s--;
+        if (esign)
+          s--;
+      }
+      else
+      {
+        while ((esign * exponent + bin_exponent) < (MAX_BIN_EXPONENT + 
1) && IS_DEC_DIGIT(*s))
+        {
+          exponent *= 10;
+          exponent += *s - '0';
+          s++;
+        }
+        bin_exponent += esign * exponent;  /*  2**bin_exponent.  */
+        while (IS_DEC_DIGIT(*s))
+          s++;  /*  Discart rest of exponent.  */
        }
-      bin_exponent += esign * exponent;  /*  2**bin_exponent.  */
-      while (IS_DEC_DIGIT(*s))
-        s++;  /*  Discart rest of exponent.  */
      }


      if (sret)
        *sret = unconst(s, char *);
@@ -284,29 +309,49 @@ strtof(const char *s, char **sret)
      }
    }
    if (flags == 0)
    {
      if (sret)
+    {
+      if (!r)
+        s--;  /*  A dot without leading numbers.  */
        *sret = unconst(s, char *);
+    }
+    errno = EINVAL;  /*  No valid mantissa, no convertion could be 
performed.  */
      return 0.0;
    }

    if ((*s == 'e') || (*s == 'E'))
    {
      s++;
      if (*s == '+')
+    {
+      esign = +1;
        s++;
+    }
      else if (*s == '-')
      {
-      s++;
        esign = -1;
+      s++;
      }
-    while (IS_DEC_DIGIT(*s))
+
+    if (!*s)
      {
-      e *= 10;
-      e += *s - '0';
-      s++;
+      /*  Mantissa followed by [eE] with/out
+          a sign but without exponent.  */
+      s--;
+      if (esign)
+        s--;
+    }
+    else
+    {
+      while (IS_DEC_DIGIT(*s))
+      {
+        e *= 10;
+        e += *s - '0';
+        s++;
+      }
      }
    }

    /* Detect overflow.  */
    if (e < 0)

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019