6 #include <talloc/talloc.h>
10 #define to_stmt_simple(stmt) \
11 container_of(stmt, struct grub2_statement_simple, st)
12 #define to_stmt_if(stmt) \
13 container_of(stmt, struct grub2_statement_if, st)
18 struct list_item list;
21 static const char *env_lookup(struct grub2_script *script,
22 const char *name, int name_len)
24 struct env_entry *entry;
26 list_for_each_entry(&script->environment, entry, list)
27 if (!strncmp(entry->name, name, name_len)
28 && entry->name[name_len] == '\0')
34 static bool expand_word(struct grub2_script *script, struct grub2_word *word)
36 const char *val, *src;
43 n = regexec(&script->var_re, src, 1, &match, 0);
48 if (src[match.rm_so + 1] == '{')
51 val = env_lookup(script, src + match.rm_so + 1 + i,
52 match.rm_eo - match.rm_so - 1 - (i * 2));
56 dest = talloc_strndup(script, src, match.rm_so);
57 dest = talloc_asprintf_append(dest, "%s%s", val, src + match.rm_eo);
63 /* iterate through the words in an argv, looking for expansions. If a
64 * word is marked with expand == true, then we process any variable
67 * Once that's done, we may (if split == true) have to split the word to create
70 static void process_expansions(struct grub2_script *script,
71 struct grub2_argv *argv)
73 struct grub2_word *word;
75 list_for_each_entry(&argv->words, word, argv_list) {
79 expand_word(script, word);
83 int statements_execute(struct grub2_script *script,
84 struct grub2_statements *stmts)
86 struct grub2_statement *stmt;
89 list_for_each_entry(&stmts->list, stmt, list) {
91 rc = stmt->exec(script, stmt);
96 int statement_simple_execute(struct grub2_script *script,
97 struct grub2_statement *statement)
99 struct grub2_statement_simple *st = to_stmt_simple(statement);
104 process_expansions(script, st->argv);
109 int statement_if_execute(struct grub2_script *script,
110 struct grub2_statement *statement)
112 struct grub2_statement_if *st = to_stmt_if(statement);
113 struct grub2_statements *case_stmts;
116 rc = st->condition->exec(script, st->condition);
119 case_stmts = st->true_case;
121 case_stmts = st->false_case;
124 statements_execute(script, case_stmts);
131 static void init_env(struct grub2_script *script)
133 struct env_entry *env;
135 list_init(&script->environment);
137 env = talloc(script, struct env_entry);
138 env->name = talloc_strdup(env, "prefix");
139 env->value = talloc_strdup(env, "/");
141 list_add(&script->environment, &env->list);
145 void script_execute(struct grub2_script *script)
147 statements_execute(script, script->statements);
150 static int script_destroy(void *p)
152 struct grub2_script *script = p;
153 regfree(&script->var_re);
157 struct grub2_script *create_script(void *ctx)
159 struct grub2_script *script;
162 script = talloc(ctx, struct grub2_script);
164 rc = regcomp(&script->var_re,
165 "\\$\\{?([[:alpha:]][_[:alnum:]]*|[0-9]|[\\?@\\*#])\\}?",
169 regerror(rc, &script->var_re, err, sizeof(err));
170 fprintf(stderr, "RE error %d: %s\n", rc, err);
175 talloc_set_destructor(script, script_destroy);