📄 strptime_l.c
字号:
break; case 'r':#ifdef _NL_CURRENT if (s.decided != raw) { if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) { if (s.decided == loc) return NULL; else rp = rp_backup; } else { if (s.decided == not && strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), HERE_T_FMT_AMPM)) s.decided = loc; break; } s.decided = raw; }#endif if (!recursive (HERE_T_FMT_AMPM)) return NULL; break; case 'R': if (!recursive ("%H:%M")) return NULL; break; case 's': { /* The number of seconds may be very high so we cannot use the `get_number' macro. Instead read the number character for character and construct the result while doing this. */ time_t secs = 0; if (*rp < '0' || *rp > '9') /* We need at least one digit. */ return NULL; do { secs *= 10; secs += *rp++ - '0'; } while (*rp >= '0' && *rp <= '9'); if (localtime_r (&secs, tm) == NULL) /* Error in function. */ return NULL; } break; case 'S': get_number (0, 61, 2); tm->tm_sec = val; break; case 'X':#ifdef _NL_CURRENT if (s.decided != raw) { if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) { if (s.decided == loc) return NULL; else rp = rp_backup; } else { if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) s.decided = loc; break; } s.decided = raw; }#endif /* Fall through. */ case 'T': if (!recursive (HERE_T_FMT)) return NULL; break; case 'u': get_number (1, 7, 1); tm->tm_wday = val % 7; s.have_wday = 1; break; case 'g': get_number (0, 99, 2); /* XXX This cannot determine any field in TM. */ break; case 'G': if (*rp < '0' || *rp > '9') return NULL; /* XXX Ignore the number since we would need some more information to compute a real date. */ do ++rp; while (*rp >= '0' && *rp <= '9'); break; case 'U': get_number (0, 53, 2); s.week_no = val; s.have_uweek = 1; break; case 'W': get_number (0, 53, 2); s.week_no = val; s.have_wweek = 1; break; case 'V': get_number (0, 53, 2); /* XXX This cannot determine any field in TM without some information. */ break; case 'w': /* Match number of weekday. */ get_number (0, 6, 1); tm->tm_wday = val; s.have_wday = 1; break; case 'y': match_year_in_century: /* Match year within century. */ get_number (0, 99, 2); /* The "Year 2000: The Millennium Rollover" paper suggests that values in the range 69-99 refer to the twentieth century. */ tm->tm_year = val >= 69 ? val : val + 100; /* Indicate that we want to use the century, if specified. */ s.want_century = 1; s.want_xday = 1; break; case 'Y': /* Match year including century number. */ get_number (0, 9999, 4); tm->tm_year = val - 1900; s.want_century = 0; s.want_xday = 1; break; case 'Z': /* XXX How to handle this? */ break; case 'z': /* We recognize two formats: if two digits are given, these specify hours. If fours digits are used, minutes are also specified. */ { val = 0; while (*rp == ' ') ++rp; if (*rp != '+' && *rp != '-') return NULL; bool neg = *rp++ == '-'; int n = 0; while (n < 4 && *rp >= '0' && *rp <= '9') { val = val * 10 + *rp++ - '0'; ++n; } if (n == 2) val *= 100; else if (n != 4) /* Only two or four digits recognized. */ return NULL; else { /* We have to convert the minutes into decimal. */ if (val % 100 >= 60) return NULL; val = (val / 100) * 100 + ((val % 100) * 50) / 30; } if (val > 1200) return NULL; tm->tm_gmtoff = (val * 3600) / 100; if (neg) tm->tm_gmtoff = -tm->tm_gmtoff; } break; case 'E':#ifdef _NL_CURRENT switch (*fmt++) { case 'c': /* Match locale's alternate date and time format. */ if (s.decided != raw) { const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); if (*fmt == '\0') fmt = _NL_CURRENT (LC_TIME, D_T_FMT); if (!recursive (fmt)) { if (s.decided == loc) return NULL; else rp = rp_backup; } else { if (strcmp (fmt, HERE_D_T_FMT)) s.decided = loc; s.want_xday = 1; break; } s.decided = raw; } /* The C locale has no era information, so use the normal representation. */ if (!recursive (HERE_D_T_FMT)) return NULL; s.want_xday = 1; break; case 'C': if (s.decided != raw) { if (s.era_cnt >= 0) { era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG); if (era != NULL && match_string (era->era_name, rp)) { s.decided = loc; break; } else return NULL; } num_eras = _NL_CURRENT_WORD (LC_TIME, _NL_TIME_ERA_NUM_ENTRIES); for (s.era_cnt = 0; s.era_cnt < (int) num_eras; ++s.era_cnt, rp = rp_backup) { era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG); if (era != NULL && match_string (era->era_name, rp)) { s.decided = loc; break; } } if (s.era_cnt != (int) num_eras) break; s.era_cnt = -1; if (s.decided == loc) return NULL; s.decided = raw; } /* The C locale has no era information, so use the normal representation. */ goto match_century; case 'y': if (s.decided != raw) { get_number(0, 9999, 4); tm->tm_year = val; s.want_era = 1; s.want_xday = 1; s.want_century = 1; if (s.era_cnt >= 0) { assert (s.decided == loc); era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG); bool match = false; if (era != NULL) { int delta = ((tm->tm_year - era->offset) * era->absolute_direction); match = (delta >= 0 && delta < (((int64_t) era->stop_date[0] - (int64_t) era->start_date[0]) * era->absolute_direction)); } if (! match) return NULL; break; } num_eras = _NL_CURRENT_WORD (LC_TIME, _NL_TIME_ERA_NUM_ENTRIES); for (s.era_cnt = 0; s.era_cnt < (int) num_eras; ++s.era_cnt) { era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG); if (era != NULL) { int delta = ((tm->tm_year - era->offset) * era->absolute_direction); if (delta >= 0 && delta < (((int64_t) era->stop_date[0] - (int64_t) era->start_date[0]) * era->absolute_direction)) { s.decided = loc; break; } } } if (s.era_cnt != (int) num_eras) break; s.era_cnt = -1; if (s.decided == loc) return NULL; s.decided = raw; } goto match_year_in_century; case 'Y': if (s.decided != raw) { num_eras = _NL_CURRENT_WORD (LC_TIME, _NL_TIME_ERA_NUM_ENTRIES); for (s.era_cnt = 0; s.era_cnt < (int) num_eras; ++s.era_cnt, rp = rp_backup) { era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG); if (era != NULL && recursive (era->era_format)) break; } if (s.era_cnt == (int) num_eras) { s.era_cnt = -1; if (s.decided == loc) return NULL; else rp = rp_backup; } else { s.decided = loc; s.era_cnt = -1; break; } s.decided = raw; } get_number (0, 9999, 4); tm->tm_year = val - 1900; s.want_century = 0; s.want_xday = 1; break; case 'x': if (s.decided != raw) { const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); if (*fmt == '\0') fmt = _NL_CURRENT (LC_TIME, D_FMT); if (!recursive (fmt)) { if (s.decided == loc) return NULL; else rp = rp_backup; } else { if (strcmp (fmt, HERE_D_FMT)) s.decided = loc; break; } s.decided = raw; } if (!recursive (HERE_D_FMT)) return NULL; break; case 'X': if (s.decided != raw) { const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); if (*fmt == '\0') fmt = _NL_CURRENT (LC_TIME, T_FMT); if (!recursive (fmt)) { if (s.decided == loc) return NULL; else rp = rp_backup; } else { if (strcmp (fmt, HERE_T_FMT)) s.decided = loc; break; } s.decided = raw; } if (!recursive (HERE_T_FMT)) return NULL; break; default: return NULL; } break;#else /* We have no information about the era format. Just use the normal format. */ if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' && *fmt != 'x' && *fmt != 'X') /* This is an illegal format. */ return NULL; goto start_over;#endif case 'O': switch (*fmt++) { case 'd': case 'e': /* Match day of month using alternate numeric symbols. */ get_alt_number (1, 31, 2); tm->tm_mday = val; s.have_mday = 1; s.want_xday = 1; break; case 'H': /* Match hour in 24-hour clock using alternate numeric symbols. */ get_alt_number (0, 23, 2); tm->tm_hour = val; s.have_I = 0; break; case 'I': /* Match hour in 12-hour clock using alternate numeric symbols. */ get_alt_number (1, 12, 2); tm->tm_hour = val % 12; s.have_I = 1; break; case 'm': /* Match month using alternate numeric symbols. */ get_alt_number (1, 12, 2); tm->tm_mon = val - 1; s.have_mon = 1; s.want_xday = 1; break; case 'M': /* Match minutes using alternate numeric symbols. */ get_alt_number (0, 59, 2); tm->tm_min = val; break; case 'S': /* Match seconds using alternate numeric symbols. */ get_alt_number (0, 61, 2); tm->tm_sec = val; break; case 'U': get_alt_number (0, 53, 2); s.week_no = val; s.have_uweek = 1; break; case 'W': get_alt_number (0, 53, 2); s.week_no = val; s.have_wweek = 1; break; case 'V': get_alt_number (0, 53, 2); /* XXX This cannot determine any field in TM without further information. */ break; case 'w': /* Match number of weekday using alternate numeric symbols. */ get_alt_number (0, 6, 1); tm->tm_wday = val; s.have_wday = 1; break; case 'y': /* Match year within century using alternate numeric symbols. */ get_alt_number (0, 99, 2); tm->tm_year = val >= 69 ? val : val + 100; s.want_xday = 1; break; default: return NULL; } break; default: return NULL; } } if (statep != NULL) { /* Recursive invocation, returning success, so update parent's struct tm and state. */ *(struct __strptime_state *) statep = s; *tmp = tmb; return (char *) rp; } if (s.have_I && s.is_pm) tm->tm_hour += 12; if (s.century != -1) { if (s.want_century) tm->tm_year = tm->tm_year % 100 + (s.century - 19) * 100; else /* Only the century, but not the year. Strange, but so be it. */ tm->tm_year = (s.century - 19) * 100; } if (s.era_cnt != -1) { era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG); if (era == NULL) return NULL; if (s.want_era) tm->tm_year = (era->start_date[0] + ((tm->tm_year - era->offset) * era->absolute_direction)); else /* Era start year assumed. */ tm->tm_year = era->start_date[0]; } else if (s.want_era) { /* No era found but we have seen an E modifier. Rectify some values. */ if (s.want_century && s.century == -1 && tm->tm_year < 69) tm->tm_year += 100; } if (s.want_xday && !s.have_wday) { if ( !(s.have_mon && s.have_mday) && s.have_yday) { /* We don't have tm_mon and/or tm_mday, compute them. */ int t_mon = 0; while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) t_mon++; if (!s.have_mon) tm->tm_mon = t_mon - 1; if (!s.have_mday) tm->tm_mday = (tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); s.have_mon = 1; s.have_mday = 1; } /* Don't crash in day_of_the_week if tm_mon is uninitialized. */ if (s.have_mon || (unsigned) tm->tm_mon <= 11) day_of_the_week (tm); } if (s.want_xday && !s.have_yday && (s.have_mon || (unsigned) tm->tm_mon <= 11)) day_of_the_year (tm); if ((s.have_uweek || s.have_wweek) && s.have_wday) { int save_wday = tm->tm_wday; int save_mday = tm->tm_mday; int save_mon = tm->tm_mon; int w_offset = s.have_uweek ? 0 : 1; tm->tm_mday = 1; tm->tm_mon = 0; day_of_the_week (tm); if (s.have_mday) tm->tm_mday = save_mday; if (s.have_mon) tm->tm_mon = save_mon; if (!s.have_yday) tm->tm_yday = ((7 - (tm->tm_wday - w_offset)) % 7 + (s.week_no - 1) *7 + save_wday - w_offset); if (!s.have_mday || !s.have_mon) { int t_mon = 0; while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) t_mon++; if (!s.have_mon) tm->tm_mon = t_mon - 1; if (!s.have_mday) tm->tm_mday = (tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); } tm->tm_wday = save_wday; } return (char *) rp;}char *strptime (buf, format, tm LOCALE_PARAM) const char *buf; const char *format; struct tm *tm; LOCALE_PARAM_DECL{ return __strptime_internal (buf, format, tm, NULL LOCALE_ARG);}#ifdef _LIBCweak_alias (__strptime_l, strptime_l)#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -