diff options
Diffstat (limited to 'src/core/support')
-rw-r--r-- | src/core/support/cmdline.c | 70 |
1 files changed, 50 insertions, 20 deletions
diff --git a/src/core/support/cmdline.c b/src/core/support/cmdline.c index 72f46c1bd7..530952c437 100644 --- a/src/core/support/cmdline.c +++ b/src/core/support/cmdline.c @@ -131,33 +131,63 @@ void gpr_cmdline_on_extra_arg( cl->extra_arg_help = help; } -static void print_usage_and_die(gpr_cmdline *cl) { +/* recursively descend argument list, adding the last element + to s first - so that arguments are added in the order they were + added to the list by api calls */ +static void add_args_to_usage(gpr_strvec *s, arg *a) { + char *tmp; + + if (!a) return; + add_args_to_usage(s, a->next); + + switch (a->type) { + case ARGTYPE_BOOL: + gpr_asprintf(&tmp, " [--%s|--no-%s]", a->name, a->name); + gpr_strvec_add(s, tmp); + break; + case ARGTYPE_STRING: + gpr_asprintf(&tmp, " [--%s=string]", a->name); + gpr_strvec_add(s, tmp); + break; + case ARGTYPE_INT: + gpr_asprintf(&tmp, " [--%s=int]", a->name); + gpr_strvec_add(s, tmp); + break; + } +} + +char *gpr_cmdline_usage_string(gpr_cmdline *cl, const char *argv0) { /* TODO(ctiller): make this prettier */ - arg *a; - const char *name = strrchr(cl->argv0, '/'); + gpr_strvec s; + char *tmp; + const char *name = strrchr(argv0, '/'); + if (name) { name++; } else { - name = cl->argv0; - } - fprintf(stderr, "Usage: %s", name); - for (a = cl->args; a; a = a->next) { - switch (a->type) { - case ARGTYPE_BOOL: - fprintf(stderr, " [--%s|--no-%s]", a->name, a->name); - break; - case ARGTYPE_STRING: - fprintf(stderr, " [--%s=string]", a->name); - break; - case ARGTYPE_INT: - fprintf(stderr, " [--%s=int]", a->name); - break; - } + name = argv0; } + + gpr_strvec_init(&s); + + gpr_asprintf(&tmp, "Usage: %s", name); + gpr_strvec_add(&s, tmp); + add_args_to_usage(&s, cl->args); if (cl->extra_arg) { - fprintf(stderr, " [%s...]", cl->extra_arg_name); + gpr_asprintf(&tmp, " [%s...]", cl->extra_arg_name); + gpr_strvec_add(&s, tmp); } - fprintf(stderr, "\n"); + gpr_strvec_add(&s, gpr_strdup("\n")); + + tmp = gpr_strvec_flatten(&s, NULL); + gpr_strvec_destroy(&s); + return tmp; +} + +static void print_usage_and_die(gpr_cmdline *cl) { + char *usage = gpr_cmdline_usage_string(cl, cl->argv0); + fprintf(stderr, "%s", usage); + gpr_free(usage); exit(1); } |