5 #include <talloc/talloc.h>
9 #define to_stmt_simple(stmt) \
10 container_of(stmt, struct grub2_statement_simple, st)
11 #define to_stmt_if(stmt) \
12 container_of(stmt, struct grub2_statement_if, st)
13 #define to_stmt_menuentry(stmt) \
14 container_of(stmt, struct grub2_statement_menuentry, st)
19 struct list_item list;
22 const char *script_env_get(struct grub2_script *script, const char *name)
24 struct env_entry *entry;
26 list_for_each_entry(&script->environment, entry, list)
27 if (!strcmp(entry->name, name))
33 void script_env_set(struct grub2_script *script,
34 const char *name, const char *value)
36 struct env_entry *e, *entry = NULL;
38 list_for_each_entry(&script->environment, e, list) {
39 if (!strcmp(e->name, name)) {
46 entry = talloc(script, struct env_entry);
48 list_add(&script->environment, &entry->list);
54 static bool expand_var(struct grub2_script *script, struct grub2_word *word)
58 val = script_env_get(script, word->var.name);
62 word->type = GRUB2_WORD_TEXT;
63 word->text = talloc_strdup(script, val);
68 /* iterate through the words in an argv_list, looking for GRUB2_WORD_VAR
71 * Once that's done, we may (if split == true) have to split the word to create
74 static void process_expansions(struct grub2_script *script,
75 struct grub2_argv *argv)
77 struct grub2_word *top_word, *word;
82 list_for_each_entry(&argv->words, top_word, argv_list) {
85 /* expand vars and squash the list of words into the top struct.
88 for (word = top_word; word; word = word->next) {
89 if (word->type == GRUB2_WORD_VAR)
90 expand_var(script, word);
95 top_word->text = talloc_asprintf_append(top_word->text,
98 top_word->next = NULL;
101 argv->argv = talloc_array(script, char *, argv->argc);
104 list_for_each_entry(&argv->words, word, argv_list)
105 argv->argv[i++] = word->text;
108 int statements_execute(struct grub2_script *script,
109 struct grub2_statements *stmts)
111 struct grub2_statement *stmt;
114 list_for_each_entry(&stmts->list, stmt, list) {
116 rc = stmt->exec(script, stmt);
121 int statement_simple_execute(struct grub2_script *script,
122 struct grub2_statement *statement)
124 struct grub2_statement_simple *st = to_stmt_simple(statement);
125 struct grub2_command *cmd;
131 process_expansions(script, st->argv);
136 cmd = script_lookup_command(script, st->argv->argv[0]);
138 fprintf(stderr, "undefined command '%s'\n", st->argv->argv[0]);
142 rc = cmd->exec(script, st->argv->argc, st->argv->argv);
147 int statement_if_execute(struct grub2_script *script,
148 struct grub2_statement *statement)
150 struct grub2_statement_if *st = to_stmt_if(statement);
151 struct grub2_statements *case_stmts;
154 rc = st->condition->exec(script, st->condition);
157 case_stmts = st->true_case;
159 case_stmts = st->false_case;
162 statements_execute(script, case_stmts);
169 int statement_menuentry_execute(struct grub2_script *script,
170 struct grub2_statement *statement)
172 struct grub2_statement_menuentry *st = to_stmt_menuentry(statement);
174 process_expansions(script, st->argv);
175 statements_execute(script, st->statements);
180 static void init_env(struct grub2_script *script)
182 struct env_entry *env;
184 list_init(&script->environment);
186 env = talloc(script, struct env_entry);
187 env->name = talloc_strdup(env, "prefix");
188 env->value = talloc_strdup(env, "/");
190 list_add(&script->environment, &env->list);
193 struct grub2_command *script_lookup_command(struct grub2_script *script,
196 struct grub2_command *command;
198 list_for_each_entry(&script->commands, command, list) {
199 if (!strcmp(command->name, name))
206 void script_register_command(struct grub2_script *script,
207 struct grub2_command *command)
209 list_add(&script->commands, &command->list);
213 void script_execute(struct grub2_script *script)
215 statements_execute(script, script->statements);
218 struct grub2_script *create_script(void *ctx)
220 struct grub2_script *script;
222 script = talloc(ctx, struct grub2_script);
225 list_init(&script->commands);
226 register_builtins(script);