|
|
|
@ -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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|