blob: 8e8114d60eb868ace5c9dde5d4b18cb8d60cfb9f [file] [log] [blame]
Klaus Heinrich Kiwid1cd8c52020-02-27 12:43:47 -03001From 0ddab9194fb2a24dbe25c848f27eb4d66e556113 Mon Sep 17 00:00:00 2001
2From: Jeremy Kerr <jk@ozlabs.org>
3Date: Thu, 31 Oct 2019 17:31:10 +0800
4Subject: [PATCH 05/18] discover/grub2: Use getopt for `search` argument
5 parsing
6
7The search command will be extended to add the full set of grub2-style
8arguments, so switch to using getopt, rather than manual parsing.
9
10This means we now support `--set=foo` and `--set foo` style arguments,
11both of which appear in the docs and common grub configs.
12
13Also, add a small test for the search argument handling.
14
15Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
16(cherry picked from commit 61ede5e0bea7d999acfdda9931e5c1f3c13c0694)
17Signed-off-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
18---
19 discover/grub2/builtins.c | 33 +++++++++++++++++++++++-----
20 test/parser/Makefile.am | 1 +
21 test/parser/test-grub2-search-args.c | 33 ++++++++++++++++++++++++++++
22 3 files changed, 62 insertions(+), 5 deletions(-)
23 create mode 100644 test/parser/test-grub2-search-args.c
24
25diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c
26index 3f09319..ab6b0ec 100644
27--- a/discover/grub2/builtins.c
28+++ b/discover/grub2/builtins.c
29@@ -1,4 +1,7 @@
30
31+#define _GNU_SOURCE
32+
33+#include <getopt.h>
34 #include <stdio.h>
35 #include <string.h>
36
37@@ -106,18 +109,35 @@ static int builtin_initrd(struct grub2_script *script,
38 return 0;
39 }
40
41+static const struct option search_options[] = {
42+ {
43+ .name = "set",
44+ .has_arg = required_argument,
45+ .val = 's',
46+ },
47+ { 0 },
48+};
49+
50 static int builtin_search(struct grub2_script *script,
51 void *data __attribute__((unused)),
52 int argc, char *argv[])
53 {
54 const char *env_var, *spec;
55- int i;
56
57 env_var = "root";
58+ optind = 0;
59+
60+ for (;;) {
61+ int c = getopt_long(argc, argv, ":", search_options, NULL);
62+ if (c == -1)
63+ break;
64
65- for (i = 1; i < argc - 1; i++) {
66- if (!strncmp(argv[i], "--set=", strlen("--set="))) {
67- env_var = argv[i] + strlen("--set=");
68+ switch (c) {
69+ case 's':
70+ env_var = optarg;
71+ break;
72+ case '?':
73+ case ':':
74 break;
75 }
76 }
77@@ -125,7 +145,10 @@ static int builtin_search(struct grub2_script *script,
78 if (!strlen(env_var))
79 return 0;
80
81- spec = argv[argc - 1];
82+ if (optind >= argc)
83+ return -1;
84+
85+ spec = argv[optind];
86
87 script_env_set(script, env_var, spec);
88
89diff --git a/test/parser/Makefile.am b/test/parser/Makefile.am
90index 748c836..df9c539 100644
91--- a/test/parser/Makefile.am
92+++ b/test/parser/Makefile.am
93@@ -29,6 +29,7 @@ parser_TESTS = \
94 test/parser/test-grub2-multiple-id \
95 test/parser/test-grub2-single-line-if \
96 test/parser/test-grub2-pos-param \
97+ test/parser/test-grub2-search-args \
98 test/parser/test-grub2-load-env \
99 test/parser/test-grub2-save-env \
100 test/parser/test-grub2-save-env-dash-f \
101diff --git a/test/parser/test-grub2-search-args.c b/test/parser/test-grub2-search-args.c
102new file mode 100644
103index 0000000..ffce853
104--- /dev/null
105+++ b/test/parser/test-grub2-search-args.c
106@@ -0,0 +1,33 @@
107+
108+/* check for multiple styles of option parsing for the 'search' command */
109+
110+#include "parser-test.h"
111+
112+#if 0 /* PARSER_EMBEDDED_CONFIG */
113+
114+# no --set arugment will set the 'root' var
115+search a
116+search --set=v1 b
117+search --set v2 c
118+
119+menuentry $root$v1$v2 {
120+ linux /vmlinux
121+}
122+
123+#endif
124+
125+void run_test(struct parser_test *test)
126+{
127+ struct discover_boot_option *opt;
128+ struct discover_context *ctx;
129+
130+ ctx = test->ctx;
131+
132+ test_read_conf_embedded(test, "/grub/grub.cfg");
133+
134+ test_run_parser(test, "grub2");
135+
136+ check_boot_option_count(ctx, 1);
137+ opt = get_boot_option(ctx, 0);
138+ check_name(opt, "abc");
139+}
140--
1412.17.1
142