]> sjero.net Git - wget/blobdiff - src/cmpt.c
[svn] Renamed strtoll_return to strtoll_type.
[wget] / src / cmpt.c
index 63305398a2d3925f7120409c5d6464eeeced0ce0..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,30 +1223,31 @@ 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. */
 
-/* Inverse of gmtime: converts struct tm to time_t, assuming the data
-   in tm is UTC rather than local timezone.  This implementation
-   returns the number of seconds since 1970-01-01, converted to
-   time_t.  */
-
-#define IS_LEAP(year)                                          \
+/* True if YEAR is a leap year. */
+#define ISLEAP(year)                                           \
   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
 
 /* Number of leap years in the range [y1, y2). */
-#define LEAPDAYS(y1, y2)                                               \
+#define LEAPYEARS(y1, y2)                                              \
   ((y2-1)/4 - (y1-1)/4) - ((y2-1)/100 - (y1-1)/100) + ((y2-1)/400 - (y1-1)/400)
 
+/* Inverse of gmtime: converts struct tm to time_t, assuming the data
+   in tm is UTC rather than local timezone.  This implementation
+   returns the number of seconds elapsed since midnight 1970-01-01,
+   converted to time_t.  */
+
 time_t
 timegm (struct tm *t)
 {
   static const unsigned short int month_to_days[][13] = {
-    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
-    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, /* normal */
+    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }  /* leap */
   };
   const int year = 1900 + t->tm_year;
-  unsigned long secs;
+  unsigned long secs;  /* until 2106-02-07 for 32-bit unsigned long */
   int days;
 
   if (year < 1970)
@@ -1254,13 +1256,138 @@ timegm (struct tm *t)
   days = 365 * (year - 1970);
   /* Take into account leap years between 1970 and YEAR, not counting
      YEAR itself.  */
-  days += LEAPDAYS (1970, year);
+  days += LEAPYEARS (1970, year);
   if (t->tm_mon < 0 || t->tm_mon >= 12)
     return (time_t) -1;
-  days += month_to_days[IS_LEAP (year)][t->tm_mon];
+  days += month_to_days[ISLEAP (year)][t->tm_mon];
   days += t->tm_mday - 1;
 
   secs = days * 86400 + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec;
   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 */