1 /* Replacements for routines missing on some systems.
2 Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
4 This file is part of Wget.
6 This program 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 This program 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 this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
28 #endif /* HAVE_STRING_H */
31 #include <sys/types.h>
40 /* A strerror() clone, for systems that don't have it. */
44 /* This loses on a system without `sys_errlist'. */
45 extern char *sys_errlist[];
46 return sys_errlist[err];
48 #endif /* not HAVE_STRERROR */
50 /* Some systems don't have some str* functions in libc. Here we
51 define them. The same goes for strptime. */
53 #ifndef HAVE_STRCASECMP
55 /* Compare S1 and S2, ignoring case, returning less than, equal to or
56 greater than zero if S1 is lexiographically less than,
57 equal to or greater than S2. */
59 strcasecmp (const char *s1, const char *s2)
61 register const unsigned char *p1 = (const unsigned char *) s1;
62 register const unsigned char *p2 = (const unsigned char *) s2;
79 #endif /* not HAVE_STRCASECMP */
81 #ifndef HAVE_STRNCASECMP
83 /* Compare no more than N characters of S1 and S2,
84 ignoring case, returning less than, equal to or
85 greater than zero if S1 is lexicographically less
86 than, equal to or greater than S2. */
88 strncasecmp (const char *s1, const char *s2, size_t n)
90 register const unsigned char *p1 = (const unsigned char *) s1;
91 register const unsigned char *p2 = (const unsigned char *) s2;
94 if (p1 == p2 || n == 0)
100 c2 = tolower (*p2++);
101 if (c1 == '\0' || c1 != c2)
107 #endif /* not HAVE_STRNCASECMP */
110 /* From GNU libc 2.0.6. */
111 /* Return the first ocurrence of NEEDLE in HAYSTACK. */
113 * My personal strstr() implementation that beats most other algorithms.
114 * Until someone tells me otherwise, I assume that this is the
115 * fastest implementation of strstr() in C.
116 * I deliberately chose not to comment it. You should have at least
117 * as much fun trying to understand it, as I had to write it :-).
119 * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
120 typedef unsigned chartype;
123 strstr (phaystack, pneedle)
124 const char *phaystack;
127 register const unsigned char *haystack, *needle;
128 register chartype b, c;
130 haystack = (const unsigned char *) phaystack;
131 needle = (const unsigned char *) pneedle;
136 haystack--; /* possible ANSI violation */
154 register const unsigned char *rhaystack, *rneedle;
169 jin: a = *++haystack;
176 rhaystack = haystack-- + 1;
194 while (*rhaystack == a);
196 needle = rneedle; /* took the register-poor approach */
203 return (char*) haystack;
207 #endif /* not HAVE_STRSTR */
210 /* From GNU libc 2.0. */
212 /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
213 This file is part of the GNU C Library.
214 Contributed by Paul Eggert (eggert@twinsun.com). */
217 # define HAVE_LIMITS_H 1
218 # define HAVE_LOCALTIME_R 1
219 # define STDC_HEADERS 1
222 /* Assume that leap seconds are possible, unless told otherwise.
223 If the host has a `zic' command with a `-L leapsecondfilename' option,
224 then it supports leap seconds; otherwise it probably doesn't. */
225 #ifndef LEAP_SECONDS_POSSIBLE
226 # define LEAP_SECONDS_POSSIBLE 1
230 # define __P(args) PARAMS (args)
231 #endif /* Not __P. */
238 # define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
241 # define INT_MAX (~0 - INT_MIN)
245 /* The outer cast to time_t works around a bug in Cray C 5.0.3.0. */
246 # define TIME_T_MIN ((time_t) \
247 (0 < (time_t) -1 ? (time_t) 0 \
248 : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
251 # define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
254 #define TM_YEAR_BASE 1900
255 #define EPOCH_YEAR 1970
258 /* Nonzero if YEAR is a leap year (every 4 years,
259 except every 100th isn't, and every 400th is). */
260 # define __isleap(year) \
261 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
264 /* How many days come before each month (0-12). */
265 const unsigned short int __mon_yday[2][13] =
268 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
270 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
273 static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
274 time_t __mktime_internal __P ((struct tm *,
275 struct tm *(*) (const time_t *, struct tm *),
280 # define localtime_r __localtime_r
282 # if ! HAVE_LOCALTIME_R && ! defined localtime_r
283 /* Approximate localtime_r as best we can in its absence. */
284 # define localtime_r my_mktime_localtime_r
285 static struct tm *localtime_r __P ((const time_t *, struct tm *));
291 struct tm *l = localtime (t);
297 # endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
301 /* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
302 measured in seconds, ignoring leap seconds.
303 YEAR uses the same numbering as TM->tm_year.
304 All values are in range, except possibly YEAR.
305 If overflow occurs, yield the low order bits of the correct answer. */
307 ydhms_tm_diff (year, yday, hour, min, sec, tp)
308 int year, yday, hour, min, sec;
311 /* Compute intervening leap days correctly even if year is negative.
312 Take care to avoid int overflow. time_t overflow is OK, since
313 only the low order bits of the correct time_t answer are needed.
314 Don't convert to time_t until after all divisions are done, since
315 time_t might be unsigned. */
316 int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
317 int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
318 int a100 = a4 / 25 - (a4 % 25 < 0);
319 int b100 = b4 / 25 - (b4 % 25 < 0);
320 int a400 = a100 >> 2;
321 int b400 = b100 >> 2;
322 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
323 time_t years = year - (time_t) tp->tm_year;
324 time_t days = (365 * years + intervening_leap_days
325 + (yday - tp->tm_yday));
326 return (60 * (60 * (24 * days + (hour - tp->tm_hour))
327 + (min - tp->tm_min))
328 + (sec - tp->tm_sec));
332 static time_t localtime_offset;
334 /* Convert *TP to a time_t value. */
340 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
341 time zone names contained in the external variable `tzname' shall
342 be set as if the tzset() function had been called. */
346 return __mktime_internal (tp, localtime_r, &localtime_offset);
349 /* Convert *TP to a time_t value, inverting
350 the monotonic and mostly-unit-linear conversion function CONVERT.
351 Use *OFFSET to keep track of a guess at the offset of the result,
352 compared to what the result would be for UTC without leap seconds.
353 If *OFFSET's guess is correct, only one CONVERT call is needed. */
355 __mktime_internal (tp, convert, offset)
357 struct tm *(*convert) __P ((const time_t *, struct tm *));
363 /* The maximum number of probes (calls to CONVERT) should be enough
364 to handle any combinations of time zone rule changes, solar time,
365 and leap seconds. Posix.1 prohibits leap seconds, but some hosts
367 int remaining_probes = 4;
369 /* Time requested. Copy it in case CONVERT modifies *TP; this can
370 occur if TP is localtime's returned value and CONVERT is localtime. */
371 int sec = tp->tm_sec;
372 int min = tp->tm_min;
373 int hour = tp->tm_hour;
374 int mday = tp->tm_mday;
375 int mon = tp->tm_mon;
376 int year_requested = tp->tm_year;
377 int isdst = tp->tm_isdst;
379 /* Ensure that mon is in range, and set year accordingly. */
380 int mon_remainder = mon % 12;
381 int negative_mon_remainder = mon_remainder < 0;
382 int mon_years = mon / 12 - negative_mon_remainder;
383 int year = year_requested + mon_years;
385 /* The other values need not be in range:
386 the remaining code handles minor overflows correctly,
387 assuming int and time_t arithmetic wraps around.
388 Major overflows are caught at the end. */
390 /* Calculate day of year from year, month, and day of month.
391 The result need not be in range. */
392 int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
393 [mon_remainder + 12 * negative_mon_remainder])
396 int sec_requested = sec;
397 #if LEAP_SECONDS_POSSIBLE
398 /* Handle out-of-range seconds specially,
399 since ydhms_tm_diff assumes every minute has 60 seconds. */
406 /* Invert CONVERT by probing. First assume the same offset as last time.
407 Then repeatedly use the error to improve the guess. */
409 tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
410 tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
411 t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
413 for (t = t0 + *offset;
414 (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
416 if (--remaining_probes == 0)
419 /* Check whether tm.tm_isdst has the requested value, if any. */
420 if (0 <= isdst && 0 <= tm.tm_isdst)
422 int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
425 /* Move two hours in the direction indicated by the disagreement,
426 probe some more, and switch to a new time if found.
427 The largest known fallback due to daylight savings is two hours:
428 once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
429 time_t ot = t - 2 * 60 * 60 * dst_diff;
430 while (--remaining_probes != 0)
433 if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
434 (*convert) (&ot, &otm))))
441 break; /* Avoid a redundant probe. */
448 #if LEAP_SECONDS_POSSIBLE
449 if (sec_requested != tm.tm_sec)
451 /* Adjust time to reflect the tm_sec requested, not the normalized value.
452 Also, repair any damage from a false match due to a leap second. */
453 t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
454 (*convert) (&t, &tm);
458 if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
460 /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
461 so check for major overflows. A gross check suffices,
462 since if t has overflowed, it is off by a multiple of
463 TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
464 the difference that is bounded by a small value. */
466 double dyear = (double) year_requested + mon_years - tm.tm_year;
467 double dday = 366 * dyear + mday;
468 double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
470 if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
479 weak_alias (mktime, timelocal)
481 #endif /* not HAVE_MKTIME */
484 #ifndef HAVE_STRPTIME
485 /* From GNU libc 2.0.6. */
486 /* Ulrich, thanks for helping me out with this! --hniksic */
488 /* strptime - Convert a string representation of time to a time value.
489 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
490 This file is part of the GNU C Library.
491 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. */
493 /* XXX This version of the implementation is not really complete.
494 Some of the fields cannot add information alone. But if seeing
495 some of them in the same format (such as year, week and weekday)
496 this is enough information for determining the date. */
499 # define __P(args) PARAMS (args)
502 #if ! HAVE_LOCALTIME_R && ! defined (localtime_r)
504 #define localtime_r __localtime_r
506 /* Approximate localtime_r as best we can in its absence. */
507 #define localtime_r my_localtime_r
508 static struct tm *localtime_r __P ((const time_t *, struct tm *));
514 struct tm *l = localtime (t);
521 #endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
524 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL
525 #if defined __GNUC__ && __GNUC__ >= 2
526 # define match_string(cs1, s2) \
527 ({ size_t len = strlen (cs1); \
528 int result = strncasecmp ((cs1), (s2), len) == 0; \
529 if (result) (s2) += len; \
532 /* Oh come on. Get a reasonable compiler. */
533 # define match_string(cs1, s2) \
534 (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
536 /* We intentionally do not use isdigit() for testing because this will
537 lead to problems with the wide character version. */
538 #define get_number(from, to) \
541 if (*rp < '0' || *rp > '9') \
545 val += *rp++ - '0'; \
546 } while (val * 10 <= to && *rp >= '0' && *rp <= '9'); \
547 if (val < from || val > to) \
551 # define get_alt_number(from, to) \
553 if (*decided != raw) \
555 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
557 while (*alts != '\0') \
559 size_t len = strlen (alts); \
560 if (strncasecmp (alts, rp, len) == 0) \
562 alts = strchr (alts, '\0') + 1; \
567 if (*decided == loc && val != 0) \
576 get_number (from, to); \
579 # define get_alt_number(from, to) \
580 /* We don't have the alternate representation. */ \
583 #define recursive(new_fmt) \
584 (*(new_fmt) != '\0' \
585 && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
589 /* This is defined in locale/C-time.c in the GNU libc. */
590 extern const struct locale_data _nl_C_LC_TIME;
592 # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
593 # define ab_weekday_name \
594 (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
595 # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
596 # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
597 # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
598 # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
599 # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
600 # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
601 # define HERE_T_FMT_AMPM \
602 (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
603 # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
605 static char const weekday_name[][10] =
607 "Sunday", "Monday", "Tuesday", "Wednesday",
608 "Thursday", "Friday", "Saturday"
610 static char const ab_weekday_name[][4] =
612 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
614 static char const month_name[][10] =
616 "January", "February", "March", "April", "May", "June",
617 "July", "August", "September", "October", "November", "December"
619 static char const ab_month_name[][4] =
621 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
622 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
624 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
625 # define HERE_D_FMT "%m/%d/%y"
626 # define HERE_AM_STR "AM"
627 # define HERE_PM_STR "PM"
628 # define HERE_T_FMT_AMPM "%I:%M:%S %p"
629 # define HERE_T_FMT "%H:%M:%S"
632 /* Status of lookup: do we use the locale data or the raw data? */
633 enum locale_status { not, loc, raw };
636 strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
637 enum locale_status *decided));
640 strptime_internal (buf, format, tm, decided)
644 enum locale_status *decided;
658 /* A white space in the format string matches 0 more or white
659 space in the input string. */
662 while (isspace (*rp))
668 /* Any character but `%' must be matched by the same character
669 in the iput string. */
672 match_char (*fmt++, *rp++);
678 /* We need this for handling the `E' modifier. */
684 /* Match the `%' character itself. */
685 match_char ('%', *rp++);
689 /* Match day of week. */
690 for (cnt = 0; cnt < 7; ++cnt)
695 if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
698 && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
703 if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
706 && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
707 ab_weekday_name[cnt]))
714 && (match_string (weekday_name[cnt], rp)
715 || match_string (ab_weekday_name[cnt], rp)))
722 /* Does not match a weekday name. */
729 /* Match month name. */
730 for (cnt = 0; cnt < 12; ++cnt)
735 if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
738 && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
743 if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
746 && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
753 if (match_string (month_name[cnt], rp)
754 || match_string (ab_month_name[cnt], rp))
761 /* Does not match a month name. */
766 /* Match locale's date and time format. */
770 if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
777 if (*decided == not &&
778 strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
785 if (!recursive (HERE_D_T_FMT))
789 /* Match century number. */
791 /* We don't need the number. */
795 /* Match day of month. */
803 if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
811 && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
820 /* Match standard day format. */
821 if (!recursive (HERE_D_FMT))
825 /* Match hour in 24-hour clock. */
831 /* Match hour in 12-hour clock. */
833 tm->tm_hour = val % 12;
837 /* Match day number of year. */
839 tm->tm_yday = val - 1;
842 /* Match number of month. */
844 tm->tm_mon = val - 1;
853 /* Match any white space. */
854 while (isspace (*rp))
858 /* Match locale's equivalent of AM/PM. */
862 if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
864 if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
868 if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
870 if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
878 if (!match_string (HERE_AM_STR, rp))
879 if (match_string (HERE_PM_STR, rp))
888 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
895 if (*decided == not &&
896 strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
904 if (!recursive (HERE_T_FMT_AMPM))
908 if (!recursive ("%H:%M"))
913 /* The number of seconds may be very high so we cannot use
914 the `get_number' macro. Instead read the number
915 character for character and construct the result while
918 if (*rp < '0' || *rp > '9')
919 /* We need at least one digit. */
927 while (*rp >= '0' && *rp <= '9');
929 if (localtime_r (&secs, tm) == NULL)
930 /* Error in function. */
942 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
949 if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
958 if (!recursive (HERE_T_FMT))
963 tm->tm_wday = val % 7;
967 /* XXX This cannot determine any field in TM. */
970 if (*rp < '0' || *rp > '9')
972 /* XXX Ignore the number since we would need some more
973 information to compute a real date. */
976 while (*rp >= '0' && *rp <= '9');
982 /* XXX This cannot determine any field in TM without some
986 /* Match number of weekday. */
991 /* Match year within century. */
993 tm->tm_year = val >= 50 ? val : val + 100;
996 /* Match year including century number. */
997 if (sizeof (time_t) > 4)
998 get_number (0, 9999);
1000 get_number (0, 2036);
1001 tm->tm_year = val - 1900;
1004 /* XXX How to handle this? */
1011 /* Match locale's alternate date and time format. */
1012 if (*decided != raw)
1014 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
1017 fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
1019 if (!recursive (fmt))
1021 if (*decided == loc)
1026 if (strcmp (fmt, HERE_D_T_FMT))
1032 /* The C locale has no era information, so use the
1033 normal representation. */
1034 if (!recursive (HERE_D_T_FMT))
1040 /* Match name of base year in locale's alternate
1042 /* XXX This is currently not implemented. It should
1043 use the value _NL_CURRENT (LC_TIME, ERA). */
1046 if (*decided != raw)
1048 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
1051 fmt = _NL_CURRENT (LC_TIME, D_FMT);
1053 if (!recursive (fmt))
1055 if (*decided == loc)
1060 if (strcmp (fmt, HERE_D_FMT))
1066 if (!recursive (HERE_D_FMT))
1070 if (*decided != raw)
1072 const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
1075 fmt = _NL_CURRENT (LC_TIME, T_FMT);
1077 if (!recursive (fmt))
1079 if (*decided == loc)
1084 if (strcmp (fmt, HERE_T_FMT))
1090 if (!recursive (HERE_T_FMT))
1098 /* We have no information about the era format. Just use
1099 the normal format. */
1100 if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
1101 && *fmt != 'x' && *fmt != 'X')
1102 /* This is an illegal format. */
1112 /* Match day of month using alternate numeric symbols. */
1113 get_alt_number (1, 31);
1117 /* Match hour in 24-hour clock using alternate numeric
1119 get_alt_number (0, 23);
1124 /* Match hour in 12-hour clock using alternate numeric
1126 get_alt_number (1, 12);
1127 tm->tm_hour = val - 1;
1131 /* Match month using alternate numeric symbols. */
1132 get_alt_number (1, 12);
1133 tm->tm_mon = val - 1;
1136 /* Match minutes using alternate numeric symbols. */
1137 get_alt_number (0, 59);
1141 /* Match seconds using alternate numeric symbols. */
1142 get_alt_number (0, 61);
1148 get_alt_number (0, 53);
1149 /* XXX This cannot determine any field in TM without
1150 further information. */
1153 /* Match number of weekday using alternate numeric symbols. */
1154 get_alt_number (0, 6);
1158 /* Match year within century using alternate numeric symbols. */
1159 get_alt_number (0, 99);
1170 if (have_I && is_pm)
1178 strptime (buf, format, tm)
1183 enum locale_status decided;
1189 return strptime_internal (buf, format, tm, &decided);
1191 #endif /* not HAVE_STRPTIME */