return PARSE_OPT_ERROR;
}
-static enum parse_opt_result parse_subcommand(const char *arg,
- const struct option *options)
+static int parse_subcommand(const char *arg, const struct option *options)
{
- for (; options->type != OPTION_END; options++)
- if (options->type == OPTION_SUBCOMMAND &&
- !strcmp(options->long_name, arg)) {
- *(parse_opt_subcommand_fn **)options->value = options->subcommand_fn;
- return PARSE_OPT_SUBCOMMAND;
- }
+ for (; options->type != OPTION_END; options++) {
+ parse_opt_subcommand_fn **opt_val;
- return PARSE_OPT_UNKNOWN;
+ if (options->type != OPTION_SUBCOMMAND ||
+ strcmp(options->long_name, arg))
+ continue;
+
+ opt_val = options->value;
+ *opt_val = options->subcommand_fn;
+ return 0;
+ }
+
+ return -1;
+}
+
+static enum parse_opt_result handle_subcommand(struct parse_opt_ctx_t *ctx,
+ const char *arg,
+ const struct option *options,
+ const char * const usagestr[])
+{
+ int err = parse_subcommand(arg, options);
+
+ if (!err)
+ return PARSE_OPT_SUBCOMMAND;
+
+ /*
+ * arg is neither a short or long option nor a subcommand. Since this
+ * command has a default operation mode, we have to treat this arg and
+ * all remaining args as args meant to that default operation mode.
+ * So we are done parsing.
+ */
+ if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
+ return PARSE_OPT_DONE;
+
+ error(_("unknown subcommand: `%s'"), arg);
+ usage_with_options(usagestr, options);
}
static void check_typos(const char *arg, const struct option *options)
if (*arg != '-' || !arg[1]) {
if (parse_nodash_opt(ctx, arg, options) == 0)
continue;
- if (!ctx->has_subcommands) {
- if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
- return PARSE_OPT_NON_OPTION;
- ctx->out[ctx->cpidx++] = ctx->argv[0];
- continue;
- }
- switch (parse_subcommand(arg, options)) {
- case PARSE_OPT_SUBCOMMAND:
- return PARSE_OPT_SUBCOMMAND;
- case PARSE_OPT_UNKNOWN:
- if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
- /*
- * arg is neither a short or long
- * option nor a subcommand. Since
- * this command has a default
- * operation mode, we have to treat
- * this arg and all remaining args
- * as args meant to that default
- * operation mode.
- * So we are done parsing.
- */
- return PARSE_OPT_DONE;
- error(_("unknown subcommand: `%s'"), arg);
- usage_with_options(usagestr, options);
- case PARSE_OPT_COMPLETE:
- case PARSE_OPT_HELP:
- case PARSE_OPT_ERROR:
- case PARSE_OPT_DONE:
- case PARSE_OPT_NON_OPTION:
- /* Impossible. */
- BUG("parse_subcommand() cannot return these");
- }
+
+ if (ctx->has_subcommands)
+ return handle_subcommand(ctx, arg, options,
+ usagestr);
+
+ if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
+ return PARSE_OPT_NON_OPTION;
+
+ ctx->out[ctx->cpidx++] = ctx->argv[0];
+ continue;
}
/* lone -h asks for help */