/******************************************************************************
    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;
}
Example #2
0
/**
 * 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;
}
Example #4
0
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;
}
Example #5
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;
}
Example #6
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);
}
Example #7
0
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;
}
Example #8
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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #12
0
	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);
}
Example #13
0
/**
 * 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;
}
Example #14
0
	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;
}
Example #15
0
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);
    }
  }
}
Example #17
0
	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;

}
Example #20
0
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;
}
Example #21
0
/*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++;
		}
	}
}
Example #22
0
    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 );
    }
}
Example #25
0
	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);
}
Example #26
0
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);
}
Example #27
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;
}
Example #28
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;
}
Example #29
0
/*
 * 从网页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;
}
Example #30
0
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;
}