summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2019-05-20 11:42:49 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-05-24 15:09:13 -0700
commite9964c4a17e192354413bf4dee6bac84e96ebcef (patch)
treeb6f2b609a641eff98afbac58f3ba6b98e5890bb7
parent72813bf7cedc63ff1cf43ed86f063cf37e850f7e (diff)
downloadchrome-ec-e9964c4a17e192354413bf4dee6bac84e96ebcef.tar.gz
gsctool: consolidate processing of optional parameters
Standard libc getopt_long() and getopt() functions do not allow the optional parameters to follow the command line option without the equal sign ('='), but gsctool utility users expect this form to be available, so additional processing is done for command line arguments accepting optional parameters. This additional processing code is duplicated for each such argument. On top of that, some arguments which described as requiring the parameter (not optional) still include code which looks for the command line option. Information about expected parameter type is included in the long options descriptor table, so it is not readily available if the user specified the short version of the argument in the command line. To consolidate processing of the optional parameters in one place, in case the user specified the short version of the command line argument, the long_opts table is looked up to find the appropriate long version, then the parameter type is checked, and if the parameter is supposed to be optional, the next command line token is examined to determine if this is the optional parameter. BRANCH=none BUG=none TEST=tried the following commands: - tried the following commands: ./extra/usb_updater/gsctool -b # reports missing file name error # All the following succeed processing command line parameters: ./extra/usb_updater/gsctool -m ./extra/usb_updater/gsctool -m enable ./extra/usb_updater/gsctool --tpm_mode enable ./extra/usb_updater/gsctool --tpm_mode=enable # All the following fail processing command line parameters # reporting 'Invalid tpm mode arg: xxx.': ./extra/usb_updater/gsctool -m xxx ./extra/usb_updater/gsctool --tpm_mode xxx ./extra/usb_updater/gsctool --tpm_mode=xxx Change-Id: I68e9cc312aa8a5a2cccbd78df66a24ac71f78c36 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1621185 Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org>
-rw-r--r--extra/usb_updater/gsctool.c91
1 files changed, 62 insertions, 29 deletions
diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c
index ce6d01b44d..c3b838e93c 100644
--- a/extra/usb_updater/gsctool.c
+++ b/extra/usb_updater/gsctool.c
@@ -2304,10 +2304,46 @@ static void set_opt_descriptors(struct option *long_opts, char *short_opts)
}
/*
+ * Find the long_opts table index where .val field is set to the passed in
+ * short option value.
+ */
+static int get_longindex(int short_opt, const struct option *long_opts)
+{
+ int i;
+
+ for (i = 0; long_opts[i].name; i++)
+ if (long_opts[i].val == short_opt)
+ return i;
+
+ /*
+ * We could never come here as the short options list is compiled
+ * based on long options table.
+ */
+ fprintf(stderr, "could not find long opt table index for %d\n",
+ short_opt);
+ exit(1);
+
+ return -1; /* Not reached. */
+}
+
+/*
* Combine searching for command line parameters and optional arguments.
+ *
+ * The canonical short options description string does not allow to specify
+ * that a command line argument expects an optional parameter. but gsctool
+ * users expect to be able to use the following styles for optional
+ * parameters:
+ *
+ * a) -x <param value>
+ * b) --x_long <param_value>
+ * c) --x_long=<param_value>
+ *
+ * Styles a) and b) are not supported standard getopt_long(), this function
+ * adds ability to handle cases a) and b).
*/
static int getopt_all(int argc, char *argv[])
{
+ int longindex = -1;
static char short_opts[2 * ARRAY_SIZE(cmd_line_options)] = {};
static struct option long_opts[ARRAY_SIZE(cmd_line_options) + 1] = {};
int i;
@@ -2315,7 +2351,29 @@ static int getopt_all(int argc, char *argv[])
if (!short_opts[0])
set_opt_descriptors(long_opts, short_opts);
- i = getopt_long(argc, argv, short_opts, long_opts, NULL);
+ i = getopt_long(argc, argv, short_opts, long_opts, &longindex);
+ if (i != -1) {
+
+ if (longindex < 0) {
+ /*
+ * longindex is not set, this must have been the short
+ * option case, Find the long_opts table index based
+ * on the short option value.
+ */
+ longindex = get_longindex(i, long_opts);
+ }
+
+ if (long_opts[longindex].has_arg == optional_argument) {
+ /*
+ * This command line option may include an argument,
+ * let's check if it is there as the next token in the
+ * command line.
+ */
+ if (!optarg && argv[optind] && argv[optind][0] != '-')
+ /* Yes, it is. */
+ optarg = argv[optind++];
+ }
+ }
return i;
}
@@ -2435,10 +2493,6 @@ int main(int argc, char *argv[])
usage(errorcnt);
break;
case 'i':
- if (!optarg && argv[optind] && argv[optind][0] != '-')
- /* optional argument present. */
- optarg = argv[optind++];
-
if (!parse_bid(optarg, &bid, &bid_action)) {
fprintf(stderr,
"Invalid board id argument: \"%s\"\n",
@@ -2448,21 +2502,15 @@ int main(int argc, char *argv[])
break;
case 'L':
get_flog = 1;
- if (!optarg && argv[optind] &&
- (argv[optind][0] != '-')) {
- prev_log_entry =
- strtoul(argv[optind++], NULL, 16);
- }
+ if (optarg)
+ prev_log_entry = strtoul(optarg, NULL, 16);
break;
case 'M':
show_machine_output = true;
break;
case 'm':
tpm_mode = 1;
- if (!optarg && argv[optind] && argv[optind][0] != '-') {
- optarg = argv[optind++];
- tpm_mode_arg = optarg;
- }
+ tpm_mode_arg = optarg;
break;
case 'n':
serial = optarg;
@@ -2472,20 +2520,10 @@ int main(int argc, char *argv[])
break;
case 'r':
rma = 1;
-
- if (!optarg && argv[optind] && argv[optind][0] != '-')
- /* optional argument present. */
- optarg = argv[optind++];
-
rma_auth_code = optarg;
break;
case 'R':
sn_inc_rma = 1;
-
- if (!optarg && argv[optind] && argv[optind][0] != '-')
- /* optional argument present. */
- optarg = argv[optind++];
-
if (!parse_sn_inc_rma(optarg, &sn_inc_rma_arg)) {
fprintf(stderr,
"Invalid sn_rma_inc argument: \"%s\"\n",
@@ -2504,11 +2542,6 @@ int main(int argc, char *argv[])
break;
case 'S':
sn_bits = 1;
-
- if (!optarg && argv[optind] && argv[optind][0] != '-')
- /* optional argument present. */
- optarg = argv[optind++];
-
if (!parse_sn_bits(optarg, sn_bits_arg)) {
fprintf(stderr,
"Invalid sn_bits argument: \"%s\"\n",