summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4a59fd1)
raw | patch | inline | side by side (parent: 4a59fd1)
author | Pierre Habouzit <madcoder@debian.org> | |
Sun, 14 Oct 2007 23:38:30 +0000 (01:38 +0200) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 30 Oct 2007 04:03:30 +0000 (21:03 -0700) |
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
parse-options.c | patch | blob | history | |
parse-options.h | patch | blob | history |
diff --git a/parse-options.c b/parse-options.c
index 7bdffdbe513f56ec995519e2992c551b4f6e22de..57a2a1126613ad31ecb2d55c9ff37f58b42d1618 100644 (file)
--- a/parse-options.c
+++ b/parse-options.c
}
int parse_options(int argc, const char **argv, const struct option *options,
- const char *usagestr, int flags)
+ const char * const usagestr[], int flags)
{
struct optparse_t args = { argv + 1, argc - 1, NULL };
int j = 0;
args.opt = arg + 1;
do {
if (*args.opt == 'h')
- usage(usagestr);
+ usage_with_options(usagestr, options);
if (parse_short_opt(&args, options) < 0)
- usage(usagestr);
+ usage_with_options(usagestr, options);
} while (args.opt);
continue;
}
}
if (!strcmp(arg + 2, "help"))
- usage(usagestr);
+ usage_with_options(usagestr, options);
if (parse_long_opt(&args, arg + 2, options))
- usage(usagestr);
+ usage_with_options(usagestr, options);
}
memmove(argv + j, args.argv, args.argc * sizeof(*argv));
argv[j + args.argc] = NULL;
return j + args.argc;
}
+
+#define USAGE_OPTS_WIDTH 24
+#define USAGE_GAP 2
+
+void usage_with_options(const char * const *usagestr,
+ const struct option *opts)
+{
+ struct strbuf sb;
+
+ strbuf_init(&sb, 4096);
+ strbuf_addstr(&sb, *usagestr);
+ strbuf_addch(&sb, '\n');
+ while (*++usagestr)
+ strbuf_addf(&sb, " %s\n", *usagestr);
+
+ if (opts->type != OPTION_GROUP)
+ strbuf_addch(&sb, '\n');
+
+ for (; opts->type != OPTION_END; opts++) {
+ size_t pos;
+ int pad;
+
+ if (opts->type == OPTION_GROUP) {
+ strbuf_addch(&sb, '\n');
+ if (*opts->help)
+ strbuf_addf(&sb, "%s\n", opts->help);
+ continue;
+ }
+
+ pos = sb.len;
+ strbuf_addstr(&sb, " ");
+ if (opts->short_name)
+ strbuf_addf(&sb, "-%c", opts->short_name);
+ if (opts->long_name && opts->short_name)
+ strbuf_addstr(&sb, ", ");
+ if (opts->long_name)
+ strbuf_addf(&sb, "--%s", opts->long_name);
+
+ switch (opts->type) {
+ case OPTION_INTEGER:
+ strbuf_addstr(&sb, " <n>");
+ break;
+ case OPTION_STRING:
+ if (opts->argh)
+ strbuf_addf(&sb, " <%s>", opts->argh);
+ else
+ strbuf_addstr(&sb, " ...");
+ break;
+ default:
+ break;
+ }
+
+ pad = sb.len - pos;
+ if (pad <= USAGE_OPTS_WIDTH)
+ pad = USAGE_OPTS_WIDTH - pad;
+ else {
+ strbuf_addch(&sb, '\n');
+ pad = USAGE_OPTS_WIDTH;
+ }
+ strbuf_addf(&sb, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
+ }
+ usage(sb.buf);
+}
diff --git a/parse-options.h b/parse-options.h
index 76d73b299f8fdfb2dcdcf881f4e813cc14ad4db5..3006a769cdd561d8a66c3eaeab3307d2e8273ca3 100644 (file)
--- a/parse-options.h
+++ b/parse-options.h
enum parse_opt_type {
OPTION_END,
+ OPTION_GROUP,
OPTION_BOOLEAN,
OPTION_STRING,
OPTION_INTEGER,
int short_name;
const char *long_name;
void *value;
+ const char *argh;
+ const char *help;
};
#define OPT_END() { OPTION_END }
-#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v) }
-#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v) }
-#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v) }
+#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
+#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) }
+#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) }
+#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
/* parse_options() will filter out the processed options and leave the
* non-option argments in argv[].
*/
extern int parse_options(int argc, const char **argv,
const struct option *options,
- const char *usagestr, int flags);
+ const char * const usagestr[], int flags);
+
+extern NORETURN void usage_with_options(const char * const *usagestr,
+ const struct option *options);
#endif