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 don't have some str* functions in libc. Here we
45 define them. The same goes for strptime. */
47 #ifndef HAVE_STRCASECMP
49 /* Compare S1 and S2, ignoring case, returning less than, equal to or
50 greater than zero if S1 is lexiographically less than,
51 equal to or greater than S2. */
53 strcasecmp (const char *s1, const char *s2)
55 register const unsigned char *p1 = (const unsigned char *) s1;
56 register const unsigned char *p2 = (const unsigned char *) s2;
73 #endif /* not HAVE_STRCASECMP */
75 #ifndef HAVE_STRNCASECMP
77 /* Compare no more than N characters of S1 and S2,
78 ignoring case, returning less than, equal to or
79 greater than zero if S1 is lexicographically less
80 than, equal to or greater than S2. */
82 strncasecmp (const char *s1, const char *s2, size_t n)
84 register const unsigned char *p1 = (const unsigned char *) s1;
85 register const unsigned char *p2 = (const unsigned char *) s2;
88 if (p1 == p2 || n == 0)
95 if (c1 == '\0' || c1 != c2)
101 #endif /* not HAVE_STRNCASECMP */
104 /* Find the first ocurrence in S of any character in ACCEPT. */
106 strpbrk (const char *s, const char *accept)
110 const char *a = accept;
119 #endif /* HAVE_STRPBRK */
122 /* From GNU libc 2.0. */
124 /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
125 This file is part of the GNU C Library.
126 Contributed by Paul Eggert (eggert@twinsun.com). */
129 # define HAVE_LIMITS_H 1
130 # define HAVE_LOCALTIME_R 1
131 # define STDC_HEADERS 1
134 /* Assume that leap seconds are possible, unless told otherwise.
135 If the host has a `zic' command with a `-L leapsecondfilename' option,
136 then it supports leap seconds; otherwise it probably doesn't. */
137 #ifndef LEAP_SECONDS_POSSIBLE
138 # define LEAP_SECONDS_POSSIBLE 1
142 # define __P(args) args
143 #endif /* Not __P. */
150 # define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
153 # define INT_MAX (~0 - INT_MIN)
157 /* The outer cast to time_t works around a bug in Cray C 5.0.3.0. */
158 # define TIME_T_MIN ((time_t) \
159 (0 < (time_t) -1 ? (time_t) 0 \
160 : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
163 # define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
166 #define TM_YEAR_BASE 1900
167 #define EPOCH_YEAR 1970
170 /* Nonzero if YEAR is a leap year (every 4 years,
171 except every 100th isn't, and every 400th is). */
172 # define __isleap(year) \
173 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
176 /* How many days come before each month (0-12). */
177 /* __mon_yday[][] is common to mktime and strptime implementations.
179 const unsigned short int __mon_yday[2][13];
180 #ifndef NEED_MON_YDAY
181 # define NEED_MON_YDAY
184 static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
185 time_t __mktime_internal __P ((struct tm *,
186 struct tm *(*) (const time_t *, struct tm *),
191 # define localtime_r __localtime_r
193 # if ! HAVE_LOCALTIME_R && ! defined localtime_r
194 /* Approximate localtime_r as best we can in its absence. */
195 # define localtime_r my_mktime_localtime_r
196 static struct tm *localtime_r __P ((const time_t *, struct tm *));
202 struct tm *l = localtime (t);
208 # endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
212 /* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
213 measured in seconds, ignoring leap seconds.
214 YEAR uses the same numbering as TM->tm_year.
215 All values are in range, except possibly YEAR.
216 If overflow occurs, yield the low order bits of the correct answer. */
218 ydhms_tm_diff (year, yday, hour, min, sec, tp)
219 int year, yday, hour, min, sec;
222 /* Compute intervening leap days correctly even if year is negative.
223 Take care to avoid int overflow. time_t overflow is OK, since
224 only the low order bits of the correct time_t answer are needed.
225 Don't convert to time_t until after all divisions are done, since
226 time_t might be unsigned. */
227 int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
228 int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
229 int a100 = a4 / 25 - (a4 % 25 < 0);
230 int b100 = b4 / 25 - (b4 % 25 < 0);
231 int a400 = a100 >> 2;
232 int b400 = b100 >> 2;
233 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
234 time_t years = year - (time_t) tp->tm_year;
235 time_t days = (365 * years + intervening_leap_days
236 + (yday - tp->tm_yday));
237 return (60 * (60 * (24 * days + (hour - tp->tm_hour))
238 + (min - tp->tm_min))
239 + (sec - tp->tm_sec));
243 static time_t localtime_offset;
245 /* Convert *TP to a time_t value. */
251 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
252 time zone names contained in the external variable `tzname' shall
253 be set as if the tzset() function had been called. */
257 return __mktime_internal (tp, localtime_r, &localtime_offset);
260 /* Convert *TP to a time_t value, inverting
261 the monotonic and mostly-unit-linear conversion function CONVERT.
262 Use *OFFSET to keep track of a guess at the offset of the result,
263 compared to what the result would be for UTC without leap seconds.
264 If *OFFSET's guess is correct, only one CONVERT call is needed. */
266 __mktime_internal (tp, convert, offset)
268 struct tm *(*convert) __P ((const time_t *, struct tm *));
274 /* The maximum number of probes (calls to CONVERT) should be enough
275 to handle any combinations of time zone rule changes, solar time,
276 and leap seconds. Posix.1 prohibits leap seconds, but some hosts
278 int remaining_probes = 4;
280 /* Time requested. Copy it in case CONVERT modifies *TP; this can
281 occur if TP is localtime's returned value and CONVERT is localtime. */
282 int sec = tp->tm_sec;
283 int min = tp->tm_min;
284 int hour = tp->tm_hour;
285 int mday = tp->tm_mday;
286 int mon = tp->tm_mon;
287 int year_requested = tp->tm_year;
288 int isdst = tp->tm_isdst;
290 /* Ensure that mon is in range, and set year accordingly. */
291 int mon_remainder = mon % 12;
292 int negative_mon_remainder = mon_remainder < 0;
293 int mon_years = mon / 12 - negative_mon_remainder;
294 int year = year_requested + mon_years;
296 /* The other values need not be in range:
297 the remaining code handles minor overflows correctly,
298 assuming int and time_t arithmetic wraps around.
299 Major overflows are caught at the end. */
301 /* Calculate day of year from year, month, and day of month.
302 The result need not be in range. */
303 int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
304 [mon_remainder + 12 * negative_mon_remainder])
307 int sec_requested = sec;
308 #if LEAP_SECONDS_POSSIBLE
309 /* Handle out-of-range seconds specially,
310 since ydhms_tm_diff assumes every minute has 60 seconds. */
317 /* Invert CONVERT by probing. First assume the same offset as last time.
318 Then repeatedly use the error to improve the guess. */
320 tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
321 tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
322 t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
324 for (t = t0 + *offset;
325 (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
327 if (--remaining_probes == 0)
330 /* Check whether tm.tm_isdst has the requested value, if any. */
331 if (0 <= isdst && 0 <= tm.tm_isdst)
333 int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
336 /* Move two hours in the direction indicated by the disagreement,
337 probe some more, and switch to a new time if found.
338 The largest known fallback due to daylight savings is two hours:
339 once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
340 time_t ot = t - 2 * 60 * 60 * dst_diff;
341 while (--remaining_probes != 0)
344 if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
345 (*convert) (&ot, &otm))))
352 break; /* Avoid a redundant probe. */
359 #if LEAP_SECONDS_POSSIBLE
360 if (sec_requested != tm.tm_sec)
362 /* Adjust time to reflect the tm_sec requested, not the normalized value.
363 Also, repair any damage from a false match due to a leap second. */
364 t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
365 (*convert) (&t, &tm);
369 if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
371 /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
372 so check for major overflows. A gross check suffices,
373 since if t has overflowed, it is off by a multiple of
374 TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
375 the difference that is bounded by a small value. */
377 double dyear = (double) year_requested + mon_years - tm.tm_year;
378 double dday = 366 * dyear + mday;
379 double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
381 if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
390 weak_alias (mktime, timelocal)
392 #endif /* not HAVE_MKTIME */
395 #ifndef HAVE_STRPTIME
396 /* From GNU libc 2.1.3. */
397 /* Ulrich, thanks for helping me out with this! --hniksic */
399 /* strptime - Convert a string representation of time to a time value.
400 Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
401 This file is part of the GNU C Library.
402 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. */
404 /* XXX This version of the implementation is not really complete.
405 Some of the fields cannot add information alone. But if seeing
406 some of them in the same format (such as year, week and weekday)
407 this is enough information for determining the date. */
410 # define __P(args) args
413 #if ! HAVE_LOCALTIME_R && ! defined localtime_r
415 # define localtime_r __localtime_r
417 /* Approximate localtime_r as best we can in its absence. */
418 # define localtime_r my_localtime_r
419 static struct tm *localtime_r __P ((const time_t *, struct tm *));
425 struct tm *l = localtime (t);
431 # endif /* ! _LIBC */
432 #endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
435 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL
436 #if defined __GNUC__ && __GNUC__ >= 2
437 # define match_string(cs1, s2) \
438 ({ size_t len = strlen (cs1); \
439 int result = strncasecmp ((cs1), (s2), len) == 0; \
440 if (result) (s2) += len; \
443 /* Oh come on. Get a reasonable compiler. */
444 # define match_string(cs1, s2) \
445 (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
447 /* We intentionally do not use isdigit() for testing because this will
448 lead to problems with the wide character version. */
449 #define get_number(from, to, n) \
455 if (*rp < '0' || *rp > '9') \
459 val += *rp++ - '0'; \
460 } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \
461 if (val < from || val > to) \
465 /* Added check for __GNUC__ extensions here for Wget. --abbotti */
466 # if defined __GNUC__ && __GNUC__ >= 2
467 # define get_alt_number(from, to, n) \
469 __label__ do_normal; \
470 if (*decided != raw) \
472 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
480 while (*alts != '\0') \
482 size_t len = strlen (alts); \
483 if (strncasecmp (alts, rp, len) == 0) \
490 if (*decided == not && ! any) \
492 /* If we haven't read anything it's an error. */ \
495 /* Correct the premature multiplication. */ \
501 } while (--__n > 0 && val * 10 <= to); \
502 if (val < from || val > to) \
508 get_number (from, to, n); \
513 # define get_alt_number(from, to, n) \
515 if (*decided != raw) \
517 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
525 while (*alts != '\0') \
527 size_t len = strlen (alts); \
528 if (strncasecmp (alts, rp, len) == 0) \
535 if (*decided == not && ! any) \
537 /* If we haven't read anything it's an error. */ \
540 /* Correct the premature multiplication. */ \
546 } while (--__n > 0 && val * 10 <= to); \
547 if (val < from || val > to) \
553 get_number (from, to, n); \
556 # endif /* defined __GNUC__ && __GNUC__ >= 2 */
558 # define get_alt_number(from, to, n) \
559 /* We don't have the alternate representation. */ \
560 get_number(from, to, n)
562 #define recursive(new_fmt) \
563 (*(new_fmt) != '\0' \
564 && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
568 /* This is defined in locale/C-time.c in the GNU libc. */
569 extern const struct locale_data _nl_C_LC_TIME;
570 extern const unsigned short int __mon_yday[2][13];
572 # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
573 # define ab_weekday_name \
574 (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
575 # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
576 # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
577 # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
578 # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
579 # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
580 # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
581 # define HERE_T_FMT_AMPM \
582 (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
583 # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
585 # define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
587 static char const weekday_name[][10] =
589 "Sunday", "Monday", "Tuesday", "Wednesday",
590 "Thursday", "Friday", "Saturday"
592 static char const ab_weekday_name[][4] =
594 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
596 static char const month_name[][10] =
598 "January", "February", "March", "April", "May", "June",
599 "July", "August", "September", "October", "November", "December"
601 static char const ab_month_name[][4] =
603 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
604 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
606 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
607 # define HERE_D_FMT "%m/%d/%y"
608 # define HERE_AM_STR "AM"
609 # define HERE_PM_STR "PM"
610 # define HERE_T_FMT_AMPM "%I:%M:%S %p"
611 # define HERE_T_FMT "%H:%M:%S"
613 /* __mon_yday[][] is common to mktime and strptime implementations.
615 const unsigned short int __mon_yday[2][13];
616 # ifndef NEED_MON_YDAY
617 # define NEED_MON_YDAY
621 /* Status of lookup: do we use the locale data or the raw data? */
622 enum locale_status { not, loc, raw };
626 /* Nonzero if YEAR is a leap year (every 4 years,
627 except every 100th isn't, and every 400th is). */
628 # define __isleap(year) \
629 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
632 /* Compute the day of the week. */
634 day_of_the_week (struct tm *tm)
636 /* We know that January 1st 1970 was a Thursday (= 4). Compute the
637 the difference between this data in the one on TM and so determine
639 int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
641 + (365 * (tm->tm_year - 70))
643 - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
644 + (((corr_year / 4) / 25) / 4)
645 + __mon_yday[0][tm->tm_mon]
647 tm->tm_wday = ((wday % 7) + 7) % 7;
650 /* Compute the day of the year. */
652 day_of_the_year (struct tm *tm)
654 tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
655 + (tm->tm_mday - 1));
662 strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
663 enum locale_status *decided));
669 strptime_internal (rp, fmt, tm, decided)
673 enum locale_status *decided;
676 const char *rp_backup;
681 int century, want_century;
682 int have_wday, want_xday;
684 int have_mon, have_mday;
689 have_wday = want_xday = have_yday = have_mon = have_mday = 0;
693 /* A white space in the format string matches 0 more or white
694 space in the input string. */
697 while (ISSPACE (*rp))
703 /* Any character but `%' must be matched by the same character
704 in the iput string. */
707 match_char (*fmt++, *rp++);
713 /* We need this for handling the `E' modifier. */
718 /* Make back up of current processing pointer. */
725 /* Match the `%' character itself. */
726 match_char ('%', *rp++);
730 /* Match day of week. */
731 for (cnt = 0; cnt < 7; ++cnt)
736 if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
739 && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
744 if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
747 && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
748 ab_weekday_name[cnt]))
755 && (match_string (weekday_name[cnt], rp)
756 || match_string (ab_weekday_name[cnt], rp)))
763 /* Does not match a weekday name. */
771 /* Match month name. */
772 for (cnt = 0; cnt < 12; ++cnt)
777 if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
780 && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
785 if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
788 && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
795 if (match_string (month_name[cnt], rp)
796 || match_string (ab_month_name[cnt], rp))
803 /* Does not match a month name. */
809 /* Match locale's date and time format. */
813 if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
822 if (*decided == not &&
823 strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
831 if (!recursive (HERE_D_T_FMT))
836 /* Match century number. */
837 get_number (0, 99, 2);
843 /* Match day of month. */
844 get_number (1, 31, 2);
850 if (!recursive ("%Y-%m-%d"))
858 if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
868 && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
878 /* Match standard day format. */
879 if (!recursive (HERE_D_FMT))
885 /* Match hour in 24-hour clock. */
886 get_number (0, 23, 2);
891 /* Match hour in 12-hour clock. */
892 get_number (1, 12, 2);
893 tm->tm_hour = val % 12;
897 /* Match day number of year. */
898 get_number (1, 366, 3);
899 tm->tm_yday = val - 1;
903 /* Match number of month. */
904 get_number (1, 12, 2);
905 tm->tm_mon = val - 1;
911 get_number (0, 59, 2);
916 /* Match any white space. */
917 while (ISSPACE (*rp))
921 /* Match locale's equivalent of AM/PM. */
925 if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
927 if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
931 if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
933 if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
941 if (!match_string (HERE_AM_STR, rp))
942 if (match_string (HERE_PM_STR, rp))
951 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
960 if (*decided == not &&
961 strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
969 if (!recursive (HERE_T_FMT_AMPM))
973 if (!recursive ("%H:%M"))
978 /* The number of seconds may be very high so we cannot use
979 the `get_number' macro. Instead read the number
980 character for character and construct the result while
983 if (*rp < '0' || *rp > '9')
984 /* We need at least one digit. */
992 while (*rp >= '0' && *rp <= '9');
994 if (localtime_r (&secs, tm) == NULL)
995 /* Error in function. */
1000 get_number (0, 61, 2);
1005 if (*decided != raw)
1007 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
1009 if (*decided == loc)
1016 if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
1025 if (!recursive (HERE_T_FMT))
1029 get_number (1, 7, 1);
1030 tm->tm_wday = val % 7;
1034 get_number (0, 99, 2);
1035 /* XXX This cannot determine any field in TM. */
1038 if (*rp < '0' || *rp > '9')
1040 /* XXX Ignore the number since we would need some more
1041 information to compute a real date. */
1044 while (*rp >= '0' && *rp <= '9');
1049 get_number (0, 53, 2);
1050 /* XXX This cannot determine any field in TM without some
1054 /* Match number of weekday. */
1055 get_number (0, 6, 1);
1060 /* Match year within century. */
1061 get_number (0, 99, 2);
1062 /* The "Year 2000: The Millennium Rollover" paper suggests that
1063 values in the range 69-99 refer to the twentieth century. */
1064 tm->tm_year = val >= 69 ? val : val + 100;
1065 /* Indicate that we want to use the century, if specified. */
1070 /* Match year including century number. */
1071 get_number (0, 9999, 4);
1072 tm->tm_year = val - 1900;
1077 /* XXX How to handle this? */
1084 /* Match locale's alternate date and time format. */
1085 if (*decided != raw)
1087 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
1090 fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
1092 if (!recursive (fmt))
1094 if (*decided == loc)
1101 if (strcmp (fmt, HERE_D_T_FMT))
1108 /* The C locale has no era information, so use the
1109 normal representation. */
1110 if (!recursive (HERE_D_T_FMT))
1117 /* Match name of base year in locale's alternate
1119 /* XXX This is currently not implemented. It should
1120 use the value _NL_CURRENT (LC_TIME, ERA). */
1123 if (*decided != raw)
1125 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
1128 fmt = _NL_CURRENT (LC_TIME, D_FMT);
1130 if (!recursive (fmt))
1132 if (*decided == loc)
1139 if (strcmp (fmt, HERE_D_FMT))
1145 if (!recursive (HERE_D_FMT))
1149 if (*decided != raw)
1151 const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
1154 fmt = _NL_CURRENT (LC_TIME, T_FMT);
1156 if (!recursive (fmt))
1158 if (*decided == loc)
1165 if (strcmp (fmt, HERE_T_FMT))
1171 if (!recursive (HERE_T_FMT))
1179 /* We have no information about the era format. Just use
1180 the normal format. */
1181 if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
1182 && *fmt != 'x' && *fmt != 'X')
1183 /* This is an illegal format. */
1193 /* Match day of month using alternate numeric symbols. */
1194 get_alt_number (1, 31, 2);
1200 /* Match hour in 24-hour clock using alternate numeric
1202 get_alt_number (0, 23, 2);
1207 /* Match hour in 12-hour clock using alternate numeric
1209 get_alt_number (1, 12, 2);
1210 tm->tm_hour = val - 1;
1214 /* Match month using alternate numeric symbols. */
1215 get_alt_number (1, 12, 2);
1216 tm->tm_mon = val - 1;
1221 /* Match minutes using alternate numeric symbols. */
1222 get_alt_number (0, 59, 2);
1226 /* Match seconds using alternate numeric symbols. */
1227 get_alt_number (0, 61, 2);
1233 get_alt_number (0, 53, 2);
1234 /* XXX This cannot determine any field in TM without
1235 further information. */
1238 /* Match number of weekday using alternate numeric symbols. */
1239 get_alt_number (0, 6, 1);
1244 /* Match year within century using alternate numeric symbols. */
1245 get_alt_number (0, 99, 2);
1246 tm->tm_year = val >= 69 ? val : val + 100;
1258 if (have_I && is_pm)
1264 tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
1266 /* Only the century, but not the year. Strange, but so be it. */
1267 tm->tm_year = (century - 19) * 100;
1270 if (want_xday && !have_wday) {
1271 if ( !(have_mon && have_mday) && have_yday) {
1272 /* we don't have tm_mon and/or tm_mday, compute them */
1274 while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
1277 tm->tm_mon = t_mon - 1;
1279 tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
1281 day_of_the_week (tm);
1283 if (want_xday && !have_yday)
1284 day_of_the_year (tm);
1291 strptime (buf, format, tm)
1296 enum locale_status decided;
1302 return strptime_internal (buf, format, tm, &decided);
1304 #endif /* not HAVE_STRPTIME */
1306 #ifdef NEED_MON_YDAY
1307 /* __mon_yday[][] is common to mktime and strptime implementations.
1309 const unsigned short int __mon_yday[2][13] =
1312 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
1314 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
1318 /* fnmatch is defined by POSIX, but we include an implementation for
1319 the sake of systems that don't have it. Some systems do have
1320 fnmatch, but Apache installs its own fnmatch.h (incompatible with
1321 the system one) in a system include directory, effectively
1322 rendering fnmatch unusable.
1324 Additionally according to anecdotal evidence and conventional
1325 wisdom I lack courage to challenge, many implementations of fnmatch
1326 are notoriously buggy and unreliable. So we use our version by
1327 default, except when compiling under systems where fnmatch is known
1328 to work (currently on GNU libc-based systems and Solaris.) */
1330 #ifndef SYSTEM_FNMATCH
1332 #define __FNM_FLAGS (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD)
1334 /* Match STRING against the filename pattern PATTERN, returning zero
1335 if it matches, FNM_NOMATCH if not. This implementation comes from
1336 an earlier version of GNU Bash. (It doesn't make sense to update
1337 it with a newer version because those versions add a lot of
1338 features Wget doesn't use or care about.) */
1341 fnmatch (const char *pattern, const char *string, int flags)
1343 register const char *p = pattern, *n = string;
1346 if ((flags & ~__FNM_FLAGS) != 0)
1352 while ((c = *p++) != '\0')
1358 return (FNM_NOMATCH);
1359 else if ((flags & FNM_PATHNAME) && *n == '/')
1360 return (FNM_NOMATCH);
1361 else if ((flags & FNM_PERIOD) && *n == '.' &&
1362 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1363 return (FNM_NOMATCH);
1367 if (!(flags & FNM_NOESCAPE))
1370 return (FNM_NOMATCH);
1374 if ((flags & FNM_PERIOD) && *n == '.' &&
1375 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1376 return (FNM_NOMATCH);
1378 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
1379 if (((flags & FNM_PATHNAME) && *n == '/') ||
1380 (c == '?' && *n == '\0'))
1381 return (FNM_NOMATCH);
1387 char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
1388 for (--p; *n != '\0'; ++n)
1389 if ((c == '[' || *n == c1) &&
1390 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
1392 return (FNM_NOMATCH);
1397 /* Nonzero if the sense of the character class is
1402 return (FNM_NOMATCH);
1404 if ((flags & FNM_PERIOD) && *n == '.' &&
1405 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1406 return (FNM_NOMATCH);
1408 /* Make sure there is a closing `]'. If there isn't,
1409 the `[' is just a character to be matched. */
1411 register const char *np;
1413 for (np = p; np && *np && *np != ']'; np++);
1418 return (FNM_NOMATCH);
1423 not = (*p == '!' || *p == '^');
1430 register char cstart = c, cend = c;
1432 if (!(flags & FNM_NOESCAPE) && c == '\\')
1433 cstart = cend = *p++;
1436 /* [ (unterminated) loses. */
1437 return (FNM_NOMATCH);
1441 if ((flags & FNM_PATHNAME) && c == '/')
1442 /* [/] can never match. */
1443 return (FNM_NOMATCH);
1445 if (c == '-' && *p != ']')
1448 if (!(flags & FNM_NOESCAPE) && cend == '\\')
1451 return (FNM_NOMATCH);
1455 if (*n >= cstart && *n <= cend)
1462 return (FNM_NOMATCH);
1468 /* Skip the rest of the [...] that already matched. */
1472 /* [... (unterminated) loses. */
1473 return (FNM_NOMATCH);
1476 if (!(flags & FNM_NOESCAPE) && c == '\\')
1477 /* 1003.2d11 is unclear if this is right. %%% */
1481 return (FNM_NOMATCH);
1487 return (FNM_NOMATCH);
1496 return (FNM_NOMATCH);
1499 #endif /* not SYSTEM_FNMATCH */