Revision: 65279
          http://sourceforge.net/p/brlcad/code/65279
Author:   starseeker
Date:     2015-06-12 14:15:11 +0000 (Fri, 12 Jun 2015)
Log Message:
-----------
Simplify bu_opt further.  The callbacks can handle the min/max arg validation, 
so there is no real need to specify it in the definition.  We're supplying a 
doc string for the args in any case - having the user handle the documentation 
piece of the optional nature of an arg is worthwhile since it saves us both 
implementation complexity in the description generator and (more importantly) 
shortens the option description.  The arg_process functions are simply supplied 
with the entire remaining argv array that hasn't been processed (with a little 
extra work to handle equals sign-bearing options), which also avoids the need 
to malloc, construct and free a duplicate argv.

Modified Paths:
--------------
    brlcad/trunk/include/bu/opt.h
    brlcad/trunk/src/conv/g-obj.c
    brlcad/trunk/src/conv/gcv/gcv.cpp
    brlcad/trunk/src/libbu/opt.c
    brlcad/trunk/src/libbu/tests/opt.c
    brlcad/trunk/src/libged/gdiff.c
    brlcad/trunk/src/libged/tire.c
    brlcad/trunk/src/util/dsp_add_opt.c

Modified: brlcad/trunk/include/bu/opt.h
===================================================================
--- brlcad/trunk/include/bu/opt.h       2015-06-12 00:59:24 UTC (rev 65278)
+++ brlcad/trunk/include/bu/opt.h       2015-06-12 14:15:11 UTC (rev 65279)
@@ -65,10 +65,10 @@
  * static int ph = 0;
  * static int i = 0;
  * static fastf_t f = 0.0;
- * struct bu_opt_desc opt_defs[4] = {
- *     {"h", "help",    0, 0, NULL,            (void *)&ph , "", help_str},
- *     {"n", "num",     1, 1, &bu_opt_int,     (void *)&i,   "#", "Read int"},
- *     {"f", "fastf_t", 1, 1, &bu_opt_fastf_t, (void *)&f,   "#", "Read 
float"},
+ * struct bu_opt_desc opt_defs[] = {
+ *     {"h", "help",    NULL,            (void *)&ph , "", help_str},
+ *     {"n", "num",     &bu_opt_int,     (void *)&i,   "#", "Read int"},
+ *     {"f", "fastf_t", &bu_opt_fastf_t, (void *)&f,   "#", "Read float"},
  *     BU_OPT_DESC_NULL
  * };
  * @endcode
@@ -84,16 +84,14 @@
 struct bu_opt_desc {
     const char *shortopt;
     const char *longopt;
-    size_t arg_cnt_min;
-    size_t arg_cnt_max;
+    const char *arg_helpstr;
     bu_opt_arg_process_t arg_process;
     void *set_var;
-    const char *arg_helpstr;
     const char *help_string;
 };
 
 /* Convenience definition for NULL bu_opt_desc struct */
-#define BU_OPT_DESC_NULL {NULL, NULL, 0, 0, NULL, NULL, NULL, NULL}
+#define BU_OPT_DESC_NULL {NULL, NULL, NULL, NULL, NULL, NULL}
 
 /**
  * Macro for assigning values to bu_opt_desc array entries.  Use this style
@@ -106,20 +104,18 @@
  * int i = 0;
  * fastf_t f = 0.0;
  * struct bu_opt_desc opt_defs[4];
- * BU_OPT(opt_defs[0], "h", "help",     0, 0, NULL,            (void *)&ph, 
"", help_str);
- * BU_OPT(opt_defs[1], "n", "num",      1, 1, &bu_opt_ind,     (void *)&i,  
"#", "Read int");
- * BU_OPT(opt_defs[2], "f", "fastf_t",  1, 1, &bu_opt_fastf_t, (void *)&f,  
"#", "Read float");
+ * BU_OPT(opt_defs[0], "h", "help",     NULL,            (void *)&ph, "", 
help_str);
+ * BU_OPT(opt_defs[1], "n", "num",      &bu_opt_ind,     (void *)&i,  "#", 
"Read int");
+ * BU_OPT(opt_defs[2], "f", "fastf_t",  &bu_opt_fastf_t, (void *)&f,  "#", 
"Read float");
  * BU_OPT_NULL(opt_defs[3]);
  *
  */
-#define BU_OPT(_desc, _so, _lo, _min, _max, _aprocess, _var, _ahelp, _help) { \
+#define BU_OPT(_desc, _so, _lo, _ahelp, _aprocess, _var, _help) { \
     _desc.shortopt = _so; \
     _desc.longopt = _lo; \
-    _desc.arg_cnt_min = _min; \
-    _desc.arg_cnt_max = _max; \
+    _desc.arg_helpstr = _ahelp; \
     _desc.arg_process = _aprocess; \
     _desc.set_var = _var; \
-    _desc.arg_helpstr = _ahelp; \
     _desc.help_string = _help; \
 }
 
@@ -127,15 +123,12 @@
 #define BU_OPT_NULL(_desc) { \
     _desc.shortopt = NULL; \
     _desc.longopt = NULL; \
-    _desc.arg_cnt_min = 0; \
-    _desc.arg_cnt_max = 0; \
+    _desc.arg_helpstr = NULL; \
     _desc.arg_process = NULL; \
     _desc.set_var = NULL; \
-    _desc.arg_helpstr = NULL; \
     _desc.help_string = NULL; \
 }
 
-
 /**
  * Parse argv array using option descs.
  *

Modified: brlcad/trunk/src/conv/g-obj.c
===================================================================
--- brlcad/trunk/src/conv/g-obj.c       2015-06-12 00:59:24 UTC (rev 65278)
+++ brlcad/trunk/src/conv/g-obj.c       2015-06-12 14:15:11 UTC (rev 65279)
@@ -129,21 +129,21 @@
 }
 
 static struct bu_opt_desc options[] = {
-    {"?", "", 0, 0, NULL, &print_help, "", "print help and exit"},
-    {"h", "", 0, 0, NULL, &print_help, "", "print help and exit"},
-    {"i", "", 0, 0, NULL, &inches, "", "change output units from mm to 
inches"},
-    {"m", "", 0, 0, NULL, &usemtl, "", "output usemtl statements"},
-    {"u", "", 0, 0, NULL, &do_normals, "", "output vertex normals"},
-    {"v", "", 0, 0, NULL, &verbose, "", "verbose output"},
-    {"a", "", 1, 1, parse_tol_abs, &ttol, "#", "absolute tolerance"},
-    {"n", "", 1, 1, parse_tol_norm, &ttol, "#", "surface normal tolerance"},
-    {"D", "", 1, 1, parse_tol_dist, &tol, "#", "distance tolerance"},
-    {"x", "", 1, 1, parse_debug_rt, NULL, "level", "set RT debug flag"},
-    {"X", "", 1, 1, parse_debug_nmg, NULL, "level", "set NMG debug flag"},
-    {"e", "", 1, 1, bu_opt_str, &error_file, "error_file", "error file name"},
-    {"o", "", 1, 1, bu_opt_str, &output_file, "output.obj", "output file 
name"},
-    {"P", "", 1, 1, bu_opt_int, &ncpu, "#", "number of CPUs"},
-    {"r", "", 1, 1, bu_opt_fastf_t, &ttol.rel, "#", "relative tolerance"},
+    {"?", "", NULL,         NULL,            &print_help,  "print help and 
exit"},
+    {"h", "", NULL,         NULL,            &print_help,  "print help and 
exit"},
+    {"i", "", NULL,         NULL,            &inches,      "change output 
units from mm to inches"},
+    {"m", "", NULL,         NULL,            &usemtl,      "output usemtl 
statements"},
+    {"u", "", NULL,         NULL,            &do_normals,  "output vertex 
normals"},
+    {"v", "", NULL,         NULL,            &verbose,     "verbose output"},
+    {"a", "", "#",          parse_tol_abs,   &ttol,        "absolute 
tolerance"},
+    {"n", "", "#",          parse_tol_norm,  &ttol,        "surface normal 
tolerance"},
+    {"D", "", "#",          parse_tol_dist,  &tol,         "distance 
tolerance"},
+    {"x", "", "level",      parse_debug_rt,  NULL,         "set RT debug 
flag"},
+    {"X", "", "level",      parse_debug_nmg, NULL,         "set NMG debug 
flag"},
+    {"e", "", "error_file", bu_opt_str,      &error_file,  "error file name"},
+    {"o", "", "output.obj", bu_opt_str,      &output_file, "output file name"},
+    {"P", "", "#",          bu_opt_int,      &ncpu,        "number of CPUs"},
+    {"r", "", "#",          bu_opt_fastf_t,  &ttol.rel,    "relative 
tolerance"},
     BU_OPT_DESC_NULL
 };
 

Modified: brlcad/trunk/src/conv/gcv/gcv.cpp
===================================================================
--- brlcad/trunk/src/conv/gcv/gcv.cpp   2015-06-12 00:59:24 UTC (rev 65278)
+++ brlcad/trunk/src/conv/gcv/gcv.cpp   2015-06-12 14:15:11 UTC (rev 65279)
@@ -40,9 +40,9 @@
     int ret_argc = 0;
     static int tol = 0.0;
     static int w_flag;
-    struct bu_opt_desc fg4_opt_desc[3] = {
-       {"t", "tol",                1, 1, &bu_opt_int, (void *)&tol, "tol", 
"Dimensional tolerance."},
-       {"w", "warn-default-names", 0, 0, NULL, (void *)&w_flag, "", "File 
format of input file."},
+    struct bu_opt_desc fg4_opt_desc[] = {
+       {"t", "tol",                "#", &bu_opt_int, (void *)&tol,    
"Dimensional tolerance."},
+       {"w", "warn-default-names", "" , NULL,        (void *)&w_flag, "File 
format of input file."},
        BU_OPT_DESC_NULL
     };
 
@@ -76,8 +76,8 @@
     static int tol = 0.0;
     static int units = 0;
     struct bu_opt_desc stl_opt_desc[3] = {
-       {"t",  "tol",   1, 1, &bu_opt_int, (void *)&tol, "tol",  "Dimensional 
tolerance." },
-       {"u",  "units", 1, 1, &bu_opt_int, (void *)&units, "unit", "Units of 
input file." },
+       {"t",  "tol",   "#", &bu_opt_int, (void *)&tol,   "Dimensional 
tolerance." },
+       {"u",  "units", "#", &bu_opt_int, (void *)&units, "Units of input 
file." },
        BU_OPT_DESC_NULL
     };
 
@@ -244,7 +244,8 @@
     char **file_set = (char **)set_var;
 
     if (!argv || strlen(argv[0]) || argc == 0) {
-       return 0;
+       if (msg) bu_vls_sprintf(msg, "Error - no file name supplied\n");
+       return -1;
     }
     if (!bu_file_exists(argv[0], NULL)){
        if (msg) bu_vls_sprintf(msg, "Error - file %s does not exist!\n", 
argv[0]);
@@ -262,7 +263,8 @@
     char **file_set = (char **)set_var;
 
     if (!argv || strlen(argv[0]) || argc == 0) {
-       return 0;
+       if (msg) bu_vls_sprintf(msg, "Error - no file name supplied\n");
+       return -1;
     }
     if (bu_file_exists(argv[0], NULL)){
        if (msg) bu_vls_sprintf(msg, "Error - file %s already exists!\n", 
argv[0]);
@@ -281,7 +283,8 @@
     mime_model_t type = MIME_MODEL_UNKNOWN;
     mime_model_t *set_type = (mime_model_t *)set_mime;
     if (!argv || argc == 0) {
-       return 0;
+       if (msg) bu_vls_sprintf(msg, "Error - no file type supplied\n");
+       return -1;
     }
     type_int = bu_file_mime(argv[0], MIME_MODEL);
     type = (type_int < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)type_int;
@@ -350,14 +353,14 @@
     int uac = 0;
 
     struct bu_opt_desc gcv_opt_desc[9] = {
-       {"h", "help",             0, 1, &gcv_help,    (void *)&hs,            
"format",     gcv_help_str,                 },
-       {"?", "",                 0, 1, &gcv_help,    (void *)&hs,            
"format",     "",                           },
-       {"i", "input",            1, 1, &file_stat,   (void *)&in_path_str,   
"file",       "Input file.",                },
-       {"o", "output",           1, 1, &file_null,   (void *)&out_path_str,  
"file",       "Output file.",               },
-       {"",  "input-format",     1, 1, &model_mime,  (void *)&in_type,       
"format",     "File format of input file.", },
-       {"",  "output-format",    1, 1, &model_mime,  (void *)&out_type,      
"format",     "File format of output file." },
-       {"I", "input-only-opts",  1, 1, &bu_opt_vls,  (void *)&in_only_opts,  
"\"[opts]\"", gcv_inopt_str,                },
-       {"O", "output-only-opts", 1, 1, &bu_opt_vls,  (void *)&out_only_opts, 
"\"[opts]\"", gcv_outopt_str,               },
+       {"h", "help",             "[format]",   &gcv_help,    (void *)&hs,      
      gcv_help_str,                 },
+       {"?", "",                 "[format]",   &gcv_help,    (void *)&hs,      
      "",                           },
+       {"i", "input",            "file",       &file_stat,   (void 
*)&in_path_str,   "Input file.",                },
+       {"o", "output",           "file",       &file_null,   (void 
*)&out_path_str,  "Output file.",               },
+       {"",  "input-format",     "format",     &model_mime,  (void *)&in_type, 
      "File format of input file.", },
+       {"",  "output-format",    "format",     &model_mime,  (void 
*)&out_type,      "File format of output file." },
+       {"I", "input-only-opts",  "\"[opts]\"", &bu_opt_vls,  (void 
*)&in_only_opts,  gcv_inopt_str,                },
+       {"O", "output-only-opts", "\"[opts]\"", &bu_opt_vls,  (void 
*)&out_only_opts, gcv_outopt_str,               },
        BU_OPT_DESC_NULL
     };
 

Modified: brlcad/trunk/src/libbu/opt.c
===================================================================
--- brlcad/trunk/src/libbu/opt.c        2015-06-12 00:59:24 UTC (rev 65278)
+++ brlcad/trunk/src/libbu/opt.c        2015-06-12 14:15:11 UTC (rev 65279)
@@ -73,8 +73,6 @@
     int non_null = 0;
     if (!ds) return 1;
 
-    if (ds->arg_cnt_min != 0) non_null++;
-    if (ds->arg_cnt_max != 0) non_null++;
     if (ds->shortopt) non_null++;
     if (ds->longopt) non_null++;
     if (ds->arg_process) non_null++;
@@ -142,28 +140,12 @@
                    if (d->shortopt && strlen(d->shortopt) > 0) {
                        struct bu_vls tmp_arg = BU_VLS_INIT_ZERO;
                        int new_len = strlen(d->arg_helpstr);
-                       if (d->arg_cnt_min == 0 && d->arg_cnt_max != 0) {
-                           if (new_len > 0) {
-                               bu_vls_sprintf(&tmp_arg, "-%s [%s]", 
d->shortopt, d->arg_helpstr);
-                               new_len = new_len + 5;
-                           } else {
-                               bu_vls_sprintf(&tmp_arg, "-%s [opts]", 
d->shortopt);
-                               new_len = 9;
-                           }
+                       if (!new_len) {
+                           bu_vls_sprintf(&tmp_arg, "-%s", d->shortopt);
+                           new_len = 2;
                        } else {
-                           if (d->arg_cnt_min == 0 && d->arg_cnt_max == 0) {
-                               bu_vls_sprintf(&tmp_arg, "-%s", d->shortopt);
-                               new_len = 2;
-                           }
-                           if (d->arg_cnt_min > 0) {
-                               if (new_len > 0) {
-                                   bu_vls_sprintf(&tmp_arg, "-%s %s", 
d->shortopt, d->arg_helpstr);
-                                   new_len = new_len + 3;
-                               } else {
-                                   bu_vls_sprintf(&tmp_arg, "-%s opts", 
d->shortopt);
-                                   new_len = 7;
-                               }
-                           }
+                           bu_vls_sprintf(&tmp_arg, "-%s %s", d->shortopt, 
d->arg_helpstr);
+                           new_len = new_len + 4;
                        }
                        if ((int)bu_vls_strlen(&opts) + new_len + offset + 2 > 
opt_cols + desc_cols) {
                            bu_vls_printf(&description, "%*s%s\n", offset, " ", 
bu_vls_addr(&opts));
@@ -188,28 +170,12 @@
                    if (d->longopt && strlen(d->longopt) > 0) {
                        struct bu_vls tmp_arg = BU_VLS_INIT_ZERO;
                        int new_len = strlen(d->arg_helpstr);
-                       if (d->arg_cnt_min == 0 && d->arg_cnt_max != 0) {
-                           if (new_len > 0) {
-                               bu_vls_sprintf(&tmp_arg, "--%s [%s]", 
d->longopt, d->arg_helpstr);
-                               new_len = new_len + strlen(d->longopt) + 5;
-                           } else {
-                               bu_vls_sprintf(&tmp_arg, "--%s [opts]", 
d->longopt);
-                               new_len = strlen(d->longopt) + 9;
-                           }
+                       if (!new_len) {
+                           bu_vls_sprintf(&tmp_arg, "--%s", d->longopt);
+                           new_len = strlen(d->longopt) + 2;
                        } else {
-                           if (d->arg_cnt_min == 0 && d->arg_cnt_max == 0) {
-                               bu_vls_sprintf(&tmp_arg, "--%s", d->longopt);
-                               new_len = strlen(d->longopt) + 2;
-                           }
-                           if (d->arg_cnt_min > 0) {
-                               if (new_len > 0) {
-                                   bu_vls_sprintf(&tmp_arg, "--%s %s", 
d->longopt, d->arg_helpstr);
-                                   new_len = strlen(d->longopt) + new_len + 3;
-                               } else {
-                                   bu_vls_sprintf(&tmp_arg, "--%s opts", 
d->longopt);
-                                   new_len = strlen(d->longopt) + 7;
-                               }
-                           }
+                           bu_vls_sprintf(&tmp_arg, "--%s %s", d->longopt, 
d->arg_helpstr);
+                           new_len = strlen(d->longopt) + new_len + 3;
                        }
                        if ((int)bu_vls_strlen(&opts) + new_len + offset + 2 > 
opt_cols + desc_cols) {
                            bu_vls_printf(&description, "%*s%s\n", offset, " ", 
bu_vls_addr(&opts));
@@ -346,7 +312,6 @@
     while (i < argc) {
        int desc_found = 0;
        int desc_ind = 0;
-       size_t arg_cnt = 0;
        char *opt = NULL;
        const char *eq_arg = NULL;
        struct bu_opt_desc *desc = NULL;
@@ -395,102 +360,78 @@
            continue;
        }
 
-       /* We've got a description of the option.  Now the real work begins. */
-       if (eq_arg) arg_cnt = 1;
+       /* record the option in known args - any remaining processing is on 
args, if any*/
+       bu_ptbl_ins(&known_args, (long *)argv[i]);
 
-       /* handled the option - any remaining processing is on args, if any*/
-       bu_ptbl_ins(&known_args, (long *)argv[i]);
+       /* any remaining processing is on trailing args, if any */
        i = i + 1;
 
-       /* If we already got an arg from the equals mechanism and we aren't
-        * supposed to have one, we're invalid - halt. */
-       if (eq_arg && desc->arg_cnt_max == 0) {
-           if (msgs) bu_vls_printf(msgs, "Option %s takes no arguments, but 
argument %s is present - halting.\n", argv[i-1], eq_arg);
-           return -1;
-       }
+       /* If we might have args and we have a validator function,
+        * construct the greediest possible interpretation of the option
+        * description and run the validator to determine the number of
+        * argv entries associated with this option (can_be_opt is not
+        * enough if the option is number based, since -9 may be both a
+        * valid option and a valid argument - the validator must make the
+        * decision.  If we do not have a validator, the best we can do
+        * is the can_be_opt test as a terminating trigger. */
+       if (desc->arg_process) {
+           /* Construct the greedy interpretation of the option argv */
+           int k = 0;
+           int arg_offset = 0;
+           int g_argc = argc - i;
+           const char *prev_opt = argv[i-1];
+           const char **g_argv = argv + i;
+           /* If we have an arg hiding in the previous option, temporarily
+            * rework the argv array for this purpose */
+           if (eq_arg) {
+               g_argv--;
+               g_argv[0] = eq_arg;
+               g_argc++;
+           }
+           arg_offset = (*desc->arg_process)(msgs, g_argc, g_argv, 
desc->set_var);
+           if (arg_offset == -1) {
+               /* This isn't just an unknown option to be passed
+                * through for possible later processing.  If the
+                * arg_process callback returns -1, something has gone
+                * seriously awry and a known-to-be-invalid arg was
+                * seen.  Fail early and hard. */
+               if (msgs) bu_vls_printf(msgs, "Invalid argument supplied to %s: 
%s - halting.\n", argv[i-1], argv[i]);
+               return -1;
+           }
+           /* Put the original opt back and adjust the arg_offset, if we 
substituted
+            * the eq_arg pointer into the argv array */
+           if (eq_arg) {
+               /* If the arg_process callback did nothing with the arg, but 
the arg was
+                * sent to this option with an = assignment, something is wrong 
- the
+                * most likely scenario is an = assignment forced an argument 
to be
+                * sent to an option that doesn't take arguments */
+               if (!arg_offset) {
+                   if (msgs) bu_vls_printf(msgs, "Option %s did not 
successfully use the supplied argument %s - haulting.\n", argv[i-1], eq_arg);
+                   return -1;
+               }
 
-       /* If we're looking for args, do so */
-       if (desc->arg_cnt_max > 0) {
-           /* If we might have args and we have a validator function,
-            * construct the greediest possible interpretation of the option
-            * description and run the validator to determine the number of
-            * argv entries associated with this option (can_be_opt is not
-            * enough if the option is number based, since -9 may be both a
-            * valid option and a valid argument - the validator must make the
-            * decision.  If we do not have a validator, the best we can do
-            * is the can_be_opt test as a terminating trigger. */
-           if (desc->arg_process) {
-               /* Construct the greedy interpretation of the option argv */
-               int k = 0;
-               int arg_offset = 0;
-               int g_argc = desc->arg_cnt_max;
-               const char **g_argv = (const char **)bu_calloc(g_argc + arg_cnt 
+ 1, sizeof(char *), "greedy argv");
-               if (!g_argc && arg_cnt) g_argc = arg_cnt;
-               if (i != argc || arg_cnt) {
-                   if (arg_cnt)
-                       g_argv[0] = eq_arg;
-                   for (k = 0; k < g_argc; k++) {
-                       g_argv[k+arg_cnt] = argv[i + k];
-                   }
-                   arg_offset = (*desc->arg_process)(msgs, g_argc, g_argv, 
desc->set_var);
-                   if (arg_offset == -1) {
-                       /* This isn't just an unknown option to be passed
-                        * through for possible later processing.  If the
-                        * arg_process callback returns -1, something has gone
-                        * seriously awry and a known-to-be-invalid arg was
-                        * seen.  Fail early and hard. */
-                       if (msgs) bu_vls_printf(msgs, "Invalid argument 
supplied to %s: %s - halting.\n", argv[i-1], argv[i]);
-                       return -1;
-                   }
-                   if (arg_offset == 0) {
-                       if (desc->arg_cnt_min > 0) {
-                           if (msgs) bu_vls_printf(msgs, "Option %s requires 
an argument but none was found - halting.\n", argv[i-1]);
-                           return -1;
-                       } else {
-                           continue;
-                       }
-                   }
-                   for (k = (int)i; k < (int)(i + arg_offset - arg_cnt); k++) {
-                       bu_ptbl_ins(&known_args, (long *)argv[k]);
-                   }
-                   i = i + arg_offset - arg_cnt;
-               } else {
-                   if (desc->arg_cnt_min == 0) {
-                       /* If this is allowed to function just as a flag, an 
int may
-                        * be supplied to record the status - try to set it */
-                       int *flag_var = (int *)desc->set_var;
-                       if (flag_var) (*flag_var) = 1;
-                   }
+               g_argv[0] = prev_opt;
+               if (arg_offset > 0) {
+                   arg_offset--;
                }
-               bu_free(g_argv, "free greedy argv");
-           } else {
-               if (desc->arg_cnt_min > 0) {
-                   if (msgs) {
-                       if (desc->arg_cnt_min == 1) {
-                           if (desc->longopt && strlen(desc->longopt) > 0) {
-                               bu_vls_printf(msgs, "Option %s found and 
requires at least one argument, but no arg processing function was defined - 
halting.\n", desc->longopt);
-                           } else {
-                               bu_vls_printf(msgs, "Option %s found and 
requires at least one argument, but no arg processing function was defined - 
halting.\n", desc->shortopt);
-                           }
-                       } else {
-                           if (desc->longopt && strlen(desc->longopt) > 0) {
-                               bu_vls_printf(msgs, "Option %s found and 
requires at least %d arguments, but no arg processing function was defined - 
halting.\n", desc->longopt, desc->arg_cnt_min);
-                           } else {
-                               bu_vls_printf(msgs, "Option %s found and 
requires at least %d arguments, but no arg processing function was defined - 
halting.\n", desc->shortopt, desc->arg_cnt_min);
-                           }
-                       }
-                   }
-                   return -1;
-               } else {
-                   /* No desc->arg_process and no minimum arg count - handle 
as a flag */
-                   int *flag_var = (int *)desc->set_var;
-                   if (flag_var) (*flag_var) = 1;
-               }
            }
+           /* If we used any of the argv entries, accumulate them for later 
reordering
+            * and increment i */
+           for (k = (int)i; k < (int)(i + arg_offset); k++) {
+               bu_ptbl_ins(&known_args, (long *)argv[k]);
+           }
+           i = i + arg_offset;
        } else {
-           /* only a flag - see if we're supposed to set an int */
+           /* no arg_process means this is a flag - try to set an int */
            int *flag_var = (int *)desc->set_var;
            if (flag_var) (*flag_var) = 1;
+
+           /* If we already got an arg from the equals mechanism and we aren't
+            * supposed to have one, we're invalid - halt. */
+           if (eq_arg) {
+               if (msgs) bu_vls_printf(msgs, "Option %s does not take an 
argument, but %s was supplied - haulting.\n", argv[i-1], eq_arg);
+               return -1;
+           }
        }
     }
 
@@ -523,7 +464,8 @@
     int *int_set = (int *)set_var;
 
     if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
-       return 0;
+       if (msg) bu_vls_printf(msg, "bu_opt_int requires arg, but arg not found 
- aborting\n");
+       return -1;
     }
 
     l = strtol(argv[0], &endptr, 0);
@@ -560,7 +502,8 @@
     long *long_set = (long *)set_var;
 
     if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
-       return 0;
+       if (msg) bu_vls_printf(msg, "bu_opt_long requires arg, but arg not 
found - aborting\n");
+       return -1;
     }
 
     l = strtol(argv[0], &endptr, 0);
@@ -588,7 +531,8 @@
     char *endptr = NULL;
 
     if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
-       return 0;
+       if (msg) bu_vls_printf(msg, "bu_opt_fastf_t requires arg, but arg not 
found - aborting\n");
+       return -1;
     }
 
     if (sizeof(fastf_t) == sizeof(float)) {
@@ -615,22 +559,28 @@
 }
 
 int
-bu_opt_str(struct bu_vls *UNUSED(msg), int argc, const char **argv, void 
*set_var)
+bu_opt_str(struct bu_vls *msg, int argc, const char **argv, void *set_var)
 {
     const char **s_set = (const char **)set_var;
 
-    if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) return 0;
+    if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
+       if (msg) bu_vls_printf(msg, "bu_opt_str requires arg, but arg not found 
- aborting\n");
+       return -1;
+    }
 
     if (s_set) (*s_set) = argv[0];
     return 1;
 }
 
 int
-bu_opt_vls(struct bu_vls *UNUSED(msg), int argc, const char **argv, void 
*set_var)
+bu_opt_vls(struct bu_vls *msg, int argc, const char **argv, void *set_var)
 {
     struct bu_vls *s_set = (struct bu_vls *)set_var;
 
-    if (!argv || !argc ) return 0;
+    if (!argv || !argc ) {
+       if (msg) bu_vls_printf(msg, "bu_opt_vls requires arg, but arg not found 
- aborting\n");
+       return -1;
+    }
 
     if (s_set) {
        int i = 0;
@@ -649,7 +599,8 @@
     int bool_val;
 
     if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
-       return 0;
+       if (msg) bu_vls_printf(msg, "bu_opt_bool requires arg, but arg not 
found - aborting\n");
+       return -1;
     }
 
     bool_val = bu_str_true(argv[0]);

Modified: brlcad/trunk/src/libbu/tests/opt.c
===================================================================
--- brlcad/trunk/src/libbu/tests/opt.c  2015-06-12 00:59:24 UTC (rev 65278)
+++ brlcad/trunk/src/libbu/tests/opt.c  2015-06-12 14:15:11 UTC (rev 65279)
@@ -176,15 +176,15 @@
     static fastf_t f = 0;
 
     /* Option descriptions */
-    struct bu_opt_desc d[9] = {
-       {"h", "help",    0, 0, NULL,     (void *)&print_help, "",       
help_str},
-       {"?", "",        0, 0, NULL,     (void *)&print_help, "",       
help_str},
-       {"v", "verb",    0, 1, &d1_verb, (void *)&verbosity,  "#",      "Set 
verbosity (range is 0 to 3)"},
-       {"b", "bool",    1, 1, &bu_opt_bool, (void *)&b,      "bool",   "Set 
boolean flag"},
-       {"s", "str",     1, 1, &bu_opt_str,  (void *)&str,    "string", "Set 
string"},
-       {"i", "int",     1, 1, &bu_opt_int,  (void *)&i,      "#",      "Set 
int"},
-       {"l", "long",    1, 1, &bu_opt_long, (void *)&l,      "#",      "Set 
long"},
-       {"f", "fastf_t", 1, 1, &bu_opt_fastf_t, (void *)&f,   "#",      "Read 
float"},
+    struct bu_opt_desc d[] = {
+       {"h", "help",    "",       NULL,     (void *)&print_help, help_str},
+       {"?", "",        "",       NULL,     (void *)&print_help, help_str},
+       {"v", "verb",    "[#]",    &d1_verb, (void *)&verbosity,  "Set 
verbosity (range is 0 to 3)"},
+       {"b", "bool",    "bool",   &bu_opt_bool, (void *)&b,      "Set boolean 
flag"},
+       {"s", "str",     "string", &bu_opt_str,  (void *)&str,    "Set string"},
+       {"i", "int",     "#",      &bu_opt_int,  (void *)&i,      "Set int"},
+       {"l", "long",    "#",      &bu_opt_long, (void *)&l,      "Set long"},
+       {"f", "fastf_t", "#",      &bu_opt_fastf_t, (void *)&f,   "Read float"},
        BU_OPT_DESC_NULL
     };
 
@@ -540,13 +540,13 @@
     struct bu_color *set_color = (struct bu_color *)set_c;
     unsigned int rgb[3];
     if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc == 0) {
-       return 0;
+       return -1;
     }
 
     /* First, see if the first string converts to rgb */
     if (!bu_str_to_rgb((char *)argv[0], (unsigned char *)&rgb)) {
        /* nope - maybe we have 3 args? */
-       if (argc == 3) {
+       if (argc >= 3) {
            struct bu_vls tmp_color = BU_VLS_INIT_ZERO;
            bu_vls_sprintf(&tmp_color, "%s/%s/%s", argv[0], argv[1], argv[2]);
            if (!bu_str_to_rgb(bu_vls_addr(&tmp_color), (unsigned char *)&rgb)) 
{
@@ -572,7 +572,7 @@
        return 1;
     }
 
-    return 0;
+    return -1;
 }
 
 int desc_2(int test_num)
@@ -587,8 +587,8 @@
     struct bu_vls parse_msgs = BU_VLS_INIT_ZERO;
 
     struct bu_opt_desc d[3];
-    BU_OPT(d[0], "h", "help",  0, 0, NULL,      (void *)&print_help, "",      
help_str);
-    BU_OPT(d[1], "C", "color", 1, 3, &dc_color, (void *)&color,      "r/g/b", 
"Set color");
+    BU_OPT(d[0], "h", "help",  "",      NULL,      (void *)&print_help, 
help_str);
+    BU_OPT(d[1], "C", "color", "r/g/b", &dc_color, (void *)&color,      "Set 
color");
     BU_OPT_NULL(d[2]);
 
     av = (const char **)bu_calloc(containers, sizeof(char *), "Input array");

Modified: brlcad/trunk/src/libged/gdiff.c
===================================================================
--- brlcad/trunk/src/libged/gdiff.c     2015-06-12 00:59:24 UTC (rev 65278)
+++ brlcad/trunk/src/libged/gdiff.c     2015-06-12 14:15:11 UTC (rev 65279)
@@ -59,11 +59,11 @@
     int ret_ac = 0;
 
     struct bu_opt_desc d[6];
-    BU_OPT(d[0], "t", "tol", 1, 1, &bu_opt_fastf_t, (void *)&len_tol, "#", 
"Tolerance")
-    BU_OPT(d[1], "R", "ray-diff", 0, 0, NULL, (void *)&do_diff_raytrace, "", 
"Test for differences with raytracing")
-    BU_OPT(d[2], "l", "view-left", 0, 0, NULL, (void *)&view_left, "", 
"Visualize volumes added only by left object")
-    BU_OPT(d[3], "b", "view-both", 0, 0, NULL, (void *)&view_overlap, "", 
"Visualize volumes common to both objects")
-    BU_OPT(d[4], "r", "view-right", 0, 0, NULL, (void *)&view_right, "", 
"Visualize volumes added only by right object")
+    BU_OPT(d[0], "t", "tol",      "#", &bu_opt_fastf_t, (void *)&len_tol, 
"Tolerance")
+    BU_OPT(d[1], "R", "ray-diff", "", NULL, (void *)&do_diff_raytrace, "Test 
for differences with raytracing")
+    BU_OPT(d[2], "l", "view-left", "", NULL, (void *)&view_left, "Visualize 
volumes added only by left object")
+    BU_OPT(d[3], "b", "view-both", "", NULL, (void *)&view_overlap, "Visualize 
volumes common to both objects")
+    BU_OPT(d[4], "r", "view-right", "", NULL, (void *)&view_right, "Visualize 
volumes added only by right object")
     BU_OPT_NULL(d[5]);
 
     GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);

Modified: brlcad/trunk/src/libged/tire.c
===================================================================
--- brlcad/trunk/src/libged/tire.c      2015-06-12 00:59:24 UTC (rev 65278)
+++ brlcad/trunk/src/libged/tire.c      2015-06-12 14:15:11 UTC (rev 65279)
@@ -1788,7 +1788,7 @@
     char s1, s2;
     int sret = 0;
     fastf_t *isoarray = (fastf_t *)set_var;
-    if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc == 0) return 0;
+    if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc == 0) return -1;
 
     sret = bu_sscanf(argv[0], "%d%c%d%c%d", &d1, &s1, &d2, &s2, &d3);
 
@@ -1854,22 +1854,22 @@
     const char *cmd_name = argv[0];
 
     struct bu_opt_desc d[17];
-    BU_OPT(d[0],  "h", "help",                0, 0, NULL,             (void 
*)&print_help,     "",           "Print help and exit");
-    BU_OPT(d[1],  "?", "",                    0, 0, NULL,             (void 
*)&print_help,     "",           "");
-    BU_OPT(d[2],  "n", "obj-name",            1, 1, &bu_opt_vls,      (void 
*)&name,           "name",       "Set top-level object name");
-    BU_OPT(d[3],  "w", "wheel",               1, 1, &bu_opt_bool,     (void 
*)&usewheel,       "bool",       "Enable/disable wheel (default is enabled).");
-    BU_OPT(d[4],  "d", "dimensions",          1, 1, &_opt_tire_iso,   (void 
*)isoarray,        ISO_TIRE_FMT, "Specify tire dimensions using ISO style 
inputs");
-    BU_OPT(d[5],  "",  "ISO",                 1, 1, &_opt_tire_iso,   (void 
*)isoarray,        ISO_TIRE_FMT, "");
-    BU_OPT(d[6],  "W", "width",               1, 1, &bu_opt_fastf_t,  (void 
*)&width,          "#",          "Tire width (mm).  Overrides -d");
-    BU_OPT(d[7],  "R", "aspect-ratio",        1, 1, &bu_opt_fastf_t,  (void 
*)&aspect,         "#",          "Aspect ratio (#/100). Overrides -d.");
-    BU_OPT(d[8],  "D", "rim-diameter",        1, 1, &bu_opt_fastf_t,  (void 
*)&rim_diam,       "#",          "Rim diameter (inches). Overrides -d.");
-    BU_OPT(d[9],  "g", "tread-depth",         1, 1, &bu_opt_fastf_t,  (void 
*)&tread_depth,    "#",          "Tread depth (1/32 inch)");
-    BU_OPT(d[10], "j", "hub-width",           1, 1, &bu_opt_fastf_t,  (void 
*)&hub_width,      "#",          "Rim width (inches)");
-    BU_OPT(d[11], "s", "max-sidewall-radius", 1, 1, &bu_opt_fastf_t,  (void 
*)&zside1,         "#",          "Maximum sidewall radius (mm)");
-    BU_OPT(d[12], "u", "tire-thickness",      1, 1, &bu_opt_fastf_t,  (void 
*)&tire_thickness, "#",          "Tire thickness (mm)");
-    BU_OPT(d[13], "p", "tread-pattern",       1, 1, &bu_opt_int,      (void 
*)&pattern_type,   "#",          "Tread pattern (integer id, range 1 - 2)");
-    BU_OPT(d[14], "c", "tread-pattern-cnt",   1, 1, &bu_opt_int,      (void 
*)&num_tread_ptns, "#",          "Number of tread patterns around tire");
-    BU_OPT(d[15], "t", "tread-shape",         1, 1, &bu_opt_int,      (void 
*)&tread_type,     "#",          "Tread shape profile (integer id, range 1 - 
2)");
+    BU_OPT(d[0],  "h", "help",                "",           NULL,             
(void *)&print_help,     "Print help and exit");
+    BU_OPT(d[1],  "?", "",                    "",           NULL,             
(void *)&print_help,     "");
+    BU_OPT(d[2],  "n", "obj-name",            "name",       &bu_opt_vls,      
(void *)&name,           "Set top-level object name");
+    BU_OPT(d[3],  "w", "wheel",               "bool",       &bu_opt_bool,     
(void *)&usewheel,       "Enable/disable wheel (default is enabled).");
+    BU_OPT(d[4],  "d", "dimensions",          ISO_TIRE_FMT, &_opt_tire_iso,   
(void *)isoarray,        "Specify tire dimensions using ISO style inputs");
+    BU_OPT(d[5],  "",  "ISO",                 ISO_TIRE_FMT, &_opt_tire_iso,   
(void *)isoarray,        "");
+    BU_OPT(d[6],  "W", "width",               "#",          &bu_opt_fastf_t,  
(void *)&width,          "Tire width (mm).  Overrides -d");
+    BU_OPT(d[7],  "R", "aspect-ratio",        "#",          &bu_opt_fastf_t,  
(void *)&aspect,         "Aspect ratio (#/100). Overrides -d.");
+    BU_OPT(d[8],  "D", "rim-diameter",        "#",          &bu_opt_fastf_t,  
(void *)&rim_diam,       "Rim diameter (inches). Overrides -d.");
+    BU_OPT(d[9],  "g", "tread-depth",         "#",          &bu_opt_fastf_t,  
(void *)&tread_depth,    "Tread depth (1/32 inch)");
+    BU_OPT(d[10], "j", "hub-width",           "#",          &bu_opt_fastf_t,  
(void *)&hub_width,      "Rim width (inches)");
+    BU_OPT(d[11], "s", "max-sidewall-radius", "#",          &bu_opt_fastf_t,  
(void *)&zside1,         "Maximum sidewall radius (mm)");
+    BU_OPT(d[12], "u", "tire-thickness",      "#",          &bu_opt_fastf_t,  
(void *)&tire_thickness, "Tire thickness (mm)");
+    BU_OPT(d[13], "p", "tread-pattern",       "#",          &bu_opt_int,      
(void *)&pattern_type,   "Tread pattern (integer id, range 1 - 2)");
+    BU_OPT(d[14], "c", "tread-pattern-cnt",   "#",          &bu_opt_int,      
(void *)&num_tread_ptns, "Number of tread patterns around tire");
+    BU_OPT(d[15], "t", "tread-shape",         "#",          &bu_opt_int,      
(void *)&tread_type,     "Tread shape profile (integer id, range 1 - 2)");
     BU_OPT_NULL(d[16]);
 
     GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);

Modified: brlcad/trunk/src/util/dsp_add_opt.c
===================================================================
--- brlcad/trunk/src/util/dsp_add_opt.c 2015-06-12 00:59:24 UTC (rev 65278)
+++ brlcad/trunk/src/util/dsp_add_opt.c 2015-06-12 14:15:11 UTC (rev 65279)
@@ -156,8 +156,8 @@
 
     static const char usage[] = "Usage: dsp_add [opts] dsp_1 dsp_2 > dsp_3\n";
     struct bu_opt_desc dsp_opt_desc[3] = {
-       {"h", "help", 0, 0, NULL, (void *)&print_help, "", "Print help and 
exit"},
-       {"?", "",     0, 0, NULL, (void *)&print_help, "", ""},
+       {"h", "help", "", NULL, (void *)&print_help, "Print help and exit"},
+       {"?", "",     "", NULL, (void *)&print_help, ""},
        BU_OPT_DESC_NULL
     };
 

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to