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 printf("%s: %.*s\n", __func__, name_len, name);
28 list_for_each_entry(&script->environment, entry, list)
29 if (!strncmp(entry->name, name, name_len)
30 && entry->name[name_len] == '\0')
36 static bool expand_word(struct grub2_script *script, struct grub2_word *word)
38 const char *val, *src;
45 n = regexec(&script->var_re, src, 1, &match, 0);
46 printf("%s %s: %d\n", __func__, word->text, n);
51 if (src[match.rm_so + 1] == '{')
54 val = env_lookup(script, src + match.rm_so + 1 + i,
55 match.rm_eo - match.rm_so - 1 - (i * 2));
59 printf("repl: %s\n", val);
61 dest = talloc_strndup(script, src, match.rm_so);
62 dest = talloc_asprintf_append(dest, "%s%s", val, src + match.rm_eo);
68 /* iterate through the words in an argv, looking for expansions. If a
69 * word is marked with expand == true, then we process any variable
72 * Once that's done, we may (if split == true) have to split the word to create
75 static void process_expansions(struct grub2_script *script,
76 struct grub2_argv *argv)
78 struct grub2_word *word;
80 list_for_each_entry(&argv->words, word, argv_list) {
84 expand_word(script, word);
88 int statements_execute(struct grub2_script *script,
89 struct grub2_statements *stmts)
91 struct grub2_statement *stmt;
94 list_for_each_entry(&stmts->list, stmt, list) {
96 rc = stmt->exec(script, stmt);
101 int statement_simple_execute(struct grub2_script *script,
102 struct grub2_statement *statement)
104 struct grub2_statement_simple *st = to_stmt_simple(statement);
109 process_expansions(script, st->argv);
114 int statement_if_execute(struct grub2_script *script,
115 struct grub2_statement *statement)
117 struct grub2_statement_if *st = to_stmt_if(statement);
118 struct grub2_statements *case_stmts;
121 rc = st->condition->exec(script, st->condition);
124 case_stmts = st->true_case;
126 case_stmts = st->false_case;
129 statements_execute(script, case_stmts);
136 static void init_env(struct grub2_script *script)
138 struct env_entry *env;
140 list_init(&script->environment);
142 env = talloc(script, struct env_entry);
143 env->name = talloc_strdup(env, "prefix");
144 env->value = talloc_strdup(env, "/");
146 list_add(&script->environment, &env->list);
150 void script_execute(struct grub2_script *script)
152 statements_execute(script, script->statements);
155 static int script_destroy(void *p)
157 struct grub2_script *script = p;
158 regfree(&script->var_re);
162 struct grub2_script *create_script(void *ctx)
164 struct grub2_script *script;
167 script = talloc(ctx, struct grub2_script);
169 rc = regcomp(&script->var_re,
170 "\\$\\{?([[:alpha:]][_[:alnum:]]*|[0-9]|[\\?@\\*#])\\}?",
174 regerror(rc, &script->var_re, err, sizeof(err));
175 fprintf(stderr, "RE error %d: %s\n", rc, err);
180 talloc_set_destructor(script, script_destroy);