00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "replace.h"
00027 #include "system/locale.h"
00028 #include "system/time.h"
00029
00030 #ifndef __P
00031 # if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
00032 # define __P(args) args
00033 # else
00034 # define __P(args) ()
00035 # endif
00036 #endif
00037
00038 #if ! HAVE_LOCALTIME_R && ! defined localtime_r
00039 # ifdef _LIBC
00040 # define localtime_r __localtime_r
00041 # else
00042
00043 # define localtime_r my_localtime_r
00044 static struct tm *localtime_r __P ((const time_t *, struct tm *));
00045 static struct tm *
00046 localtime_r (t, tp)
00047 const time_t *t;
00048 struct tm *tp;
00049 {
00050 struct tm *l = localtime (t);
00051 if (! l)
00052 return 0;
00053 *tp = *l;
00054 return tp;
00055 }
00056 # endif
00057 #endif
00058
00059
00060 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL
00061 #if defined __GNUC__ && __GNUC__ >= 2
00062 # define match_string(cs1, s2) \
00063 ({ size_t len = strlen (cs1); \
00064 int result = strncasecmp ((cs1), (s2), len) == 0; \
00065 if (result) (s2) += len; \
00066 result; })
00067 #else
00068
00069 # define match_string(cs1, s2) \
00070 (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
00071 #endif
00072
00073
00074 #define get_number(from, to, n) \
00075 do { \
00076 int __n = n; \
00077 val = 0; \
00078 while (*rp == ' ') \
00079 ++rp; \
00080 if (*rp < '0' || *rp > '9') \
00081 return NULL; \
00082 do { \
00083 val *= 10; \
00084 val += *rp++ - '0'; \
00085 } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \
00086 if (val < from || val > to) \
00087 return NULL; \
00088 } while (0)
00089 #ifdef _NL_CURRENT
00090 # define get_alt_number(from, to, n) \
00091 ({ \
00092 __label__ do_normal; \
00093 if (*decided != raw) \
00094 { \
00095 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
00096 int __n = n; \
00097 int any = 0; \
00098 while (*rp == ' ') \
00099 ++rp; \
00100 val = 0; \
00101 do { \
00102 val *= 10; \
00103 while (*alts != '\0') \
00104 { \
00105 size_t len = strlen (alts); \
00106 if (strncasecmp (alts, rp, len) == 0) \
00107 break; \
00108 alts += len + 1; \
00109 ++val; \
00110 } \
00111 if (*alts == '\0') \
00112 { \
00113 if (*decided == not && ! any) \
00114 goto do_normal; \
00115 \
00116 if (! any) \
00117 return NULL; \
00118 \
00119 val /= 10; \
00120 break; \
00121 } \
00122 else \
00123 *decided = loc; \
00124 } while (--__n > 0 && val * 10 <= to); \
00125 if (val < from || val > to) \
00126 return NULL; \
00127 } \
00128 else \
00129 { \
00130 do_normal: \
00131 get_number (from, to, n); \
00132 } \
00133 0; \
00134 })
00135 #else
00136 # define get_alt_number(from, to, n) \
00137 \
00138 get_number(from, to, n)
00139 #endif
00140 #define recursive(new_fmt) \
00141 (*(new_fmt) != '\0' \
00142 && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL)
00143
00144
00145 #ifdef _LIBC
00146
00147 extern const struct locale_data _nl_C_LC_TIME;
00148 extern const unsigned short int __mon_yday[2][13];
00149
00150 # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
00151 # define ab_weekday_name \
00152 (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
00153 # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
00154 # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
00155 # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
00156 # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
00157 # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
00158 # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
00159 # define HERE_T_FMT_AMPM \
00160 (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
00161 # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
00162
00163 # define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
00164 #else
00165 static char const weekday_name[][10] =
00166 {
00167 "Sunday", "Monday", "Tuesday", "Wednesday",
00168 "Thursday", "Friday", "Saturday"
00169 };
00170 static char const ab_weekday_name[][4] =
00171 {
00172 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
00173 };
00174 static char const month_name[][10] =
00175 {
00176 "January", "February", "March", "April", "May", "June",
00177 "July", "August", "September", "October", "November", "December"
00178 };
00179 static char const ab_month_name[][4] =
00180 {
00181 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00182 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
00183 };
00184 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
00185 # define HERE_D_FMT "%m/%d/%y"
00186 # define HERE_AM_STR "AM"
00187 # define HERE_PM_STR "PM"
00188 # define HERE_T_FMT_AMPM "%I:%M:%S %p"
00189 # define HERE_T_FMT "%H:%M:%S"
00190
00191 static const unsigned short int __mon_yday[2][13] =
00192 {
00193
00194 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
00195
00196 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
00197 };
00198 #endif
00199
00200
00201 enum locale_status { not, loc, raw };
00202
00203
00204 #ifndef __isleap
00205
00206
00207 # define __isleap(year) \
00208 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
00209 #endif
00210
00211
00212 static void
00213 day_of_the_week (struct tm *tm)
00214 {
00215
00216
00217
00218 int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
00219 int wday = (-473
00220 + (365 * (tm->tm_year - 70))
00221 + (corr_year / 4)
00222 - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
00223 + (((corr_year / 4) / 25) / 4)
00224 + __mon_yday[0][tm->tm_mon]
00225 + tm->tm_mday - 1);
00226 tm->tm_wday = ((wday % 7) + 7) % 7;
00227 }
00228
00229
00230 static void
00231 day_of_the_year (struct tm *tm)
00232 {
00233 tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
00234 + (tm->tm_mday - 1));
00235 }
00236
00237 static char *
00238 #ifdef _LIBC
00239 internal_function
00240 #endif
00241 strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm,
00242 enum locale_status *decided, int era_cnt));
00243
00244 static char *
00245 #ifdef _LIBC
00246 internal_function
00247 #endif
00248 strptime_internal (rp, fmt, tm, decided, era_cnt)
00249 const char *rp;
00250 const char *fmt;
00251 struct tm *tm;
00252 enum locale_status *decided;
00253 int era_cnt;
00254 {
00255 const char *rp_backup;
00256 int cnt;
00257 size_t val;
00258 int have_I, is_pm;
00259 int century, want_century;
00260 int want_era;
00261 int have_wday, want_xday;
00262 int have_yday;
00263 int have_mon, have_mday;
00264 #ifdef _NL_CURRENT
00265 size_t num_eras;
00266 #endif
00267 struct era_entry *era;
00268
00269 have_I = is_pm = 0;
00270 century = -1;
00271 want_century = 0;
00272 want_era = 0;
00273 era = NULL;
00274
00275 have_wday = want_xday = have_yday = have_mon = have_mday = 0;
00276
00277 while (*fmt != '\0')
00278 {
00279
00280
00281 if (isspace (*fmt))
00282 {
00283 while (isspace (*rp))
00284 ++rp;
00285 ++fmt;
00286 continue;
00287 }
00288
00289
00290
00291 if (*fmt != '%')
00292 {
00293 match_char (*fmt++, *rp++);
00294 continue;
00295 }
00296
00297 ++fmt;
00298 #ifndef _NL_CURRENT
00299
00300 start_over:
00301 #endif
00302
00303
00304 rp_backup = rp;
00305
00306 switch (*fmt++)
00307 {
00308 case '%':
00309
00310 match_char ('%', *rp++);
00311 break;
00312 case 'a':
00313 case 'A':
00314
00315 for (cnt = 0; cnt < 7; ++cnt)
00316 {
00317 #ifdef _NL_CURRENT
00318 if (*decided !=raw)
00319 {
00320 if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
00321 {
00322 if (*decided == not
00323 && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
00324 weekday_name[cnt]))
00325 *decided = loc;
00326 break;
00327 }
00328 if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
00329 {
00330 if (*decided == not
00331 && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
00332 ab_weekday_name[cnt]))
00333 *decided = loc;
00334 break;
00335 }
00336 }
00337 #endif
00338 if (*decided != loc
00339 && (match_string (weekday_name[cnt], rp)
00340 || match_string (ab_weekday_name[cnt], rp)))
00341 {
00342 *decided = raw;
00343 break;
00344 }
00345 }
00346 if (cnt == 7)
00347
00348 return NULL;
00349 tm->tm_wday = cnt;
00350 have_wday = 1;
00351 break;
00352 case 'b':
00353 case 'B':
00354 case 'h':
00355
00356 for (cnt = 0; cnt < 12; ++cnt)
00357 {
00358 #ifdef _NL_CURRENT
00359 if (*decided !=raw)
00360 {
00361 if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
00362 {
00363 if (*decided == not
00364 && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
00365 month_name[cnt]))
00366 *decided = loc;
00367 break;
00368 }
00369 if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
00370 {
00371 if (*decided == not
00372 && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
00373 ab_month_name[cnt]))
00374 *decided = loc;
00375 break;
00376 }
00377 }
00378 #endif
00379 if (match_string (month_name[cnt], rp)
00380 || match_string (ab_month_name[cnt], rp))
00381 {
00382 *decided = raw;
00383 break;
00384 }
00385 }
00386 if (cnt == 12)
00387
00388 return NULL;
00389 tm->tm_mon = cnt;
00390 want_xday = 1;
00391 break;
00392 case 'c':
00393
00394 #ifdef _NL_CURRENT
00395 if (*decided != raw)
00396 {
00397 if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
00398 {
00399 if (*decided == loc)
00400 return NULL;
00401 else
00402 rp = rp_backup;
00403 }
00404 else
00405 {
00406 if (*decided == not &&
00407 strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
00408 *decided = loc;
00409 want_xday = 1;
00410 break;
00411 }
00412 *decided = raw;
00413 }
00414 #endif
00415 if (!recursive (HERE_D_T_FMT))
00416 return NULL;
00417 want_xday = 1;
00418 break;
00419 case 'C':
00420
00421 #ifdef _NL_CURRENT
00422 match_century:
00423 #endif
00424 get_number (0, 99, 2);
00425 century = val;
00426 want_xday = 1;
00427 break;
00428 case 'd':
00429 case 'e':
00430
00431 get_number (1, 31, 2);
00432 tm->tm_mday = val;
00433 have_mday = 1;
00434 want_xday = 1;
00435 break;
00436 case 'F':
00437 if (!recursive ("%Y-%m-%d"))
00438 return NULL;
00439 want_xday = 1;
00440 break;
00441 case 'x':
00442 #ifdef _NL_CURRENT
00443 if (*decided != raw)
00444 {
00445 if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
00446 {
00447 if (*decided == loc)
00448 return NULL;
00449 else
00450 rp = rp_backup;
00451 }
00452 else
00453 {
00454 if (*decided == not
00455 && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
00456 *decided = loc;
00457 want_xday = 1;
00458 break;
00459 }
00460 *decided = raw;
00461 }
00462 #endif
00463
00464 case 'D':
00465
00466 if (!recursive (HERE_D_FMT))
00467 return NULL;
00468 want_xday = 1;
00469 break;
00470 case 'k':
00471 case 'H':
00472
00473 get_number (0, 23, 2);
00474 tm->tm_hour = val;
00475 have_I = 0;
00476 break;
00477 case 'I':
00478
00479 get_number (1, 12, 2);
00480 tm->tm_hour = val % 12;
00481 have_I = 1;
00482 break;
00483 case 'j':
00484
00485 get_number (1, 366, 3);
00486 tm->tm_yday = val - 1;
00487 have_yday = 1;
00488 break;
00489 case 'm':
00490
00491 get_number (1, 12, 2);
00492 tm->tm_mon = val - 1;
00493 have_mon = 1;
00494 want_xday = 1;
00495 break;
00496 case 'M':
00497
00498 get_number (0, 59, 2);
00499 tm->tm_min = val;
00500 break;
00501 case 'n':
00502 case 't':
00503
00504 while (isspace (*rp))
00505 ++rp;
00506 break;
00507 case 'p':
00508
00509 #ifdef _NL_CURRENT
00510 if (*decided != raw)
00511 {
00512 if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
00513 {
00514 if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
00515 *decided = loc;
00516 break;
00517 }
00518 if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
00519 {
00520 if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
00521 *decided = loc;
00522 is_pm = 1;
00523 break;
00524 }
00525 *decided = raw;
00526 }
00527 #endif
00528 if (!match_string (HERE_AM_STR, rp)) {
00529 if (match_string (HERE_PM_STR, rp)) {
00530 is_pm = 1;
00531 } else {
00532 return NULL;
00533 }
00534 }
00535 break;
00536 case 'r':
00537 #ifdef _NL_CURRENT
00538 if (*decided != raw)
00539 {
00540 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
00541 {
00542 if (*decided == loc)
00543 return NULL;
00544 else
00545 rp = rp_backup;
00546 }
00547 else
00548 {
00549 if (*decided == not &&
00550 strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
00551 HERE_T_FMT_AMPM))
00552 *decided = loc;
00553 break;
00554 }
00555 *decided = raw;
00556 }
00557 #endif
00558 if (!recursive (HERE_T_FMT_AMPM))
00559 return NULL;
00560 break;
00561 case 'R':
00562 if (!recursive ("%H:%M"))
00563 return NULL;
00564 break;
00565 case 's':
00566 {
00567
00568
00569
00570
00571 time_t secs = 0;
00572 if (*rp < '0' || *rp > '9')
00573
00574 return NULL;
00575
00576 do
00577 {
00578 secs *= 10;
00579 secs += *rp++ - '0';
00580 }
00581 while (*rp >= '0' && *rp <= '9');
00582
00583 if (localtime_r (&secs, tm) == NULL)
00584
00585 return NULL;
00586 }
00587 break;
00588 case 'S':
00589 get_number (0, 61, 2);
00590 tm->tm_sec = val;
00591 break;
00592 case 'X':
00593 #ifdef _NL_CURRENT
00594 if (*decided != raw)
00595 {
00596 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
00597 {
00598 if (*decided == loc)
00599 return NULL;
00600 else
00601 rp = rp_backup;
00602 }
00603 else
00604 {
00605 if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
00606 *decided = loc;
00607 break;
00608 }
00609 *decided = raw;
00610 }
00611 #endif
00612
00613 case 'T':
00614 if (!recursive (HERE_T_FMT))
00615 return NULL;
00616 break;
00617 case 'u':
00618 get_number (1, 7, 1);
00619 tm->tm_wday = val % 7;
00620 have_wday = 1;
00621 break;
00622 case 'g':
00623 get_number (0, 99, 2);
00624
00625 break;
00626 case 'G':
00627 if (*rp < '0' || *rp > '9')
00628 return NULL;
00629
00630
00631 do
00632 ++rp;
00633 while (*rp >= '0' && *rp <= '9');
00634 break;
00635 case 'U':
00636 case 'V':
00637 case 'W':
00638 get_number (0, 53, 2);
00639
00640
00641 break;
00642 case 'w':
00643
00644 get_number (0, 6, 1);
00645 tm->tm_wday = val;
00646 have_wday = 1;
00647 break;
00648 case 'y':
00649 #ifdef _NL_CURRENT
00650 match_year_in_century:
00651 #endif
00652
00653 get_number (0, 99, 2);
00654
00655
00656 tm->tm_year = val >= 69 ? val : val + 100;
00657
00658 want_century = 1;
00659 want_xday = 1;
00660 break;
00661 case 'Y':
00662
00663 get_number (0, 9999, 4);
00664 tm->tm_year = val - 1900;
00665 want_century = 0;
00666 want_xday = 1;
00667 break;
00668 case 'Z':
00669
00670 break;
00671 case 'E':
00672 #ifdef _NL_CURRENT
00673 switch (*fmt++)
00674 {
00675 case 'c':
00676
00677 if (*decided != raw)
00678 {
00679 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
00680
00681 if (*fmt == '\0')
00682 fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
00683
00684 if (!recursive (fmt))
00685 {
00686 if (*decided == loc)
00687 return NULL;
00688 else
00689 rp = rp_backup;
00690 }
00691 else
00692 {
00693 if (strcmp (fmt, HERE_D_T_FMT))
00694 *decided = loc;
00695 want_xday = 1;
00696 break;
00697 }
00698 *decided = raw;
00699 }
00700
00701
00702 if (!recursive (HERE_D_T_FMT))
00703 return NULL;
00704 want_xday = 1;
00705 break;
00706 case 'C':
00707 if (*decided != raw)
00708 {
00709 if (era_cnt >= 0)
00710 {
00711 era = _nl_select_era_entry (era_cnt);
00712 if (match_string (era->era_name, rp))
00713 {
00714 *decided = loc;
00715 break;
00716 }
00717 else
00718 return NULL;
00719 }
00720 else
00721 {
00722 num_eras = _NL_CURRENT_WORD (LC_TIME,
00723 _NL_TIME_ERA_NUM_ENTRIES);
00724 for (era_cnt = 0; era_cnt < (int) num_eras;
00725 ++era_cnt, rp = rp_backup)
00726 {
00727 era = _nl_select_era_entry (era_cnt);
00728 if (match_string (era->era_name, rp))
00729 {
00730 *decided = loc;
00731 break;
00732 }
00733 }
00734 if (era_cnt == (int) num_eras)
00735 {
00736 era_cnt = -1;
00737 if (*decided == loc)
00738 return NULL;
00739 }
00740 else
00741 break;
00742 }
00743
00744 *decided = raw;
00745 }
00746
00747
00748 goto match_century;
00749 case 'y':
00750 if (*decided == raw)
00751 goto match_year_in_century;
00752
00753 get_number(0, 9999, 4);
00754 tm->tm_year = val;
00755 want_era = 1;
00756 want_xday = 1;
00757 break;
00758 case 'Y':
00759 if (*decided != raw)
00760 {
00761 num_eras = _NL_CURRENT_WORD (LC_TIME,
00762 _NL_TIME_ERA_NUM_ENTRIES);
00763 for (era_cnt = 0; era_cnt < (int) num_eras;
00764 ++era_cnt, rp = rp_backup)
00765 {
00766 era = _nl_select_era_entry (era_cnt);
00767 if (recursive (era->era_format))
00768 break;
00769 }
00770 if (era_cnt == (int) num_eras)
00771 {
00772 era_cnt = -1;
00773 if (*decided == loc)
00774 return NULL;
00775 else
00776 rp = rp_backup;
00777 }
00778 else
00779 {
00780 *decided = loc;
00781 era_cnt = -1;
00782 break;
00783 }
00784
00785 *decided = raw;
00786 }
00787 get_number (0, 9999, 4);
00788 tm->tm_year = val - 1900;
00789 want_century = 0;
00790 want_xday = 1;
00791 break;
00792 case 'x':
00793 if (*decided != raw)
00794 {
00795 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
00796
00797 if (*fmt == '\0')
00798 fmt = _NL_CURRENT (LC_TIME, D_FMT);
00799
00800 if (!recursive (fmt))
00801 {
00802 if (*decided == loc)
00803 return NULL;
00804 else
00805 rp = rp_backup;
00806 }
00807 else
00808 {
00809 if (strcmp (fmt, HERE_D_FMT))
00810 *decided = loc;
00811 break;
00812 }
00813 *decided = raw;
00814 }
00815 if (!recursive (HERE_D_FMT))
00816 return NULL;
00817 break;
00818 case 'X':
00819 if (*decided != raw)
00820 {
00821 const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
00822
00823 if (*fmt == '\0')
00824 fmt = _NL_CURRENT (LC_TIME, T_FMT);
00825
00826 if (!recursive (fmt))
00827 {
00828 if (*decided == loc)
00829 return NULL;
00830 else
00831 rp = rp_backup;
00832 }
00833 else
00834 {
00835 if (strcmp (fmt, HERE_T_FMT))
00836 *decided = loc;
00837 break;
00838 }
00839 *decided = raw;
00840 }
00841 if (!recursive (HERE_T_FMT))
00842 return NULL;
00843 break;
00844 default:
00845 return NULL;
00846 }
00847 break;
00848 #else
00849
00850
00851 if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
00852 && *fmt != 'x' && *fmt != 'X')
00853
00854 return NULL;
00855
00856 goto start_over;
00857 #endif
00858 case 'O':
00859 switch (*fmt++)
00860 {
00861 case 'd':
00862 case 'e':
00863
00864 get_alt_number (1, 31, 2);
00865 tm->tm_mday = val;
00866 have_mday = 1;
00867 want_xday = 1;
00868 break;
00869 case 'H':
00870
00871
00872 get_alt_number (0, 23, 2);
00873 tm->tm_hour = val;
00874 have_I = 0;
00875 break;
00876 case 'I':
00877
00878
00879 get_alt_number (1, 12, 2);
00880 tm->tm_hour = val - 1;
00881 have_I = 1;
00882 break;
00883 case 'm':
00884
00885 get_alt_number (1, 12, 2);
00886 tm->tm_mon = val - 1;
00887 have_mon = 1;
00888 want_xday = 1;
00889 break;
00890 case 'M':
00891
00892 get_alt_number (0, 59, 2);
00893 tm->tm_min = val;
00894 break;
00895 case 'S':
00896
00897 get_alt_number (0, 61, 2);
00898 tm->tm_sec = val;
00899 break;
00900 case 'U':
00901 case 'V':
00902 case 'W':
00903 get_alt_number (0, 53, 2);
00904
00905
00906 break;
00907 case 'w':
00908
00909 get_alt_number (0, 6, 1);
00910 tm->tm_wday = val;
00911 have_wday = 1;
00912 break;
00913 case 'y':
00914
00915 get_alt_number (0, 99, 2);
00916 tm->tm_year = val >= 69 ? val : val + 100;
00917 want_xday = 1;
00918 break;
00919 default:
00920 return NULL;
00921 }
00922 break;
00923 default:
00924 return NULL;
00925 }
00926 }
00927
00928 if (have_I && is_pm)
00929 tm->tm_hour += 12;
00930
00931 if (century != -1)
00932 {
00933 if (want_century)
00934 tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
00935 else
00936
00937 tm->tm_year = (century - 19) * 100;
00938 }
00939
00940 #ifdef _NL_CURRENT
00941 if (era_cnt != -1)
00942 {
00943 era = _nl_select_era_entry(era_cnt);
00944 if (want_era)
00945 tm->tm_year = (era->start_date[0]
00946 + ((tm->tm_year - era->offset)
00947 * era->absolute_direction));
00948 else
00949
00950 tm->tm_year = era->start_date[0];
00951 }
00952 else
00953 #endif
00954 if (want_era)
00955 return NULL;
00956
00957 if (want_xday && !have_wday)
00958 {
00959 if ( !(have_mon && have_mday) && have_yday)
00960 {
00961
00962 int t_mon = 0;
00963 while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
00964 t_mon++;
00965 if (!have_mon)
00966 tm->tm_mon = t_mon - 1;
00967 if (!have_mday)
00968 tm->tm_mday =
00969 (tm->tm_yday
00970 - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1);
00971 }
00972 day_of_the_week (tm);
00973 }
00974 if (want_xday && !have_yday)
00975 day_of_the_year (tm);
00976
00977 return discard_const_p(char, rp);
00978 }
00979
00980
00981 char *rep_strptime(const char *buf, const char *format, struct tm *tm)
00982 {
00983 enum locale_status decided;
00984
00985 #ifdef _NL_CURRENT
00986 decided = not;
00987 #else
00988 decided = raw;
00989 #endif
00990 return strptime_internal (buf, format, tm, &decided, -1);
00991 }