1 /* Replacements for routines missing on some systems.
2 Copyright (C) 1995, 1996, 1997 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. */
28 #endif /* HAVE_STRING_H */
30 #include <sys/types.h>
39 /* A strerror() clone, for systems that don't have it. */
43 /* This loses on a system without `sys_errlist'. */
44 extern char *sys_errlist[];
45 return sys_errlist[err];
47 #endif /* not HAVE_STRERROR */
49 /* Some systems don't have some str* functions in libc. Here we
50 define them. The same goes for strptime. */
52 #ifndef HAVE_STRCASECMP
54 /* Compare S1 and S2, ignoring case, returning less than, equal to or
55 greater than zero if S1 is lexiographically less than,
56 equal to or greater than S2. */
58 strcasecmp (const char *s1, const char *s2)
60 register const unsigned char *p1 = (const unsigned char *) s1;
61 register const unsigned char *p2 = (const unsigned char *) s2;
78 #endif /* not HAVE_STRCASECMP */
80 #ifndef HAVE_STRNCASECMP
82 /* Compare no more than N characters of S1 and S2,
83 ignoring case, returning less than, equal to or
84 greater than zero if S1 is lexicographically less
85 than, equal to or greater than S2. */
87 strncasecmp (const char *s1, const char *s2, size_t n)
89 register const unsigned char *p1 = (const unsigned char *) s1;
90 register const unsigned char *p2 = (const unsigned char *) s2;
93 if (p1 == p2 || n == 0)
100 if (c1 == '\0' || c1 != c2)
106 #endif /* not HAVE_STRNCASECMP */
109 /* From GNU libc 2.0.6. */
110 /* Return the first ocurrence of NEEDLE in HAYSTACK. */
112 * My personal strstr() implementation that beats most other algorithms.
113 * Until someone tells me otherwise, I assume that this is the
114 * fastest implementation of strstr() in C.
115 * I deliberately chose not to comment it. You should have at least
116 * as much fun trying to understand it, as I had to write it :-).
118 * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
119 typedef unsigned chartype;
122 strstr (phaystack, pneedle)
123 const char *phaystack;
126 register const unsigned char *haystack, *needle;
127 register chartype b, c;
129 haystack = (const unsigned char *) phaystack;
130 needle = (const unsigned char *) pneedle;
135 haystack--; /* possible ANSI violation */
153 register const unsigned char *rhaystack, *rneedle;
168 jin: a = *++haystack;
175 rhaystack = haystack-- + 1;
193 while (*rhaystack == a);
195 needle = rneedle; /* took the register-poor approach */
202 return (char*) haystack;
206 #endif /* not HAVE_STRSTR */
209 /* Find the first ocurrence in S of any character in ACCEPT. */
211 strpbrk (const char *s, const char *accept)
215 const char *a = accept;
224 #endif /* HAVE_STRPBRK */
227 /* From GNU libc 2.0. */
229 /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
230 This file is part of the GNU C Library.
231 Contributed by Paul Eggert (eggert@twinsun.com). */
234 # define HAVE_LIMITS_H 1
235 # define HAVE_LOCALTIME_R 1
236 # define STDC_HEADERS 1
239 /* Assume that leap seconds are possible, unless told otherwise.
240 If the host has a `zic' command with a `-L leapsecondfilename' option,
241 then it supports leap seconds; otherwise it probably doesn't. */
242 #ifndef LEAP_SECONDS_POSSIBLE
243 # define LEAP_SECONDS_POSSIBLE 1
247 # define __P(args) PARAMS (args)
248 #endif /* Not __P. */
255 # define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
258 # define INT_MAX (~0 - INT_MIN)
262 /* The outer cast to time_t works around a bug in Cray C 5.0.3.0. */
263 # define TIME_T_MIN ((time_t) \
264 (0 < (time_t) -1 ? (time_t) 0 \
265 : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
268 # define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
271 #define TM_YEAR_BASE 1900
272 #define EPOCH_YEAR 1970
275 /* Nonzero if YEAR is a leap year (every 4 years,
276 except every 100th isn't, and every 400th is). */
277 # define __isleap(year) \
278 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
281 /* How many days come before each month (0-12). */
282 /* __mon_yday[][] is common to mktime and strptime implementations.
284 const unsigned short int __mon_yday[2][13];
285 #ifndef NEED_MON_YDAY
286 # define NEED_MON_YDAY
289 static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
290 time_t __mktime_internal __P ((struct tm *,
291 struct tm *(*) (const time_t *, struct tm *),
296 # define localtime_r __localtime_r
298 # if ! HAVE_LOCALTIME_R && ! defined localtime_r
299 /* Approximate localtime_r as best we can in its absence. */
300 # define localtime_r my_mktime_localtime_r
301 static struct tm *localtime_r __P ((const time_t *, struct tm *));
307 struct tm *l = localtime (t);
313 # endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
317 /* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
318 measured in seconds, ignoring leap seconds.
319 YEAR uses the same numbering as TM->tm_year.
320 All values are in range, except possibly YEAR.
321 If overflow occurs, yield the low order bits of the correct answer. */
323 ydhms_tm_diff (year, yday, hour, min, sec, tp)
324 int year, yday, hour, min, sec;
327 /* Compute intervening leap days correctly even if year is negative.
328 Take care to avoid int overflow. time_t overflow is OK, since
329 only the low order bits of the correct time_t answer are needed.
330 Don't convert to time_t until after all divisions are done, since
331 time_t might be unsigned. */
332 int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
333 int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
334 int a100 = a4 / 25 - (a4 % 25 < 0);
335 int b100 = b4 / 25 - (b4 % 25 < 0);
336 int a400 = a100 >> 2;
337 int b400 = b100 >> 2;
338 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
339 time_t years = year - (time_t) tp->tm_year;
340 time_t days = (365 * years + intervening_leap_days
341 + (yday - tp->tm_yday));
342 return (60 * (60 * (24 * days + (hour - tp->tm_hour))
343 + (min - tp->tm_min))
344 + (sec - tp->tm_sec));
348 static time_t localtime_offset;
350 /* Convert *TP to a time_t value. */
356 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
357 time zone names contained in the external variable `tzname' shall
358 be set as if the tzset() function had been called. */
362 return __mktime_internal (tp, localtime_r, &localtime_offset);
365 /* Convert *TP to a time_t value, inverting
366 the monotonic and mostly-unit-linear conversion function CONVERT.
367 Use *OFFSET to keep track of a guess at the offset of the result,
368 compared to what the result would be for UTC without leap seconds.
369 If *OFFSET's guess is correct, only one CONVERT call is needed. */
371 __mktime_internal (tp, convert, offset)
373 struct tm *(*convert) __P ((const time_t *, struct tm *));
379 /* The maximum number of probes (calls to CONVERT) should be enough
380 to handle any combinations of time zone rule changes, solar time,
381 and leap seconds. Posix.1 prohibits leap seconds, but some hosts
383 int remaining_probes = 4;
385 /* Time requested. Copy it in case CONVERT modifies *TP; this can
386 occur if TP is localtime's returned value and CONVERT is localtime. */
387 int sec = tp->tm_sec;
388 int min = tp->tm_min;
389 int hour = tp->tm_hour;
390 int mday = tp->tm_mday;
391 int mon = tp->tm_mon;
392 int year_requested = tp->tm_year;
393 int isdst = tp->tm_isdst;
395 /* Ensure that mon is in range, and set year accordingly. */
396 int mon_remainder = mon % 12;
397 int negative_mon_remainder = mon_remainder < 0;
398 int mon_years = mon / 12 - negative_mon_remainder;
399 int year = year_requested + mon_years;
401 /* The other values need not be in range:
402 the remaining code handles minor overflows correctly,
403 assuming int and time_t arithmetic wraps around.
404 Major overflows are caught at the end. */
406 /* Calculate day of year from year, month, and day of month.
407 The result need not be in range. */
408 int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
409 [mon_remainder + 12 * negative_mon_remainder])
412 int sec_requested = sec;
413 #if LEAP_SECONDS_POSSIBLE
414 /* Handle out-of-range seconds specially,
415 since ydhms_tm_diff assumes every minute has 60 seconds. */
422 /* Invert CONVERT by probing. First assume the same offset as last time.
423 Then repeatedly use the error to improve the guess. */
425 tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
426 tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
427 t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
429 for (t = t0 + *offset;
430 (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
432 if (--remaining_probes == 0)
435 /* Check whether tm.tm_isdst has the requested value, if any. */
436 if (0 <= isdst && 0 <= tm.tm_isdst)
438 int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
441 /* Move two hours in the direction indicated by the disagreement,
442 probe some more, and switch to a new time if found.
443 The largest known fallback due to daylight savings is two hours:
444 once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
445 time_t ot = t - 2 * 60 * 60 * dst_diff;
446 while (--remaining_probes != 0)
449 if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
450 (*convert) (&ot, &otm))))
457 break; /* Avoid a redundant probe. */
464 #if LEAP_SECONDS_POSSIBLE
465 if (sec_requested != tm.tm_sec)
467 /* Adjust time to reflect the tm_sec requested, not the normalized value.
468 Also, repair any damage from a false match due to a leap second. */
469 t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
470 (*convert) (&t, &tm);
474 if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
476 /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
477 so check for major overflows. A gross check suffices,
478 since if t has overflowed, it is off by a multiple of
479 TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
480 the difference that is bounded by a small value. */
482 double dyear = (double) year_requested + mon_years - tm.tm_year;
483 double dday = 366 * dyear + mday;
484 double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
486 if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
495 weak_alias (mktime, timelocal)
497 #endif /* not HAVE_MKTIME */
500 #ifndef HAVE_STRPTIME
501 /* From GNU libc 2.1.3. */
502 /* Ulrich, thanks for helping me out with this! --hniksic */
504 /* strptime - Convert a string representation of time to a time value.
505 Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
506 This file is part of the GNU C Library.
507 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. */
509 /* XXX This version of the implementation is not really complete.
510 Some of the fields cannot add information alone. But if seeing
511 some of them in the same format (such as year, week and weekday)
512 this is enough information for determining the date. */
515 # define __P(args) PARAMS (args)
518 #if ! HAVE_LOCALTIME_R && ! defined localtime_r
520 # define localtime_r __localtime_r
522 /* Approximate localtime_r as best we can in its absence. */
523 # define localtime_r my_localtime_r
524 static struct tm *localtime_r __P ((const time_t *, struct tm *));
530 struct tm *l = localtime (t);
536 # endif /* ! _LIBC */
537 #endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
540 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL
541 #if defined __GNUC__ && __GNUC__ >= 2
542 # define match_string(cs1, s2) \
543 ({ size_t len = strlen (cs1); \
544 int result = strncasecmp ((cs1), (s2), len) == 0; \
545 if (result) (s2) += len; \
548 /* Oh come on. Get a reasonable compiler. */
549 # define match_string(cs1, s2) \
550 (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
552 /* We intentionally do not use isdigit() for testing because this will
553 lead to problems with the wide character version. */
554 #define get_number(from, to, n) \
560 if (*rp < '0' || *rp > '9') \
564 val += *rp++ - '0'; \
565 } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \
566 if (val < from || val > to) \
570 /* Added check for __GNUC__ extensions here for Wget. --abbotti */
571 # if defined __GNUC__ && __GNUC__ >= 2
572 # define get_alt_number(from, to, n) \
574 __label__ do_normal; \
575 if (*decided != raw) \
577 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
585 while (*alts != '\0') \
587 size_t len = strlen (alts); \
588 if (strncasecmp (alts, rp, len) == 0) \
595 if (*decided == not && ! any) \
597 /* If we haven't read anything it's an error. */ \
600 /* Correct the premature multiplication. */ \
606 } while (--__n > 0 && val * 10 <= to); \
607 if (val < from || val > to) \
613 get_number (from, to, n); \
618 # define get_alt_number(from, to, n) \
620 if (*decided != raw) \
622 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
630 while (*alts != '\0') \
632 size_t len = strlen (alts); \
633 if (strncasecmp (alts, rp, len) == 0) \
640 if (*decided == not && ! any) \
642 /* If we haven't read anything it's an error. */ \
645 /* Correct the premature multiplication. */ \
651 } while (--__n > 0 && val * 10 <= to); \
652 if (val < from || val > to) \
658 get_number (from, to, n); \
661 # endif /* defined __GNUC__ && __GNUC__ >= 2 */
663 # define get_alt_number(from, to, n) \
664 /* We don't have the alternate representation. */ \
665 get_number(from, to, n)
667 #define recursive(new_fmt) \
668 (*(new_fmt) != '\0' \
669 && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
673 /* This is defined in locale/C-time.c in the GNU libc. */
674 extern const struct locale_data _nl_C_LC_TIME;
675 extern const unsigned short int __mon_yday[2][13];
677 # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
678 # define ab_weekday_name \
679 (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
680 # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
681 # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
682 # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
683 # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
684 # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
685 # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
686 # define HERE_T_FMT_AMPM \
687 (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
688 # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
690 # define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
692 static char const weekday_name[][10] =
694 "Sunday", "Monday", "Tuesday", "Wednesday",
695 "Thursday", "Friday", "Saturday"
697 static char const ab_weekday_name[][4] =
699 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
701 static char const month_name[][10] =
703 "January", "February", "March", "April", "May", "June",
704 "July", "August", "September", "October", "November", "December"
706 static char const ab_month_name[][4] =
708 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
709 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
711 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
712 # define HERE_D_FMT "%m/%d/%y"
713 # define HERE_AM_STR "AM"
714 # define HERE_PM_STR "PM"
715 # define HERE_T_FMT_AMPM "%I:%M:%S %p"
716 # define HERE_T_FMT "%H:%M:%S"
718 /* __mon_yday[][] is common to mktime and strptime implementations.
720 const unsigned short int __mon_yday[2][13];
721 # ifndef NEED_MON_YDAY
722 # define NEED_MON_YDAY
726 /* Status of lookup: do we use the locale data or the raw data? */
727 enum locale_status { not, loc, raw };
731 /* Nonzero if YEAR is a leap year (every 4 years,
732 except every 100th isn't, and every 400th is). */
733 # define __isleap(year) \
734 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
737 /* Compute the day of the week. */
739 day_of_the_week (struct tm *tm)
741 /* We know that January 1st 1970 was a Thursday (= 4). Compute the
742 the difference between this data in the one on TM and so determine
744 int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
746 + (365 * (tm->tm_year - 70))
748 - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
749 + (((corr_year / 4) / 25) / 4)
750 + __mon_yday[0][tm->tm_mon]
752 tm->tm_wday = ((wday % 7) + 7) % 7;
755 /* Compute the day of the year. */
757 day_of_the_year (struct tm *tm)
759 tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
760 + (tm->tm_mday - 1));
767 strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
768 enum locale_status *decided));
774 strptime_internal (rp, fmt, tm, decided)
778 enum locale_status *decided;
780 const char *rp_backup;
784 int century, want_century;
785 int have_wday, want_xday;
787 int have_mon, have_mday;
792 have_wday = want_xday = have_yday = have_mon = have_mday = 0;
796 /* A white space in the format string matches 0 more or white
797 space in the input string. */
800 while (ISSPACE (*rp))
806 /* Any character but `%' must be matched by the same character
807 in the iput string. */
810 match_char (*fmt++, *rp++);
816 /* We need this for handling the `E' modifier. */
820 /* Make back up of current processing pointer. */
826 /* Match the `%' character itself. */
827 match_char ('%', *rp++);
831 /* Match day of week. */
832 for (cnt = 0; cnt < 7; ++cnt)
837 if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
840 && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
845 if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
848 && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
849 ab_weekday_name[cnt]))
856 && (match_string (weekday_name[cnt], rp)
857 || match_string (ab_weekday_name[cnt], rp)))
864 /* Does not match a weekday name. */
872 /* Match month name. */
873 for (cnt = 0; cnt < 12; ++cnt)
878 if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
881 && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
886 if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
889 && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
896 if (match_string (month_name[cnt], rp)
897 || match_string (ab_month_name[cnt], rp))
904 /* Does not match a month name. */
910 /* Match locale's date and time format. */
914 if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
923 if (*decided == not &&
924 strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
932 if (!recursive (HERE_D_T_FMT))
937 /* Match century number. */
938 get_number (0, 99, 2);
944 /* Match day of month. */
945 get_number (1, 31, 2);
951 if (!recursive ("%Y-%m-%d"))
959 if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
969 && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
979 /* Match standard day format. */
980 if (!recursive (HERE_D_FMT))
986 /* Match hour in 24-hour clock. */
987 get_number (0, 23, 2);
992 /* Match hour in 12-hour clock. */
993 get_number (1, 12, 2);
994 tm->tm_hour = val % 12;
998 /* Match day number of year. */
999 get_number (1, 366, 3);
1000 tm->tm_yday = val - 1;
1004 /* Match number of month. */
1005 get_number (1, 12, 2);
1006 tm->tm_mon = val - 1;
1012 get_number (0, 59, 2);
1017 /* Match any white space. */
1018 while (ISSPACE (*rp))
1022 /* Match locale's equivalent of AM/PM. */
1024 if (*decided != raw)
1026 if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
1028 if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
1032 if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
1034 if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
1042 if (!match_string (HERE_AM_STR, rp))
1043 if (match_string (HERE_PM_STR, rp))
1050 if (*decided != raw)
1052 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
1054 if (*decided == loc)
1061 if (*decided == not &&
1062 strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
1070 if (!recursive (HERE_T_FMT_AMPM))
1074 if (!recursive ("%H:%M"))
1079 /* The number of seconds may be very high so we cannot use
1080 the `get_number' macro. Instead read the number
1081 character for character and construct the result while
1084 if (*rp < '0' || *rp > '9')
1085 /* We need at least one digit. */
1091 secs += *rp++ - '0';
1093 while (*rp >= '0' && *rp <= '9');
1095 if (localtime_r (&secs, tm) == NULL)
1096 /* Error in function. */
1101 get_number (0, 61, 2);
1106 if (*decided != raw)
1108 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
1110 if (*decided == loc)
1117 if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
1126 if (!recursive (HERE_T_FMT))
1130 get_number (1, 7, 1);
1131 tm->tm_wday = val % 7;
1135 get_number (0, 99, 2);
1136 /* XXX This cannot determine any field in TM. */
1139 if (*rp < '0' || *rp > '9')
1141 /* XXX Ignore the number since we would need some more
1142 information to compute a real date. */
1145 while (*rp >= '0' && *rp <= '9');
1150 get_number (0, 53, 2);
1151 /* XXX This cannot determine any field in TM without some
1155 /* Match number of weekday. */
1156 get_number (0, 6, 1);
1161 /* Match year within century. */
1162 get_number (0, 99, 2);
1163 /* The "Year 2000: The Millennium Rollover" paper suggests that
1164 values in the range 69-99 refer to the twentieth century. */
1165 tm->tm_year = val >= 69 ? val : val + 100;
1166 /* Indicate that we want to use the century, if specified. */
1171 /* Match year including century number. */
1172 get_number (0, 9999, 4);
1173 tm->tm_year = val - 1900;
1178 /* XXX How to handle this? */
1185 /* Match locale's alternate date and time format. */
1186 if (*decided != raw)
1188 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
1191 fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
1193 if (!recursive (fmt))
1195 if (*decided == loc)
1202 if (strcmp (fmt, HERE_D_T_FMT))
1209 /* The C locale has no era information, so use the
1210 normal representation. */
1211 if (!recursive (HERE_D_T_FMT))
1218 /* Match name of base year in locale's alternate
1220 /* XXX This is currently not implemented. It should
1221 use the value _NL_CURRENT (LC_TIME, ERA). */
1224 if (*decided != raw)
1226 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
1229 fmt = _NL_CURRENT (LC_TIME, D_FMT);
1231 if (!recursive (fmt))
1233 if (*decided == loc)
1240 if (strcmp (fmt, HERE_D_FMT))
1246 if (!recursive (HERE_D_FMT))
1250 if (*decided != raw)
1252 const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
1255 fmt = _NL_CURRENT (LC_TIME, T_FMT);
1257 if (!recursive (fmt))
1259 if (*decided == loc)
1266 if (strcmp (fmt, HERE_T_FMT))
1272 if (!recursive (HERE_T_FMT))
1280 /* We have no information about the era format. Just use
1281 the normal format. */
1282 if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
1283 && *fmt != 'x' && *fmt != 'X')
1284 /* This is an illegal format. */
1294 /* Match day of month using alternate numeric symbols. */
1295 get_alt_number (1, 31, 2);
1301 /* Match hour in 24-hour clock using alternate numeric
1303 get_alt_number (0, 23, 2);
1308 /* Match hour in 12-hour clock using alternate numeric
1310 get_alt_number (1, 12, 2);
1311 tm->tm_hour = val - 1;
1315 /* Match month using alternate numeric symbols. */
1316 get_alt_number (1, 12, 2);
1317 tm->tm_mon = val - 1;
1322 /* Match minutes using alternate numeric symbols. */
1323 get_alt_number (0, 59, 2);
1327 /* Match seconds using alternate numeric symbols. */
1328 get_alt_number (0, 61, 2);
1334 get_alt_number (0, 53, 2);
1335 /* XXX This cannot determine any field in TM without
1336 further information. */
1339 /* Match number of weekday using alternate numeric symbols. */
1340 get_alt_number (0, 6, 1);
1345 /* Match year within century using alternate numeric symbols. */
1346 get_alt_number (0, 99, 2);
1347 tm->tm_year = val >= 69 ? val : val + 100;
1359 if (have_I && is_pm)
1365 tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
1367 /* Only the century, but not the year. Strange, but so be it. */
1368 tm->tm_year = (century - 19) * 100;
1371 if (want_xday && !have_wday) {
1372 if ( !(have_mon && have_mday) && have_yday) {
1373 /* we don't have tm_mon and/or tm_mday, compute them */
1375 while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
1378 tm->tm_mon = t_mon - 1;
1380 tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
1382 day_of_the_week (tm);
1384 if (want_xday && !have_yday)
1385 day_of_the_year (tm);
1392 strptime (buf, format, tm)
1397 enum locale_status decided;
1403 return strptime_internal (buf, format, tm, &decided);
1405 #endif /* not HAVE_STRPTIME */
1407 #ifdef NEED_MON_YDAY
1408 /* __mon_yday[][] is common to mktime and strptime implementations.
1410 const unsigned short int __mon_yday[2][13] =
1413 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
1415 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
1422 /* A simple usleep implementation based on select(). For Unix and
1423 Unix-like systems. */
1426 usleep (unsigned long usec)
1431 select (0, NULL, NULL, NULL, &tm);
1435 #endif /* not WINDOWS */
1436 #endif /* not HAVE_USLEEP */
1439 #ifndef HAVE_MEMMOVE
1441 memmove (char *dest, const char *source, unsigned length)
1445 /* Moving from low mem to hi mem; start at end. */
1446 for (source += length, dest += length; length; --length)
1447 *--dest = *--source;
1448 else if (source != dest)
1450 /* Moving from hi mem to low mem; start at beginning. */
1451 for (; length; --length)
1452 *dest++ = *source++;
1456 #endif /* not HAVE_MEMMOVE */