From 44e10d816427c001d60eb5e7b3e75b740e5a2823 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Wed, 15 Jan 2014 15:10:25 -0800 Subject: [PATCH 1/1] discover/grub: Use --id values for default option detection Fix Petitboot's grub.cfg parser to handle --id=label argument to menuentry, and use it (in preference to the option name) when looking for a default option. Signed-off-by: Jeremy Kerr --- discover/grub2/script.c | 31 +++++++++++++++++++++------- test/parser/Makefile.am | 1 + test/parser/test-grub2-multiple-id.c | 28 +++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 test/parser/test-grub2-multiple-id.c diff --git a/discover/grub2/script.c b/discover/grub2/script.c index a58f1a0..aeb5978 100644 --- a/discover/grub2/script.c +++ b/discover/grub2/script.c @@ -103,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; @@ -117,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 @@ -340,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++; diff --git a/test/parser/Makefile.am b/test/parser/Makefile.am index 4c3cc69..47fd458 100644 --- a/test/parser/Makefile.am +++ b/test/parser/Makefile.am @@ -32,6 +32,7 @@ TESTS = \ test-grub2-default-index \ test-grub2-default-multiword \ test-grub2-multiple-resolve \ + test-grub2-multiple-id \ test-grub2-single-line-if \ test-grub2-load-env \ test-grub2-save-env \ diff --git a/test/parser/test-grub2-multiple-id.c b/test/parser/test-grub2-multiple-id.c new file mode 100644 index 0000000..8cfb17e --- /dev/null +++ b/test/parser/test-grub2-multiple-id.c @@ -0,0 +1,28 @@ + +#include "parser-test.h" + +#if 0 /* PARSER_EMBEDDED_CONFIG */ +set default="linux2" + +menuentry 'Linux 1' --id=linux1 { + linux /vmlinux1 +} + +menuentry 'Linux 2' --id=linux2 { + linux /vmlinux2 +} +#endif + +void run_test(struct parser_test *test) +{ + struct discover_boot_option *opt; + struct discover_context *ctx; + + test_read_conf_embedded(test, "/grub2/grub.cfg"); + test_run_parser(test, "grub2"); + + ctx = test->ctx; + check_boot_option_count(ctx, 2); + opt = get_boot_option(ctx, 1); + check_is_default(opt); +} -- 2.39.2