1 /* Replacements for routines missing on some systems.
2 Copyright (C) 1995-2005 Free Software Foundation, Inc.
4 This file is part of GNU Wget.
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables. You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL". If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so. If you do not wish to do
28 so, delete this exception statement from your version. */
44 /* Some systems lack certain functions normally taken for granted.
45 For example, Windows doesn't have strptime, and some systems lack
46 strcasecmp and strncasecmp. This file should contain fallback
47 implementations of the missing functions. It should *not* define
48 new Wget-specific functions -- those should placed in utils.c or
51 /* strcasecmp and strncasecmp apparently originated with BSD 4.4.
52 SUSv3 seems to be the only standard out there (that I can find)
53 that requires their existence, so there are systems that lack them
54 still in use. Note that these don't get defined under Windows
55 because mswindows.h defines them to the equivalent Windows
56 functions stricmp and strnicmp. */
58 #ifndef HAVE_STRCASECMP
60 /* Compare S1 and S2, ignoring case, returning less than, equal to or
61 greater than zero if S1 is lexiographically less than,
62 equal to or greater than S2. */
64 strcasecmp (const char *s1, const char *s2)
66 register const unsigned char *p1 = (const unsigned char *) s1;
67 register const unsigned char *p2 = (const unsigned char *) s2;
84 #endif /* not HAVE_STRCASECMP */
86 #ifndef HAVE_STRNCASECMP
88 /* Compare no more than N characters of S1 and S2,
89 ignoring case, returning less than, equal to or
90 greater than zero if S1 is lexicographically less
91 than, equal to or greater than S2. */
93 strncasecmp (const char *s1, const char *s2, size_t n)
95 register const unsigned char *p1 = (const unsigned char *) s1;
96 register const unsigned char *p2 = (const unsigned char *) s2;
99 if (p1 == p2 || n == 0)
104 c1 = TOLOWER (*p1++);
105 c2 = TOLOWER (*p2++);
106 if (c1 == '\0' || c1 != c2)
112 #endif /* not HAVE_STRNCASECMP */
114 /* strpbrk is a BSD 4.3 function mandated by POSIX and C99 and present
115 on Windows. It might be missing from older Unixes of non-BSD
116 ancestry or possibly from non-Unix systems Wget gets ported to, so
120 /* Find the first ocurrence in S of any character in ACCEPT. */
122 strpbrk (const char *s, const char *accept)
126 const char *a = accept;
135 #endif /* HAVE_STRPBRK */
137 /* mktime is a BSD 4.3 function also required by POSIX and C99. I
138 don't know if there is a widely used system that lacks it, so it
139 might be a candidate for removal. */
142 /* From GNU libc 2.0. */
144 /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
145 This file is part of the GNU C Library.
146 Contributed by Paul Eggert (eggert@twinsun.com). */
149 # define HAVE_LIMITS_H 1
150 # define HAVE_LOCALTIME_R 1
151 # define STDC_HEADERS 1
154 /* Assume that leap seconds are possible, unless told otherwise.
155 If the host has a `zic' command with a `-L leapsecondfilename' option,
156 then it supports leap seconds; otherwise it probably doesn't. */
157 #ifndef LEAP_SECONDS_POSSIBLE
158 # define LEAP_SECONDS_POSSIBLE 1
162 # define __P(args) args
163 #endif /* Not __P. */
170 # define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
173 # define INT_MAX (~0 - INT_MIN)
177 /* The outer cast to time_t works around a bug in Cray C 5.0.3.0. */
178 # define TIME_T_MIN ((time_t) \
179 (0 < (time_t) -1 ? (time_t) 0 \
180 : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
183 # define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
186 #define TM_YEAR_BASE 1900
187 #define EPOCH_YEAR 1970
190 /* Nonzero if YEAR is a leap year (every 4 years,
191 except every 100th isn't, and every 400th is). */
192 # define __isleap(year) \
193 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
196 /* How many days come before each month (0-12). */
197 /* __mon_yday[][] is common to mktime and strptime implementations.
199 const unsigned short int __mon_yday[2][13];
200 #ifndef NEED_MON_YDAY
201 # define NEED_MON_YDAY
204 static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
205 time_t __mktime_internal __P ((struct tm *,
206 struct tm *(*) (const time_t *, struct tm *),
211 # define localtime_r __localtime_r
213 # if ! HAVE_LOCALTIME_R && ! defined localtime_r
214 /* Approximate localtime_r as best we can in its absence. */
215 # define localtime_r my_mktime_localtime_r
216 static struct tm *localtime_r __P ((const time_t *, struct tm *));
222 struct tm *l = localtime (t);
228 # endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
232 /* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
233 measured in seconds, ignoring leap seconds.
234 YEAR uses the same numbering as TM->tm_year.
235 All values are in range, except possibly YEAR.
236 If overflow occurs, yield the low order bits of the correct answer. */
238 ydhms_tm_diff (year, yday, hour, min, sec, tp)
239 int year, yday, hour, min, sec;
242 /* Compute intervening leap days correctly even if year is negative.
243 Take care to avoid int overflow. time_t overflow is OK, since
244 only the low order bits of the correct time_t answer are needed.
245 Don't convert to time_t until after all divisions are done, since
246 time_t might be unsigned. */
247 int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
248 int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
249 int a100 = a4 / 25 - (a4 % 25 < 0);
250 int b100 = b4 / 25 - (b4 % 25 < 0);
251 int a400 = a100 >> 2;
252 int b400 = b100 >> 2;
253 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
254 time_t years = year - (time_t) tp->tm_year;
255 time_t days = (365 * years + intervening_leap_days
256 + (yday - tp->tm_yday));
257 return (60 * (60 * (24 * days + (hour - tp->tm_hour))
258 + (min - tp->tm_min))
259 + (sec - tp->tm_sec));
263 static time_t localtime_offset;
265 /* Convert *TP to a time_t value. */
271 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
272 time zone names contained in the external variable `tzname' shall
273 be set as if the tzset() function had been called. */
277 return __mktime_internal (tp, localtime_r, &localtime_offset);
280 /* Convert *TP to a time_t value, inverting
281 the monotonic and mostly-unit-linear conversion function CONVERT.
282 Use *OFFSET to keep track of a guess at the offset of the result,
283 compared to what the result would be for UTC without leap seconds.
284 If *OFFSET's guess is correct, only one CONVERT call is needed. */
286 __mktime_internal (tp, convert, offset)
288 struct tm *(*convert) __P ((const time_t *, struct tm *));
294 /* The maximum number of probes (calls to CONVERT) should be enough
295 to handle any combinations of time zone rule changes, solar time,
296 and leap seconds. Posix.1 prohibits leap seconds, but some hosts
298 int remaining_probes = 4;
300 /* Time requested. Copy it in case CONVERT modifies *TP; this can
301 occur if TP is localtime's returned value and CONVERT is localtime. */
302 int sec = tp->tm_sec;
303 int min = tp->tm_min;
304 int hour = tp->tm_hour;
305 int mday = tp->tm_mday;
306 int mon = tp->tm_mon;
307 int year_requested = tp->tm_year;
308 int isdst = tp->tm_isdst;
310 /* Ensure that mon is in range, and set year accordingly. */
311 int mon_remainder = mon % 12;
312 int negative_mon_remainder = mon_remainder < 0;
313 int mon_years = mon / 12 - negative_mon_remainder;
314 int year = year_requested + mon_years;
316 /* The other values need not be in range:
317 the remaining code handles minor overflows correctly,
318 assuming int and time_t arithmetic wraps around.
319 Major overflows are caught at the end. */
321 /* Calculate day of year from year, month, and day of month.
322 The result need not be in range. */
323 int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
324 [mon_remainder + 12 * negative_mon_remainder])
327 int sec_requested = sec;
328 #if LEAP_SECONDS_POSSIBLE
329 /* Handle out-of-range seconds specially,
330 since ydhms_tm_diff assumes every minute has 60 seconds. */
337 /* Invert CONVERT by probing. First assume the same offset as last time.
338 Then repeatedly use the error to improve the guess. */
340 tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
341 tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
342 t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
344 for (t = t0 + *offset;
345 (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
347 if (--remaining_probes == 0)
350 /* Check whether tm.tm_isdst has the requested value, if any. */
351 if (0 <= isdst && 0 <= tm.tm_isdst)
353 int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
356 /* Move two hours in the direction indicated by the disagreement,
357 probe some more, and switch to a new time if found.
358 The largest known fallback due to daylight savings is two hours:
359 once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
360 time_t ot = t - 2 * 60 * 60 * dst_diff;
361 while (--remaining_probes != 0)
364 if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
365 (*convert) (&ot, &otm))))
372 break; /* Avoid a redundant probe. */
379 #if LEAP_SECONDS_POSSIBLE
380 if (sec_requested != tm.tm_sec)
382 /* Adjust time to reflect the tm_sec requested, not the normalized value.
383 Also, repair any damage from a false match due to a leap second. */
384 t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
385 (*convert) (&t, &tm);
389 if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
391 /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
392 so check for major overflows. A gross check suffices,
393 since if t has overflowed, it is off by a multiple of
394 TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
395 the difference that is bounded by a small value. */
397 double dyear = (double) year_requested + mon_years - tm.tm_year;
398 double dday = 366 * dyear + mday;
399 double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
401 if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
410 weak_alias (mktime, timelocal)
412 #endif /* not HAVE_MKTIME */
414 /* strptime is required by POSIX, but it is missing from Windows,
415 which means we must keep a fallback implementation. It is
416 reportedly missing or broken on many older systems as well. */
418 #ifndef HAVE_STRPTIME
419 /* From GNU libc 2.1.3. */
420 /* Ulrich, thanks for helping me out with this! --hniksic */
422 /* strptime - Convert a string representation of time to a time value.
423 Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
424 This file is part of the GNU C Library.
425 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. */
427 /* XXX This version of the implementation is not really complete.
428 Some of the fields cannot add information alone. But if seeing
429 some of them in the same format (such as year, week and weekday)
430 this is enough information for determining the date. */
433 # define __P(args) args
436 #if ! HAVE_LOCALTIME_R && ! defined localtime_r
438 # define localtime_r __localtime_r
440 /* Approximate localtime_r as best we can in its absence. */
441 # define localtime_r my_localtime_r
442 static struct tm *localtime_r __P ((const time_t *, struct tm *));
448 struct tm *l = localtime (t);
454 # endif /* ! _LIBC */
455 #endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
458 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL
459 #if defined __GNUC__ && __GNUC__ >= 2
460 # define match_string(cs1, s2) \
461 ({ size_t len = strlen (cs1); \
462 int result = strncasecmp ((cs1), (s2), len) == 0; \
463 if (result) (s2) += len; \
466 /* Oh come on. Get a reasonable compiler. */
467 # define match_string(cs1, s2) \
468 (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
470 /* We intentionally do not use isdigit() for testing because this will
471 lead to problems with the wide character version. */
472 #define get_number(from, to, n) \
478 if (*rp < '0' || *rp > '9') \
482 val += *rp++ - '0'; \
483 } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \
484 if (val < from || val > to) \
488 /* Added check for __GNUC__ extensions here for Wget. --abbotti */
489 # if defined __GNUC__ && __GNUC__ >= 2
490 # define get_alt_number(from, to, n) \
492 __label__ do_normal; \
493 if (*decided != raw) \
495 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
503 while (*alts != '\0') \
505 size_t len = strlen (alts); \
506 if (strncasecmp (alts, rp, len) == 0) \
513 if (*decided == not && ! any) \
515 /* If we haven't read anything it's an error. */ \
518 /* Correct the premature multiplication. */ \
524 } while (--__n > 0 && val * 10 <= to); \
525 if (val < from || val > to) \
531 get_number (from, to, n); \
536 # define get_alt_number(from, to, n) \
538 if (*decided != raw) \
540 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
548 while (*alts != '\0') \
550 size_t len = strlen (alts); \
551 if (strncasecmp (alts, rp, len) == 0) \
558 if (*decided == not && ! any) \
560 /* If we haven't read anything it's an error. */ \
563 /* Correct the premature multiplication. */ \
569 } while (--__n > 0 && val * 10 <= to); \
570 if (val < from || val > to) \
576 get_number (from, to, n); \
579 # endif /* defined __GNUC__ && __GNUC__ >= 2 */
581 # define get_alt_number(from, to, n) \
582 /* We don't have the alternate representation. */ \
583 get_number(from, to, n)
585 #define recursive(new_fmt) \
586 (*(new_fmt) != '\0' \
587 && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
591 /* This is defined in locale/C-time.c in the GNU libc. */
592 extern const struct locale_data _nl_C_LC_TIME;
593 extern const unsigned short int __mon_yday[2][13];
595 # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
596 # define ab_weekday_name \
597 (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
598 # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
599 # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
600 # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
601 # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
602 # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
603 # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
604 # define HERE_T_FMT_AMPM \
605 (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
606 # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
608 # define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
610 static char const weekday_name[][10] =
612 "Sunday", "Monday", "Tuesday", "Wednesday",
613 "Thursday", "Friday", "Saturday"
615 static char const ab_weekday_name[][4] =
617 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
619 static char const month_name[][10] =
621 "January", "February", "March", "April", "May", "June",
622 "July", "August", "September", "October", "November", "December"
624 static char const ab_month_name[][4] =
626 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
627 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
629 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
630 # define HERE_D_FMT "%m/%d/%y"
631 # define HERE_AM_STR "AM"
632 # define HERE_PM_STR "PM"
633 # define HERE_T_FMT_AMPM "%I:%M:%S %p"
634 # define HERE_T_FMT "%H:%M:%S"
636 /* __mon_yday[][] is common to mktime and strptime implementations.
638 const unsigned short int __mon_yday[2][13];
639 # ifndef NEED_MON_YDAY
640 # define NEED_MON_YDAY
644 /* Status of lookup: do we use the locale data or the raw data? */
645 enum locale_status { not, loc, raw };
649 /* Nonzero if YEAR is a leap year (every 4 years,
650 except every 100th isn't, and every 400th is). */
651 # define __isleap(year) \
652 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
655 /* Compute the day of the week. */
657 day_of_the_week (struct tm *tm)
659 /* We know that January 1st 1970 was a Thursday (= 4). Compute the
660 the difference between this data in the one on TM and so determine
662 int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
664 + (365 * (tm->tm_year - 70))
666 - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
667 + (((corr_year / 4) / 25) / 4)
668 + __mon_yday[0][tm->tm_mon]
670 tm->tm_wday = ((wday % 7) + 7) % 7;
673 /* Compute the day of the year. */
675 day_of_the_year (struct tm *tm)
677 tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
678 + (tm->tm_mday - 1));
685 strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
686 enum locale_status *decided));
692 strptime_internal (rp, fmt, tm, decided)
696 enum locale_status *decided;
699 const char *rp_backup;
704 int century, want_century;
705 int have_wday, want_xday;
707 int have_mon, have_mday;
712 have_wday = want_xday = have_yday = have_mon = have_mday = 0;
716 /* A white space in the format string matches 0 more or white
717 space in the input string. */
720 while (ISSPACE (*rp))
726 /* Any character but `%' must be matched by the same character
727 in the iput string. */
730 match_char (*fmt++, *rp++);
736 /* We need this for handling the `E' modifier. */
741 /* Make back up of current processing pointer. */
748 /* Match the `%' character itself. */
749 match_char ('%', *rp++);
753 /* Match day of week. */
754 for (cnt = 0; cnt < 7; ++cnt)
759 if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
762 && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
767 if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
770 && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
771 ab_weekday_name[cnt]))
778 && (match_string (weekday_name[cnt], rp)
779 || match_string (ab_weekday_name[cnt], rp)))
786 /* Does not match a weekday name. */
794 /* Match month name. */
795 for (cnt = 0; cnt < 12; ++cnt)
800 if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
803 && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
808 if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
811 && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
818 if (match_string (month_name[cnt], rp)
819 || match_string (ab_month_name[cnt], rp))
826 /* Does not match a month name. */
832 /* Match locale's date and time format. */
836 if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
845 if (*decided == not &&
846 strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
854 if (!recursive (HERE_D_T_FMT))
859 /* Match century number. */
860 get_number (0, 99, 2);
866 /* Match day of month. */
867 get_number (1, 31, 2);
873 if (!recursive ("%Y-%m-%d"))
881 if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
891 && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
901 /* Match standard day format. */
902 if (!recursive (HERE_D_FMT))
908 /* Match hour in 24-hour clock. */
909 get_number (0, 23, 2);
914 /* Match hour in 12-hour clock. */
915 get_number (1, 12, 2);
916 tm->tm_hour = val % 12;
920 /* Match day number of year. */
921 get_number (1, 366, 3);
922 tm->tm_yday = val - 1;
926 /* Match number of month. */
927 get_number (1, 12, 2);
928 tm->tm_mon = val - 1;
934 get_number (0, 59, 2);
939 /* Match any white space. */
940 while (ISSPACE (*rp))
944 /* Match locale's equivalent of AM/PM. */
948 if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
950 if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
954 if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
956 if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
964 if (!match_string (HERE_AM_STR, rp))
965 if (match_string (HERE_PM_STR, rp))
974 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
983 if (*decided == not &&
984 strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
992 if (!recursive (HERE_T_FMT_AMPM))
996 if (!recursive ("%H:%M"))
1001 /* The number of seconds may be very high so we cannot use
1002 the `get_number' macro. Instead read the number
1003 character for character and construct the result while
1006 if (*rp < '0' || *rp > '9')
1007 /* We need at least one digit. */
1013 secs += *rp++ - '0';
1015 while (*rp >= '0' && *rp <= '9');
1017 if (localtime_r (&secs, tm) == NULL)
1018 /* Error in function. */
1023 get_number (0, 61, 2);
1028 if (*decided != raw)
1030 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
1032 if (*decided == loc)
1039 if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
1048 if (!recursive (HERE_T_FMT))
1052 get_number (1, 7, 1);
1053 tm->tm_wday = val % 7;
1057 get_number (0, 99, 2);
1058 /* XXX This cannot determine any field in TM. */
1061 if (*rp < '0' || *rp > '9')
1063 /* XXX Ignore the number since we would need some more
1064 information to compute a real date. */
1067 while (*rp >= '0' && *rp <= '9');
1072 get_number (0, 53, 2);
1073 /* XXX This cannot determine any field in TM without some
1077 /* Match number of weekday. */
1078 get_number (0, 6, 1);
1083 /* Match year within century. */
1084 get_number (0, 99, 2);
1085 /* The "Year 2000: The Millennium Rollover" paper suggests that
1086 values in the range 69-99 refer to the twentieth century. */
1087 tm->tm_year = val >= 69 ? val : val + 100;
1088 /* Indicate that we want to use the century, if specified. */
1093 /* Match year including century number. */
1094 get_number (0, 9999, 4);
1095 tm->tm_year = val - 1900;
1100 /* XXX How to handle this? */
1107 /* Match locale's alternate date and time format. */
1108 if (*decided != raw)
1110 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
1113 fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
1115 if (!recursive (fmt))
1117 if (*decided == loc)
1124 if (strcmp (fmt, HERE_D_T_FMT))
1131 /* The C locale has no era information, so use the
1132 normal representation. */
1133 if (!recursive (HERE_D_T_FMT))
1140 /* Match name of base year in locale's alternate
1142 /* XXX This is currently not implemented. It should
1143 use the value _NL_CURRENT (LC_TIME, ERA). */
1146 if (*decided != raw)
1148 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
1151 fmt = _NL_CURRENT (LC_TIME, D_FMT);
1153 if (!recursive (fmt))
1155 if (*decided == loc)
1162 if (strcmp (fmt, HERE_D_FMT))
1168 if (!recursive (HERE_D_FMT))
1172 if (*decided != raw)
1174 const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
1177 fmt = _NL_CURRENT (LC_TIME, T_FMT);
1179 if (!recursive (fmt))
1181 if (*decided == loc)
1188 if (strcmp (fmt, HERE_T_FMT))
1194 if (!recursive (HERE_T_FMT))
1202 /* We have no information about the era format. Just use
1203 the normal format. */
1204 if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
1205 && *fmt != 'x' && *fmt != 'X')
1206 /* This is an illegal format. */
1216 /* Match day of month using alternate numeric symbols. */
1217 get_alt_number (1, 31, 2);
1223 /* Match hour in 24-hour clock using alternate numeric
1225 get_alt_number (0, 23, 2);
1230 /* Match hour in 12-hour clock using alternate numeric
1232 get_alt_number (1, 12, 2);
1233 tm->tm_hour = val - 1;
1237 /* Match month using alternate numeric symbols. */
1238 get_alt_number (1, 12, 2);
1239 tm->tm_mon = val - 1;
1244 /* Match minutes using alternate numeric symbols. */
1245 get_alt_number (0, 59, 2);
1249 /* Match seconds using alternate numeric symbols. */
1250 get_alt_number (0, 61, 2);
1256 get_alt_number (0, 53, 2);
1257 /* XXX This cannot determine any field in TM without
1258 further information. */
1261 /* Match number of weekday using alternate numeric symbols. */
1262 get_alt_number (0, 6, 1);
1267 /* Match year within century using alternate numeric symbols. */
1268 get_alt_number (0, 99, 2);
1269 tm->tm_year = val >= 69 ? val : val + 100;
1281 if (have_I && is_pm)
1287 tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
1289 /* Only the century, but not the year. Strange, but so be it. */
1290 tm->tm_year = (century - 19) * 100;
1293 if (want_xday && !have_wday) {
1294 if ( !(have_mon && have_mday) && have_yday) {
1295 /* we don't have tm_mon and/or tm_mday, compute them */
1297 while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
1300 tm->tm_mon = t_mon - 1;
1302 tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
1304 day_of_the_week (tm);
1306 if (want_xday && !have_yday)
1307 day_of_the_year (tm);
1314 strptime (buf, format, tm)
1319 enum locale_status decided;
1325 return strptime_internal (buf, format, tm, &decided);
1327 #endif /* not HAVE_STRPTIME */
1329 #ifdef NEED_MON_YDAY
1330 /* __mon_yday[][] is common to mktime and strptime implementations.
1332 const unsigned short int __mon_yday[2][13] =
1335 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
1337 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
1341 /* fnmatch is required by POSIX, but we include an implementation for
1342 the sake of systems that don't have it, most notably Windows. Some
1343 systems do have fnmatch, but Apache's installation process installs
1344 its own fnmatch.h (incompatible with the system one!) in a system
1345 include directory, effectively rendering fnmatch unusable. This
1346 has been fixed with Apache 2, where fnmatch has been moved to apr
1347 and given a prefix, but many systems out there are still (as of
1348 this writing in 2005) broken and we must cater to them.
1350 Additionally, according to anecdotal evidence and conventional
1351 wisdom I lack courage to challenge, many implementations of fnmatch
1352 are notoriously buggy and unreliable. So we use our version by
1353 default, except when compiling under systems where fnmatch is known
1354 to work (currently on GNU libc-based systems and Solaris.) */
1356 #ifndef SYSTEM_FNMATCH
1358 #define __FNM_FLAGS (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD)
1360 /* Match STRING against the filename pattern PATTERN, returning zero
1361 if it matches, FNM_NOMATCH if not. This implementation comes from
1362 an earlier version of GNU Bash. (It doesn't make sense to update
1363 it with a newer version because those versions add a lot of
1364 features Wget doesn't use or care about.) */
1367 fnmatch (const char *pattern, const char *string, int flags)
1369 register const char *p = pattern, *n = string;
1372 if ((flags & ~__FNM_FLAGS) != 0)
1378 while ((c = *p++) != '\0')
1384 return (FNM_NOMATCH);
1385 else if ((flags & FNM_PATHNAME) && *n == '/')
1386 return (FNM_NOMATCH);
1387 else if ((flags & FNM_PERIOD) && *n == '.' &&
1388 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1389 return (FNM_NOMATCH);
1393 if (!(flags & FNM_NOESCAPE))
1396 return (FNM_NOMATCH);
1400 if ((flags & FNM_PERIOD) && *n == '.' &&
1401 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1402 return (FNM_NOMATCH);
1404 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
1405 if (((flags & FNM_PATHNAME) && *n == '/') ||
1406 (c == '?' && *n == '\0'))
1407 return (FNM_NOMATCH);
1413 char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
1414 for (--p; *n != '\0'; ++n)
1415 if ((c == '[' || *n == c1) &&
1416 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
1418 return (FNM_NOMATCH);
1423 /* Nonzero if the sense of the character class is
1428 return (FNM_NOMATCH);
1430 if ((flags & FNM_PERIOD) && *n == '.' &&
1431 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1432 return (FNM_NOMATCH);
1434 /* Make sure there is a closing `]'. If there isn't,
1435 the `[' is just a character to be matched. */
1437 register const char *np;
1439 for (np = p; np && *np && *np != ']'; np++);
1444 return (FNM_NOMATCH);
1449 not = (*p == '!' || *p == '^');
1456 register char cstart = c, cend = c;
1458 if (!(flags & FNM_NOESCAPE) && c == '\\')
1459 cstart = cend = *p++;
1462 /* [ (unterminated) loses. */
1463 return (FNM_NOMATCH);
1467 if ((flags & FNM_PATHNAME) && c == '/')
1468 /* [/] can never match. */
1469 return (FNM_NOMATCH);
1471 if (c == '-' && *p != ']')
1474 if (!(flags & FNM_NOESCAPE) && cend == '\\')
1477 return (FNM_NOMATCH);
1481 if (*n >= cstart && *n <= cend)
1488 return (FNM_NOMATCH);
1494 /* Skip the rest of the [...] that already matched. */
1498 /* [... (unterminated) loses. */
1499 return (FNM_NOMATCH);
1502 if (!(flags & FNM_NOESCAPE) && c == '\\')
1503 /* 1003.2d11 is unclear if this is right. %%% */
1507 return (FNM_NOMATCH);
1513 return (FNM_NOMATCH);
1522 return (FNM_NOMATCH);
1525 #endif /* not SYSTEM_FNMATCH */