summaryrefslogtreecommitdiffstats
path: root/discover
diff options
context:
space:
mode:
Diffstat (limited to 'discover')
-rw-r--r--discover/grub2/grub2.h13
-rw-r--r--discover/grub2/parser.y19
-rw-r--r--discover/grub2/script.c23
3 files changed, 55 insertions, 0 deletions
diff --git a/discover/grub2/grub2.h b/discover/grub2/grub2.h
index 6166289..e79bf41 100644
--- a/discover/grub2/grub2.h
+++ b/discover/grub2/grub2.h
@@ -83,6 +83,13 @@ struct grub2_statement_function {
struct grub2_statements *body;
};
+struct grub2_statement_for {
+ struct grub2_statement st;
+ struct grub2_word *var;
+ struct grub2_argv *list;
+ struct grub2_statements *body;
+};
+
struct grub2_script {
struct grub2_statements *statements;
struct list environment;
@@ -125,6 +132,10 @@ struct grub2_statement *create_statement_block(struct grub2_parser *parser,
struct grub2_statement *create_statement_function(struct grub2_parser *parser,
struct grub2_word *name, struct grub2_statements *body);
+struct grub2_statement *create_statement_for(struct grub2_parser *parser,
+ struct grub2_word *var, struct grub2_argv *list,
+ struct grub2_statements *body);
+
struct grub2_word *create_word_text(struct grub2_parser *parser,
const char *text);
@@ -153,6 +164,8 @@ int statement_menuentry_execute(struct grub2_script *script,
struct grub2_statement *statement);
int statement_function_execute(struct grub2_script *script,
struct grub2_statement *statement);
+int statement_for_execute(struct grub2_script *script,
+ struct grub2_statement *statement);
struct grub2_script *create_script(struct grub2_parser *parser,
struct discover_context *ctx);
diff --git a/discover/grub2/parser.y b/discover/grub2/parser.y
index 0beddd6..23bf427 100644
--- a/discover/grub2/parser.y
+++ b/discover/grub2/parser.y
@@ -130,6 +130,12 @@ statement:
/* we just flatten everything */
$$ = create_statement_block(parser, $6);
}
+ | "for" TOKEN_DELIM word TOKEN_DELIM "in" TOKEN_DELIM words TOKEN_EOL
+ "do" sep
+ statements
+ "done" {
+ $$ = create_statement_for(parser, $3, $7, $11);
+ }
words: word {
$$ = create_argv(parser);
@@ -243,6 +249,19 @@ struct grub2_statement *create_statement_function(struct grub2_parser *parser,
return &stmt->st;
}
+struct grub2_statement *create_statement_for(struct grub2_parser *parser,
+ struct grub2_word *var, struct grub2_argv *list,
+ struct grub2_statements *body)
+{
+ struct grub2_statement_for *stmt =
+ talloc(parser, struct grub2_statement_for);
+ stmt->st.exec = statement_for_execute;
+ stmt->var = var;
+ stmt->list = list;
+ stmt->body = body;
+ return &stmt->st;
+}
+
void statement_append(struct grub2_statements *stmts,
struct grub2_statement *stmt)
{
diff --git a/discover/grub2/script.c b/discover/grub2/script.c
index bfca607..0618297 100644
--- a/discover/grub2/script.c
+++ b/discover/grub2/script.c
@@ -19,6 +19,8 @@
container_of(stmt, struct grub2_statement_menuentry, st)
#define to_stmt_function(stmt) \
container_of(stmt, struct grub2_statement_function, st)
+#define to_stmt_for(stmt) \
+ container_of(stmt, struct grub2_statement_for, st)
#define to_stmt_conditional(stmt) \
container_of(stmt, struct grub2_statement_conditional, st)
@@ -401,6 +403,27 @@ int statement_function_execute(struct grub2_script *script,
return 0;
}
+int statement_for_execute(struct grub2_script *script,
+ struct grub2_statement *statement)
+{
+ struct grub2_statement_for *st = to_stmt_for(statement);
+ const char *varname;
+ int i, rc = 0;
+
+ if (st->var->type == GRUB2_WORD_VAR)
+ expand_var(script, st->var);
+ varname = st->var->text;
+
+ process_expansions(script, st->list);
+
+ for (i = 0; i < st->list->argc; ++i) {
+ script_env_set(script, varname, st->list->argv[i]);
+ rc = statements_execute(script, st->body);
+ }
+
+ return rc;
+}
+
static void init_env(struct grub2_script *script)
{
struct env_entry *env;
OpenPOWER on IntegriCloud