static void skip_white_spc(port *in) { int ch; while ((ch = get_next_char(in)) != EOF && is_white_space(ch)) ; if (ch != EOF) push_back_char(in, ch); }
static enum TOK_T get_next_token(port *in, pointer *token) { char ch, *t; skip_white_spc(in); switch (ch = get_next_char(in)) { case EOF: return FILE_END; case '(': return LIST_START; case ')': return LIST_END; case '"': *token = mk_string(read_string(in)); return STRING; case '\'': return QUOTE; case '`': return BACKQUOTE; case ',': if ((ch = get_next_char(in)) == '@') return SPLICE; else { push_back_char(in, ch); return UNQUOTE; } case '.': return DOT; default: push_back_char(in, ch); t = get_char_until_delim(in); if (test_number(t)) { *token = mk_number(atoi(t)); return NUMBER; } else { *token = mk_symbol(t); return SYMBOL; } } }
Vector_chars* get_name_file_without_path(char* str, int size) { Vector_chars* result; result = create_vector_of_chars(15); int slashs = count_slash_from_string(str, size); int i = 0; while(i < size) { if(slashs == 0) { push_back_char(result, str[i]); } if(str[i] == '/') { slashs--; } i++; } push_back_char(result, '\0'); return result; }
static char *get_char_until_delim(port *in) { int i = 0, ch; char str[MAX_SYM_NUM_LEN], *dst; str[0] = '\0'; while ((ch = get_next_char(in)) != EOF && !is_white_space(ch) && ch != '(' && ch != ')') str[i++] = ch; str[i] = '\0'; memcpy((dst = alloc_strseg(i + 1)), str, i + 1); if (ch != EOF) push_back_char(in, ch); return dst; }
/* * 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. */ int yylex( struct FILE_INFO *ip_file ) { static follby followedby = FOLLBY_TOKEN; size_t i; int instring; int yylval_was_set; int converted; int token; /* The return value */ int ch; if (input_from_file) ip_file = fp[curr_include_level]; instring = FALSE; yylval_was_set = FALSE; do { /* Ignore whitespace at the beginning */ while (EOF != (ch = get_next_char(ip_file)) && isspace(ch) && !is_EOC(ch)) ; /* Null Statement */ if (EOF == ch) { if (!input_from_file || curr_include_level <= 0) return 0; FCLOSE(fp[curr_include_level]); ip_file = fp[--curr_include_level]; token = T_EOC; goto normal_return; } else if (is_EOC(ch)) { /* end FOLLBY_STRINGS_TO_EOC effect */ followedby = FOLLBY_TOKEN; token = T_EOC; goto normal_return; } else if (is_special(ch) && FOLLBY_TOKEN == followedby) { /* special chars are their own token values */ token = ch; /* * '=' outside simulator configuration implies * a single string following as in: * setvar Owner = "The Boss" default */ if ('=' == ch && old_config_style) followedby = FOLLBY_STRING; yytext[0] = (char)ch; yytext[1] = '\0'; goto normal_return; } else push_back_char(ip_file, ch); /* save the position of start of the token */ ip_file->prev_token_line_no = ip_file->line_no; ip_file->prev_token_col_no = ip_file->col_no; /* Read in the lexeme */ i = 0; while (EOF != (ch = get_next_char(ip_file))) { yytext[i] = (char)ch; /* Break on whitespace or a special character */ if (isspace(ch) || is_EOC(ch) || '"' == ch || (FOLLBY_TOKEN == followedby && is_special(ch))) break; /* Read the rest of the line on reading a start of comment character */ if ('#' == ch) { while (EOF != (ch = get_next_char(ip_file)) && '\n' != ch) ; /* Null Statement */ break; } i++; if (i >= COUNTOF(yytext)) goto lex_too_long; } /* 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 " */ if ('"' == ch) { instring = TRUE; while (EOF != (ch = get_next_char(ip_file)) && ch != '"' && ch != '\n') { yytext[i++] = (char)ch; if (i >= COUNTOF(yytext)) goto lex_too_long; } /* * 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. */ if ('"' == ch) ch = get_next_char(ip_file); } /* Pushback the last character read that is not a part * of this lexeme. * If the last character read was an EOF, pushback a * newline character. This is to prevent a parse error * when there is no newline at the end of a file. */ if (EOF == ch) push_back_char(ip_file, '\n'); else push_back_char(ip_file, ch); yytext[i] = '\0'; } while (i == 0); /* 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. */ if (followedby == FOLLBY_TOKEN && !instring) { token = is_keyword(yytext, &followedby); if (token) { /* * 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. */ 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 (input_from_file) { exit(1); } else { /* force end of parsing */ 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 char)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 (input_from_file) { exit(1); } else { /* force end of parsing */ 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 { /* Default: Everything is a string */ yylval_was_set = TRUE; token = create_string_token(yytext); goto normal_return; } } /* * 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 ('-' == 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'", ip_file->line_no, (u_long)min(sizeof(yytext) - 1, 50), yytext); /* * If we hit the length limit reading the startup configuration * file, abort. */ if (input_from_file) exit(sizeof(yytext) - 1); /* * If it's runtime configuration via ntpq :config treat it as * if the configuration text ended before the too-long lexeme, * hostname, or string. */ yylval.Integer = 0; return 0; }