diff --git a/parse-options.c b/parse-options.c
index 8071711..2635e18 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -131,7 +131,8 @@ static int get_value(struct optparse_t *p,
}
}
-static int parse_short_opt(struct optparse_t *p, const struct option *options)
+static int parse_short_opt(struct optparse_t *p, const struct option *options,
+ int flags)
{
for (; options->type != OPTION_END; options++) {
if (options->short_name == *p->opt) {@@ -139,11 +140,16 @@ static int parse_short_opt(struct optparse_t *p, const struct option *options)
return get_value(p, options, OPT_SHORT);
}
}
+
+ if (flags & PARSE_OPT_NO_ERROR_ON_UNKNOWN) {
+ p->out[p->cpidx++] = p->argv[0];
+ return 0;
+ }
return error("unknown switch `%c'", *p->opt);
}
static int parse_long_opt(struct optparse_t *p, const char *arg,
- const struct option *options)
+ const struct option *options, int flags)
{
const char *arg_end = strchr(arg, '=');
const struct option *abbrev_option = NULL, *ambiguous_option = NULL;@@ -224,6 +230,11 @@ is_abbreviated:
abbrev_option->long_name);
if (abbrev_option)
return get_value(p, abbrev_option, abbrev_flags);
+
+ if (flags & PARSE_OPT_NO_ERROR_ON_UNKNOWN) {
+ p->out[p->cpidx++] = p->argv[0];
+ return 0;
+ }
return error("unknown option `%s'", arg);
}
@@ -254,6 +265,8 @@ int parse_options(int argc, const char **argv, const struct option *options,
const char * const usagestr[], int flags)
{
struct optparse_t args = { argv + 1, argv, argc - 1, 0, NULL };
+ if (flags & PARSE_OPT_NO_ERROR_ON_UNKNOWN)
+ args.out = argv + 1;
for (; args.argc; args.argc--, args.argv++) {
const char *arg = args.argv[0];@@ -269,14 +282,14 @@ int parse_options(int argc, const char **argv, const struct option *options,
args.opt = arg + 1;
if (*args.opt == 'h')
usage_with_options(usagestr, options);
- if (parse_short_opt(&args, options) < 0)
+ if (parse_short_opt(&args, options, flags) < 0)
usage_with_options(usagestr, options);
if (args.opt)
check_typos(arg + 1, options);
while (args.opt) {
if (*args.opt == 'h')
usage_with_options(usagestr, options);
- if (parse_short_opt(&args, options) < 0)
+ if (parse_short_opt(&args, options, flags) < 0)
usage_with_options(usagestr, options);
}
continue;@@ -294,11 +307,13 @@ int parse_options(int argc, const char **argv, const struct option *options,
usage_with_options_internal(usagestr, options, 1);
if (!strcmp(arg + 2, "help"))
usage_with_options(usagestr, options);
- if (parse_long_opt(&args, arg + 2, options))
+ if (parse_long_opt(&args, arg + 2, options, flags))
usage_with_options(usagestr, options);
}
memmove(args.out + args.cpidx, args.argv, args.argc * sizeof(*args.out));
+ if (flags & PARSE_OPT_NO_ERROR_ON_UNKNOWN)
+ ++args.cpidx;
args.out[args.cpidx + args.argc] = NULL;
return args.cpidx + args.argc;
}
diff --git a/parse-options.h b/parse-options.h
index 4ee443d..416ccdd 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -18,8 +18,9 @@ enum parse_opt_type {
};
enum parse_opt_flags {
- PARSE_OPT_KEEP_DASHDASH = 1,
- PARSE_OPT_STOP_AT_NON_OPTION = 2,
+ PARSE_OPT_KEEP_DASHDASH = 1,
+ PARSE_OPT_STOP_AT_NON_OPTION = 2,
+ PARSE_OPT_NO_ERROR_ON_UNKNOWN = 4
};
enum parse_opt_option_flags {--
1.5.4.3