/****************************************************************************** num_op := num rest_num_op ( expr ) rest_num_op *****************************************************************************/ void parse_num_op( val_t* val ) { printtab(); dprintf("parse_num_op()\n"); level++; if ( match_num( val ) ) { parse_rest_num_op( val ); } else if ( match_variable( val ) ) { resolve_variable( val ); parse_rest_num_op( val ); } else if ( match_char( '(' ) ) { parse_expr( val ); if ( !match_char( ')' ) ) { buffer[bpos] = 0; printf("Missing bracket: %s\n", buffer); longjmp( env, 1 ); } parse_rest_num_op( val ); } else { buffer[bpos] = 0; printf("Parse error: %s\n", buffer); longjmp( env, 1 ); } level--; return; }
/** * aa_dfa_match - traverse @dfa to find state @str stops at * @dfa: the dfa to match @str against (NOT NULL) * @start: the state of the dfa to start matching in * @str: the null terminated string of bytes to match against the dfa (NOT NULL) * * aa_dfa_match will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. * * Returns: final state reached after input is consumed */ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, const char *str) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ while (*str) match_char(state, def, base, next, check, equiv[(u8) *str++]); } else { /* default is direct to next state */ while (*str) match_char(state, def, base, next, check, (u8) *str++); } return state; }
/****************************************************************************** rest_expr := + term rest_expr - term rest_expr (nil) *****************************************************************************/ void parse_rest_expr( val_t* val ) { printtab(); dprintf("parse_rest_expr()\n"); level++; if ( match_char( '+' ) ) { val_t val2; parse_term( &val2 ); val->d.fval += val2.d.fval; parse_rest_expr( val ); } else if ( match_char( '-' ) ) { val_t val2; parse_term( &val2 ); val->d.fval /= val2.d.fval; parse_rest_expr( val ); } else if ( match_eof() ) { } else { } level--; return; }
int match_hms(char **p, int *hour, int *min, int *sec) { char *q = *p, *t; assert(p && *p && hour && min && sec); if (!match_char(&q, ' ')) match_2chars(&q, " "); if (match_digits(&q, hour) && *hour >= 0 && *hour <= 23 && match_char(&q, ':') && match_digits(&q, min) && *min >= 0 && *min <= 59) { t = q; if (match_char(&q, ':') && match_digits(&q, sec) && *sec >= 0 && *sec <= 59) *p = q; else { *p = t; *sec = 0; } return 1; } else return 0; }
static char *aptok_r(char *str, const char *delim, char **token) { const char *d; char *s; if (!str) str = *token; *token = 0; for (s = str; *s; ++s) { if (*s == '[') s = match_char(s, "[]"); if (*s == '(') s = match_char(s, "()"); if (!s || !(*s)) break; d = delim; while (*d && *s != *d) ++d; if (*d) { *s = 0; *token = s + 1; } else if (*token) return str; } if (str && s > str) { *token = s; return str; } return 0; }
static bool match_plus(unsigned c, int flags, struct utf8_iter expr, struct utf8_iter text, char **end) { if (!match_char(c, flags, &text)) return false; do utf8_next(&text); while (text.chr != 0 && match_char(c, flags, &text)); return match_here(expr, text, end); }
int main() { int temp; while( scanf("%s",line+1) != -1 ) { max = pos = 0; match[0] = 0; for( int i = 1; line[i] != '\0'; i++ ) { if( i == 1 || line[i] == '(' || line[i] == '[' ) { match[i] = 0; continue; } if( match_char( line[i-1],line[i]) == true ) { match[i] = match[i-2] + 2; if( max < match[i] ) { max = match[i]; pos = i; } } else { temp = i-match[i-1]-1; if( match[i-1] > 0 && temp >= 1 && match_char( line[temp],line[i] ) == true ) { match[i] = match[i-1] + 2; if( temp-1 >= 1 ) match[i] += match[temp-1]; if( max < match[i] ) { max = match[i]; pos = i; } } else match[i] = 0; } } if( max > 0 ) { for( int i = pos-max+1; i <= pos; i++ ) printf("%c",line[i]); } printf("\n\n"); } return 0; }
/* FIXME: this function and it's callers are getting progressively uglier as more features are added :) */ static client_t * SV_Match_User (const char *substr) { int i, j, uid; int count = 0; char *str; client_t *cl; client_t *match = 0; if (!substr || !*substr) return 0; uid = strtol (substr, &str, 10); if (!*str) { for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) { if (cl->state < cs_zombie) continue; if (cl->userid == uid) { SV_Printf ("User %04d matches with name: %s\n", cl->userid, cl->name); return cl; } } SV_Printf ("No such uid: %d\n", uid); return 0; } for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) { if (cl->state < cs_zombie) continue; for (str = cl->name; *str && !match_char (*str, substr[0]); str++) ; while (*str) { for (j = 0; substr[j] && str[j]; j++) if (!match_char (substr[j], str[j])) break; if (!substr[j]) { // found a match; match = cl; count++; SV_Printf ("User %04d matches with name: %s\n", cl->userid, cl->name); break; } str++; } } if (count != 1) { SV_Printf ("No unique matches, ignoring command!\n"); return 0; } return match; }
char* strnstr(const char *haystack, const char *needle, int max_len, bool sensitive) { if (haystack == NULL || needle == NULL) return NULL; const char *tmp = needle; const char *rem_pos = haystack; max_len = (max_len < 0 ? (int)((unsigned int)(~0) >> 1) : max_len); int rem_len = max_len; while ((*haystack != '\0') && (max_len != 0)) { tmp = needle; rem_pos = haystack; rem_len = max_len; while ((*tmp != '\0') && (max_len-- > 0)) { if ( ! match_char(*haystack, *tmp, sensitive) ) break; ++haystack; ++tmp; } if (*tmp == '\0') break; haystack = rem_pos + 1; max_len = rem_len - 1; rem_pos = NULL; } return (char*)rem_pos; }
static here_search_result_ctx *here_execute_search_program_step( const char *buffer, const char *buffer_end, here_search_program_ctx *step) { here_search_result_ctx *search_result = NULL; switch (step->ctype) { case HERE_CTYPE_CMATCH: search_result = match_char(buffer, buffer_end, step); break; case HERE_CTYPE_END: search_result = match_end(buffer, buffer_end, step); break; case HERE_CTYPE_DOT: search_result = match_dot(buffer, buffer_end, step); break; case HERE_CTYPE_LIST: search_result = match_list(buffer, buffer_end, step); break; case HERE_CTYPE_OPTION: search_result = match_opt(buffer, buffer_end, step); break; default: //bypass duh! break; } return search_result; }
static bool match_star(unsigned c, int flags, struct utf8_iter expr, struct utf8_iter text, char **end) { for (; !match_here(expr, text, end); utf8_next(&text)) if (text.chr == 0 || !match_char(c, flags, &text)) return false; return true; }
static void flytec_pbrrts(flytec_t *flytec) { flytec_puts_nmea(flytec, "PBRRTS,"); flytec_expectc(flytec, XOFF); route_head *route = 0; char line[128]; while (flytec_gets_nmea(flytec, line, sizeof line)) { const char *p = line; p = match_literal(p, "PBRRTS,"); int index = 0, count = 0, routepoint_index = 0; p = match_unsigned(p, &index); p = match_char(p, ','); p = match_unsigned(p, &count); p = match_char(p, ','); p = match_unsigned(p, &routepoint_index); p = match_char(p, ','); if (!p) continue; if (routepoint_index == 0) { char *name = 0; p = match_string_until(p, '\0', 0, &name); p = match_eos(p); if (p) { route = route_head_alloc(); route->rte_num = index + 1; route->rte_name = rstrip(name); route_add_head(route); } else { free(name); } } else { char *name = 0; p = match_string_until(p, ',', 1, 0); p = match_string_until(p, '\0', 0, &name); p = match_eos(p); if (p) { const waypoint *w = find_waypt_by_name(rstrip(name)); if (w) route_add_wpt(route, waypt_dupe(w)); } free(name); } } flytec_expectc(flytec, XON); }
/** * aa_dfa_next - step one character to the next state in the dfa * @dfa: the dfa to tranverse (NOT NULL) * @state: the state to start in * @c: the input character to transition on * * aa_dfa_match will step through the dfa by one input character @c * * Returns: state reach after input @c */ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, const char c) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); match_char(state, def, base, next, check, equiv[(u8) c]); } else match_char(state, def, base, next, check, (u8) c); return state; }
static track_t * track_new(const char *p) { track_t *track = xmalloc(sizeof(track_t)); memset(track, 0, sizeof *track); p = match_literal(p, "PBRTL,"); p = match_unsigned(p, &track->count); p = match_char(p, ','); p = match_unsigned(p, &track->index); p = match_char(p, ','); struct tm tm; memset(&tm, 0, sizeof tm); p = match_unsigned(p, &tm.tm_mday); p = match_char(p, '.'); p = match_unsigned(p, &tm.tm_mon); p = match_char(p, '.'); p = match_unsigned(p, &tm.tm_year); p = match_char(p, ','); p = match_unsigned(p, &tm.tm_hour); p = match_char(p, ':'); p = match_unsigned(p, &tm.tm_min); p = match_char(p, ':'); p = match_unsigned(p, &tm.tm_sec); p = match_char(p, ','); int duration_hour = 0, duration_min = 0, duration_sec = 0; p = match_unsigned(p, &duration_hour); p = match_char(p, ':'); p = match_unsigned(p, &duration_min); p = match_char(p, ':'); p = match_unsigned(p, &duration_sec); p = match_eos(p); if (!p) { track_delete(track); return 0; } tm.tm_mon -= 1; tm.tm_year += 2000 - 1900; track->date = DATE_NEW(tm); track->time = mktime(&tm); if (track->time == (time_t) -1) DIE("mktime", errno); track->duration = 3600 * duration_hour + 60 * duration_min + duration_sec; return track; }
static bool match_here(struct utf8_iter expr, struct utf8_iter text, char **end) { unsigned pre = expr.chr; int flags = 0; if (pre == 0) { if (end != NULL) *end = text.head; return true; } if (pre == '~') { pre = utf8_next(&expr); flags |= NEGATE; } if (pre == '%') { pre = utf8_next(&expr); switch (pre) { case 'a': /* alpha */ case 'd': /* digit */ case 'f': /* float */ case 'g': /* graphic */ case 'n': /* newline */ case 's': /* space */ case 'x': /* hex */ case '?': /* anything */ flags |= CLASS; } } utf8_next(&expr); if (expr.chr == '*') { utf8_next(&expr); return match_star(pre, flags, expr, text, end); } else if (expr.chr == '+') { utf8_next(&expr); return match_plus(pre, flags, expr, text, end); } if (pre == '$' && expr.chr == 0) { if (end != NULL) *end = text.head; return text.chr == 0; } if (text.chr != 0 && match_char(pre, flags, &text)) { utf8_next(&text); return match_here(expr, text, end); } return false; }
void check_case(FILE *in) { int params[MAX_M]; int n, m; int i, j; read_int(in, 2, params); n = params[0]; m = params[1]; check_int_range(n, 1, MAX_N, "n"); check_int_range(m, 1, MAX_M, "m"); check_EOL(in); char appeared[MAX_N+1]; for (j = 1; j <= n; j++) { appeared[j] = 0; } for (i = 0; i < m; i++) { int p, s; read_int(in, 2, params); p = params[0]; s = params[1]; check_int_range(p, 1, MAX_P, "p"); check_int_range(s, 1, n, "s"); match_char(in, ' '); read_int(in, s, params); char used[MAX_N+1]; for (j = 1; j <= n; j++) { used[j] = 0; } for (j = 0; j < s; j++) { check_int_range(params[j], 1, n, "si"); if (used[params[j]]) { fprintf(stderr, "Case %d: bundle %d has duplicate items\n", get_case(), i+1); exit(1); } used[params[j]] = 1; appeared[params[j]] = 1; } check_EOL(in); } for (j = 1; j <= n; j++) { if (!appeared[j]) { fprintf(stderr, "Case %d: item %d does not appear in any bundle.\n", get_case(), j); exit(1); } } }
static const char * match_b_record(const char *p, struct tm *tm, route_head **track) { waypoint *w = waypt_new(); p = match_char(p, 'B'); struct tm _tm = *tm; p = match_n_digits(p, 2, &_tm.tm_hour); p = match_n_digits(p, 2, &_tm.tm_min); p = match_n_digits(p, 2, &_tm.tm_sec); w->creation_time = mktime(&_tm); int lat = 0, lat_min = 0, lat_mmin = 0; p = match_n_digits(p, 2, &lat); p = match_n_digits(p, 2, &lat_min); p = match_n_digits(p, 3, &lat_mmin); w->latitude = lat + lat_min / 60.0 + lat_mmin / 60000.0; char lat_hemi = 0; p = match_one_of(p, "NS", &lat_hemi); if (lat_hemi == 'S') w->latitude = -w->latitude; int lon = 0, lon_min = 0, lon_mmin = 0; p = match_n_digits(p, 3, &lon); p = match_n_digits(p, 2, &lon_min); p = match_n_digits(p, 3, &lon_mmin); w->longitude = lon + lon_min / 60.0 + lon_mmin / 60000.0; char lon_hemi = 0; p = match_one_of(p, "EW", &lon_hemi); if (lon_hemi == 'W') w->longitude = -w->longitude; char av = 0; p = match_one_of(p, "AV", &av); switch (av) { case 'A': w->fix = fix_3d; break; case 'V': w->fix = fix_2d; break; } int alt = 0, ele = 0; p = match_n_digits(p, 5, &alt); w->altitude = alt; p = match_n_digits(p, 5, &ele); p = match_until_eol(p); if (!p) goto error; if (!*track) { *track = route_head_alloc(); track_add_head(*track); } track_add_wpt(*track, w); return p; error: waypt_del(w); return 0; }
/****************************************************************************** rest_num_op := ^ num_op rest_num_op <nil> *****************************************************************************/ void parse_rest_num_op( val_t* val ) { if ( match_char( '^' ) ) { val_t val2; parse_num_op( &val2 ); val->d.fval = pow( val->d.fval, val2.d.fval ); parse_rest_num_op( val ); } return; }
/****************************************************************************** rest_term := * factor rest_term / factor rest_term % factor rest_term <nil> *****************************************************************************/ void parse_rest_term( val_t* val ) { printtab(); dprintf("parse_rest_term()\n"); level++; if ( match_char( '*' ) ) { val_t val2; parse_factor( &val2 ); val->d.fval *= val2.d.fval; parse_rest_term( val ); } else if ( match_char( '/' ) ) { val_t val2; parse_factor( &val2 ); if ( val2.d.fval != 0 ) { val->d.fval /= val2.d.fval; } else { printf("Division by 0\n"); longjmp(env, 0); } parse_rest_term( val ); } else if ( match_char( '%' ) ) { val_t val2; parse_factor( &val2 ); val->d.fval = fmod( val->d.fval, val2.d.fval ); parse_rest_term( val ); } else if ( match_eof() ) { } else { } level--; return; }
snp_t *snp_new(const char *p) { snp_t *snp = alloc(sizeof(snp_t)); p = match_literal(p, "PBRSNP,"); p = match_string_until(p, ',', 1, &snp->instrument_id); p = match_string_until(p, ',', 1, &snp->pilot_name); p = match_unsigned(p, &snp->serial_number); p = match_char(p, ','); p = match_string_until(p, '\0', 0, &snp->software_version); p = match_eos(p); if (!p) { snp_delete(snp); return 0; } return snp; }
/*CREATE LIST OF TOKENS*/ void Createlist(char *exp,List infix_l) { char p[MAXNAME]; //store var name int cnt; while((*exp == ' ' || *exp == '\t') && *exp!='\0') //remove spaces exp++; if(*exp=='\'') //override check eval symbol. exp++; if(*exp == '\0') return; while(*exp!='\0') //read till end of line { while((*exp == ' ' || *exp == '\t') && *exp!='\0') exp++; if(match_char(*exp)==0) //if variable { exp = Extract_word(exp,p); cnt = Count(infix_l); InsertAfter(p,infix_l,cnt); } else if(match_num(*exp)==0) //if number { exp = Extract_num(exp,p); cnt = Count(infix_l); InsertAfter(p,infix_l,cnt); add_value(p,0,p); } else if(match_bool(*exp)==0) //if boolean op { exp = Extract_bool(exp,p); cnt = Count(infix_l); InsertAfter(p,infix_l,cnt); } else { p[0] = *exp; //else single letter operator p[1]='\0'; cnt = Count(infix_l); InsertAfter(p,infix_l,cnt); exp++; } } }
static const char * match_b_record(const char *p, struct tm *tm) { p = match_char(p, 'B'); if (!p) return 0; int hour = 0, min = 0, sec = 0; p = match_n_digits(p, 2, &hour); p = match_n_digits(p, 2, &min); p = match_n_digits(p, 2, &sec); if (!p) return 0; p = match_until_eol(p); if (!p) return 0; tm->tm_hour = hour; tm->tm_min = min; tm->tm_sec = sec; return p; }
/****************************************************************************** factor := - factor num_op *****************************************************************************/ void parse_factor( val_t* val ) { printtab(); dprintf("parse_factor()\n"); level++; if ( match_char( '-' ) ) { parse_factor( val ); val->d.fval = val->d.fval; } else { parse_num_op( val ); } level--; return; }
/****************************************************************************** rest_var := '=' expr rest_num_op *****************************************************************************/ void parse_rest_var( val_t* val ) { if ( match_char( '=' ) ) { val_t vexp; parse_expr( &vexp ); if ( vexp.type != TYPE_FLOAT ) { printf("Error: Tried to assign non-number to %s.\n", val->d.variable ); longjmp( env, 1 ); } printf("Assigned to %s: ", val->d.variable ); map_add( val->d.variable, vexp.d.fval ); *val = vexp; } else { parse_rest_num_op( val ); } }
static void flytec_pbrwps(flytec_t *flytec) { flytec_puts_nmea(flytec, "PBRWPS,"); flytec_expectc(flytec, XOFF); char line[128]; while (flytec_gets_nmea(flytec, line, sizeof line)) { const char *p = line; p = match_literal(p, "PBRWPS,"); int lat_deg = 0, lat_min = 0, lat_mmin = 0; p = match_n_digits(p, 2, &lat_deg); p = match_n_digits(p, 2, &lat_min); p = match_char(p, '.'); p = match_n_digits(p, 3, &lat_mmin); p = match_char(p, ','); char lat_hemi = '\0'; p = match_one_of(p, "NS", &lat_hemi); p = match_char(p, ','); int lon_deg = 0, lon_min = 0, lon_mmin = 0; p = match_n_digits(p, 3, &lon_deg); p = match_n_digits(p, 2, &lon_min); p = match_char(p, '.'); p = match_n_digits(p, 3, &lon_mmin); p = match_char(p, ','); char lon_hemi = '\0'; p = match_one_of(p, "EW", &lon_hemi); p = match_char(p, ','); char *name = 0; p = match_string_until(p, ',', 1, 0); p = match_string_until(p, ',', 1, &name); int ele = 0; p = match_unsigned(p, &ele); p = match_eos(p); if (p) { waypoint *w = waypt_new(); w->latitude = lat_deg + lat_min / 60.0 + lat_mmin / 60000.0; if (lat_hemi == 'S') w->latitude = -w->latitude; w->longitude = lon_deg + lon_min / 60.0 + lon_mmin / 60000.0; if (lon_hemi == 'W') w->longitude = -w->longitude; w->altitude = ele; w->shortname = rstrip(name); waypt_add(w); } else { free(name); } } flytec_expectc(flytec, XON); }
bool strncmp_sen(char *s1, char *s2, int n, bool sensitive) { if ( ! sensitive) { while ( (*s1 != 0) && n) { if ( ! match_char(*s1, *s2, sensitive)) break; ++s1; ++s2; --n; } if ( n > 0 && (*s1 != 0 || *s2 != 0)) return false; return true; } return (strncmp(s1, s2, n) == 0); }
int pick_a_time(char *text) { char *pstart, *p, *q, sepChar; struct tm ttm; int tmp; int curTime; pstart = text; curTime = 0; // 找所有有效的时间串,取权值最大的一个 while (1) { // 找到一个时间 p = strstr(pstart, "200"); q = strstr(pstart, "199"); if (p) { ttm.tm_year = 100; if (q && p > q) { p = q; ttm.tm_year = 90; } } else { if (!(p = q)) break; ttm.tm_year = 90; } // 目前p指向可能的时间串的开头 q = p + 3; if (!match_digit(&q, &tmp)) { pstart = q; continue; } ttm.tm_year += tmp; if (*q == '-' || *q == '/' || *q == '.') { sepChar = *q; q++; if (!match_digits(&q, &(ttm.tm_mon)) || ttm.tm_mon < 1 || ttm.tm_mon > 12 || !match_char(&q, sepChar) || !match_digits(&q, &(ttm.tm_mday)) || ttm.tm_mday < 1 || ttm.tm_mday > 31) { pstart = q; continue; } if (!match_hms (&q, &(ttm.tm_hour), &(ttm.tm_min), &(ttm.tm_sec))) ttm.tm_hour = ttm.tm_min = ttm.tm_sec = 0; } else { if (!match_2chars(&q, yearStr)) { pstart = q; continue; } else { match_char(&q, ' '); if (!match_digits(&q, &(ttm.tm_mon)) || ttm.tm_mon < 1 || ttm.tm_mon > 12 || !match_2chars(&q, monthStr)) { pstart = q; continue; } else { match_char(&q, ' '); if (!match_digits(&q, &(ttm.tm_mday)) || ttm.tm_mday < 1 || ttm.tm_mday > 31 || !match_2chars(&q, dayStr)) { pstart = q; continue; } } } if (!match_hms (&q, &(ttm.tm_hour), &(ttm.tm_min), &(ttm.tm_sec))) ttm.tm_hour = ttm.tm_min = ttm.tm_sec = 0; } ttm.tm_mon--; ttm.tm_isdst = 0; //ttm.tm_gmtoff=0; curTime = (int) mktime(&ttm); break; } if (curTime > 0) { return curTime; } return 0; }
/* * 从网页HTML代码中提取发布时间 * 返回值: * >=0 - 成功,返回发布时间的秒数 * -1 - 失败 */ int get_webpage_time2(char *page) { char *pstart, *p, *q, sepChar; int curTime = -1; struct tm ttm; int tmp; assert(page); for (pstart = page;;) { // 找到一个时间 p = strstr(pstart, "200"); q = strstr(pstart, "199"); if (p) { ttm.tm_year = 100; if (q && p > q) { p = q; ttm.tm_year = 90; } } else { if (!(p = q)) break; ttm.tm_year = 90; } // 目前p指向可能的时间串的开头 q = p + 3; if (!match_digit(&q, &tmp)) { pstart = q; continue; } ttm.tm_year += tmp; if (*q == '-' || *q == '/' || *q == '.') { sepChar = *q; q++; if (!match_digits(&q, &(ttm.tm_mon)) || ttm.tm_mon < 1 || ttm.tm_mon > 12 || !match_char(&q, sepChar) || !match_digits(&q, &(ttm.tm_mday)) || ttm.tm_mday < 1 || ttm.tm_mday > 31) { pstart = q; continue; } if (!match_hms (&q, &(ttm.tm_hour), &(ttm.tm_min), &(ttm.tm_sec))) ttm.tm_hour = ttm.tm_min = ttm.tm_sec = 0; } else { if (!match_2chars(&q, yearStr) || !match_digits(&q, &(ttm.tm_mon)) || ttm.tm_mon < 1 || ttm.tm_mon > 12 || !match_2chars(&q, monthStr) || !match_digits(&q, &(ttm.tm_mday)) || ttm.tm_mday < 1 || ttm.tm_mday > 31 || !match_2chars(&q, dayStr)) { pstart = q; continue; } if (!match_hms (&q, &(ttm.tm_hour), &(ttm.tm_min), &(ttm.tm_sec))) ttm.tm_hour = ttm.tm_min = ttm.tm_sec = 0; } tmp = *q; *q = 0; printf("\n%s\n", p); *q = tmp; ttm.tm_mon--; ttm.tm_isdst = 0; //ttm.tm_gmtoff=0; curTime = (int) mktime(&ttm); assert(curTime != -1); return curTime; } return -1; }
/* * 从网页HTML代码中提取发布时间 * 返回值: * >=0 - 成功,返回发布时间的秒数 * -1 - 失败 */ int get_webpage_time(char *page) { char *pstart, *p, *q, sepChar; struct tm ttm; int tmp; int ttime, weight; int curTime, curWeight; char *paraLeft, *paraRight; char tmpCh; char *hint; // 提示信息的位置,比如“发布时间”就是一个提示信息 time_t now = time(NULL);; assert(page); // 让pstart指向HTML文档的BODY域开头(没有BODY以文档开头代替) if (!(pstart = (char *) strcasestr(page, "<body"))) { pstart = page; } assert(pstart); // 找所有有效的时间串,取权值最大的一个 for (ttime = -1, weight = -1;;) { curWeight = WEIGHT_BASE; // 找到一个时间 p = strstr(pstart, "200"); q = strstr(pstart, "199"); if (p) { ttm.tm_year = 100; if (q && p > q) { p = q; ttm.tm_year = 90; } } else { if (!(p = q)) break; ttm.tm_year = 90; } // 目前p指向可能的时间串的开头 q = p + 3; if (!match_digit(&q, &tmp)) { pstart = q; continue; } ttm.tm_year += tmp; if (*q == '-' || *q == '/' || *q == '.') { sepChar = *q; q++; if (!match_digits(&q, &(ttm.tm_mon)) || ttm.tm_mon < 1 || ttm.tm_mon > 12 || !match_char(&q, sepChar) || !match_digits(&q, &(ttm.tm_mday)) || ttm.tm_mday < 1 || ttm.tm_mday > 31) { pstart = q; continue; } if (!match_hms (&q, &(ttm.tm_hour), &(ttm.tm_min), &(ttm.tm_sec))) ttm.tm_hour = ttm.tm_min = ttm.tm_sec = 0; else curWeight += WEIGHT_HMS; } else { if (!match_2chars(&q, yearStr)) { pstart = q; continue; } else { match_char(&q, ' '); if (!match_digits(&q, &(ttm.tm_mon)) || ttm.tm_mon < 1 || ttm.tm_mon > 12 || !match_2chars(&q, monthStr)) { pstart = q; continue; } else { match_char(&q, ' '); if (!match_digits(&q, &(ttm.tm_mday)) || ttm.tm_mday < 1 || ttm.tm_mday > 31 || !match_2chars(&q, dayStr)) { pstart = q; continue; } } } if (!match_hms (&q, &(ttm.tm_hour), &(ttm.tm_min), &(ttm.tm_sec))) ttm.tm_hour = ttm.tm_min = ttm.tm_sec = 0; else curWeight += WEIGHT_HMS; } /* tmp=*q; *q=0; printf("\n%s\n",p); *q=tmp; */ ttm.tm_mon--; ttm.tm_isdst = 0; //ttm.tm_gmtoff=0; curTime = (int) mktime(&ttm); assert(curTime != -1); // 扔掉比当前时间还大的时间 if (curTime > now) { pstart = p + 1; continue; } // 找到当前时间串所在的标签段落 // 找开头 for (paraLeft = p - 1; *paraLeft && *paraLeft != '>' && *paraLeft != '<'; paraLeft--) ; if (!*paraLeft) paraLeft = pstart; else if (*paraLeft == '<') { pstart = p + 1; continue; } else paraLeft++; // 找结尾 paraRight = strchr(q, '<'); if (paraRight) { tmpCh = *paraRight; *paraRight = 0; if (strchr(q, '>')) { *paraRight = tmpCh; pstart = p + 1; continue; } } // 时间所在字段过长放弃 if ((int) strlen(paraLeft) > TAG_DIST) { pstart = p + 1; continue; } printf("%s\n", paraLeft); // 现在各变量指向的位置如下: // p - 时间串开头 // q - 时间串末尾的下一个字符 // paraLeft - 时间串所在的标签段落开头 // paraRight - 时间串所在的标签段落末尾的下一个字符(或者NULL) // 调整权值 if ((hint = strstr(paraLeft, "发布时间")) && hint < p && p - hint < HINT_DIST) curWeight += 100; if ((hint = strstr(paraLeft, "发帖时间")) && hint < p && p - hint < HINT_DIST) curWeight += 100; if ((hint = strstr(paraLeft, "发表")) && hint < p && p - hint < HINT_DIST) curWeight += 90; if ((hint = strstr(paraLeft, "post")) && hint < p && p - hint < HINT_DIST) curWeight += 90; if ((hint = strstr(paraLeft, "发行")) && hint < p && p - hint < HINT_DIST) curWeight -= 50; if ((hint = strstr(paraLeft, "现在")) && hint < p && p - hint < HINT_DIST) curWeight -= 100; if ((hint = strstr(paraLeft, "注册")) && hint < p && p - hint < HINT_DIST) curWeight -= 200; if (((hint = strstr(paraLeft, "新闻来源")) || (hint = strstr(paraLeft, "稿源"))) && abs((int) (p - hint)) < HINT_DIST) curWeight += 90; if (((hint = strstr(paraLeft, "新闻网")) || (hint = strstr(paraLeft, "晨报")) || (hint = strstr(paraLeft, "早报")) || (hint = strstr(paraLeft, "日报")) || (hint = strstr(paraLeft, "晚报")) || (hint = strstr(paraLeft, "信息港")) || (hint = strstr(paraLeft, "在线"))) && abs((int) (p - hint)) < HINT_DIST) curWeight += 50; if (((hint = strstr(paraLeft, "编辑")) || (hint = strstr(paraLeft, "责编")) || (hint = strstr(paraLeft, "责任编辑")) || (hint = strstr(paraLeft, "作者"))) && abs((int) (p - hint)) < HINT_DIST) curWeight += 50; if (((hint = strstr(paraLeft, "【")) || (hint = strstr(paraLeft, "】")) || (hint = strstr(paraLeft, "〖")) || (hint = strstr(paraLeft, "〗"))) && abs((int) (p - hint)) < HINT_DIST) curWeight += 40; if (((hint = strstr(paraLeft, "(")) || (hint = strstr(paraLeft, ")")) || (hint = strstr(paraLeft, "(")) || (hint = strstr(paraLeft, ")"))) && abs((int) (p - hint)) < HINT_DIST) curWeight += 20; if (((hint = strstr(paraLeft, "来源")) || (hint = strstr(paraLeft, "时间"))) && abs((int) (p - hint)) < HINT_DIST) curWeight += 10; if ((hint = strstr(paraLeft, "http://")) && abs((int) (p - hint)) < HINT_DIST) curWeight += 10; if (((hint = strstr(paraLeft, "网")) || (hint = strstr(paraLeft, "报")) || (hint = strstr(paraLeft, "社")) || (hint = strstr(paraLeft, "讯"))) && abs((int) (p - hint)) < HINT_DIST) curWeight += 10; // 恢复 if (paraRight) *paraRight = tmpCh; printf("curWeight : %d\n", curWeight); // 比较权值,取权值更大的时间值 if (curWeight > weight) { ttime = curTime; weight = curWeight; } else if (curWeight == weight) { if (curTime > ttime) ttime = curTime; } pstart = p + 1; } if (ttime > 0) return ttime; return -1; }
static char * __strptime_internal (const char *rp, const char *fmt, struct tm *tmp, void *statep) { const char *rp_backup; const char *rp_longest; int cnt; int cnt_longest; size_t val; #ifdef _NL_CURRENT size_t num_eras; struct era_entry *era = NULL; #endif enum ptime_locale_status { nott, loc, raw } decided_longest; struct __strptime_state { unsigned int have_I : 1; unsigned int have_wday : 1; unsigned int have_yday : 1; unsigned int have_mon : 1; unsigned int have_mday : 1; unsigned int have_uweek : 1; unsigned int have_wweek : 1; unsigned int is_pm : 1; unsigned int want_century : 1; unsigned int want_era : 1; unsigned int want_xday : 1; enum ptime_locale_status decided : 2; signed char week_no; signed char century; int era_cnt; } s; struct tm tmb; struct tm *tm; if (statep == NULL) { memset (&s, 0, sizeof (s)); s.century = -1; s.era_cnt = -1; #ifdef _NL_CURRENT s.decided = nott; #else s.decided = raw; #endif tm = tmp; } else { s = *(struct __strptime_state *) statep; tmb = *tmp; tm = &tmb; } while (*fmt != '\0') { /* A white space in the format string matches 0 more or white space in the input string. */ if (isspace (*fmt)) { while (isspace (*rp)) ++rp; ++fmt; continue; } /* Any character but `%' must be matched by the same character in the iput string. */ if (*fmt != '%') { match_char (*fmt++, *rp++); continue; } ++fmt; if (statep != NULL) { /* In recursive calls silently discard strftime modifiers. */ while (*fmt == '-' || *fmt == '_' || *fmt == '0' || *fmt == '^' || *fmt == '#') ++fmt; /* And field width. */ while (*fmt >= '0' && *fmt <= '9') ++fmt; } #ifndef _NL_CURRENT /* We need this for handling the `E' modifier. */ start_over: #endif /* Make back up of current processing pointer. */ rp_backup = rp; switch (*fmt++) { case '%': /* Match the `%' character itself. */ match_char ('%', *rp++); break; case 'a': case 'A': /* Match day of week. */ rp_longest = NULL; decided_longest = s.decided; cnt_longest = -1; for (cnt = 0; cnt < 7; ++cnt) { const char *trp; #ifdef _NL_CURRENT if (s.decided !=raw) { trp = rp; if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), trp) && trp > rp_longest) { rp_longest = trp; cnt_longest = cnt; if (s.decided == nott && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), weekday_name[cnt])) decided_longest = loc; } trp = rp; if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), trp) && trp > rp_longest) { rp_longest = trp; cnt_longest = cnt; if (s.decided == nott && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), ab_weekday_name[cnt])) decided_longest = loc; } } #endif if (s.decided != loc && (((trp = rp, match_string (weekday_name[cnt], trp)) && trp > rp_longest) || ((trp = rp, match_string (ab_weekday_name[cnt], rp)) && trp > rp_longest))) { rp_longest = trp; cnt_longest = cnt; decided_longest = raw; } } if (rp_longest == NULL) /* Does not match a weekday name. */ return NULL; rp = rp_longest; s.decided = decided_longest; tm->tm_wday = cnt_longest; s.have_wday = 1; break; case 'b': case 'B': case 'h': /* Match month name. */ rp_longest = NULL; decided_longest = s.decided; cnt_longest = -1; for (cnt = 0; cnt < 12; ++cnt) { const char *trp; #ifdef _NL_CURRENT if (s.decided !=raw) { trp = rp; if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), trp) && trp > rp_longest) { rp_longest = trp; cnt_longest = cnt; if (s.decided == nott && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), month_name[cnt])) decided_longest = loc; } trp = rp; if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), trp) && trp > rp_longest) { rp_longest = trp; cnt_longest = cnt; if (s.decided == nott && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), ab_month_name[cnt])) decided_longest = loc; } } #endif if (s.decided != loc && (((trp = rp, match_string (month_name[cnt], trp)) && trp > rp_longest) || ((trp = rp, match_string (ab_month_name[cnt], trp)) && trp > rp_longest))) { rp_longest = trp; cnt_longest = cnt; decided_longest = raw; } } if (rp_longest == NULL) /* Does not match a month name. */ return NULL; rp = rp_longest; s.decided = decided_longest; tm->tm_mon = cnt_longest; s.have_mon = 1; s.want_xday = 1; break; case 'c': /* Match locale's date and time format. */ #ifdef _NL_CURRENT if (s.decided != raw) { if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) { if (s.decided == loc) return NULL; else rp = rp_backup; } else { if (s.decided == nott && strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) s.decided = loc; s.want_xday = 1; break; } s.decided = raw; } #endif if (!recursive (HERE_D_T_FMT)) return NULL; s.want_xday = 1; break; case 'C': /* Match century number. */ #ifdef _NL_CURRENT match_century: #endif get_number (0, 99, 2); s.century = val; s.want_xday = 1; break; case 'd': case 'e': /* Match day of month. */ get_number (1, 31, 2); tm->tm_mday = val; s.have_mday = 1; s.want_xday = 1; break; case 'F': if (!recursive ("%Y-%m-%d")) return NULL; s.want_xday = 1; break; case 'x': #ifdef _NL_CURRENT if (s.decided != raw) { if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) { if (s.decided == loc) return NULL; else rp = rp_backup; } else { if (s.decided == nott && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) s.decided = loc; s.want_xday = 1; break; } s.decided = raw; } #endif /* Fall through. */ case 'D': /* Match standard day format. */ if (!recursive (HERE_D_FMT)) return NULL; s.want_xday = 1; break; case 'k': case 'H': /* Match hour in 24-hour clock. */ get_number (0, 23, 2); tm->tm_hour = val; s.have_I = 0; break; case 'l': /* Match hour in 12-hour clock. GNU extension. */ case 'I': /* Match hour in 12-hour clock. */ get_number (1, 12, 2); tm->tm_hour = val % 12; s.have_I = 1; break; case 'j': /* Match day number of year. */ get_number (1, 366, 3); tm->tm_yday = val - 1; s.have_yday = 1; break; case 'm': /* Match number of month. */ get_number (1, 12, 2); tm->tm_mon = val - 1; s.have_mon = 1; s.want_xday = 1; break; case 'M': /* Match minute. */ get_number (0, 59, 2); tm->tm_min = val; break; case 'n': case 't': /* Match any white space. */ while (isspace (*rp)) ++rp; break; case 'p': /* Match locale's equivalent of AM/PM. */ #ifdef _NL_CURRENT if (s.decided != raw) { if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) { if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) s.decided = loc; s.is_pm = 0; break; } if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) { if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) s.decided = loc; s.is_pm = 1; break; } s.decided = raw; } #endif if (!match_string (HERE_AM_STR, rp)) { if (match_string (HERE_PM_STR, rp)) s.is_pm = 1; else return NULL; } else s.is_pm = 0; 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 == nott && 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': #ifdef _NL_CURRENT match_year_in_century: #endif /* 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; 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; } 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); 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); 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); 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); 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); 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.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; }