parse-options: add OPT_STRING_LIST helper

This just adds repeated invocations of an option to a list of strings. Using the "--no-<var>" form will reset the list to empty. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jun 9, 2011 at 11:55 UTC c8ba163916554e9ffd3ce8cb2beeff003d90c0c3
4 files changed +44
parse-options.c
+17
@@ -3,6 +3,7 @@
3 #include "cache.h"
4 #include "commit.h"
5 #include "color.h"
6 +#include "string-list.h"
7
8 static int parse_options_usage(struct parse_opt_ctx_t *ctx,
9 const char * const *usagestr,
@@ -687,3 +688,19 @@ int parse_options_concat(struct option *dst, size_t dst_size, struct option *src
688 }
689 return -1;
690 }
691 +
692 +int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
693 +{
694 + struct string_list *v = opt->value;
695 +
696 + if (unset) {
697 + string_list_clear(v, 0);
698 + return 0;
699 + }
700 +
701 + if (!arg)
702 + return -1;
703 +
704 + string_list_append(v, xstrdup(arg));
705 + return 0;
706 +}
parse-options.h
+4
@@ -130,6 +130,9 @@ struct option {
130 (h), PARSE_OPT_NOARG, NULL, (p) }
131 #define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) }
132 #define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
133 +#define OPT_STRING_LIST(s, l, v, a, h) \
134 + { OPTION_CALLBACK, (s), (l), (v), (a), \
135 + (h), 0, &parse_opt_string_list }
136 #define OPT_UYN(s, l, v, h) { OPTION_CALLBACK, (s), (l), (v), NULL, \
137 (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
138 #define OPT_DATE(s, l, v, h) \
@@ -204,6 +207,7 @@ extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
207 extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
208 extern int parse_opt_with_commit(const struct option *, const char *, int);
209 extern int parse_opt_tertiary(const struct option *, const char *, int);
210 +extern int parse_opt_string_list(const struct option *, const char *, int);
211
212 #define OPT__VERBOSE(var, h) OPT_BOOLEAN('v', "verbose", (var), (h))
213 #define OPT__QUIET(var, h) OPT_BOOLEAN('q', "quiet", (var), (h))
t/t0040-parse-options.sh
+17
@@ -28,6 +28,7 @@ String options
28 --st <st> get another string (pervert ordering)
29 -o <str> get another string
30 --default-string set string to default
31 + --list <str> add str to list
32
33 Magic arguments
34 --quux means --quux
@@ -337,4 +338,20 @@ test_expect_success 'negation of OPT_NONEG flags is not ambiguous' '
338 test_cmp expect output
339 '
340
341 +cat >>expect <<'EOF'
342 +list: foo
343 +list: bar
344 +list: baz
345 +EOF
346 +test_expect_success '--list keeps list of strings' '
347 + test-parse-options --list foo --list=bar --list=baz >output &&
348 + test_cmp expect output
349 +'
350 +
351 +test_expect_success '--no-list resets list' '
352 + test-parse-options --list=other --list=irrelevant --list=options \
353 + --no-list --list=foo --list=bar --list=baz >output &&
354 + test_cmp expect output
355 +'
356 +
357 test_done
test-parse-options.c
+6
@@ -1,5 +1,6 @@
1 #include "cache.h"
2 #include "parse-options.h"
3 +#include "string-list.h"
4
5 static int boolean = 0;
6 static int integer = 0;
@@ -9,6 +10,7 @@ static int verbose = 0, dry_run = 0, quiet = 0;
10 static char *string = NULL;
11 static char *file = NULL;
12 static int ambiguous;
13 +static struct string_list list;
14
15 static int length_callback(const struct option *opt, const char *arg, int unset)
16 {
@@ -54,6 +56,7 @@ int main(int argc, const char **argv)
56 OPT_STRING('o', NULL, &string, "str", "get another string"),
57 OPT_SET_PTR(0, "default-string", &string,
58 "set string to default", (unsigned long)"default"),
59 + OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
60 OPT_GROUP("Magic arguments"),
61 OPT_ARGUMENT("quux", "means --quux"),
62 OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
@@ -85,6 +88,9 @@ int main(int argc, const char **argv)
88 printf("dry run: %s\n", dry_run ? "yes" : "no");
89 printf("file: %s\n", file ? file : "(not set)");
90
91 + for (i = 0; i < list.nr; i++)
92 + printf("list: %s\n", list.items[i].string);
93 +
94 for (i = 0; i < argc; i++)
95 printf("arg %02d: %s\n", i, argv[i]);
96