]> mj.ucw.cz Git - libucw.git/commitdiff
Opt: Make OPT_LAST_ARG actually work and document interface of opt_parse()
authorMartin Mares <mj@ucw.cz>
Mon, 27 Jan 2014 18:38:25 +0000 (19:38 +0100)
committerMartin Mares <mj@ucw.cz>
Mon, 27 Jan 2014 18:38:25 +0000 (19:38 +0100)
ucw/opt.c
ucw/opt.h

index edbd5223048d7c43d3a993d25d0058d6aab8a977..2552efceb1a80fb1597ab52fe041ad7e3355eb3f 100644 (file)
--- a/ucw/opt.c
+++ b/ucw/opt.c
@@ -16,6 +16,7 @@
 
 #include <alloca.h>
 #include <math.h>
+#include <stdbool.h>
 
 /***
  * Value flags defaults
@@ -49,6 +50,7 @@ struct opt_context {
   short hooks_after_value_count;
   int positional_max;
   int positional_count;
+  bool stop_parsing;
 };
 
 void opt_failure(const char * mesg, ...) {
@@ -144,6 +146,9 @@ static void opt_parse_value(struct opt_context * oc, struct opt_precomputed * op
   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);
 
@@ -385,7 +390,7 @@ static void opt_check_required(struct opt_context *oc)
   }
 }
 
-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));
 
@@ -404,7 +409,8 @@ void opt_parse(const struct opt_section * options, char ** argv) {
   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);
@@ -424,4 +430,5 @@ void opt_parse(const struct opt_section * options, char ** argv) {
   }
 
   opt_check_required(oc);
+  return i;
 }
index c50bac009e509379bb1804c5f9087932c7649c39..0ae88e97a0378063d360af4417377d596942e283 100644 (file)
--- a/ucw/opt.h
+++ b/ucw/opt.h
@@ -183,10 +183,18 @@ static inline void opt_show_help_internal(struct opt_item * opt UNUSED, const ch
 }
 
 /**
- * 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