]> sjero.net Git - wget/blobdiff - src/cmpt.c
[svn] Renamed strtoll_return to strtoll_type.
[wget] / src / cmpt.c
index 23d7dec9c6bf422288b7e4f7f57d232e0a1f522f..37b3e7b4b6c549d8eecd9c47af590c774589021a 100644 (file)
@@ -1133,7 +1133,8 @@ fnmatch (const char *pattern, const char *string, int flags)
            {
              register const char *np;
 
-             for (np = p; np && *np && *np != ']'; np++);
+             for (np = p; np && *np && *np != ']'; np++)
+               ;
 
              if (np && !*np)
                {
@@ -1222,8 +1223,8 @@ fnmatch (const char *pattern, const char *string, int flags)
 #endif /* not SYSTEM_FNMATCH */
 \f
 #ifndef HAVE_TIMEGM
-/* timegm is a GNU extension, but lately also available on *BSD and
-   possibly elsewhere. */
+/* timegm is a GNU extension, but lately also available on *BSD
+   systems and possibly elsewhere. */
 
 /* True if YEAR is a leap year. */
 #define ISLEAP(year)                                           \
@@ -1265,3 +1266,128 @@ timegm (struct tm *t)
   return (time_t) secs;
 }
 #endif /* HAVE_TIMEGM */
+
+#ifdef NEED_STRTOLL
+/* strtoll is required by C99 and used by Wget only on systems with
+   LFS.  Unfortunately, some systems have LFS, but no strtoll or
+   equivalent.  These include HPUX 11.0 and Windows.
+
+   We use #ifdef NEED_STRTOLL instead of #ifndef HAVE_STRTOLL because
+   of the systems which have a suitable replacement (e.g. _strtoi64 on
+   Windows), on which Wget's str_to_wgint is instructed to use that
+   instead.  */
+
+static inline int
+char_value (char c, int base)
+{
+  int value;
+  if (c < '0')
+    return -1;
+  if ('0' <= c && c <= '9')
+    value = c - '0';
+  else if ('a' <= c && c <= 'z')
+    value = c - 'a' + 10;
+  else if ('A' <= c && c <= 'Z')
+    value = c - 'A' + 10;
+  else
+    return -1;
+  if (value >= base)
+    return -1;
+  return value;
+}
+
+#define LL strtoll_type                /* long long or __int64 */
+
+/* These constants assume 64-bit strtoll_type. */
+
+/* A roundabout way of writing 2**63-1 = 9223372036854775807 */
+#define STRTOLL_OVERFLOW (((LL) 1 << 62) - 1 + ((LL) 1 << 62))
+/* A roundabout way of writing -2**63 = -9223372036854775808 */
+#define STRTOLL_UNDERFLOW (-STRTOLL_OVERFLOW - 1)
+
+/* A strtoll replacement for systems that have LFS but don't supply
+   strtoll.  The headers typedef strtoll_type to long long or to
+   __int64.  */
+
+strtoll_type
+strtoll (const char *nptr, char **endptr, int base)
+{
+  strtoll_type result = 0;
+  bool negative;
+
+  if (base != 0 && (base < 2 || base > 36))
+    {
+      errno = EINVAL;
+      return 0;
+    }
+
+  while (*nptr == ' ' || *nptr == '\t')
+    ++nptr;
+  if (*nptr == '-')
+    {
+      negative = true;
+      ++nptr;
+    }
+  else if (*nptr == '+')
+    {
+      negative = false;
+      ++nptr;
+    }
+  else
+    negative = false;
+
+  /* If base is 0, determine the real base based on the beginning on
+     the number; octal numbers begin with "0", hexadecimal with "0x",
+     and the others are considered octal.  */
+  if (*nptr == '0')
+    {
+      if ((base == 0 || base == 16)
+         &&
+         (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
+       {
+         base = 16;
+         nptr += 2;
+       }
+      else if (base == 0)
+       base = 8;
+    }
+  else if (base == 0)
+    base = 10;
+
+  if (!negative)
+    {
+      /* Parse positive number, checking for overflow. */
+      int val;
+      for (; (val = char_value (*nptr, base)) != -1; ++nptr)
+       {
+         strtoll_type newresult = base * result + val;
+         if (newresult < result)
+           {
+             result = STRTOLL_OVERFLOW;
+             errno = ERANGE;
+             break;
+           }
+         result = newresult;
+       }
+    }
+  else
+    {
+      /* Parse negative number, checking for underflow. */
+      int val;
+      for (; (val = char_value (*nptr, base)) != -1; ++nptr)
+       {
+         strtoll_type newresult = base * result - val;
+         if (newresult > result)
+           {
+             result = STRTOLL_UNDERFLOW;
+             errno = ERANGE;
+             break;
+           }
+         result = newresult;
+       }
+    }
+  if (endptr)
+    *endptr = (char *) nptr;
+  return result;
+}
+#endif /* NEED_STRTOLL */