container_of(stmt, struct grub2_statement_conditional, st)
struct env_entry {
- const char *name;
- const char *value;
+ char *name;
+ char *value;
struct list_item list;
};
if (!entry) {
entry = talloc(script, struct env_entry);
- entry->name = name;
+ entry->name = talloc_strdup(entry, name);
list_add(&script->environment, &entry->list);
+ } else {
+ talloc_free(entry->value);
}
- entry->value = value;
+ entry->value = talloc_strdup(entry, value);
}
static bool expand_var(struct grub2_script *script, struct grub2_word *word)
}
static bool option_is_default(struct grub2_script *script,
- struct discover_boot_option *opt)
+ struct discover_boot_option *opt, const char *id)
{
unsigned int default_idx;
const char *var;
if (end != var && *end == '\0')
return default_idx == script->n_options;
- return !strcmp(opt->option->name, var);
+ /* if we don't have an explicit id for this option, fall back to
+ * the name */
+ if (!id)
+ id = opt->option->name;
+
+ return !strcmp(id, var);
}
/* For non-double-quoted variable expansions, we may need to split the
struct grub2_statement_if *st = to_stmt_if(statement);
struct grub2_statement *conditional;
bool executed;
- int rc;
+ int rc = 0;
list_for_each_entry(&st->conditionals->list, conditional, list) {
rc = statement_conditional_execute(script,
{
struct grub2_statement_menuentry *st = to_stmt_menuentry(statement);
struct discover_boot_option *opt;
+ const char *id = NULL;
+ int i;
process_expansions(script, st->argv);
opt = discover_boot_option_create(script->ctx, script->ctx->device);
- if (st->argv->argc > 0) {
+
+ /* XXX: --options=values need to be parsed properly; this is a simple
+ * implementation to get --id= working.
+ */
+ for (i = 1; i < st->argv->argc; ++i) {
+ if (strncmp("--id=", st->argv->argv[i], 5) == 0) {
+ id = st->argv->argv[i] + 5;
+ break;
+ }
+ }
+ if (st->argv->argc > 0)
opt->option->name = talloc_strdup(opt, st->argv->argv[0]);
- } else {
+ else
opt->option->name = talloc_strdup(opt, "(unknown)");
- }
+
opt->option->id = talloc_asprintf(opt->option, "%s#%s",
script->ctx->device->device->id,
- opt->option->name);
+ id ? id : opt->option->name);
script->opt = opt;
statements_execute(script, st->statements);
- opt->option->is_default = option_is_default(script, opt);
+ opt->option->is_default = option_is_default(script, opt, id);
discover_context_add_boot_option(script->ctx, opt);
script->n_options++;
static void init_env(struct grub2_script *script)
{
struct env_entry *env;
+ char *prefix, *sep;
list_init(&script->environment);
+ /* use location of the parsed config file to determine the prefix */
env = talloc(script, struct env_entry);
+
+ prefix = NULL;
+ if (script->filename) {
+ sep = strrchr(script->filename, '/');
+ if (sep)
+ prefix = talloc_strndup(env, script->filename,
+ sep - script->filename);
+ }
+
env->name = talloc_strdup(env, "prefix");
- env->value = talloc_strdup(env, default_prefix);
+ if (prefix)
+ env->value = prefix;
+ else
+ env->value = talloc_strdup(env, default_prefix);
list_add(&script->environment, &env->list);
}
void script_execute(struct grub2_script *script)
{
+ init_env(script);
statements_execute(script, script->statements);
}
script = talloc_zero(parser, struct grub2_script);
- init_env(script);
script->ctx = ctx;
list_init(&script->symtab);