- len += sprintf(p + len, " <arg>");
- if (opt_table[i].desc || opt_table[i].show)
- len += sprintf(p + len, "%.*s",
- len < strlen(OPT_SPACE_PAD)
- ? strlen(OPT_SPACE_PAD) - len : 1,
- OPT_SPACE_PAD);
-
- if (opt_table[i].desc)
- 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, "%s(default: %s)",
- opt_table[i].desc ? " " : "", buf);
+ l += strlen(" <arg>");
+ if (l + 2 > indent)
+ indent = l + 2;
+ }
+
+ /* Now we know how much to indent */
+ if (indent + MIN_DESC_WIDTH > width)
+ indent = width - MIN_DESC_WIDTH;
+
+ len = max = 0;
+ ret = NULL;
+
+ ret = add_str(ret, &len, &max, "Usage: ");
+ ret = add_str(ret, &len, &max, argv0);
+
+ /* Find usage message from among registered options if necessary. */
+ if (!extra) {
+ extra = "";
+ for (i = 0; i < opt_count; i++) {
+ if (opt_table[i].cb == (void *)opt_usage_and_exit
+ && opt_table[i].u.carg) {
+ extra = opt_table[i].u.carg;
+ break;
+ }
+ }
+ }
+ ret = add_str(ret, &len, &max, " ");
+ ret = add_str(ret, &len, &max, extra);
+ ret = add_str(ret, &len, &max, "\n");
+
+ for (i = 0; i < opt_count; i++) {
+ if (opt_table[i].desc == opt_hidden)
+ continue;
+ if (opt_table[i].type == OPT_SUBTABLE) {
+ ret = add_str(ret, &len, &max, opt_table[i].desc);
+ ret = add_str(ret, &len, &max, ":\n");
+ continue;