From 352621fe8719c8488098719240252bc04c303963 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 13 Sep 2013 11:53:46 +0800 Subject: [PATCH] discover/grub2: Add initial execution code Signed-off-by: Jeremy Kerr --- discover/grub2/grub2.h | 10 +++++- discover/grub2/parser-api.c | 4 +++ discover/grub2/script.c | 65 +++++++++++++++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/discover/grub2/grub2.h b/discover/grub2/grub2.h index 33180d4..07a1e6c 100644 --- a/discover/grub2/grub2.h +++ b/discover/grub2/grub2.h @@ -5,7 +5,7 @@ #include #include -struct grub2_parser; +struct grub2_script; struct grub2_word { const char *text; @@ -31,6 +31,8 @@ struct grub2_statement { STMT_TYPE_IF, STMT_TYPE_BLOCK, } type; + int (*exec)(struct grub2_script *, + struct grub2_statement *); }; struct grub2_statement_simple { @@ -96,6 +98,12 @@ void argv_append(struct grub2_argv *argv, struct grub2_word *word); void word_append(struct grub2_word *w1, struct grub2_word *w2); /* script interface */ +void script_execute(struct grub2_script *script); + +int statement_simple_execute(struct grub2_script *script, + struct grub2_statement *statement); +int statement_if_execute(struct grub2_script *script, + struct grub2_statement *statement); struct grub2_script *create_script(void *ctx); diff --git a/discover/grub2/parser-api.c b/discover/grub2/parser-api.c index d3bec3d..9ccf15e 100644 --- a/discover/grub2/parser-api.c +++ b/discover/grub2/parser-api.c @@ -17,6 +17,7 @@ struct grub2_statement *create_statement_simple(struct grub2_parser *parser, struct grub2_statement_simple *stmt = talloc(parser, struct grub2_statement_simple); stmt->st.type = STMT_TYPE_SIMPLE; + stmt->st.exec = statement_simple_execute; stmt->argv = argv; return &stmt->st; } @@ -27,6 +28,7 @@ struct grub2_statement *create_statement_menuentry(struct grub2_parser *parser, struct grub2_statement_menuentry *stmt = talloc(parser, struct grub2_statement_menuentry); stmt->st.type = STMT_TYPE_MENUENTRY; + stmt->st.exec = NULL; stmt->argv = argv; stmt->statements = stmts; return &stmt->st; @@ -40,6 +42,7 @@ struct grub2_statement *create_statement_if(struct grub2_parser *parser, struct grub2_statement_if *stmt = talloc(parser, struct grub2_statement_if); stmt->st.type = STMT_TYPE_IF; + stmt->st.exec = statement_if_execute; stmt->condition = condition; stmt->true_case = true_case; stmt->false_case = false_case; @@ -52,6 +55,7 @@ struct grub2_statement *create_statement_block(struct grub2_parser *parser, struct grub2_statement_block *stmt = talloc(parser, struct grub2_statement_block); stmt->st.type = STMT_TYPE_BLOCK; + stmt->st.exec = NULL; stmt->statements = stmts; return &stmt->st; } diff --git a/discover/grub2/script.c b/discover/grub2/script.c index 067b0c9..b6d3221 100644 --- a/discover/grub2/script.c +++ b/discover/grub2/script.c @@ -7,6 +7,11 @@ #include "grub2.h" +#define to_stmt_simple(stmt) \ + container_of(stmt, struct grub2_statement_simple, st) +#define to_stmt_if(stmt) \ + container_of(stmt, struct grub2_statement_if, st) + struct env_entry { const char *name; const char *value; @@ -39,12 +44,13 @@ static bool expand_word(struct grub2_script *script, struct grub2_word *word) src = word->text; n = regexec(&script->var_re, src, 1, &match, 0); - if (n == 0) + printf("%s %s: %d\n", __func__, word->text, n); + if (n != 0) return false; val = env_lookup(script, src + match.rm_so, match.rm_eo - match.rm_so); - if (val) + if (!val) val = ""; dest = talloc_strndup(script, src, match.rm_so); @@ -74,6 +80,61 @@ static void process_expansions(struct grub2_script *script, } } +int statements_execute(struct grub2_script *script, + struct grub2_statements *stmts) +{ + struct grub2_statement *stmt; + int rc = 0; + + list_for_each_entry(&stmts->list, stmt, list) { + if (stmt->exec) + rc = stmt->exec(script, stmt); + printf("%s(%p)\n", __func__, stmt); + } + return rc; +} + +int statement_simple_execute(struct grub2_script *script, + struct grub2_statement *statement) +{ + struct grub2_statement_simple *st = to_stmt_simple(statement); + + if (!st->argv) + return 0; + + process_expansions(script, st->argv); + + return 0; +} + +int statement_if_execute(struct grub2_script *script, + struct grub2_statement *statement) +{ + struct grub2_statement_if *st = to_stmt_if(statement); + struct grub2_statements *case_stmts; + int rc; + + rc = st->condition->exec(script, st->condition); + + if (rc == 0) + case_stmts = st->true_case; + else + case_stmts = st->false_case; + + if (case_stmts) + statements_execute(script, case_stmts); + else + rc = 0; + + return rc; +} + + +void script_execute(struct grub2_script *script) +{ + statements_execute(script, script->statements); +} + static int script_destroy(void *p) { struct grub2_script *script = p; -- 2.39.2