X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=discover%2Fgrub2%2Fparser.y;h=859eba30479b93eeac8fa4a8c00d21d7916931d4;hp=0d02bc155aa6793134e25ee05bc607e68d68eaac;hb=a77e8d42cd7b983d9fa5746f07e66a6fe04b6a0d;hpb=5c6263a12dd7f859daa0feba8b58a0558f0ff21c diff --git a/discover/grub2/parser.y b/discover/grub2/parser.y index 0d02bc1..859eba3 100644 --- a/discover/grub2/parser.y +++ b/discover/grub2/parser.y @@ -2,6 +2,7 @@ %pure-parser %lex-param { yyscan_t scanner } %parse-param { struct grub2_parser *parser } +%error-verbose %{ #include @@ -29,6 +30,7 @@ static void yyerror(struct grub2_parser *, char const *s); %token TOKEN_DO "do" %token TOKEN_DONE "done" %token TOKEN_ELIF "elif" +%token TOKEN_ELSE "else" %token TOKEN_ESAC "esac" %token TOKEN_FI "fi" %token TOKEN_FOR "for" @@ -37,6 +39,7 @@ static void yyerror(struct grub2_parser *, char const *s); %token TOKEN_IN "in" %token TOKEN_MENUENTRY "menuentry" %token TOKEN_SELECT "select" +%token TOKEN_SUBMENU "submenu" %token TOKEN_THEN "then" %token TOKEN_TIME "time" %token TOKEN_UTIL "until" @@ -85,11 +88,28 @@ statement: TOKEN_EOL { "fi" TOKEN_EOL { $$ = create_statement_if(parser, $3, $6, NULL); } + | "if" TOKEN_DELIM statement + "then" TOKEN_EOL + statements + "else" TOKEN_EOL + statements + "fi" TOKEN_EOL { + $$ = create_statement_if(parser, $3, $6, $9); + } + | "function" TOKEN_DELIM word TOKEN_DELIM '{' statements '}' { + $$ = create_statement_function(parser, $3, $6); + } | "menuentry" TOKEN_DELIM words TOKEN_DELIM '{' statements '}' TOKEN_EOL { $$ = create_statement_menuentry(parser, $3, $6); } + | "submenu" TOKEN_DELIM words TOKEN_DELIM + '{' statements '}' + TOKEN_EOL { + /* we just flatten everything */ + $$ = create_statement_block(parser, $6); + } words: word { $$ = create_argv(parser); @@ -171,6 +191,17 @@ struct grub2_statement *create_statement_block(struct grub2_parser *parser, return &stmt->st; } +struct grub2_statement *create_statement_function(struct grub2_parser *parser, + struct grub2_word *name, struct grub2_statements *body) +{ + struct grub2_statement_function *stmt = + talloc(parser, struct grub2_statement_function); + stmt->st.exec = statement_function_execute; + stmt->name = name; + stmt->body = body; + return &stmt->st; +} + void statement_append(struct grub2_statements *stmts, struct grub2_statement *stmt) { @@ -220,3 +251,30 @@ void word_append(struct grub2_word *w1, struct grub2_word *w2) w1->last->next = w2; w1->last = w2; } + +struct grub2_parser *grub2_parser_create(struct discover_context *ctx) +{ + struct grub2_parser *parser; + + parser = talloc(ctx, struct grub2_parser); + yylex_init_extra(parser, &parser->scanner); + parser->script = create_script(parser, ctx); + + return parser; +} + +void grub2_parser_parse(struct grub2_parser *parser, char *buf, int len) +{ + YY_BUFFER_STATE bufstate; + int rc; + + bufstate = yy_scan_bytes(buf, len - 1, parser->scanner); + + rc = yyparse(parser); + + yy_delete_buffer(bufstate, parser->scanner); + + if (!rc) + script_execute(parser->script); +} +