void usage_with_options(const char * const *usagestr, const struct option *opts) { exit_browser(false); usage_with_options_internal(usagestr, opts, 0); exit(129); }
void usage_with_options_msg(const char * const *usagestr, const struct option *opts, const char *fmt, ...) { va_list ap; char *tmp = error_buf; va_start(ap, fmt); if (vasprintf(&error_buf, fmt, ap) == -1) die("vasprintf failed"); va_end(ap); free(tmp); usage_with_options_internal(usagestr, opts, 0, NULL); exit(129); }
static int parse_options_usage(struct parse_opt_ctx_t *ctx, const char * const *usagestr, const struct option *opts, int err) { return usage_with_options_internal(ctx, usagestr, opts, 0, err); }
void NORETURN usage_with_options(const char * const *usagestr, const struct option *opts) { usage_with_options_internal(NULL, usagestr, opts, 0, 1); exit(129); }
int parse_options_step(struct parse_opt_ctx_t *ctx, const struct option *options, const char * const usagestr[]) { int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); /* we must reset ->opt, unknown short option leave it dangling */ ctx->opt = NULL; for (; ctx->argc; ctx->argc--, ctx->argv++) { const char *arg = ctx->argv[0]; if (*arg != '-' || !arg[1]) { if (parse_nodash_opt(ctx, arg, options) == 0) continue; if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION) return PARSE_OPT_NON_OPTION; ctx->out[ctx->cpidx++] = ctx->argv[0]; continue; } if (arg[1] != '-') { ctx->opt = arg + 1; if (internal_help && *ctx->opt == 'h') return parse_options_usage(ctx, usagestr, options, 0); switch (parse_short_opt(ctx, options)) { case -1: return parse_options_usage(ctx, usagestr, options, 1); case -2: if (ctx->opt) check_typos(arg + 1, options); goto unknown; } if (ctx->opt) check_typos(arg + 1, options); while (ctx->opt) { if (internal_help && *ctx->opt == 'h') return parse_options_usage(ctx, usagestr, options, 0); switch (parse_short_opt(ctx, options)) { case -1: return parse_options_usage(ctx, usagestr, options, 1); case -2: /* fake a short option thing to hide the fact that we may have * started to parse aggregated stuff * * This is leaky, too bad. */ ctx->argv[0] = xstrdup(ctx->opt - 1); *(char *)ctx->argv[0] = '-'; goto unknown; } } continue; } if (!arg[2]) { /* "--" */ if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) { ctx->argc--; ctx->argv++; } break; } if (internal_help && !strcmp(arg + 2, "help-all")) return usage_with_options_internal(ctx, usagestr, options, 1, 0); if (internal_help && !strcmp(arg + 2, "help")) return parse_options_usage(ctx, usagestr, options, 0); switch (parse_long_opt(ctx, arg + 2, options)) { case -1: return parse_options_usage(ctx, usagestr, options, 1); case -2: goto unknown; } continue; unknown: if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN)) return PARSE_OPT_UNKNOWN; ctx->out[ctx->cpidx++] = ctx->argv[0]; ctx->opt = NULL; } return PARSE_OPT_DONE; }
int parse_options_usage(const char * const *usagestr, const struct option *opts) { return usage_with_options_internal(usagestr, opts, 0); }
void usage_with_options(const char * const *usagestr, const struct option *opts) { usage_with_options_internal(usagestr, opts, 0); exit(129); }
static int parse_options_step(struct parse_opt_ctx_t *ctx, const struct option *options, const char * const usagestr[]) { int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); int excl_short_opt = 1; const char *arg; /* we must reset ->opt, unknown short option leave it dangling */ ctx->opt = NULL; for (; ctx->argc; ctx->argc--, ctx->argv++) { arg = ctx->argv[0]; if (*arg != '-' || !arg[1]) { if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION) break; ctx->out[ctx->cpidx++] = ctx->argv[0]; continue; } if (arg[1] != '-') { ctx->opt = ++arg; if (internal_help && *ctx->opt == 'h') { return usage_with_options_internal(usagestr, options, 0, ctx); } switch (parse_short_opt(ctx, options)) { case -1: return parse_options_usage(usagestr, options, arg, 1); case -2: goto unknown; case -3: goto exclusive; default: break; } if (ctx->opt) check_typos(arg, options); while (ctx->opt) { if (internal_help && *ctx->opt == 'h') return usage_with_options_internal(usagestr, options, 0, ctx); arg = ctx->opt; switch (parse_short_opt(ctx, options)) { case -1: return parse_options_usage(usagestr, options, arg, 1); case -2: /* fake a short option thing to hide the fact that we may have * started to parse aggregated stuff * * This is leaky, too bad. */ ctx->argv[0] = strdup(ctx->opt - 1); *(char *)ctx->argv[0] = '-'; goto unknown; case -3: goto exclusive; default: break; } } continue; } if (!arg[2]) { /* "--" */ if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) { ctx->argc--; ctx->argv++; } break; } arg += 2; if (internal_help && !strcmp(arg, "help-all")) return usage_with_options_internal(usagestr, options, 1, ctx); if (internal_help && !strcmp(arg, "help")) return usage_with_options_internal(usagestr, options, 0, ctx); if (!strcmp(arg, "list-opts")) return PARSE_OPT_LIST_OPTS; if (!strcmp(arg, "list-cmds")) return PARSE_OPT_LIST_SUBCMDS; switch (parse_long_opt(ctx, arg, options)) { case -1: return parse_options_usage(usagestr, options, arg, 0); case -2: goto unknown; case -3: excl_short_opt = 0; goto exclusive; default: break; } continue; unknown: if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN)) return PARSE_OPT_UNKNOWN; ctx->out[ctx->cpidx++] = ctx->argv[0]; ctx->opt = NULL; } return PARSE_OPT_DONE; exclusive: parse_options_usage(usagestr, options, arg, excl_short_opt); if ((excl_short_opt && ctx->excl_opt->short_name) || ctx->excl_opt->long_name == NULL) { char opt = ctx->excl_opt->short_name; parse_options_usage(NULL, options, &opt, 1); } else { parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0); } return PARSE_OPT_HELP; }