FreeBSD/contrib/ntp/ntpd/ntp_scanner.c
/*
 * yylex() - function that does the actual scanning.
 * Bison expects this function to be called yylex and for it to take no
 * input and return an int.
 * Conceptually yylex "returns" yylval as well as the actual return
 * value representing the token or type.
 */
function that does the actual scanning.
Bison expects this function to be called yylex and for it to take no
input and return an int.
Conceptually yylex "returns" yylval as well as the actual return
value representing the token or type.
function that does the actual scanning . Bison expects this function to be called yylex and for it to take no input and return an int . Conceptually yylex " returns " yylval as well as the actual return value representing the token or type .
int
yylex(void)
{
	static follby	followedby = FOLLBY_TOKEN;
	size_t		i;
	int		instring;
	int		yylval_was_set;
	int		converted;
	int		token;		
	int		ch;
	instring = FALSE;
	yylval_was_set = FALSE;
	do {
		while (EOF != (ch = lex_getch(lex_stack)) &&
		       isspace(ch) &&
		       !is_EOC(ch))
			; 
		if (EOF == ch) {
			if ( ! lex_pop_file())
				return 0;
			token = T_EOC;
			goto normal_return;
		} else if (is_EOC(ch)) {
			followedby = FOLLBY_TOKEN;
			token = T_EOC;
			goto normal_return;
		} else if (is_special(ch) && FOLLBY_TOKEN == followedby) {
			token = ch;
			if ('=' == ch && old_config_style)
				followedby = FOLLBY_STRING;
			yytext[0] = (char)ch;
			yytext[1] = '\0';
			goto normal_return;
		} else
			lex_ungetch(ch, lex_stack);
		lex_stack->tokpos = lex_stack->curpos;
		i = 0;
		while (EOF != (ch = lex_getch(lex_stack))) {
			yytext[i] = (char)ch;
			if (isspace(ch) || is_EOC(ch) 
			    || '"' == ch
			    || (FOLLBY_TOKEN == followedby
				&& is_special(ch)))
				break;
			if ('#' == ch) {
				while (EOF != (ch = lex_getch(lex_stack))
				       && '\n' != ch)
					; 
				break;
			}
			i++;
			if (i >= COUNTOF(yytext))
				goto lex_too_long;
		}
		if ('"' == ch) {
			instring = TRUE;
			while (EOF != (ch = lex_getch(lex_stack)) &&
			       ch != '"' && ch != '\n') {
				yytext[i++] = (char)ch;
				if (i >= COUNTOF(yytext))
					goto lex_too_long;
			}
			if ('"' == ch)
				ch = lex_getch(lex_stack);
		}
		lex_ungetch(ch, lex_stack);
		yytext[i] = '\0';
	} while (i == 0);
	if (followedby == FOLLBY_TOKEN && !instring) {
		token = is_keyword(yytext, &followedby);
		if (token) {
			if (T_Server == token && !old_config_style)
				followedby = FOLLBY_TOKEN;
			goto normal_return;
		} else if (is_integer(yytext)) {
			yylval_was_set = TRUE;
			errno = 0;
			if ((yylval.Integer = strtol(yytext, NULL, 10)) == 0
			    && ((errno == EINVAL) || (errno == ERANGE))) {
				msyslog(LOG_ERR, 
					"Integer cannot be represented: %s",
					yytext);
				if (lex_from_file()) {
					exit(1);
				} else {
					yylval.Integer = 0;
					return 0;
				}
			}
			token = T_Integer;
			goto normal_return;
		} else if (is_u_int(yytext)) {
			yylval_was_set = TRUE;
			if ('0' == yytext[0] &&
			    'x' == tolower((unsigned long)yytext[1]))
				converted = sscanf(&yytext[2], "%x",
						   &yylval.U_int);
			else
				converted = sscanf(yytext, "%u",
						   &yylval.U_int);
			if (1 != converted) {
				msyslog(LOG_ERR, 
					"U_int cannot be represented: %s",
					yytext);
				if (lex_from_file()) {
					exit(1);
				} else {
					yylval.Integer = 0;
					return 0;
				}
			}
			token = T_U_int;
			goto normal_return;
		} else if (is_double(yytext)) {
			yylval_was_set = TRUE;
			errno = 0;
			if ((yylval.Double = atof(yytext)) == 0 && errno == ERANGE) {
				msyslog(LOG_ERR,
					"Double too large to represent: %s",
					yytext);
				exit(1);
			} else {
				token = T_Double;
				goto normal_return;
			}
		} else {
			yylval_was_set = TRUE;
			token = create_string_token(yytext);
			goto normal_return;
		}
	}
	if ('-' == yytext[0]) {
		if ('4' == yytext[1]) {
			token = T_Ipv4_flag;
			goto normal_return;
		} else if ('6' == yytext[1]) {
			token = T_Ipv6_flag;
			goto normal_return;
		}
	}
	instring = FALSE;
	if (FOLLBY_STRING == followedby)
		followedby = FOLLBY_TOKEN;
	yylval_was_set = TRUE;
	token = create_string_token(yytext);
normal_return:
	if (T_EOC == token)
		DPRINTF(4,("\t<end of command>\n"));
	else
		DPRINTF(4, ("yylex: lexeme '%s' -> %s\n", yytext,
			    token_name(token)));
	if (!yylval_was_set)
		yylval.Integer = token;
	return token;
lex_too_long:
	yytext[min(sizeof(yytext) - 1, 50)] = 0;
	msyslog(LOG_ERR, 
		"configuration item on line %d longer than limit of %lu, began with '%s'",
		lex_stack->curpos.nline, (u_long)min(sizeof(yytext) - 1, 50),
		yytext);
	if (lex_from_file())
		exit(sizeof(yytext) - 1);
	yylval.Integer = 0;
	return 0;
}
int yylex ( void ) { static follby followedby = FOLLBY_TOKEN ; size_t i ; int instring ; int yylval_was_set ; int converted ; int token ; int ch ; instring = FALSE ; yylval_was_set = FALSE ; do { while ( EOF != ( ch = lex_getch ( lex_stack ) ) && isspace ( ch ) && ! is_EOC ( ch ) ) ; if ( EOF == ch ) { if ( ! lex_pop_file ( ) ) return 0 ; token = T_EOC ; goto normal_return ; } else if ( is_EOC ( ch ) ) { followedby = FOLLBY_TOKEN ; token = T_EOC ; goto normal_return ; } else if ( is_special ( ch ) && FOLLBY_TOKEN == followedby ) { token = ch ; if ( ' ' == ch && old_config_style ) followedby = FOLLBY_STRING ; yytext [ 0 ] = ( char ) ch ; yytext [ 1 ] = ' \0 ' ; goto normal_return ; } else lex_ungetch ( ch , lex_stack ) ; lex_stack -> tokpos = lex_stack -> curpos ; i = 0 ; while ( EOF != ( ch = lex_getch ( lex_stack ) ) ) { yytext [ i ] = ( char ) ch ; if ( isspace ( ch ) || is_EOC ( ch ) || ' ' == ch || ( FOLLBY_TOKEN == followedby && is_special ( ch ) ) ) break ; if ( ' ' == ch ) { while ( EOF != ( ch = lex_getch ( lex_stack ) ) && ' \n ' != ch ) ; break ; } i ++ ; if ( i >= COUNTOF ( yytext ) ) goto lex_too_long ; } if ( ' ' == ch ) { instring = TRUE ; while ( EOF != ( ch = lex_getch ( lex_stack ) ) && ch != ' ' && ch != ' \n ' ) { yytext [ i ++ ] = ( char ) ch ; if ( i >= COUNTOF ( yytext ) ) goto lex_too_long ; } if ( ' ' == ch ) ch = lex_getch ( lex_stack ) ; } lex_ungetch ( ch , lex_stack ) ; yytext [ i ] = ' \0 ' ; } while ( i == 0 ) ; if ( followedby == FOLLBY_TOKEN && ! instring ) { token = is_keyword ( yytext , & followedby ) ; if ( token ) { if ( T_Server == token && ! old_config_style ) followedby = FOLLBY_TOKEN ; goto normal_return ; } else if ( is_integer ( yytext ) ) { yylval_was_set = TRUE ; errno = 0 ; if ( ( yylval . Integer = strtol ( yytext , NULL , 10 ) ) == 0 && ( ( errno == EINVAL ) || ( errno == ERANGE ) ) ) { msyslog ( LOG_ERR , " " , yytext ) ; if ( lex_from_file ( ) ) { exit ( 1 ) ; } else { yylval . Integer = 0 ; return 0 ; } } token = T_Integer ; goto normal_return ; } else if ( is_u_int ( yytext ) ) { yylval_was_set = TRUE ; if ( ' ' == yytext [ 0 ] && ' ' == tolower ( ( unsigned long ) yytext [ 1 ] ) ) converted = sscanf ( & yytext [ 2 ] , " " , & yylval . U_int ) ; else converted = sscanf ( yytext , " " , & yylval . U_int ) ; if ( 1 != converted ) { msyslog ( LOG_ERR , " " , yytext ) ; if ( lex_from_file ( ) ) { exit ( 1 ) ; } else { yylval . Integer = 0 ; return 0 ; } } token = T_U_int ; goto normal_return ; } else if ( is_double ( yytext ) ) { yylval_was_set = TRUE ; errno = 0 ; if ( ( yylval . Double = atof ( yytext ) ) == 0 && errno == ERANGE ) { msyslog ( LOG_ERR , " " , yytext ) ; exit ( 1 ) ; } else { token = T_Double ; goto normal_return ; } } else { yylval_was_set = TRUE ; token = create_string_token ( yytext ) ; goto normal_return ; } } if ( ' ' == yytext [ 0 ] ) { if ( ' ' == yytext [ 1 ] ) { token = T_Ipv4_flag ; goto normal_return ; } else if ( ' ' == yytext [ 1 ] ) { token = T_Ipv6_flag ; goto normal_return ; } } instring = FALSE ; if ( FOLLBY_STRING == followedby ) followedby = FOLLBY_TOKEN ; yylval_was_set = TRUE ; token = create_string_token ( yytext ) ; normal_return : if ( T_EOC == token ) DPRINTF ( 4 , ( " \t \n " ) ) ; else DPRINTF ( 4 , ( " \n " , yytext , token_name ( token ) ) ) ; if ( ! yylval_was_set ) yylval . Integer = token ; return token ; lex_too_long : yytext [ min ( sizeof ( yytext ) - 1 , 50 ) ] = 0 ; msyslog ( LOG_ERR , " " , lex_stack -> curpos . nline , ( u_long ) min ( sizeof ( yytext ) - 1 , 50 ) , yytext ) ; if ( lex_from_file ( ) ) exit ( sizeof ( yytext ) - 1 ) ; yylval . Integer = 0 ; return 0 ; }
yylex() - function that does the actual scanning.
yylex () - function that does the actual scanning .
/* The return value */ /* Ignore whitespace at the beginning */ /* Null Statement */ /* end FOLLBY_STRINGS_TO_EOC effect */ /* special chars are their own token values */ /*
			 * '=' outside simulator configuration implies
			 * a single string following as in:
			 * setvar Owner = "The Boss" default
			 */ /* save the position of start of the token */ /* Read in the lexeme */ /* Break on whitespace or a special character */ /* Read the rest of the line on reading a start
			   of comment character */ /* Null Statement */ /* Pick up all of the string inside between " marks, to
		 * end of line.  If we make it to EOL without a
		 * terminating " assume it for them.
		 *
		 * XXX - HMS: I'm not sure we want to assume the closing "
		 */ /*
			 * yytext[i] will be pushed back as not part of
			 * this lexeme, but any closing quote should
			 * not be pushed back, so we read another char.
			 */ /* Pushback the last character read that is not a part
		 * of this lexeme. This fails silently if ch is EOF,
		 * but then the EOF condition persists and is handled on
		 * the next turn by the include stack mechanism.
		 */ /* Now return the desired token */ /* First make sure that the parser is *not* expecting a string
	 * as the next token (based on the previous token that was
	 * returned) and that we haven't read a string.
	 */ /*
			 * T_Server is exceptional as it forces the
			 * following token to be a string in the
			 * non-simulator parts of the configuration,
			 * but in the simulator configuration section,
			 * "server" is followed by "=" which must be
			 * recognized as a token not a string.
			 */ /* force end of parsing */ /* force end of parsing */ /* Default: Everything is a string */ /*
	 * Either followedby is not FOLLBY_TOKEN or this lexeme is part
	 * of a string.  Hence, we need to return T_String.
	 * 
	 * _Except_ we might have a -4 or -6 flag on a an association
	 * configuration line (server, peer, pool, etc.).
	 *
	 * This is a terrible hack, but the grammar is ambiguous so we
	 * don't have a choice.  [SK]
	 *
	 * The ambiguity is in the keyword scanner, not ntp_parser.y.
	 * We do not require server addresses be quoted in ntp.conf,
	 * complicating the scanner's job.  To avoid trying (and
	 * failing) to match an IP address or DNS name to a keyword,
	 * the association keywords use FOLLBY_STRING in the keyword
	 * table, which tells the scanner to force the next token to be
	 * a T_String, so it does not try to match a keyword but rather
	 * expects a string when -4/-6 modifiers to server, peer, etc.
	 * are encountered.
	 * restrict -4 and restrict -6 parsing works correctly without
	 * this hack, as restrict uses FOLLBY_TOKEN.  [DH]
	 */ /*
	 * If we hit the length limit reading the startup configuration
	 * file, abort.
	 */ /*
	 * If it's runtime configuration via ntpq :config treat it as
	 * if the configuration text ended before the too-long lexeme,
	 * hostname, or string.
	 */