#include <alloca.h>
#include <math.h>
+#include <stdbool.h>
/***
* Value flags defaults
short hooks_after_value_count;
int positional_max;
int positional_count;
+ bool stop_parsing;
};
void opt_failure(const char * mesg, ...) {
if (opt->count++ && (opt->flags & OPT_SINGLE))
opt_failure("Option %s must be specified at most once.", THIS_OPT);
+ if (opt->flags & OPT_LAST_ARG)
+ oc->stop_parsing = 1;
+
for (int i = 0; i < oc->hooks_before_value_count; i++)
oc->hooks_before_value[i]->u.call(item, value, oc->hooks_before_value[i]->ptr);
}
}
-void opt_parse(const struct opt_section * options, char ** argv) {
+int opt_parse(const struct opt_section * options, char ** argv) {
struct opt_context * oc = alloca(sizeof(*oc));
memset(oc, 0, sizeof (*oc));
opt_prepare_items(oc, options);
int force_positional = 0;
- for (int i = 0; argv[i]; i++) {
+ int i;
+ for (i=0; argv[i] && !oc->stop_parsing; i++) {
char *arg = argv[i];
for (int j = 0; j < oc->hooks_before_arg_count; j++)
oc->hooks_before_arg[j]->u.call(NULL, NULL, oc->hooks_before_arg[j]->ptr);
}
opt_check_required(oc);
+ return i;
}
}
/**
- * Parse all the arguments.
+ * Parse all arguments, given in a NULL-terminated array of strings.
+ *
+ * Typically, this is called from `main(argc, argv)` as `opt_parse(options, argv+1)`,
+ * skipping the 0th argument, which contains program name.
+ *
+ * Returns the number of arguments used (which need not be all of them
+ * if `OPT_LAST_ARG` was encountered).
+ *
+ * The argument array is left untouched.
+ * However, option values are not necessarily copied, the variables
+ * set by the parser may point to the argument array.
**/
-void opt_parse(const struct opt_section * options, char ** argv);
-// FIXME: When parsing finishes (possibly due to OPT_LAST_ARG), what is guaranteed
-// about the state of argv[]?
+int opt_parse(const struct opt_section * options, char ** argv);
#endif