1 #include <ccan/opt/opt.h>
8 /* We only use this for pointer comparisons. */
9 const char opt_table_hidden[1];
11 static unsigned write_short_options(char *str)
13 unsigned int i, num = 0;
15 for (i = 0; i < opt_count; i++) {
16 if (opt_table[i].flags == OPT_SUBTABLE) {
17 if (opt_table[i].desc == opt_table_hidden) {
18 /* Skip these options. */
19 i += (intptr_t)opt_table[i].arg - 1;
22 } else if (opt_table[i].shortopt)
23 str[num++] = opt_table[i].shortopt;
28 #define OPT_SPACE_PAD " "
30 /* FIXME: Get all purdy. */
31 char *opt_usage(const char *argv0, const char *extra)
33 unsigned int i, num, len;
36 /* An overestimate of our length. */
37 len = strlen("Usage: %s ") + strlen(argv0)
38 + strlen("[-%.*s]") + opt_count + 1
39 + strlen(" ") + strlen(extra)
42 for (i = 0; i < opt_count; i++) {
43 if (opt_table[i].flags == OPT_SUBTABLE) {
44 len += strlen("\n") + strlen(opt_table[i].desc)
47 len += strlen("--%s/-%c") + strlen(" <arg>");
48 if (opt_table[i].longopt)
49 len += strlen(opt_table[i].longopt);
50 if (opt_table[i].desc) {
51 len += strlen(OPT_SPACE_PAD)
52 + strlen(opt_table[i].desc) + 1;
54 if (opt_table[i].show) {
55 len += strlen("(default: %s)")
56 + OPT_SHOW_LEN + sizeof("...");
62 p = ret = malloc(len);
66 p += sprintf(p, "Usage: %s", argv0);
67 p += sprintf(p, " [-");
68 num = write_short_options(p);
73 /* Remove start of single-entry options */
77 p += sprintf(p, " %s", extra);
78 p += sprintf(p, "\n");
80 for (i = 0; i < opt_count; i++) {
81 if (opt_table[i].flags == OPT_SUBTABLE) {
82 if (opt_table[i].desc == opt_table_hidden) {
83 /* Skip these options. */
84 i += (intptr_t)opt_table[i].arg - 1;
87 p += sprintf(p, "%s:\n", opt_table[i].desc);
90 if (opt_table[i].shortopt && opt_table[i].longopt)
91 len = sprintf(p, "--%s/-%c",
93 opt_table[i].shortopt);
94 else if (opt_table[i].shortopt)
95 len = sprintf(p, "-%c", opt_table[i].shortopt);
97 len = sprintf(p, "--%s", opt_table[i].longopt);
98 if (opt_table[i].flags == OPT_HASARG)
99 len += sprintf(p + len, " <arg>");
100 if (opt_table[i].desc || opt_table[i].show)
101 len += sprintf(p + len, "%.*s",
102 len < strlen(OPT_SPACE_PAD)
103 ? strlen(OPT_SPACE_PAD) - len : 1,
106 if (opt_table[i].desc)
107 len += sprintf(p + len, "%s", opt_table[i].desc);
108 if (opt_table[i].show) {
109 char buf[OPT_SHOW_LEN + sizeof("...")];
110 strcpy(buf + OPT_SHOW_LEN, "...");
111 opt_table[i].show(buf, opt_table[i].arg);
112 len += sprintf(p + len, "%s(default: %s)",
113 opt_table[i].desc ? " " : "", buf);
116 p += sprintf(p, "\n");