discover/grub2: Populate $prefix from config file location
authorJeremy Kerr <jk@ozlabs.org>
Wed, 27 Nov 2013 11:51:49 +0000 (19:51 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Wed, 27 Nov 2013 12:02:30 +0000 (20:02 +0800)
Rather than always using the default prefix, we should determine it from
the location of the grub2 config file.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/grub2/grub2.c
discover/grub2/grub2.h
discover/grub2/parser.y
discover/grub2/script.c
test/parser/Makefile.am
test/parser/test-grub2-nondefault-prefix.c [new file with mode: 0644]

index ffb6ecefcb5ab13a166cbdab8a0092db85a81ccd..7f63c351eedb25f2e161730fa26fb5a665de219f 100644 (file)
@@ -103,7 +103,7 @@ static int grub2_parse(struct discover_context *dc)
                        continue;
 
                parser = grub2_parser_create(dc);
                        continue;
 
                parser = grub2_parser_create(dc);
-               grub2_parser_parse(parser, buf, len);
+               grub2_parser_parse(parser, *filename, buf, len);
                talloc_free(buf);
                talloc_free(parser);
                break;
                talloc_free(buf);
                talloc_free(parser);
                break;
index 1515d690a528ed1931ec1d07692748da09b8bb38..61662892f615e5a1fc0069a29180faa0a2772680 100644 (file)
@@ -89,6 +89,7 @@ struct grub2_script {
        struct list                     symtab;
        struct discover_context         *ctx;
        struct discover_boot_option     *opt;
        struct list                     symtab;
        struct discover_context         *ctx;
        struct discover_boot_option     *opt;
+       const char                      *filename;
        unsigned int                    n_options;
 };
 
        unsigned int                    n_options;
 };
 
@@ -176,6 +177,7 @@ bool resolve_grub2_resource(struct device_handler *handler,
 
 /* external parser api */
 struct grub2_parser *grub2_parser_create(struct discover_context *ctx);
 
 /* external parser api */
 struct grub2_parser *grub2_parser_create(struct discover_context *ctx);
-void grub2_parser_parse(struct grub2_parser *parser, char *buf, int len);
+void grub2_parser_parse(struct grub2_parser *parser, const char *filename,
+               char *buf, int len);
 #endif /* GRUB2_H */
 
 #endif /* GRUB2_H */
 
index a3473ca9051100df47bbe96a0062c6d9699e688c..5a4d4f8e204a97181396ee8ea9800a56113b313f 100644 (file)
@@ -303,11 +303,14 @@ struct grub2_parser *grub2_parser_create(struct discover_context *ctx)
        return parser;
 }
 
        return parser;
 }
 
-void grub2_parser_parse(struct grub2_parser *parser, char *buf, int len)
+void grub2_parser_parse(struct grub2_parser *parser, const char *filename,
+               char *buf, int len)
 {
        YY_BUFFER_STATE bufstate;
        int rc;
 
 {
        YY_BUFFER_STATE bufstate;
        int rc;
 
+       parser->script->filename = filename;
+
        bufstate = yy_scan_bytes(buf, len - 1, parser->scanner);
        yyset_lineno(1, parser->scanner);
 
        bufstate = yy_scan_bytes(buf, len - 1, parser->scanner);
        yyset_lineno(1, parser->scanner);
 
index e29d43702b1e0099435ab76b2f3966ad559cee90..a58f1a0f58eccb51abee06f9127ca0ac30450091 100644 (file)
@@ -400,12 +400,26 @@ int statement_function_execute(struct grub2_script *script,
 static void init_env(struct grub2_script *script)
 {
        struct env_entry *env;
 static void init_env(struct grub2_script *script)
 {
        struct env_entry *env;
+       char *prefix, *sep;
 
        list_init(&script->environment);
 
 
        list_init(&script->environment);
 
+       /* use location of the parsed config file to determine the prefix */
        env = talloc(script, struct env_entry);
        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->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);
 }
 
        list_add(&script->environment, &env->list);
 }
@@ -426,6 +440,7 @@ void script_register_function(struct grub2_script *script,
 
 void script_execute(struct grub2_script *script)
 {
 
 void script_execute(struct grub2_script *script)
 {
+       init_env(script);
        statements_execute(script, script->statements);
 }
 
        statements_execute(script, script->statements);
 }
 
@@ -436,7 +451,6 @@ struct grub2_script *create_script(struct grub2_parser *parser,
 
        script = talloc_zero(parser, struct grub2_script);
 
 
        script = talloc_zero(parser, struct grub2_script);
 
-       init_env(script);
        script->ctx = ctx;
 
        list_init(&script->symtab);
        script->ctx = ctx;
 
        list_init(&script->symtab);
index e355af3e11ecd95dddd86b6b2bf0f3f392249f0e..f2ee67e00b1c0a0b45a64ac639014b8001f41d48 100644 (file)
@@ -36,6 +36,7 @@ TESTS = \
        test-grub2-load-env \
        test-grub2-save-env \
        test-grub2-saved-default \
        test-grub2-load-env \
        test-grub2-save-env \
        test-grub2-saved-default \
+       test-grub2-nondefault-prefix \
        test-grub2-f18-ppc64 \
        test-grub2-ubuntu-13_04-x86 \
        test-grub2-lexer-error \
        test-grub2-f18-ppc64 \
        test-grub2-ubuntu-13_04-x86 \
        test-grub2-lexer-error \
diff --git a/test/parser/test-grub2-nondefault-prefix.c b/test/parser/test-grub2-nondefault-prefix.c
new file mode 100644 (file)
index 0000000..420cf76
--- /dev/null
@@ -0,0 +1,29 @@
+
+#include "parser-test.h"
+
+#if 0 /* PARSER_EMBEDDED_CONFIG */
+menuentry 'test option' {
+       linux   ${prefix}/vmlinux
+}
+#endif
+
+
+
+void run_test(struct parser_test *test)
+{
+       struct discover_boot_option *opt;
+       struct discover_context *ctx;
+
+       test_read_conf_embedded(test, "/grub/grub.cfg");
+
+       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,
+                       "/grub/vmlinux");
+}