Klaus Heinrich Kiwi | d1cd8c5 | 2020-02-27 12:43:47 -0300 | [diff] [blame] | 1 | From 0ddab9194fb2a24dbe25c848f27eb4d66e556113 Mon Sep 17 00:00:00 2001 |
| 2 | From: Jeremy Kerr <jk@ozlabs.org> |
| 3 | Date: Thu, 31 Oct 2019 17:31:10 +0800 |
| 4 | Subject: [PATCH 05/18] discover/grub2: Use getopt for `search` argument |
| 5 | parsing |
| 6 | |
| 7 | The search command will be extended to add the full set of grub2-style |
| 8 | arguments, so switch to using getopt, rather than manual parsing. |
| 9 | |
| 10 | This means we now support `--set=foo` and `--set foo` style arguments, |
| 11 | both of which appear in the docs and common grub configs. |
| 12 | |
| 13 | Also, add a small test for the search argument handling. |
| 14 | |
| 15 | Signed-off-by: Jeremy Kerr <jk@ozlabs.org> |
| 16 | (cherry picked from commit 61ede5e0bea7d999acfdda9931e5c1f3c13c0694) |
| 17 | Signed-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 | |
| 25 | diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c |
| 26 | index 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 | |
| 89 | diff --git a/test/parser/Makefile.am b/test/parser/Makefile.am |
| 90 | index 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 \ |
| 101 | diff --git a/test/parser/test-grub2-search-args.c b/test/parser/test-grub2-search-args.c |
| 102 | new file mode 100644 |
| 103 | index 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 | -- |
| 141 | 2.17.1 |
| 142 | |