autoupdate
[pspp] / lib / strtod.c
index 61887598cab0543097841b015906ffe526747013..94eb8175e7bbea86db0cc70b110245ae8efacd3c 100644 (file)
@@ -45,7 +45,12 @@ locale_isspace (char c)
 
 #if !HAVE_LDEXP_IN_LIBC
  #define ldexp dummy_ldexp
- static double ldexp (double x, int exponent) { return x + exponent; }
+ /* A dummy definition that will never be invoked.  */
+ static double ldexp (double x _GL_UNUSED, int exponent _GL_UNUSED)
+ {
+   abort ();
+   return 0.0;
+ }
 #endif
 
 /* Return X * BASE**EXPONENT.  Return an extreme value and set errno
@@ -210,10 +215,25 @@ strtod (const char *nptr, char **endptr)
 
   if (c_isdigit (s[*s == '.']))
     {
-      /* If a hex float was converted incorrectly, do it ourselves.  */
-      if (*s == '0' && c_tolower (s[1]) == 'x' && end <= s + 2
-          && c_isxdigit (s[2 + (s[2] == '.')]))
-        num = parse_number (s + 2, 16, 2, 4, 'p', &end);
+      /* If a hex float was converted incorrectly, do it ourselves.
+         If the string starts with "0x" but does not contain digits,
+         consume the "0" ourselves.  If a hex float is followed by a
+         'p' but no exponent, then adjust the end pointer.  */
+      if (*s == '0' && c_tolower (s[1]) == 'x')
+        {
+          if (! c_isxdigit (s[2 + (s[2] == '.')]))
+            end = s + 1;
+          else if (end <= s + 2)
+            num = parse_number (s + 2, 16, 2, 4, 'p', &end);
+          else
+            {
+              const char *p = s + 2;
+              while (p < end && c_tolower (*p) != 'p')
+                p++;
+              if (p < end && ! c_isdigit (p[1 + (p[1] == '-' || p[1] == '+')]))
+                end = p;
+            }
+        }
 
       s = end;
     }