2N/A/* yylex.l The scripting lexer. */ 2N/A * GRUB -- GRand Unified Bootloader 2N/A * Copyright (C) 2009,2010 Free Software Foundation, Inc. 2N/A * GRUB is free software: you can redistribute it and/or modify 2N/A * it under the terms of the GNU General Public License as published by 2N/A * the Free Software Foundation, either version 3 of the License, or 2N/A * (at your option) any later version. 2N/A * GRUB is distributed in the hope that it will be useful, 2N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of 2N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2N/A * GNU General Public License for more details. 2N/A * You should have received a copy of the GNU General Public License 2N/A * As we don't have access to yyscanner, we cannot do much except to 2N/A * print the fatal error. 2N/A/* We don't need YY_INPUT, as we rely on yy_scan_strings */ 2N/A/* forward declarations */ 2N/A * Some flex hacks for -nostdinc; XXX We need to fix these when libc 2N/A * support becomes availble in GRUB. 2N/A/* Reduce lexer size, by not defining these. */ 2N/ANAME [[:alpha:]_][[:alnum:]_]* 2N/AVARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|${SPECIAL}|$\{{SPECIAL}\} 2N/AWORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ 2N/AMULTILINE {WORD}?((\"{DQCHR}*)|(\'{SQCHR}*)|(\\\n)) 2N/A{COMMENT} { RECORD; } 2N/A /* Special symbols */ 2N/A"\n" { RECORD; return GRUB_PARSER_TOKEN_NEWLINE; } 2N/A"||" { RECORD; return GRUB_PARSER_TOKEN_OR; } 2N/A"&&" { RECORD; return GRUB_PARSER_TOKEN_AND; } 2N/A";;" { RECORD; return GRUB_PARSER_TOKEN_SEMI2; } 2N/A"|" { RECORD; return GRUB_PARSER_TOKEN_PIPE; } 2N/A"&" { RECORD; return GRUB_PARSER_TOKEN_AMP; } 2N/A";" { RECORD; return GRUB_PARSER_TOKEN_SEMI; } 2N/A"<" { RECORD; return GRUB_PARSER_TOKEN_LT; } 2N/A">" { RECORD; return GRUB_PARSER_TOKEN_GT; } 2N/A /* Reserved words */ 2N/A"{" { RECORD; return GRUB_PARSER_TOKEN_LBR; } 2N/A"}" { RECORD; return GRUB_PARSER_TOKEN_RBR; } 2N/A"[[" { RECORD; return GRUB_PARSER_TOKEN_RSQBR2; } 2N/A"]]" { RECORD; return GRUB_PARSER_TOKEN_LSQBR2; } 2N/A"case" { RECORD; return GRUB_PARSER_TOKEN_CASE; } 2N/A"do" { RECORD; return GRUB_PARSER_TOKEN_DO; } 2N/A"done" { RECORD; return GRUB_PARSER_TOKEN_DONE; } 2N/A"elif" { RECORD; return GRUB_PARSER_TOKEN_ELIF; } 2N/A"else" { RECORD; return GRUB_PARSER_TOKEN_ELSE; } 2N/A"esac" { RECORD; return GRUB_PARSER_TOKEN_ESAC; } 2N/A"fi" { RECORD; return GRUB_PARSER_TOKEN_FI; } 2N/A"for" { RECORD; return GRUB_PARSER_TOKEN_FOR; } 2N/A"if" { RECORD; return GRUB_PARSER_TOKEN_IF; } 2N/A"in" { RECORD; return GRUB_PARSER_TOKEN_IN; } 2N/A"select" { RECORD; return GRUB_PARSER_TOKEN_SELECT; } 2N/A"then" { RECORD; return GRUB_PARSER_TOKEN_THEN; } 2N/A"until" { RECORD; return GRUB_PARSER_TOKEN_UNTIL; } 2N/A"while" { RECORD; return GRUB_PARSER_TOKEN_WHILE; } 2N/A"function" { RECORD; return GRUB_PARSER_TOKEN_FUNCTION; } 2N/A if (grub_lexer_unput (yytext, yyscanner)) 2N/A return GRUB_PARSER_TOKEN_BAD; 2N/A{NAME} { RECORD; return GRUB_PARSER_TOKEN_NAME; } 2N/A yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner); 2N/A if (grub_lexer_resplit (yytext, yyscanner)) 2N/A yypop_buffer_state (yyscanner); 2N/A return GRUB_PARSER_TOKEN_WORD; 2N/A yyextra->lexerstate->resplit = 1; 2N/A grub_script_yyerror (yyextra, yytext); 2N/A return GRUB_PARSER_TOKEN_BAD; 2N/A /* Split word into multiple args */ 2N/A \\. { COPY (yytext + 1, yyleng - 1); } 2N/A \\\n { /* ignore */ } 2N/A yy_push_state (DQUOTE, yyscanner); 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); 2N/A yy_push_state (SQUOTE, yyscanner); 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); 2N/A yy_push_state (VAR, yyscanner); 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); 2N/A [^\"\'\$\\]+ { COPY (yytext, yyleng); } 2N/A yy_pop_state (yyscanner); 2N/A yypop_buffer_state (yyscanner); 2N/A yyextra->lexerstate->resplit = 0; 2N/A yyextra->lexerstate->merge_end = 1; 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); 2N/A COPY (yytext, yyleng); 2N/A yy_pop_state (yyscanner); 2N/A if (YY_START == SPLIT) 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_VAR); 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); 2N/A yytext[yyleng - 1] = '\0
'; 2N/A COPY (yytext + 1, yyleng - 2); 2N/A yy_pop_state (yyscanner); 2N/A if (YY_START == SPLIT) 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_VAR); 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); 2N/A .|\n { return GRUB_PARSER_TOKEN_BAD; } 2N/A yy_pop_state (yyscanner); 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR); 2N/A [^\']+ { COPY (yytext, yyleng); } 2N/A \\\$ { COPY ("$", 1); } 2N/A \\\\ { COPY ("\\", 1); } 2N/A \\\" { COPY ("\"", 1); } 2N/A \\\n { /* ignore */ } 2N/A [^\"\$\\\n]+ { COPY (yytext, yyleng); } 2N/A yy_pop_state (yyscanner); 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); 2N/A yy_push_state (VAR, yyscanner); 2N/A ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); 2N/A (.|\n) { COPY (yytext, yyleng); } 2N/A yypop_buffer_state (yyscanner); 2N/A yyextra->lexerstate->eof = 1; 2N/A return GRUB_PARSER_TOKEN_EOF; 2N/Ayywrap (yyscan_t yyscanner) 2N/A if (yyget_extra (yyscanner)->lexerstate->resplit) 2N/A return grub_script_lexer_yywrap (yyget_extra (yyscanner), 0); 2N/Agrub_lexer_yyfree (void *ptr, yyscan_t yyscanner __attribute__ ((unused))) 2N/Agrub_lexer_yyalloc (yy_size_t size, yyscan_t yyscanner __attribute__ ((unused))) 2N/A return grub_malloc (size); 2N/Agrub_lexer_yyrealloc (void *ptr, yy_size_t size, 2N/A yyscan_t yyscanner __attribute__ ((unused))) 2N/A return grub_realloc (ptr, size); 2N/Astatic void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint) 2N/A len = hint ? hint : grub_strlen (str); 2N/A if (parser->lexerstate->used + len >= parser->lexerstate->size) 2N/A if (size < parser->lexerstate->size * 2) 2N/A size = parser->lexerstate->size * 2; 2N/A ptr = grub_realloc (parser->lexerstate->text, size); 2N/A grub_script_yyerror (parser, 0); 2N/A parser->lexerstate->text = ptr; 2N/A parser->lexerstate->size = size; 2N/A grub_strcpy (parser->lexerstate->text + parser->lexerstate->used - 1, str); 2N/A parser->lexerstate->used += len; 2N/Agrub_lexer_resplit (const char *text, yyscan_t yyscanner) 2N/A if (yy_scan_string (text, yyscanner)) 2N/A yyget_extra (yyscanner)->lexerstate->merge_start = 1; 2N/A yy_push_state (SPLIT, yyscanner); 2N/A grub_script_yyerror (yyget_extra (yyscanner), 0); 2N/Agrub_lexer_unput (const char *text, yyscan_t yyscanner) 2N/A struct grub_lexer_param *lexerstate = yyget_extra (yyscanner)->lexerstate; 2N/A grub_free (lexerstate->prefix); 2N/A lexerstate->prefix = grub_strdup (text); 2N/A if (! lexerstate->prefix) 2N/A grub_script_yyerror (yyget_extra (yyscanner), "out of memory");