X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fopt%2Fusage.c;h=60e1586861adc0981a5bf0eaf00bc63bcff450a4;hp=37ba3ed712d51fe63a8c236a6f3e45acea2f2b0d;hb=b30c544bd1486e7b60b99259e3d0dcbc1ec9efd0;hpb=d7d5abe98caeec82d784ce525e0444ff438acd46 diff --git a/ccan/opt/usage.c b/ccan/opt/usage.c index 37ba3ed7..60e15868 100644 --- a/ccan/opt/usage.c +++ b/ccan/opt/usage.c @@ -6,47 +6,57 @@ #include "private.h" /* We only use this for pointer comparisons. */ -const char opt_table_hidden[1]; +const char opt_hidden[1]; static unsigned write_short_options(char *str) { unsigned int i, num = 0; + const char *p; - for (i = 0; i < opt_count; i++) { - if (opt_table[i].flags == OPT_SUBTABLE) { - if (opt_table[i].desc == opt_table_hidden) { - /* Skip these options. */ - i += (intptr_t)opt_table[i].arg - 1; - continue; - } - } else if (opt_table[i].shortopt) - str[num++] = opt_table[i].shortopt; + for (p = first_sopt(&i); p; p = next_sopt(p, &i)) { + if (opt_table[i].desc != opt_hidden) + str[num++] = *p; } return num; } +#define OPT_SPACE_PAD " " + /* FIXME: Get all purdy. */ char *opt_usage(const char *argv0, const char *extra) { unsigned int i, num, len; char *ret, *p; + if (!extra) { + extra = ""; + for (i = 0; i < opt_count; i++) { + if (opt_table[i].cb == (void *)opt_usage_and_exit + && opt_table[i].arg) { + extra = opt_table[i].arg; + break; + } + } + } + /* An overestimate of our length. */ len = strlen("Usage: %s ") + strlen(argv0) - + strlen("[-%.*s]") + opt_count + 1 + + strlen("[-%.*s]") + opt_num_short + 1 + strlen(" ") + strlen(extra) + strlen("\n"); for (i = 0; i < opt_count; i++) { - if (opt_table[i].flags == OPT_SUBTABLE) { + if (opt_table[i].type == OPT_SUBTABLE) { len += strlen("\n") + strlen(opt_table[i].desc) + strlen(":\n"); - } else { - len += strlen("--%s/-%c") + strlen(" "); - if (opt_table[i].longopt) - len += strlen(opt_table[i].longopt); - if (opt_table[i].desc) - len += 20 + strlen(opt_table[i].desc); + } else if (opt_table[i].desc != opt_hidden) { + len += strlen(opt_table[i].names) + strlen(" "); + len += strlen(OPT_SPACE_PAD) + + strlen(opt_table[i].desc) + 1; + if (opt_table[i].show) { + len += strlen("(default: %s)") + + OPT_SHOW_LEN + sizeof("..."); + } len += strlen("\n"); } } @@ -70,30 +80,28 @@ char *opt_usage(const char *argv0, const char *extra) p += sprintf(p, "\n"); for (i = 0; i < opt_count; i++) { - if (opt_table[i].flags == OPT_SUBTABLE) { - if (opt_table[i].desc == opt_table_hidden) { - /* Skip these options. */ - i += (intptr_t)opt_table[i].arg - 1; - continue; - } + if (opt_table[i].desc == opt_hidden) + continue; + if (opt_table[i].type == OPT_SUBTABLE) { p += sprintf(p, "%s:\n", opt_table[i].desc); continue; } - if (opt_table[i].shortopt && opt_table[i].longopt) - len = sprintf(p, "--%s/-%c", - opt_table[i].longopt, - opt_table[i].shortopt); - else if (opt_table[i].shortopt) - len = sprintf(p, "-%c", opt_table[i].shortopt); - else - len = sprintf(p, "--%s", opt_table[i].longopt); - if (opt_table[i].flags == OPT_HASARG) + len = sprintf(p, "%s", opt_table[i].names); + if (opt_table[i].type == OPT_HASARG + && !strchr(opt_table[i].names, ' ') + && !strchr(opt_table[i].names, '=')) len += sprintf(p + len, " "); - if (opt_table[i].desc) { - len += sprintf(p + len, "%.*s", - len < 20 ? 20 - len : 1, - " "); - len += sprintf(p + len, "%s", opt_table[i].desc); + len += sprintf(p + len, "%.*s", + len < strlen(OPT_SPACE_PAD) + ? (unsigned)strlen(OPT_SPACE_PAD) - len : 1, + OPT_SPACE_PAD); + + len += sprintf(p + len, "%s", opt_table[i].desc); + if (opt_table[i].show) { + char buf[OPT_SHOW_LEN + sizeof("...")]; + strcpy(buf + OPT_SHOW_LEN, "..."); + opt_table[i].show(buf, opt_table[i].arg); + len += sprintf(p + len, " (default: %s)", buf); } p += len; p += sprintf(p, "\n");