4 #include "grub2-parser.h"
5 #include <talloc/talloc.h>
7 void yyerror(struct grub2_parser *parser, const char *fmt, ...);
10 %option nounput noinput
11 %option batch never-interactive
14 %option stack noyy_top_state
18 %option noyyalloc noyyfree noyyrealloc
19 %option extra-type="struct grub2_parser *"
24 WORD [^{}|&$;<> \t\n'"#]+
28 VARNAME ([[:alpha:]][_[:alnum:]]*|{NUMBER}|[\?@\*#])
32 /* discard whitespace, unless we're looking for inter-word delimiters */
33 {DELIM} { if (yyget_extra(yyscanner)->inter_word) return TOKEN_DELIM; }
36 "[[" return TOKEN_LDSQBRACKET;
37 "]]" return TOKEN_RDSQBRACKET;
38 "case" return TOKEN_CASE;
40 "done" return TOKEN_DONE;
41 "elif" return TOKEN_ELIF;
42 "else" return TOKEN_ELSE;
43 "esac" return TOKEN_ESAC;
45 "for" return TOKEN_FOR;
46 "function" return TOKEN_FUNCTION;
49 "menuentry" return TOKEN_MENUENTRY;
50 "select" return TOKEN_SELECT;
51 "submenu" return TOKEN_SUBMENU;
52 "then" return TOKEN_THEN;
53 "time" return TOKEN_TIME;
54 "until" return TOKEN_UTIL;
55 "while" return TOKEN_WHILE;
57 /* ignore quoted empty strings */
59 yylval->word = create_word_text(yyget_extra(yyscanner), "");
60 yyget_extra(yyscanner)->inter_word = true;
63 /* anything that's not a metachar: return as a plain word */
65 yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
66 yyget_extra(yyscanner)->inter_word = true;
72 if (yytext[1] == '{') {
73 yytext[yyleng-1] = '\0';
77 yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
79 yyget_extra(yyscanner)->inter_word = true;
83 /* single-quoted strings: return a single, non-expanded word token */
85 yy_push_state(sqstring, yyscanner);
88 yy_pop_state(yyscanner);
91 yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
92 yyget_extra(yyscanner)->inter_word = true;
96 /* double-quoted strings: return a single, expanded word token */
98 yy_push_state(dqstring, yyscanner);
101 yy_pop_state(yyscanner);
103 <dqstring>([^"\$]|\\\")+ {
104 yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
105 yyget_extra(yyscanner)->inter_word = true;
108 <dqstring>\${VARNAME} |
109 <dqstring>\$\{{VARNAME}\} {
110 if (yytext[1] == '{') {
111 yytext[yyleng-1] = '\0';
115 yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
117 yyget_extra(yyscanner)->inter_word = true;
124 "{" { yyget_extra(yyscanner)->inter_word = false; return '{'; }
125 "}" { yyget_extra(yyscanner)->inter_word = false; return '}'; }
129 yyget_extra(yyscanner)->inter_word = false;
137 yyerror(yyget_extra(yyscanner), yyscanner,
138 "unknown token '%s'\n", yytext);
146 void *yyalloc(size_t bytes, void *yyscanner)
148 struct grub2_parser *parser = yyget_extra(yyscanner);
149 return talloc_size(parser, bytes);
152 void *yyrealloc(void *ptr, size_t bytes, void *yyscanner)
154 struct grub2_parser *parser = yyget_extra(yyscanner);
155 return talloc_realloc_size(parser, ptr, bytes);
158 void yyfree(void *ptr, void *yyscanner __attribute__((unused)))