From 1972d9cfcc5300cd8cb2f587d9bc5f856322ae8f Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 25 Sep 2013 08:37:50 +0800 Subject: [PATCH] discover/grub2: Reimplement default options Signed-off-by: Jeremy Kerr --- discover/grub2/grub2.h | 1 + discover/grub2/script.c | 25 ++++++++++++++-- test/parser/Makefile.am | 3 ++ test/parser/test-grub2-default-index.c | 34 ++++++++++++++++++++++ test/parser/test-grub2-default-multiword.c | 30 +++++++++++++++++++ test/parser/test-grub2-default.c | 27 +++++++++++++++++ 6 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 test/parser/test-grub2-default-index.c create mode 100644 test/parser/test-grub2-default-multiword.c create mode 100644 test/parser/test-grub2-default.c diff --git a/discover/grub2/grub2.h b/discover/grub2/grub2.h index 4d083ae..5ee8503 100644 --- a/discover/grub2/grub2.h +++ b/discover/grub2/grub2.h @@ -89,6 +89,7 @@ struct grub2_script { struct list symtab; struct discover_context *ctx; struct discover_boot_option *opt; + unsigned int n_options; }; struct grub2_parser { diff --git a/discover/grub2/script.c b/discover/grub2/script.c index 3f5bc23..0cf2196 100644 --- a/discover/grub2/script.c +++ b/discover/grub2/script.c @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -96,6 +97,24 @@ static bool is_delim(char c) return c == ' ' || c == '\t'; } +static bool option_is_default(struct grub2_script *script, + struct discover_boot_option *opt) +{ + unsigned int default_idx; + const char *var; + char *end; + + var = script_env_get(script, "default"); + if (!var) + return false; + + default_idx = strtoul(var, &end, 10); + if (end != var && *end == '\0') + return default_idx == script->n_options; + + return !strcmp(opt->option->name, var); +} + /* For non-double-quoted variable expansions, we may need to split the * variable's value into multiple argv items. * @@ -333,7 +352,10 @@ int statement_menuentry_execute(struct grub2_script *script, statements_execute(script, st->statements); + opt->option->is_default = option_is_default(script, opt); + discover_context_add_boot_option(script->ctx, opt); + script->n_options++; script->opt = NULL; return 0; @@ -407,11 +429,10 @@ struct grub2_script *create_script(struct grub2_parser *parser, { struct grub2_script *script; - script = talloc(parser, struct grub2_script); + script = talloc_zero(parser, struct grub2_script); init_env(script); script->ctx = ctx; - script->opt = NULL; list_init(&script->symtab); register_builtins(script); diff --git a/test/parser/Makefile.am b/test/parser/Makefile.am index fbf9c50..8159bd6 100644 --- a/test/parser/Makefile.am +++ b/test/parser/Makefile.am @@ -28,6 +28,9 @@ LDADD = $(top_builddir)/lib/libpbcore.la libtest.ro TESTS = \ test-null \ test-grub2-single \ + test-grub2-default \ + test-grub2-default-index \ + test-grub2-default-multiword \ test-grub2-multiple-resolve \ test-grub2-single-line-if \ test-grub2-f18-ppc64 \ diff --git a/test/parser/test-grub2-default-index.c b/test/parser/test-grub2-default-index.c new file mode 100644 index 0000000..78835cd --- /dev/null +++ b/test/parser/test-grub2-default-index.c @@ -0,0 +1,34 @@ + +#include "parser-test.h" + +#if 0 /* PARSER_EMBEDDED_CONFIG */ +set default=1 +menuentry 'test-option-0' { + linux /vmlinux.0 +} +menuentry 'test-option-1' { + linux /vmlinux.1 +} +menuentry 'test-option-2' { + linux /vmlinux.2 +} +#endif + +void run_test(struct parser_test *test) +{ + struct discover_boot_option *opt; + struct discover_context *ctx; + + test_read_conf_embedded(test); + test_run_parser(test, "grub2"); + + ctx = test->ctx; + + check_boot_option_count(ctx, 3); + opt = get_boot_option(ctx, 1); + + check_name(opt, "test-option-1"); + check_resolved_local_resource(opt->boot_image, ctx->device, + "/vmlinux.1"); + check_is_default(opt); +} diff --git a/test/parser/test-grub2-default-multiword.c b/test/parser/test-grub2-default-multiword.c new file mode 100644 index 0000000..f7993fe --- /dev/null +++ b/test/parser/test-grub2-default-multiword.c @@ -0,0 +1,30 @@ + +#include "parser-test.h" + +#if 0 /* PARSER_EMBEDDED_CONFIG */ +set default="Multiple word option" +menuentry 'Non-defalt option' { + linux /vmlinux.non-default +} +menuentry 'Multiple word option' { + linux /vmlinux +} +#endif + +void run_test(struct parser_test *test) +{ + struct discover_boot_option *opt; + struct discover_context *ctx; + + test_read_conf_embedded(test); + test_run_parser(test, "grub2"); + + ctx = test->ctx; + + check_boot_option_count(ctx, 2); + + opt = get_boot_option(ctx, 1); + check_name(opt, "Multiple word option"); + check_resolved_local_resource(opt->boot_image, ctx->device, "/vmlinux"); + check_is_default(opt); +} diff --git a/test/parser/test-grub2-default.c b/test/parser/test-grub2-default.c new file mode 100644 index 0000000..b3359d0 --- /dev/null +++ b/test/parser/test-grub2-default.c @@ -0,0 +1,27 @@ + +#include "parser-test.h" + +#if 0 /* PARSER_EMBEDDED_CONFIG */ +set default="test-option" +menuentry 'test-option' { + linux /vmlinux +} +#endif + +void run_test(struct parser_test *test) +{ + struct discover_boot_option *opt; + struct discover_context *ctx; + + test_read_conf_embedded(test); + test_run_parser(test, "grub2"); + + ctx = test->ctx; + + check_boot_option_count(ctx, 1); + opt = get_boot_option(ctx, 0); + + check_name(opt, "test-option"); + check_resolved_local_resource(opt->boot_image, ctx->device, "/vmlinux"); + check_is_default(opt); +} -- 2.39.2