1 #include <ccan/opt/opt.h>
8 /* We only use this for pointer comparisons. */
9 const char opt_hidden[1];
11 static unsigned write_short_options(char *str)
13 unsigned int i, num = 0;
16 for (p = first_sopt(&i); p; p = next_sopt(p, &i)) {
17 if (opt_table[i].desc != opt_hidden)
23 #define OPT_SPACE_PAD " "
25 /* FIXME: Get all purdy. */
26 char *opt_usage(const char *argv0, const char *extra)
28 unsigned int i, num, len;
31 /* An overestimate of our length. */
32 len = strlen("Usage: %s ") + strlen(argv0)
33 + strlen("[-%.*s]") + opt_num_short + 1
34 + strlen(" ") + strlen(extra)
37 for (i = 0; i < opt_count; i++) {
38 if (opt_table[i].flags == OPT_SUBTABLE) {
39 len += strlen("\n") + strlen(opt_table[i].desc)
41 } else if (opt_table[i].desc != opt_hidden) {
42 len += strlen(opt_table[i].names) + strlen(" <arg>");
43 if (opt_table[i].desc) {
44 len += strlen(OPT_SPACE_PAD)
45 + strlen(opt_table[i].desc) + 1;
47 if (opt_table[i].show) {
48 len += strlen("(default: %s)")
49 + OPT_SHOW_LEN + sizeof("...");
55 p = ret = malloc(len);
59 p += sprintf(p, "Usage: %s", argv0);
60 p += sprintf(p, " [-");
61 num = write_short_options(p);
66 /* Remove start of single-entry options */
70 p += sprintf(p, " %s", extra);
71 p += sprintf(p, "\n");
73 for (i = 0; i < opt_count; i++) {
74 if (opt_table[i].desc == opt_hidden)
76 if (opt_table[i].flags == OPT_SUBTABLE) {
77 p += sprintf(p, "%s:\n", opt_table[i].desc);
80 len = sprintf(p, "%s", opt_table[i].names);
81 if (opt_table[i].flags == OPT_HASARG)
82 len += sprintf(p + len, " <arg>");
83 if (opt_table[i].desc || opt_table[i].show)
84 len += sprintf(p + len, "%.*s",
85 len < strlen(OPT_SPACE_PAD)
86 ? strlen(OPT_SPACE_PAD) - len : 1,
89 if (opt_table[i].desc)
90 len += sprintf(p + len, "%s", opt_table[i].desc);
91 if (opt_table[i].show) {
92 char buf[OPT_SHOW_LEN + sizeof("...")];
93 strcpy(buf + OPT_SHOW_LEN, "...");
94 opt_table[i].show(buf, opt_table[i].arg);
95 len += sprintf(p + len, "%s(default: %s)",
96 opt_table[i].desc ? " " : "", buf);
99 p += sprintf(p, "\n");