cli: use argpar for parsing help command's arguments
authorSimon Marchi <simon.marchi@efficios.com>
Sat, 27 Jul 2019 03:37:22 +0000 (23:37 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 2 Aug 2019 15:46:54 +0000 (11:46 -0400)
All straightforward, except that there is a functional change as part
of this patch.  It was possible to pass multiple leftovers, and only the
first one was considered.

    babeltrace2 help ctf tintin

did the same as

    babeltrace2 help ctf

It now prints a beautiful error:

./src/cli/babeltrace2 help ctf tintin

    ERROR:    [Babeltrace CLI] (/home/smarchi/src/babeltrace/src/cli/babeltrace2.c:2564)
      Command-line error: retcode=1
    CAUSED BY [Babeltrace CLI] (/home/smarchi/src/babeltrace/src/cli/babeltrace2-cfg-cli-args.c:1461)
      Extraneous command-line argument specified to `help` command: `tintin`.

Change-Id: I2c8f8610004d60a0844d18c9d622037cc7c1c04c
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1792
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
src/cli/babeltrace2-cfg-cli-args.c

index 351ccaa50d72ec63ed9edbf2f9c50be66fb9d8fb..975fc4897579f25b9f3d07867f0621a065bcfe1b 100644 (file)
@@ -1394,13 +1394,13 @@ void print_help_usage(FILE *fp)
 }
 
 static
-struct poptOption help_long_options[] = {
-       /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
-       { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
-       { "omit-home-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_HOME_PLUGIN_PATH, NULL, NULL },
-       { "omit-system-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_SYSTEM_PLUGIN_PATH, NULL, NULL },
-       { "plugin-path", '\0', POPT_ARG_STRING, NULL, OPT_PLUGIN_PATH, NULL, NULL },
-       { NULL, 0, '\0', NULL, 0, NULL, NULL },
+const struct bt_argpar_opt_descr help_options[] = {
+       /* id, short_name, long_name, with_arg */
+       { OPT_HELP, 'h', "help", false },
+       { OPT_OMIT_HOME_PLUGIN_PATH, '\0', "omit-home-plugin-path", false },
+       { OPT_OMIT_SYSTEM_PLUGIN_PATH, '\0', "omit-system-plugin-path", false },
+       { OPT_PLUGIN_PATH, '\0', "plugin-path", true },
+       BT_ARGPAR_OPT_DESCR_SENTINEL
 };
 
 /*
@@ -1415,13 +1415,11 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[],
                bool force_omit_home_plugin_path,
                const bt_value *initial_plugin_paths, int default_log_level)
 {
-       poptContext pc = NULL;
-       char *arg = NULL;
-       int opt;
-       int ret;
+       int ret, i;
        struct bt_config *cfg = NULL;
-       const char *leftover;
+       const char *leftover = NULL;
        char *plugin_name = NULL, *comp_cls_name = NULL;
+       struct bt_argpar_parse_ret argpar_parse_ret;
 
        *retcode = 0;
        cfg = bt_config_help_create(initial_plugin_paths, default_log_level);
@@ -1437,54 +1435,63 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[],
        }
 
        /* Parse options */
-       pc = poptGetContext(NULL, argc, (const char **) argv,
-               help_long_options, POPT_CONTEXT_KEEP_FIRST);
-       if (!pc) {
-               BT_CLI_LOGE_APPEND_CAUSE("Cannot get popt context.");
+       argpar_parse_ret = bt_argpar_parse(argc, argv, help_options, true);
+       if (argpar_parse_ret.error) {
+               BT_CLI_LOGE_APPEND_CAUSE(
+                       "While parsing `help` command's command-line arguments: %s",
+                       argpar_parse_ret.error->str);
                goto error;
        }
 
-       poptReadDefaultConfig(pc, 0);
+       if (help_option_is_specified(&argpar_parse_ret)) {
+               print_help_usage(stdout);
+               *retcode = -1;
+               BT_OBJECT_PUT_REF_AND_RESET(cfg);
+               goto end;
+       }
 
-       while ((opt = poptGetNextOpt(pc)) > 0) {
-               arg = poptGetOptArg(pc);
+       for (i = 0; i < argpar_parse_ret.items->len; i++) {
+               struct bt_argpar_item *argpar_item =
+                       g_ptr_array_index(argpar_parse_ret.items, i);
 
-               switch (opt) {
-               case OPT_PLUGIN_PATH:
-                       if (bt_config_append_plugin_paths_check_setuid_setgid(
-                                       cfg->plugin_paths, arg)) {
+               if (argpar_item->type == BT_ARGPAR_ITEM_TYPE_OPT) {
+                       struct bt_argpar_item_opt *argpar_item_opt;
+                       const char *arg;
+                       argpar_item_opt = (struct bt_argpar_item_opt *) argpar_item;
+                       arg = argpar_item_opt->arg;
+
+                       switch (argpar_item_opt->descr->id) {
+                       case OPT_PLUGIN_PATH:
+                               if (bt_config_append_plugin_paths_check_setuid_setgid(
+                                               cfg->plugin_paths, arg)) {
+                                       goto error;
+                               }
+                               break;
+                       case OPT_OMIT_SYSTEM_PLUGIN_PATH:
+                               cfg->omit_system_plugin_path = true;
+                               break;
+                       case OPT_OMIT_HOME_PLUGIN_PATH:
+                               cfg->omit_home_plugin_path = true;
+                               break;
+                       default:
+                               BT_CLI_LOGE_APPEND_CAUSE("Unknown command-line option specified (option code %d).",
+                                       argpar_item_opt->descr->id);
                                goto error;
                        }
-                       break;
-               case OPT_OMIT_SYSTEM_PLUGIN_PATH:
-                       cfg->omit_system_plugin_path = true;
-                       break;
-               case OPT_OMIT_HOME_PLUGIN_PATH:
-                       cfg->omit_home_plugin_path = true;
-                       break;
-               case OPT_HELP:
-                       print_help_usage(stdout);
-                       *retcode = -1;
-                       BT_OBJECT_PUT_REF_AND_RESET(cfg);
-                       goto end;
-               default:
-                       BT_CLI_LOGE_APPEND_CAUSE("Unknown command-line option specified (option code %d).",
-                               opt);
-                       goto error;
-               }
+               } else {
+                       struct bt_argpar_item_non_opt *argpar_item_non_opt
+                               = (struct bt_argpar_item_non_opt *) argpar_item;
 
-               free(arg);
-               arg = NULL;
-       }
+                       if (leftover) {
+                               BT_CLI_LOGE_APPEND_CAUSE("Extraneous command-line argument specified to `help` command: `%s`.",
+                                       argpar_item_non_opt->arg);
+                               goto error;
+                       }
 
-       /* Check for option parsing error */
-       if (opt < -1) {
-               BT_CLI_LOGE_APPEND_CAUSE("While parsing command-line options, at option %s: `%s`.",
-                       poptBadOption(pc, 0), poptStrerror(opt));
-               goto error;
+                       leftover = argpar_item_non_opt->arg;
+               }
        }
 
-       leftover = poptGetArg(pc);
        if (leftover) {
                plugin_comp_cls_names(leftover, NULL,
                        &plugin_name, &comp_cls_name,
@@ -1524,11 +1531,8 @@ end:
        g_free(plugin_name);
        g_free(comp_cls_name);
 
-       if (pc) {
-               poptFreeContext(pc);
-       }
+       bt_argpar_parse_ret_fini(&argpar_parse_ret);
 
-       free(arg);
        return cfg;
 }
 
This page took 0.029388 seconds and 4 git commands to generate.