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 */
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 /* From GNU libc 2.0. */
211 /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
212 This file is part of the GNU C Library.
213 Contributed by Paul Eggert (eggert@twinsun.com). */
216 # define HAVE_LIMITS_H 1
217 # define HAVE_LOCALTIME_R 1
218 # define STDC_HEADERS 1
221 /* Assume that leap seconds are possible, unless told otherwise.
222 If the host has a `zic' command with a `-L leapsecondfilename' option,
223 then it supports leap seconds; otherwise it probably doesn't. */
224 #ifndef LEAP_SECONDS_POSSIBLE
225 # define LEAP_SECONDS_POSSIBLE 1
229 # define __P(args) PARAMS (args)
230 #endif /* Not __P. */
237 # define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
240 # define INT_MAX (~0 - INT_MIN)
244 /* The outer cast to time_t works around a bug in Cray C 5.0.3.0. */
245 # define TIME_T_MIN ((time_t) \
246 (0 < (time_t) -1 ? (time_t) 0 \
247 : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
250 # define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
253 #define TM_YEAR_BASE 1900
254 #define EPOCH_YEAR 1970
257 /* Nonzero if YEAR is a leap year (every 4 years,
258 except every 100th isn't, and every 400th is). */
259 # define __isleap(year) \
260 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
263 /* How many days come before each month (0-12). */
264 const unsigned short int __mon_yday[2][13] =
267 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
269 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
272 static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
273 time_t __mktime_internal __P ((struct tm *,
274 struct tm *(*) (const time_t *, struct tm *),
279 # define localtime_r __localtime_r
281 # if ! HAVE_LOCALTIME_R && ! defined localtime_r
282 /* Approximate localtime_r as best we can in its absence. */
283 # define localtime_r my_mktime_localtime_r
284 static struct tm *localtime_r __P ((const time_t *, struct tm *));
290 struct tm *l = localtime (t);
296 # endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
300 /* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
301 measured in seconds, ignoring leap seconds.
302 YEAR uses the same numbering as TM->tm_year.
303 All values are in range, except possibly YEAR.
304 If overflow occurs, yield the low order bits of the correct answer. */
306 ydhms_tm_diff (year, yday, hour, min, sec, tp)
307 int year, yday, hour, min, sec;
310 /* Compute intervening leap days correctly even if year is negative.
311 Take care to avoid int overflow. time_t overflow is OK, since
312 only the low order bits of the correct time_t answer are needed.
313 Don't convert to time_t until after all divisions are done, since
314 time_t might be unsigned. */
315 int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
316 int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
317 int a100 = a4 / 25 - (a4 % 25 < 0);
318 int b100 = b4 / 25 - (b4 % 25 < 0);
319 int a400 = a100 >> 2;
320 int b400 = b100 >> 2;
321 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
322 time_t years = year - (time_t) tp->tm_year;
323 time_t days = (365 * years + intervening_leap_days
324 + (yday - tp->tm_yday));
325 return (60 * (60 * (24 * days + (hour - tp->tm_hour))
326 + (min - tp->tm_min))
327 + (sec - tp->tm_sec));
331 static time_t localtime_offset;
333 /* Convert *TP to a time_t value. */
339 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
340 time zone names contained in the external variable `tzname' shall
341 be set as if the tzset() function had been called. */
345 return __mktime_internal (tp, localtime_r, &localtime_offset);
348 /* Convert *TP to a time_t value, inverting
349 the monotonic and mostly-unit-linear conversion function CONVERT.
350 Use *OFFSET to keep track of a guess at the offset of the result,
351 compared to what the result would be for UTC without leap seconds.
352 If *OFFSET's guess is correct, only one CONVERT call is needed. */
354 __mktime_internal (tp, convert, offset)
356 struct tm *(*convert) __P ((const time_t *, struct tm *));
362 /* The maximum number of probes (calls to CONVERT) should be enough
363 to handle any combinations of time zone rule changes, solar time,
364 and leap seconds. Posix.1 prohibits leap seconds, but some hosts
366 int remaining_probes = 4;
368 /* Time requested. Copy it in case CONVERT modifies *TP; this can
369 occur if TP is localtime's returned value and CONVERT is localtime. */
370 int sec = tp->tm_sec;
371 int min = tp->tm_min;
372 int hour = tp->tm_hour;
373 int mday = tp->tm_mday;
374 int mon = tp->tm_mon;
375 int year_requested = tp->tm_year;
376 int isdst = tp->tm_isdst;
378 /* Ensure that mon is in range, and set year accordingly. */
379 int mon_remainder = mon % 12;
380 int negative_mon_remainder = mon_remainder < 0;
381 int mon_years = mon / 12 - negative_mon_remainder;
382 int year = year_requested + mon_years;
384 /* The other values need not be in range:
385 the remaining code handles minor overflows correctly,
386 assuming int and time_t arithmetic wraps around.
387 Major overflows are caught at the end. */
389 /* Calculate day of year from year, month, and day of month.
390 The result need not be in range. */
391 int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
392 [mon_remainder + 12 * negative_mon_remainder])
395 int sec_requested = sec;
396 #if LEAP_SECONDS_POSSIBLE
397 /* Handle out-of-range seconds specially,
398 since ydhms_tm_diff assumes every minute has 60 seconds. */
405 /* Invert CONVERT by probing. First assume the same offset as last time.
406 Then repeatedly use the error to improve the guess. */
408 tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
409 tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
410 t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
412 for (t = t0 + *offset;
413 (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
415 if (--remaining_probes == 0)
418 /* Check whether tm.tm_isdst has the requested value, if any. */
419 if (0 <= isdst && 0 <= tm.tm_isdst)
421 int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
424 /* Move two hours in the direction indicated by the disagreement,
425 probe some more, and switch to a new time if found.
426 The largest known fallback due to daylight savings is two hours:
427 once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
428 time_t ot = t - 2 * 60 * 60 * dst_diff;
429 while (--remaining_probes != 0)
432 if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
433 (*convert) (&ot, &otm))))
440 break; /* Avoid a redundant probe. */
447 #if LEAP_SECONDS_POSSIBLE
448 if (sec_requested != tm.tm_sec)
450 /* Adjust time to reflect the tm_sec requested, not the normalized value.
451 Also, repair any damage from a false match due to a leap second. */
452 t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
453 (*convert) (&t, &tm);
457 if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
459 /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
460 so check for major overflows. A gross check suffices,
461 since if t has overflowed, it is off by a multiple of
462 TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
463 the difference that is bounded by a small value. */
465 double dyear = (double) year_requested + mon_years - tm.tm_year;
466 double dday = 366 * dyear + mday;
467 double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
469 if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
478 weak_alias (mktime, timelocal)
480 #endif /* not HAVE_MKTIME */
483 #ifndef HAVE_STRPTIME
484 /* From GNU libc 2.0.6. */
485 /* Ulrich, thanks for helping me out with this! --hniksic */
487 /* strptime - Convert a string representation of time to a time value.
488 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
489 This file is part of the GNU C Library.
490 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. */
492 /* XXX This version of the implementation is not really complete.
493 Some of the fields cannot add information alone. But if seeing
494 some of them in the same format (such as year, week and weekday)
495 this is enough information for determining the date. */
498 # define __P(args) PARAMS (args)
501 #if ! HAVE_LOCALTIME_R && ! defined (localtime_r)
503 #define localtime_r __localtime_r
505 /* Approximate localtime_r as best we can in its absence. */
506 #define localtime_r my_localtime_r
507 static struct tm *localtime_r __P ((const time_t *, struct tm *));
513 struct tm *l = localtime (t);
520 #endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
523 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL
524 #if defined __GNUC__ && __GNUC__ >= 2
525 # define match_string(cs1, s2) \
526 ({ size_t len = strlen (cs1); \
527 int result = strncasecmp ((cs1), (s2), len) == 0; \
528 if (result) (s2) += len; \
531 /* Oh come on. Get a reasonable compiler. */
532 # define match_string(cs1, s2) \
533 (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
535 /* We intentionally do not use isdigit() for testing because this will
536 lead to problems with the wide character version. */
537 #define get_number(from, to) \
540 if (*rp < '0' || *rp > '9') \
544 val += *rp++ - '0'; \
545 } while (val * 10 <= to && *rp >= '0' && *rp <= '9'); \
546 if (val < from || val > to) \
550 # define get_alt_number(from, to) \
552 if (*decided != raw) \
554 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
556 while (*alts != '\0') \
558 size_t len = strlen (alts); \
559 if (strncasecmp (alts, rp, len) == 0) \
561 alts = strchr (alts, '\0') + 1; \
566 if (*decided == loc && val != 0) \
575 get_number (from, to); \
578 # define get_alt_number(from, to) \
579 /* We don't have the alternate representation. */ \
582 #define recursive(new_fmt) \
583 (*(new_fmt) != '\0' \
584 && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
588 /* This is defined in locale/C-time.c in the GNU libc. */
589 extern const struct locale_data _nl_C_LC_TIME;
591 # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
592 # define ab_weekday_name \
593 (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
594 # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
595 # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
596 # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
597 # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
598 # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
599 # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
600 # define HERE_T_FMT_AMPM \
601 (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
602 # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
604 static char const weekday_name[][10] =
606 "Sunday", "Monday", "Tuesday", "Wednesday",
607 "Thursday", "Friday", "Saturday"
609 static char const ab_weekday_name[][4] =
611 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
613 static char const month_name[][10] =
615 "January", "February", "March", "April", "May", "June",
616 "July", "August", "September", "October", "November", "December"
618 static char const ab_month_name[][4] =
620 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
621 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
623 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
624 # define HERE_D_FMT "%m/%d/%y"
625 # define HERE_AM_STR "AM"
626 # define HERE_PM_STR "PM"
627 # define HERE_T_FMT_AMPM "%I:%M:%S %p"
628 # define HERE_T_FMT "%H:%M:%S"
631 /* Status of lookup: do we use the locale data or the raw data? */
632 enum locale_status { not, loc, raw };
635 strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
636 enum locale_status *decided));
639 strptime_internal (buf, format, tm, decided)
643 enum locale_status *decided;
657 /* A white space in the format string matches 0 more or white
658 space in the input string. */
661 while (ISSPACE (*rp))
667 /* Any character but `%' must be matched by the same character
668 in the iput string. */
671 match_char (*fmt++, *rp++);
677 /* We need this for handling the `E' modifier. */
683 /* Match the `%' character itself. */
684 match_char ('%', *rp++);
688 /* Match day of week. */
689 for (cnt = 0; cnt < 7; ++cnt)
694 if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
697 && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
702 if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
705 && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
706 ab_weekday_name[cnt]))
713 && (match_string (weekday_name[cnt], rp)
714 || match_string (ab_weekday_name[cnt], rp)))
721 /* Does not match a weekday name. */
728 /* Match month name. */
729 for (cnt = 0; cnt < 12; ++cnt)
734 if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
737 && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
742 if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
745 && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
752 if (match_string (month_name[cnt], rp)
753 || match_string (ab_month_name[cnt], rp))
760 /* Does not match a month name. */
765 /* Match locale's date and time format. */
769 if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
776 if (*decided == not &&
777 strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
784 if (!recursive (HERE_D_T_FMT))
788 /* Match century number. */
790 /* We don't need the number. */
794 /* Match day of month. */
802 if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
810 && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
819 /* Match standard day format. */
820 if (!recursive (HERE_D_FMT))
824 /* Match hour in 24-hour clock. */
830 /* Match hour in 12-hour clock. */
832 tm->tm_hour = val % 12;
836 /* Match day number of year. */
838 tm->tm_yday = val - 1;
841 /* Match number of month. */
843 tm->tm_mon = val - 1;
852 /* Match any white space. */
853 while (ISSPACE (*rp))
857 /* Match locale's equivalent of AM/PM. */
861 if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
863 if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
867 if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
869 if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
877 if (!match_string (HERE_AM_STR, rp))
878 if (match_string (HERE_PM_STR, rp))
887 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
894 if (*decided == not &&
895 strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
903 if (!recursive (HERE_T_FMT_AMPM))
907 if (!recursive ("%H:%M"))
912 /* The number of seconds may be very high so we cannot use
913 the `get_number' macro. Instead read the number
914 character for character and construct the result while
917 if (*rp < '0' || *rp > '9')
918 /* We need at least one digit. */
926 while (*rp >= '0' && *rp <= '9');
928 if (localtime_r (&secs, tm) == NULL)
929 /* Error in function. */
941 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
948 if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
957 if (!recursive (HERE_T_FMT))
962 tm->tm_wday = val % 7;
966 /* XXX This cannot determine any field in TM. */
969 if (*rp < '0' || *rp > '9')
971 /* XXX Ignore the number since we would need some more
972 information to compute a real date. */
975 while (*rp >= '0' && *rp <= '9');
981 /* XXX This cannot determine any field in TM without some
985 /* Match number of weekday. */
990 /* Match year within century. */
992 tm->tm_year = val >= 50 ? val : val + 100;
995 /* Match year including century number. */
996 if (sizeof (time_t) > 4)
997 get_number (0, 9999);
999 get_number (0, 2036);
1000 tm->tm_year = val - 1900;
1003 /* XXX How to handle this? */
1010 /* Match locale's alternate date and time format. */
1011 if (*decided != raw)
1013 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
1016 fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
1018 if (!recursive (fmt))
1020 if (*decided == loc)
1025 if (strcmp (fmt, HERE_D_T_FMT))
1031 /* The C locale has no era information, so use the
1032 normal representation. */
1033 if (!recursive (HERE_D_T_FMT))
1039 /* Match name of base year in locale's alternate
1041 /* XXX This is currently not implemented. It should
1042 use the value _NL_CURRENT (LC_TIME, ERA). */
1045 if (*decided != raw)
1047 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
1050 fmt = _NL_CURRENT (LC_TIME, D_FMT);
1052 if (!recursive (fmt))
1054 if (*decided == loc)
1059 if (strcmp (fmt, HERE_D_FMT))
1065 if (!recursive (HERE_D_FMT))
1069 if (*decided != raw)
1071 const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
1074 fmt = _NL_CURRENT (LC_TIME, T_FMT);
1076 if (!recursive (fmt))
1078 if (*decided == loc)
1083 if (strcmp (fmt, HERE_T_FMT))
1089 if (!recursive (HERE_T_FMT))
1097 /* We have no information about the era format. Just use
1098 the normal format. */
1099 if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
1100 && *fmt != 'x' && *fmt != 'X')
1101 /* This is an illegal format. */
1111 /* Match day of month using alternate numeric symbols. */
1112 get_alt_number (1, 31);
1116 /* Match hour in 24-hour clock using alternate numeric
1118 get_alt_number (0, 23);
1123 /* Match hour in 12-hour clock using alternate numeric
1125 get_alt_number (1, 12);
1126 tm->tm_hour = val - 1;
1130 /* Match month using alternate numeric symbols. */
1131 get_alt_number (1, 12);
1132 tm->tm_mon = val - 1;
1135 /* Match minutes using alternate numeric symbols. */
1136 get_alt_number (0, 59);
1140 /* Match seconds using alternate numeric symbols. */
1141 get_alt_number (0, 61);
1147 get_alt_number (0, 53);
1148 /* XXX This cannot determine any field in TM without
1149 further information. */
1152 /* Match number of weekday using alternate numeric symbols. */
1153 get_alt_number (0, 6);
1157 /* Match year within century using alternate numeric symbols. */
1158 get_alt_number (0, 99);
1169 if (have_I && is_pm)
1177 strptime (buf, format, tm)
1182 enum locale_status decided;
1188 return strptime_internal (buf, format, tm, &decided);
1190 #endif /* not HAVE_STRPTIME */