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>
This commit is contained in:
Pierre Habouzit 2008-03-02 11:35:56 +01:00 коммит произвёл Junio C Hamano
Родитель ff962a3f19
Коммит 580d5bffde
4 изменённых файлов: 39 добавлений и 7 удалений

Просмотреть файл

@ -6,7 +6,8 @@
struct optparse_t {
const char **argv;
int argc;
const char **out;
int argc, cpidx;
const char *opt;
};
@ -159,6 +160,16 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
continue;
rest = skip_prefix(arg, options->long_name);
if (options->type == OPTION_ARGUMENT) {
if (!rest)
continue;
if (*rest == '=')
return opterror(options, "takes no value", flags);
if (*rest)
continue;
p->out[p->cpidx++] = arg - 2;
return 0;
}
if (!rest) {
/* abbreviated? */
if (!strncmp(options->long_name, arg, arg_end - arg)) {
@ -242,14 +253,13 @@ static NORETURN void usage_with_options_internal(const char * const *,
int parse_options(int argc, const char **argv, const struct option *options,
const char * const usagestr[], int flags)
{
struct optparse_t args = { argv + 1, argc - 1, NULL };
int j = 0;
struct optparse_t args = { argv + 1, argv, argc - 1, 0, NULL };
for (; args.argc; args.argc--, args.argv++) {
const char *arg = args.argv[0];
if (*arg != '-' || !arg[1]) {
argv[j++] = args.argv[0];
args.out[args.cpidx++] = args.argv[0];
continue;
}
@ -286,9 +296,9 @@ int parse_options(int argc, const char **argv, const struct option *options,
usage_with_options(usagestr, options);
}
memmove(argv + j, args.argv, args.argc * sizeof(*argv));
argv[j + args.argc] = NULL;
return j + args.argc;
memmove(args.out + args.cpidx, args.argv, args.argc * sizeof(*args.out));
args.out[args.cpidx + args.argc] = NULL;
return args.cpidx + args.argc;
}
#define USAGE_OPTS_WIDTH 24
@ -328,6 +338,8 @@ void usage_with_options_internal(const char * const *usagestr,
pos += fprintf(stderr, "--%s", opts->long_name);
switch (opts->type) {
case OPTION_ARGUMENT:
break;
case OPTION_INTEGER:
if (opts->flags & PARSE_OPT_OPTARG)
pos += fprintf(stderr, " [<n>]");

Просмотреть файл

@ -4,6 +4,7 @@
enum parse_opt_type {
/* special types */
OPTION_END,
OPTION_ARGUMENT,
OPTION_GROUP,
/* options with no arguments */
OPTION_BIT,
@ -84,6 +85,7 @@ struct option {
};
#define OPT_END() { OPTION_END }
#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) }
#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) }

Просмотреть файл

@ -21,6 +21,9 @@ string options
--st <st> get another string (pervert ordering)
-o <str> get another string
magic arguments
--quux means --quux
EOF
test_expect_success 'test help' '
@ -114,4 +117,17 @@ test_expect_success 'detect possible typos' '
git diff expect.err output.err
'
cat > expect <<EOF
boolean: 0
integer: 0
string: (not set)
arg 00: --quux
EOF
test_expect_success 'keep some options as arguments' '
test-parse-options --quux > output 2> output.err &&
test ! -s output.err &&
git diff expect output
'
test_done

Просмотреть файл

@ -20,6 +20,8 @@ int main(int argc, const char **argv)
OPT_STRING(0, "string2", &string, "str", "get another string"),
OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
OPT_STRING('o', NULL, &string, "str", "get another string"),
OPT_GROUP("magic arguments"),
OPT_ARGUMENT("quux", "means --quux"),
OPT_END(),
};
int i;