@matheusbsbs / matheus-bagliano / commits / 580d5bffde
Fork 0

parse-options: new option type to treat an option-like parameter as an argument.

This is meant to be used to keep --not and --all during revision parsing. Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Pierre Habouzit committed Mar 2, 2008 at 11:35 UTC 580d5bffdea56dfae1e745dbda94f326bb161274
4 files changed +39 -7
parse-options.c
+19 -7
@@ -6,7 +6,8 @@
6
7 struct optparse_t {
8 const char **argv;
9 - int argc;
9 + const char **out;
10 + int argc, cpidx;
11 const char *opt;
12 };
13
@@ -159,6 +160,16 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
160 continue;
161
162 rest = skip_prefix(arg, options->long_name);
163 + if (options->type == OPTION_ARGUMENT) {
164 + if (!rest)
165 + continue;
166 + if (*rest == '=')
167 + return opterror(options, "takes no value", flags);
168 + if (*rest)
169 + continue;
170 + p->out[p->cpidx++] = arg - 2;
171 + return 0;
172 + }
173 if (!rest) {
174 /* abbreviated? */
175 if (!strncmp(options->long_name, arg, arg_end - arg)) {
@@ -242,14 +253,13 @@ static NORETURN void usage_with_options_internal(const char * const *,
253 int parse_options(int argc, const char **argv, const struct option *options,
254 const char * const usagestr[], int flags)
255 {
245 - struct optparse_t args = { argv + 1, argc - 1, NULL };
246 - int j = 0;
256 + struct optparse_t args = { argv + 1, argv, argc - 1, 0, NULL };
257
258 for (; args.argc; args.argc--, args.argv++) {
259 const char *arg = args.argv[0];
260
261 if (*arg != '-' || !arg[1]) {
252 - argv[j++] = args.argv[0];
262 + args.out[args.cpidx++] = args.argv[0];
263 continue;
264 }
265
@@ -286,9 +296,9 @@ int parse_options(int argc, const char **argv, const struct option *options,
296 usage_with_options(usagestr, options);
297 }
298
289 - memmove(argv + j, args.argv, args.argc * sizeof(*argv));
290 - argv[j + args.argc] = NULL;
291 - return j + args.argc;
299 + memmove(args.out + args.cpidx, args.argv, args.argc * sizeof(*args.out));
300 + args.out[args.cpidx + args.argc] = NULL;
301 + return args.cpidx + args.argc;
302 }
303
304 #define USAGE_OPTS_WIDTH 24
@@ -328,6 +338,8 @@ void usage_with_options_internal(const char * const *usagestr,
338 pos += fprintf(stderr, "--%s", opts->long_name);
339
340 switch (opts->type) {
341 + case OPTION_ARGUMENT:
342 + break;
343 case OPTION_INTEGER:
344 if (opts->flags & PARSE_OPT_OPTARG)
345 pos += fprintf(stderr, " [<n>]");
parse-options.h
+2
@@ -4,6 +4,7 @@
4 enum parse_opt_type {
5 /* special types */
6 OPTION_END,
7 + OPTION_ARGUMENT,
8 OPTION_GROUP,
9 /* options with no arguments */
10 OPTION_BIT,
@@ -84,6 +85,7 @@ struct option {
85 };
86
87 #define OPT_END() { OPTION_END }
88 +#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) }
89 #define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
90 #define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
91 #define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) }
t/t0040-parse-options.sh
+16
@@ -21,6 +21,9 @@ string options
21 --st <st> get another string (pervert ordering)
22 -o <str> get another string
23
24 +magic arguments
25 + --quux means --quux
26 +
27 EOF
28
29 test_expect_success 'test help' '
@@ -114,4 +117,17 @@ test_expect_success 'detect possible typos' '
117 git diff expect.err output.err
118 '
119
120 +cat > expect <<EOF
121 +boolean: 0
122 +integer: 0
123 +string: (not set)
124 +arg 00: --quux
125 +EOF
126 +
127 +test_expect_success 'keep some options as arguments' '
128 + test-parse-options --quux > output 2> output.err &&
129 + test ! -s output.err &&
130 + git diff expect output
131 +'
132 +
133 test_done
test-parse-options.c
+2
@@ -20,6 +20,8 @@ int main(int argc, const char **argv)
20 OPT_STRING(0, "string2", &string, "str", "get another string"),
21 OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
22 OPT_STRING('o', NULL, &string, "str", "get another string"),
23 + OPT_GROUP("magic arguments"),
24 + OPT_ARGUMENT("quux", "means --quux"),
25 OPT_END(),
26 };
27 int i;