1 /* Licensed under GPLv3+ - see LICENSE file for details */
2 #include <ccan/opt/opt.h>
9 /* We only use this for pointer comparisons. */
10 const char opt_hidden[1];
12 static unsigned write_short_options(char *str)
14 unsigned int i, num = 0;
17 for (p = first_sopt(&i); p; p = next_sopt(p, &i)) {
18 if (opt_table[i].desc != opt_hidden)
24 #define OPT_SPACE_PAD " "
26 /* FIXME: Get all purdy. */
27 char *opt_usage(const char *argv0, const char *extra)
29 unsigned int i, num, len;
34 for (i = 0; i < opt_count; i++) {
35 if (opt_table[i].cb == (void *)opt_usage_and_exit
36 && opt_table[i].u.carg) {
37 extra = opt_table[i].u.carg;
43 /* An overestimate of our length. */
44 len = strlen("Usage: %s ") + strlen(argv0)
45 + strlen("[-%.*s]") + opt_num_short + 1
46 + strlen(" ") + strlen(extra)
49 for (i = 0; i < opt_count; i++) {
50 if (opt_table[i].type == OPT_SUBTABLE) {
51 len += strlen("\n") + strlen(opt_table[i].desc)
53 } else if (opt_table[i].desc != opt_hidden) {
54 len += strlen(opt_table[i].names) + strlen(" <arg>");
55 len += strlen(OPT_SPACE_PAD)
56 + strlen(opt_table[i].desc) + 1;
57 if (opt_table[i].show) {
58 len += strlen("(default: %s)")
59 + OPT_SHOW_LEN + sizeof("...");
65 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].desc == opt_hidden)
83 if (opt_table[i].type == OPT_SUBTABLE) {
84 p += sprintf(p, "%s:\n", opt_table[i].desc);
87 len = sprintf(p, "%s", opt_table[i].names);
88 if (opt_table[i].type == OPT_HASARG
89 && !strchr(opt_table[i].names, ' ')
90 && !strchr(opt_table[i].names, '='))
91 len += sprintf(p + len, " <arg>");
92 len += sprintf(p + len, "%.*s",
93 len < strlen(OPT_SPACE_PAD)
94 ? (unsigned)strlen(OPT_SPACE_PAD) - len : 1,
97 len += sprintf(p + len, "%s", opt_table[i].desc);
98 if (opt_table[i].show) {
99 char buf[OPT_SHOW_LEN + sizeof("...")];
100 strcpy(buf + OPT_SHOW_LEN, "...");
101 opt_table[i].show(buf, opt_table[i].u.arg);
102 len += sprintf(p + len, " (default: %s)", buf);
105 p += sprintf(p, "\n");