X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=discover%2Fgrub2%2Fscript.c;h=c4f58d92bacb27395647a23d9c4f9feb5d8d6016;hp=75b8aaaae474fc6348215dea26d7e963f31e4562;hb=d6b11766acb4457457419a84f460a3ce7a8f4693;hpb=57293e2111fcba58a7b399cb1332012414bffeeb diff --git a/discover/grub2/script.c b/discover/grub2/script.c index 75b8aaa..c4f58d9 100644 --- a/discover/grub2/script.c +++ b/discover/grub2/script.c @@ -23,8 +23,8 @@ 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; }; @@ -75,11 +75,13 @@ void script_env_set(struct grub2_script *script, 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) @@ -101,7 +103,7 @@ static bool is_delim(char c) } 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; @@ -115,7 +117,12 @@ static bool option_is_default(struct grub2_script *script, 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 @@ -318,7 +325,7 @@ int statement_if_execute(struct grub2_script *script, 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, @@ -338,24 +345,36 @@ int statement_menuentry_execute(struct grub2_script *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++; @@ -398,14 +417,24 @@ int statement_function_execute(struct grub2_script *script, 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); - env->name = talloc_strdup(env, "prefix"); - env->value = talloc_strdup(env, default_prefix); - list_add(&script->environment, &env->list); + prefix = NULL; + if (script->filename) { + sep = strrchr(script->filename, '/'); + if (sep) + prefix = talloc_strndup(env, script->filename, + sep - script->filename); + } + + script_env_set(script, "prefix", prefix ? : default_prefix); + if (prefix) + talloc_free(prefix); } void script_register_function(struct grub2_script *script, @@ -424,6 +453,7 @@ void script_register_function(struct grub2_script *script, void script_execute(struct grub2_script *script) { + init_env(script); statements_execute(script, script->statements); } @@ -434,7 +464,6 @@ struct grub2_script *create_script(struct grub2_parser *parser, script = talloc_zero(parser, struct grub2_script); - init_env(script); script->ctx = ctx; list_init(&script->symtab);