Revision: 65334
          http://sourceforge.net/p/brlcad/code/65334
Author:   n_reed
Date:     2015-06-16 19:53:24 +0000 (Tue, 16 Jun 2015)
Log Message:
-----------
sync from trunk

Modified Paths:
--------------
    brlcad/branches/brep-debug/CMakeLists.txt
    brlcad/branches/brep-debug/doc/docbook/system/man1/en/bwrect.xml
    brlcad/branches/brep-debug/include/bu/opt.h
    brlcad/branches/brep-debug/include/common.h
    brlcad/branches/brep-debug/include/rt/ray_partition.h
    brlcad/branches/brep-debug/misc/doxygen/libbu.dox
    brlcad/branches/brep-debug/src/conv/csg/CMakeLists.txt
    brlcad/branches/brep-debug/src/conv/csg/csg.c
    brlcad/branches/brep-debug/src/conv/g-obj.c
    brlcad/branches/brep-debug/src/conv/gcv/gcv.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/Axis2Placement.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/Axis2Placement.h
    brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedDefinition.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedDefinition.h
    
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedProductDefinition.cpp
    
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedProductDefinition.h
    brlcad/branches/brep-debug/src/conv/step/step-g/Conic.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSet.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSetSelect.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSetSelect.h
    brlcad/branches/brep-debug/src/conv/step/step-g/PCurveOrSurface.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/PCurveOrSurface.h
    brlcad/branches/brep-debug/src/conv/step/step-g/PropertyDefinition.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/RepresentedDefinition.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/RepresentedDefinition.h
    brlcad/branches/brep-debug/src/conv/step/step-g/ShapeDefinition.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/ShapeDefinition.h
    brlcad/branches/brep-debug/src/conv/step/step-g/SurfaceCurve.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/TrimmedCurve.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/TrimmingSelect.cpp
    brlcad/branches/brep-debug/src/conv/step/step-g/TrimmingSelect.h
    brlcad/branches/brep-debug/src/conv/step/step-g/step-g.cpp
    brlcad/branches/brep-debug/src/libanalyze/raydiff.c
    brlcad/branches/brep-debug/src/libanalyze/tests/CMakeLists.txt
    brlcad/branches/brep-debug/src/libbu/opt.c
    brlcad/branches/brep-debug/src/libbu/tests/opt.c
    brlcad/branches/brep-debug/src/libgcv/conv/fastgen4/NOTES
    brlcad/branches/brep-debug/src/libgcv/conv/fastgen4/fastgen4_write.cpp
    brlcad/branches/brep-debug/src/libged/analyze.c
    brlcad/branches/brep-debug/src/libged/gdiff.c
    brlcad/branches/brep-debug/src/libged/tire.c
    brlcad/branches/brep-debug/src/libicv/crop.c
    brlcad/branches/brep-debug/src/librt/primitives/brep/brep.cpp
    brlcad/branches/brep-debug/src/librt/primitives/rhc/rhc.c
    brlcad/branches/brep-debug/src/librt/primitives/table.c
    brlcad/branches/brep-debug/src/other/libutahrle/include/rle_config.h
    brlcad/branches/brep-debug/src/other/libutahrle/rle_open_f.c
    brlcad/branches/brep-debug/src/other/libz/CMakeLists.txt
    brlcad/branches/brep-debug/src/other/openNURBS/opennurbs_archive.cpp
    brlcad/branches/brep-debug/src/other/openNURBS/opennurbs_system.h
    brlcad/branches/brep-debug/src/other/openNURBS/opennurbs_uuid.h
    brlcad/branches/brep-debug/src/other/tcl/CMakeLists.txt
    brlcad/branches/brep-debug/src/other/tk/CMakeLists.txt
    brlcad/branches/brep-debug/src/util/bwcrop.c
    brlcad/branches/brep-debug/src/util/bwscale.c
    brlcad/branches/brep-debug/src/util/dsp_add_opt.c
    brlcad/branches/brep-debug/src/util/pixrect.c

Property Changed:
----------------
    brlcad/branches/brep-debug/
    brlcad/branches/brep-debug/src/libged/polyclip.cpp

Index: brlcad/branches/brep-debug
===================================================================
--- brlcad/branches/brep-debug  2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug  2015-06-16 19:53:24 UTC (rev 65334)

Property changes on: brlcad/branches/brep-debug
___________________________________________________________________
Modified: svn:mergeinfo
## -3,4 +3,4 ##
 /brlcad/branches/cmake:43219
 /brlcad/branches/gct:62423-62425
 /brlcad/branches/osg:62110-62113
-/brlcad/trunk:61364-65248
+/brlcad/trunk:61364-65333
\ No newline at end of property
Modified: brlcad/branches/brep-debug/CMakeLists.txt
===================================================================
--- brlcad/branches/brep-debug/CMakeLists.txt   2015-06-16 19:37:48 UTC (rev 
65333)
+++ brlcad/branches/brep-debug/CMakeLists.txt   2015-06-16 19:53:24 UTC (rev 
65334)
@@ -2455,10 +2455,10 @@
 CONFIG_H_APPEND(BRLCAD "#define BRLCAD_COMPILE_USER ${BRLCAD_COMPILE_USER}\n")
 CONFIG_H_APPEND(BRLCAD "#define BRLCAD_COMPILE_COUNT 
${BRLCAD_COMPILE_COUNT}\n")
 
-# If we're building on Windows, use config_win.h file
-if(WIN32)
+# If we're building on Windows with MSVC, use config_win.h file
+if(MSVC)
   CONFIG_H_APPEND(BRLCAD "#include \"config_win.h\"\n")
-endif(WIN32)
+endif(MSVC)
 
 # Now that all the tests are done, configure the brlcad_config.h file:
 CONFIG_H_APPEND(BRLCAD "#endif /* __CONFIG_H__ */\n")

Modified: brlcad/branches/brep-debug/doc/docbook/system/man1/en/bwrect.xml
===================================================================
--- brlcad/branches/brep-debug/doc/docbook/system/man1/en/bwrect.xml    
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/doc/docbook/system/man1/en/bwrect.xml    
2015-06-16 19:53:24 UTC (rev 65334)
@@ -40,7 +40,7 @@
 format file. The default input image size is 512x512.
 The x,y coordinates of the origin (the default xorig=0, yorig=0 corresponds to 
the
 lower left corner) are passed as
-command line arguments.</para>
+arguments for <option>-x</option> and <option>-y</option>.</para>
 
 <para>The
 <option>-w </option><replaceable>file_width</replaceable>
@@ -52,7 +52,7 @@
 <option>-n </option><replaceable>file_height</replaceable>
 and
 <option>-N </option><replaceable>scr_height</replaceable>
-flags specifies the height in scanlines of the input file or display device
+flags specify the height in scanlines of the input file and display device
 respectively.</para>
 
 <para><option>-s </option><replaceable>squarefilesize</replaceable>
@@ -60,6 +60,12 @@
 <option>-S </option><replaceable>squarescrsize</replaceable>
 set both the height and width to the size given (for input file and display 
device respectively).</para>
 
+<para>
+(<replaceable>scr_width</replaceable> and 
<replaceable>scr_height</replaceable> must be set
+to positive values, either separately via <option>-W</option> and 
<option>-N</option>, or
+jointly via <option>-S</option>.  This is because they start with default 
values of zero.)
+</para>
+
 <para><option>-o </option><replaceable>out_file.bw</replaceable> is a way of 
specifying output
 file name.</para>
 

Modified: brlcad/branches/brep-debug/include/bu/opt.h
===================================================================
--- brlcad/branches/brep-debug/include/bu/opt.h 2015-06-16 19:37:48 UTC (rev 
65333)
+++ brlcad/branches/brep-debug/include/bu/opt.h 2015-06-16 19:53:24 UTC (rev 
65334)
@@ -32,141 +32,188 @@
  * @brief
  * Generalized option handling.
  *
- */
-/** @{ */
-/** @file bu/opt.h */
-
-/**
- * Callback function signature for bu_opt_desc argument processing functions.
+ * This module implements a callback and assignment based mechanism for 
generalized
+ * handling of option handling.  Functionally it is intended to provide 
capabilities
+ * similar to getopt_long, Qt's QCommandLineParser, and the tclap library.  
Results
+ * are returned by way of variable assignment, and function callbacks are used 
to
+ * convert and validate argument strings.
  *
- * Return values:
+ * The bu_opt option parsing system does not make any use of global values, 
unless
+ * a user defines an option definition array that passes in pointers to global 
variables
+ * for setting.
  *
- * -1 - Invalid argument encountered.
- *  0 - No argument processed.
- * >0 - Number of argv elements used in valid argument processing.
+ * To set up a bu_opt parsing system, an array of bu_opt_desc (option 
description)
+ * structures is defined and terminated with a BU_OPT_DESC_NULL entry.  This 
array
+ * is then used by @link bu_opt_parse @endlink to process an argv array.
  *
- */
-typedef int (*bu_opt_arg_process_t)(struct bu_vls *, int argc, const char 
**argv, void *);
-
-/**
- * "Option description" structure.
+ * When defining a bu_opt_desc entry, the type of the set_var assignment 
variable
+ * needed is determined by the arg_process callback.  If no callback is 
present,
+ * set_var is expected to be an integer that will be set to 1 if the option is
+ * present in the argv string.  Because it is necessary for arbitrary variables
+ * to be assigned to the set_var slot (the type needed is determined by the
+ * arg_process callback function and may be anything) all set_var variables are
+ * identified by their pointers (which are in turn cast to void.)
  *
- * This structure is used to define a command line option.  The usage pattern 
is to
- * build up a BU_OPT_DESC_NULL terminated array of option descriptions, which 
are
- * used by bu_opt_parse to process an argv array.
+ * There are two styles in which a bu_opt_desc array may be initialized.  The 
first
+ * is very compact but in C89 based code requires static variables as set_var 
entries,
+ * as seen in the following example:
  *
- * The set_var pointer points to a user selected variable.  The type of the 
variable
- * needed is determined by the arg_process callback.  If no callback is 
present and
- * the max arg count is zero, set_var is expected to be an integer that will 
be set
- * to 1 if the option is present in the argv string.
-*
  * @code
  * #define help_str "Print help and exit"
  * 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
  *
- * If an array initialization of an option description array is provided as in
- * the above example , the variables specified by the user for setting must all
- * be static (as long as C89 is used.) This should work for executable
- * argc/argv parsing, but for libraries it is not advisable due to static
- * variables rendering the function in question thread unsafe.  For an approach
- * usable in a library see the BU_OPT macro documentation.
+ * This style of initialization is suitable for application programs, but in 
libraries
+ * such static variables will preclude thread and reentrant safety.  For 
libraries,
+ * the BU_OPT and BU_OPT_NULL macros are used to construct a bu_opt_desc array 
that
+ * does not require static variables:
  *
- */
-struct bu_opt_desc {
-    const char *shortopt;
-    const char *longopt;
-    size_t arg_cnt_min;
-    size_t arg_cnt_max;
-    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}
-
-/**
- * Macro for assigning values to bu_opt_desc array entries.  Use this style
- * when it isn't possible to use static variables as set_var entries
- * (such as libraries which need to be thread safe.)
- *
  * @code
  * #define help_str "Print help and exit"
  * int ph = 0;
  * 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_int,     (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]);
+ * @endcode
  *
+ * Given the option description array and argc/argv data, @link bu_opt_parse 
@endlink will do the
+ * rest.  The design of @link bu_opt_parse @endlink is to fail early when an 
invalid option
+ * situation is encountered, so code using this system needs to be ready to 
handle
+ * such cases.
+ *
+ * For generating descriptive help strings from a bu_opt_desc array use the 
@link bu_opt_describe @endlink
+ * function, which supports multiple output styles and formats.
  */
-#define BU_OPT(_desc, _so, _lo, _min, _max, _aprocess, _var, _ahelp, _help) { \
+/** @{ */
+/** @file bu/opt.h */
+
+/**
+ * Callback function signature for bu_opt_desc argument processing functions. 
Any
+ * user defined argument processing function should match this signature and 
return
+ * values as documented below.
+ *
+ * @param[out]    msg     If not NULL, callback messages (usually
+ *                        error descriptions) may be appended here. 
+ * @param[in]     argc    Number of arguments in argv.
+ * @param[in]     argv    @em All arguments that follow the option flag.
+ * @param[in,out] set_var The value specified in the associated bu_opt_desc.
+ *
+ * @returns
+ * Val | Interpretation
+ * --- | --------------
+ * -1  | Invalid argument encountered, or argument expected but not found.
+ *  0  | No argument processed (not an error.)
+ * >0  | Number of argv elements used in valid argument processing.
+ *
+ * An example user-defined argument processing function:
+ * @code
+ * static int
+ * parse_opt_mode(struct bu_vls *msg, int argc, const char **argv, void 
*set_var)
+ * {
+ *     int ret, mode;
+ *
+ *     BU_OPT_CHECK_ARGV0(msg, argc, argv, "mode");
+ *
+ *     ret = bu_opt_int(msg, argc, argv, set_var);
+ *     mode = *(int *)set_var;
+ *
+ *     if (mode < 0 || mode > 2) {
+ *         ret = -1;
+ *         if (msg) {
+ *             bu_vls_printf(msg, "Error: mode must be 0, 1, or 2.");
+ *         }
+ *     }
+ *     return ret;
+ * }
+ * @endcode
+ */
+typedef int (*bu_opt_arg_process_t)(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
+
+/**
+ * A common task when writing bu_opt_arg_process_t validators is to check the
+ * first argument of the argv array - this macro encapsulates that into a
+ * standard check.
+ */
+#define BU_OPT_CHECK_ARGV0(_msg, _argc, _argv, _opt_name) \
+if (_argc < 1 || !_argv || !_argv[0] || _argv[0][0] == '\0') { \
+    if (_msg) { \
+       bu_vls_printf(_msg, "Error: missing required argument: " _opt_name 
"\n"); \
+    } \
+    return -1; \
+}
+
+/**
+ * @brief
+ * "Option description" structure.
+ *
+ * Arrays of this structure are used to define command line options.
+ */
+struct bu_opt_desc {
+    const char *shortopt;             /**< @brief "Short" option (i.e. -h for 
help option) */
+    const char *longopt;              /**< @brief "Long" option (i.e. --help 
for help option) */
+    const char *arg_helpstr;          /**< @brief Documentation describing 
option argument, if any (i.e. "file" in --input file)*/
+    bu_opt_arg_process_t arg_process; /**< @brief Argument processing function 
pointer */
+    void *set_var;                    /**< @brief Pointer to the variable or 
structure that collects this option's results */
+    const char *help_string;          /**< @brief Option description */
+};
+
+/** Convenience initializer for NULL bu_opt_desc array terminator */
+#define BU_OPT_DESC_NULL {NULL, NULL, NULL, NULL, NULL, NULL}
+
+/** Macro for assigning values to bu_opt_desc array entries. */
+#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; \
 }
 
-/* Convenience macro for setting a bu_opt_desc struct to BU_OPT_DESC_NULL */
+/** Convenience macro for setting a bu_opt_desc struct to BU_OPT_DESC_NULL */
 #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.
+ * Parse @p argv array using option descriptions.
  *
- * The bu_opt_desc array ds must be null terminated with BU_OPT_DESC_NULL.
+ * The bu_opt_desc array @p ds must be terminated with BU_OPT_DESC_NULL.
  *
- * Return vals:
+ * @returns
+ * Val | Interpretation
+ * --- | --------------
+ * -1  | Fatal error in parsing.  Program must decide to recover or exit.
+ *  0  | All argv options handled.
+ *  >0 | Number of unused argv entries returned at the beginning of the argv 
array.
  *
- * -1  - fatal error in parsing.  Program must decide to recover or exit.
- *  0  - all argv options handled.
- *  >0 - some unused argv entries returned in unused array (if provided), 
return int is unused argc count.
- *
+ * @param msgs[out]    will collect any informational messages
+ *                     generated by the parser (typically used for
+ *                     error reporting)
+ * @param argv[in,out] a return value >0 indicates that argv has been
+ *                     reordered to move the indicated number of
+ *                     unused args to the beginning of the array
  */
-BU_EXPORT extern int bu_opt_parse(const char ***unused, size_t sizeof_unused, 
struct bu_vls *msgs, int ac, const char **argv, struct bu_opt_desc *ds);
+BU_EXPORT extern int bu_opt_parse(struct bu_vls *msgs, int ac, const char 
**argv, struct bu_opt_desc *ds);
 
 
-/* Standard option validators - if a custom option argument
- * validation isn't needed, the functions below can be
- * used for most valid data types. When data conversion is successful,
- * the user_data pointer in bu_opt_data will point to the results
- * of the string->[type] translation in order to allow a calling
- * program to use the int/long/etc. without having to repeat the
- * conversion.
- */
-BU_EXPORT extern int bu_opt_bool(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
-BU_EXPORT extern int bu_opt_int(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
-BU_EXPORT extern int bu_opt_long(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
-BU_EXPORT extern int bu_opt_fastf_t(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
-BU_EXPORT extern int bu_opt_str(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
-BU_EXPORT extern int bu_opt_vls(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
-
-
 /** Output format options for bu_opt documentation generation */
 typedef enum {
     BU_OPT_ASCII,
@@ -195,12 +242,90 @@
     int description_columns;
 };
 
+/**
+ *
+ * Using the example definition:
+ *
+ * @code
+ * struct bu_opt_desc opt_defs[] = {
+ *     {"h", "help",    "",  NULL,            (void *)&ph, "Print help string 
and exit."},
+ *     {"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
+ *
+ * bu_opt_describe would generate the following help string by default:
+ *
+@verbatim
+  -h, --help                    Print help string and exit.
+  -n #, --num #                 Read int
+  -f #, --fastf_t #             Read float
+@endverbatim
+ *
+ * When multiple options use the same set_var to capture
+ * their effect, they are considered aliases for documentation
+ * purposes.  For example, if we add multiple aliases to the
+ * help option and make it more elaborate:
+ *
+ * @code
+ * #define help_str "Print help and exit. If a type is specified to --help, 
print help specific to that type"
+ * struct help_struct hs;
+ * struct bu_opt_desc opt_defs[] = {
+ *     {"h", "help",    "[type]",  &hfun, (void *)&hs, help_str},
+ *     {"H", "HELP",    "[type]",  &hfun, (void *)&hs, help_str},
+ *     {"?", "",        "[type]",  &hfun, (void *)&hs, 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
+ *
+ * the generated help string reflects this:
+ *
+@verbatim
+  -h [type], -H [type], -? [type], --help [type], --HELP [type]
+                                Print help and exit. If a type is specified to
+                                --help, print help specific to that type
+  -n #, --num #                 Read int
+  -f #, --fastf_t #             Read float
+@endverbatim
+ *
+ * @returns
+ * The generated help string.  Note that the string uses allocated memory - it 
is the responsibility of the
+ * caller to free it with @link bu_free @endlink.
+ */
 BU_EXPORT extern const char *bu_opt_describe(struct bu_opt_desc *ds, struct 
bu_opt_desc_opts *settings);
 
 
+/** @} */
 
+/** @addtogroup bu_opt_arg_process
+ *
+ * Standard option validators - if a custom option argument
+ * validation isn't needed, the functions below can be
+ * used for most valid data types. When data conversion is successful,
+ * the user_data pointer in bu_opt_data will point to the results
+ * of the string->[type] translation in order to allow a calling
+ * program to use the int/long/etc. without having to repeat the
+ * conversion.
+ */
+/** @{ */
+/** Process 1 argument to set a boolean type */
+BU_EXPORT extern int bu_opt_bool(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
+/** Process 1 argument to set an integer */
+BU_EXPORT extern int bu_opt_int(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
+/** Process 1 argument to set a long */
+BU_EXPORT extern int bu_opt_long(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
+/** Process 1 argument to set a @link fastf_t @endlink (either a float or a 
double, depending on how BRL-CAD was compiled) */
+BU_EXPORT extern int bu_opt_fastf_t(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
+/** Process 1 argument to set a char pointer (uses the original argv string, 
does not make a copy) */
+BU_EXPORT extern int bu_opt_str(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
+/** Process 1 argument to append to a vls (places a space before the new entry 
if the target vls is not empty) */
+BU_EXPORT extern int bu_opt_vls(struct bu_vls *msg, int argc, const char 
**argv, void *set_var);
 /** @} */
 
+
 __END_DECLS
 
 #endif  /* BU_OPT_H */

Modified: brlcad/branches/brep-debug/include/common.h
===================================================================
--- brlcad/branches/brep-debug/include/common.h 2015-06-16 19:37:48 UTC (rev 
65333)
+++ brlcad/branches/brep-debug/include/common.h 2015-06-16 19:53:24 UTC (rev 
65334)
@@ -41,7 +41,7 @@
  */
 #if defined(BRLCADBUILD) && defined(HAVE_CONFIG_H)
 
-#  if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_HEADERS)
+#  if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__) && 
!defined(CMAKE_HEADERS)
 #    include "config_win.h"
 #  else
 #    include "brlcad_config.h"

Modified: brlcad/branches/brep-debug/include/rt/ray_partition.h
===================================================================
--- brlcad/branches/brep-debug/include/rt/ray_partition.h       2015-06-16 
19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/include/rt/ray_partition.h       2015-06-16 
19:53:24 UTC (rev 65334)
@@ -36,6 +36,7 @@
 #include "vmath.h"
 #include "bu/ptbl.h"
 #include "rt/defines.h"
+#include "rt/seg.h"
 
 __BEGIN_DECLS
 

Modified: brlcad/branches/brep-debug/misc/doxygen/libbu.dox
===================================================================
--- brlcad/branches/brep-debug/misc/doxygen/libbu.dox   2015-06-16 19:37:48 UTC 
(rev 65333)
+++ brlcad/branches/brep-debug/misc/doxygen/libbu.dox   2015-06-16 19:53:24 UTC 
(rev 65334)
@@ -72,27 +72,29 @@
 
 /* I/O */
 /** @ingroup bu_io */
-/**   @defgroup bu_str Strings */
+/**   @defgroup bu_getopt Basic Command-line Option Parsing*/
 /** @ingroup bu_io */
-/**   @defgroup bu_debug Debugging */
+/**   @defgroup bu_opt Generalized Command-line Option Parsing*/
+/**   @ingroup bu_opt */
+/**     @defgroup bu_opt_arg_process Pre-Defined Option Parsers*/
 /** @ingroup bu_io */
+/**   @defgroup bu_cmd Sub-Command Processing */
+/** @ingroup bu_io */
 /**   @defgroup bu_path Path Processing */
 /** @ingroup bu_io */
+/**   @defgroup bu_file File Processing */
+/** @ingroup bu_io */
 /**   @defgroup bu_log Logging */
 /** @ingroup bu_io */
-/**   @defgroup bu_file File Processing */
+/**   @defgroup bu_vfont Vector Fonts */
 /** @ingroup bu_io */
-/**   @defgroup bu_vfont Vector Fonts */
+/**   @defgroup bu_debug Debugging */
 
 
 /* Data Management */
 /** @ingroup bu_data */
-/**   @defgroup bu_cmd Command Processing */
-/** @ingroup bu_data */
 /**   @defgroup bu_conv Data Conversion */
 /** @ingroup bu_data */
-/**   @defgroup bu_getopt Command-line Option Parsing*/
-/** @ingroup bu_data */
 /**   @defgroup bu_hist Histogram Handling */
 /** @ingroup bu_data */
 /**   @defgroup bu_sort Sorting Algorithms */
@@ -101,6 +103,8 @@
 /** @ingroup bu_data */
 /**   @defgroup bu_time Time Support */
 /** @ingroup bu_data */
+/**   @defgroup bu_str Strings */
+/** @ingroup bu_data */
 /**   @defgroup bu_units Units */
 
 

Modified: brlcad/branches/brep-debug/src/conv/csg/CMakeLists.txt
===================================================================
--- brlcad/branches/brep-debug/src/conv/csg/CMakeLists.txt      2015-06-16 
19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/csg/CMakeLists.txt      2015-06-16 
19:53:24 UTC (rev 65334)
@@ -26,7 +26,7 @@
 
 BRLCAD_ADDEXEC(csg "${CSG_SRCS}" "libgcv;libbu" NO_INSTALL)
 
-CMAKEFILES(csg.h)
+CMAKEFILES(csg.h csg_parser.lemon csg_scanner.perplex)
 
 # Local Variables:
 # tab-width: 8

Modified: brlcad/branches/brep-debug/src/conv/csg/csg.c
===================================================================
--- brlcad/branches/brep-debug/src/conv/csg/csg.c       2015-06-16 19:37:48 UTC 
(rev 65333)
+++ brlcad/branches/brep-debug/src/conv/csg/csg.c       2015-06-16 19:53:24 UTC 
(rev 65334)
@@ -23,6 +23,7 @@
  *
  */
 
+#include "common.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include "csg.h"

Modified: brlcad/branches/brep-debug/src/conv/g-obj.c
===================================================================
--- brlcad/branches/brep-debug/src/conv/g-obj.c 2015-06-16 19:37:48 UTC (rev 
65333)
+++ brlcad/branches/brep-debug/src/conv/g-obj.c 2015-06-16 19:53:24 UTC (rev 
65334)
@@ -35,6 +35,7 @@
 
 /* interface headers */
 #include "bu/getopt.h"
+#include "bu/opt.h"
 #include "bu/parallel.h"
 #include "vmath.h"
 #include "nmg.h"
@@ -85,12 +86,87 @@
 static int regions_converted = 0;
 static int regions_written = 0;
 static int inches = 0;
+static int print_help = 0;
 
+static int
+parse_tol_abs(struct bu_vls *error_msg, int argc, const char **argv, void 
*UNUSED(set_var))
+{
+    int ret;
+    BU_OPT_CHECK_ARGV0(error_msg, argc, argv, "absolute tolerance");
+
+    ret = bu_opt_fastf_t(error_msg, argc, argv, (void *)&(ttol.abs));
+    ttol.rel = 0.0;
+    return ret;
+}
+
+static int
+parse_tol_norm(struct bu_vls *error_msg, int argc, const char **argv, void 
*UNUSED(set_var))
+{
+    int ret;
+    BU_OPT_CHECK_ARGV0(error_msg, argc, argv, "normal tolerance");
+
+    ret = bu_opt_fastf_t(error_msg, argc, argv, (void *)&(ttol.norm));
+    ttol.rel = 0.0;
+    return ret;
+}
+
+static int
+parse_tol_dist(struct bu_vls *error_msg, int argc, const char **argv, void 
*UNUSED(set_var))
+{
+    int ret;
+    BU_OPT_CHECK_ARGV0(error_msg, argc, argv, "distance tolerance");
+
+    ret = bu_opt_fastf_t(error_msg, argc, argv, (void *)&(tol.dist));
+    tol.dist_sq = tol.dist * tol.dist;
+    rt_pr_tol(&tol);
+    return ret;
+}
+
+static int
+parse_debug_rt(struct bu_vls *error_msg, int argc, const char **argv, void 
*UNUSED(set_var))
+{
+    BU_OPT_CHECK_ARGV0(error_msg, argc, argv, "debug rt");
+
+    sscanf(argv[0], "%x", (unsigned int *)&RTG.debug);
+    return 1;
+}
+
+static int
+parse_debug_nmg(struct bu_vls *error_msg, int argc, const char **argv, void 
*UNUSED(set_var))
+{
+    BU_OPT_CHECK_ARGV0(error_msg, argc, argv, "debug nmg");
+
+    sscanf(argv[0], "%x", (unsigned int *)&RTG.NMG_debug);
+    NMG_debug = RTG.NMG_debug;
+    return 1;
+}
+
+static struct bu_opt_desc options[] = {
+    {"?", "", 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
+};
+
 int
-main(int argc, char **argv)
+main(int argc, const char **argv)
 {
     int c;
     double percent;
+    struct bu_vls parse_msgs = BU_VLS_INIT_ZERO;
+    const char *prog_name = argv[0];
 
     bu_setprogname(argv[0]);
     bu_setlinebuf(stderr);
@@ -117,60 +193,17 @@
     BU_LIST_INIT(&RTG.rtg_vlfree);     /* for vlist macros */
 
     /* Get command line arguments. */
-    while ((c = bu_getopt(argc, argv, "mua:n:o:r:vx:D:P:X:e:ih?")) != -1) {
-       switch (c) {
-           case 'm':           /* include 'usemtl' statements */
-               usemtl = 1;
-               break;
-           case 'u':           /* Include vertexuse normals */
-               do_normals = 1;
-               break;
-           case 'a':           /* Absolute tolerance. */
-               ttol.abs = atof(bu_optarg);
-               ttol.rel = 0.0;
-               break;
-           case 'n':           /* Surface normal tolerance. */
-               ttol.norm = atof(bu_optarg);
-               ttol.rel = 0.0;
-               break;
-           case 'o':           /* Output file name. */
-               output_file = bu_optarg;
-               break;
-           case 'r':           /* Relative tolerance. */
-               ttol.rel = atof(bu_optarg);
-               break;
-           case 'v':
-               verbose = 1;
-               break;
-           case 'P':
-               ncpu = atoi(bu_optarg);
-               break;
-           case 'x':
-               sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug);
-               break;
-           case 'D':
-               tol.dist = atof(bu_optarg);
-               tol.dist_sq = tol.dist * tol.dist;
-               rt_pr_tol(&tol);
-               break;
-           case 'X':
-               sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug);
-               NMG_debug = RTG.NMG_debug;
-               break;
-           case 'e':           /* Error file name. */
-               error_file = bu_optarg;
-               break;
-           case 'i':
-               inches = 1;
-               break;
-           default:
-               print_usage(argv[0]);
-       }
+    ++argv; --argc;
+
+    argc = bu_opt_parse(&parse_msgs, argc, argv, options);
+
+    if (bu_vls_strlen(&parse_msgs) > 0) {
+       bu_log("%s\n", bu_vls_cstr(&parse_msgs));
     }
+    if (argc < 2 || print_help) {
+       print_usage(prog_name);
+    }
 
-    if (bu_optind+1 >= argc)
-       print_usage(argv[0]);
-
     if (!output_file)
        fp = stdout;
     else {
@@ -191,8 +224,6 @@
     }
 
     /* Open BRL-CAD database */
-    argc -= bu_optind;
-    argv += bu_optind;
     if ((dbip = db_open(argv[0], DB_OPEN_READONLY)) == DBI_NULL) {
        perror(argv[0]);
        bu_exit(1, "Unable to open geometry database file (%s)\n", argv[0]);
@@ -226,10 +257,10 @@
 
     if (regions_tried>0) {
        percent = ((double)regions_converted * 100.0) / regions_tried;
-       printf("Tried %d regions, %d converted to NMG's successfully.  %g%%\n",
+       bu_log("Tried %d regions, %d converted to NMG's successfully.  %g%%\n",
               regions_tried, regions_converted, percent);
        percent = ((double)regions_written * 100.0) / regions_tried;
-       printf("                 %d triangulated successfully. %g%%\n",
+       bu_log("                 %d triangulated successfully. %g%%\n",
               regions_written, percent);
     }
 
@@ -456,11 +487,6 @@
            }
        }
     }
-    /* regions_converted++;
-       printf("Processed region %s\n", region_name);
-       printf("Regions attempted = %d Regions done = %d\n", regions_tried, 
regions_converted);
-       fflush(stdout);
-    */
     vert_offset += numverts;
     bu_ptbl_free(&verts);
     if (do_normals) {
@@ -652,7 +678,7 @@
 
        npercent = (float)(regions_converted * 100) / regions_tried;
        tpercent = (float)(regions_written * 100) / regions_tried;
-       printf("Tried %d regions; %d conv. to NMG's, %d conv. to tri.; nmgper = 
%.2f%%, triper = %.2f%%\n",
+       bu_log("Tried %d regions; %d conv. to NMG's, %d conv. to tri.; nmgper = 
%.2f%%, triper = %.2f%%\n",
               regions_tried, regions_converted, regions_written, npercent, 
tpercent);
     }
 

Modified: brlcad/branches/brep-debug/src/conv/gcv/gcv.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/gcv/gcv.cpp     2015-06-16 19:37:48 UTC 
(rev 65333)
+++ brlcad/branches/brep-debug/src/conv/gcv/gcv.cpp     2015-06-16 19:53:24 UTC 
(rev 65334)
@@ -30,80 +30,139 @@
 
 #include "bu.h"
 
+struct gcv_fmt_opts {
+    struct bu_ptbl *args;
+    struct bu_opt_desc *ds;
+};
 
+void gcv_fmt_opts_init(struct gcv_fmt_opts *gfo, bu_opt_desc *ds)
+{
+    BU_GET(gfo->args, struct bu_ptbl);
+    bu_ptbl_init(gfo->args, 8, "init opts tbl");
+    gfo->ds = ds;
+}
+
+void gcv_fmt_opts_free(struct gcv_fmt_opts *gfo)
+{
+    bu_ptbl_free(gfo->args);
+    BU_PUT(gfo->args, struct bu_ptbl);
+}
+
+int
+gcv_fmt_fun(struct bu_vls *UNUSED(msgs), int argc, const char **argv, void 
*set_var)
+{
+    int i = 0;
+    int args_used = 0;
+    struct gcv_fmt_opts *gfo = (struct gcv_fmt_opts *)set_var;
+
+    if (!argv || argc < 1 ) return 0;
+
+    for (i = 0; i < argc; i++) {
+       struct bu_vls cmp_arg = BU_VLS_INIT_ZERO;
+       const char *arg = argv[i]+1;
+       const char *equal_pos;
+       int d_ind = 0;
+       int in_desc = 0;
+       if (arg[0] == '-') arg++;
+       equal_pos = strchr(arg, '=');
+       bu_vls_sprintf(&cmp_arg, "%s", arg);
+       if (equal_pos)
+           bu_vls_trunc(&cmp_arg, -1 * strlen(equal_pos));
+
+       struct bu_opt_desc *d = &(gfo->ds[d_ind]);
+       while (((d->shortopt && strlen(d->shortopt) > 0) || (d->longopt && 
strlen(d->longopt) > 0)) && !in_desc) {
+           if (BU_STR_EQUAL(bu_vls_addr(&cmp_arg), d->shortopt) || 
BU_STR_EQUAL(bu_vls_addr(&cmp_arg), d->longopt)) {
+               /* Top level option hit - we're done */
+               bu_vls_free(&cmp_arg);
+               return args_used;
+           } else {
+               d_ind++;
+               d = &(gfo->ds[d_ind]);
+           }
+       }
+       bu_ptbl_ins(gfo->args, (long *)argv[i]);
+       args_used++;
+       bu_vls_free(&cmp_arg);
+    }
+
+    return args_used;
+}
+
+int
+io_opt_files(int argc, const char **argv)
+{
+    int i_opts = 0;
+    int o_opts = 0;
+    const char *equal_pos = NULL;
+    int i = 0;
+    for (i = 0; i < argc; i++) {
+       struct bu_vls cmp_arg = BU_VLS_INIT_ZERO;
+       const char *arg = argv[i];
+       if (arg[0] != '-') continue;
+       arg++;
+       if (arg[0] == '-') arg++;
+       equal_pos = strchr(arg, '=');
+       bu_vls_sprintf(&cmp_arg, "%s", arg);
+       if (equal_pos)
+           bu_vls_trunc(&cmp_arg, -1 * strlen(equal_pos));
+
+       if (BU_STR_EQUAL(bu_vls_addr(&cmp_arg), "input")) i_opts++;
+       if (BU_STR_EQUAL(bu_vls_addr(&cmp_arg), "output")) o_opts++;
+    }
+    i_opts = (i_opts > 0) ? 1 : 0;
+    o_opts = (o_opts > 0) ? 1 : 0;
+    return i_opts + o_opts;
+}
+
 /* Emulate a FASTGEN4 format option processor */
-void fast4_arg_process(const char *args) {
+void fast4_arg_process(int argc, const char **argv) {
     int i = 0;
-    char *input = NULL;
-    int argc = 0;
-    char **argv = NULL;
     int ret_argc = 0;
-    const char **non_opts;
     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
     };
 
-    input = bu_strdup(args);
-    argv = (char **)bu_calloc(strlen(input) + 1, sizeof(char *), "argv array");
-    argc = bu_argv_from_string(argv, strlen(input), input);
+    ret_argc = bu_opt_parse(NULL, argc, (const char **)argv, fg4_opt_desc);
 
-    non_opts = (const char **)bu_calloc(strlen(args) + 1, sizeof(const char 
*), "non_opts array");
-    ret_argc = bu_opt_parse(&non_opts, strlen(args), NULL, argc, (const char 
**)argv, fg4_opt_desc);
-
     if (w_flag)        bu_log("FASTGEN 4 warn default names set\n");
     bu_log("FASTGEN 4 tol: %d\n", tol);
 
     if (ret_argc) {
        bu_log("Unknown args: ");
        for (i = 0; i < ret_argc - 1; i++) {
-           bu_log("%s, ", non_opts[i]);
+           bu_log("%s, ", argv[i]);
        }
-       bu_log("%s\n", non_opts[ret_argc - 1]);
+       bu_log("%s\n", argv[ret_argc - 1]);
     }
-
-    bu_free(input, "free array");
-    bu_free(argv, "free argv");
 }
 
-void stl_arg_process(const char *args) {
+void stl_arg_process(int argc, const char **argv) {
     int i= 0;
-    char *input = NULL;
-    int argc = 0;
-    char **argv = NULL;
     int ret_argc = 0;
-    const char **non_opts;
     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
     };
 
-    input = bu_strdup(args);
-    argv = (char **)bu_calloc(strlen(input) + 1, sizeof(char *), "argv array");
-    argc = bu_argv_from_string(argv, strlen(input), input);
+    ret_argc = bu_opt_parse(NULL, argc, (const char **)argv, stl_opt_desc);
 
-    non_opts = (const char **)bu_calloc(strlen(args) + 1, sizeof(const char 
*), "non_opts array");
-    ret_argc = bu_opt_parse(&non_opts, strlen(args), NULL, argc, (const char 
**)argv, stl_opt_desc);
-
     bu_log("STL tol: %d\n", tol);
     bu_log("STL units: %d\n", units);
 
     if (ret_argc) {
        bu_log("Unknown args: ");
        for (i = 0; i < ret_argc - 1; i++) {
-           bu_log("%s, ", non_opts[i]);
+           bu_log("%s, ", argv[i]);
        }
-       bu_log("%s\n", non_opts[ret_argc - 1]);
+       bu_log("%s\n", argv[ret_argc - 1]);
     }
-
-    bu_free(input, "free array");
-    bu_free(argv, "free argv");
 }
 
 HIDDEN int
@@ -247,9 +306,8 @@
 {
     char **file_set = (char **)set_var;
 
-    if (!argv || strlen(argv[0]) || argc == 0) {
-       return 0;
-    }
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "input file");
+
     if (!bu_file_exists(argv[0], NULL)){
        if (msg) bu_vls_sprintf(msg, "Error - file %s does not exist!\n", 
argv[0]);
        return -1;
@@ -265,9 +323,8 @@
 {
     char **file_set = (char **)set_var;
 
-    if (!argv || strlen(argv[0]) || argc == 0) {
-       return 0;
-    }
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "output file");
+
     if (bu_file_exists(argv[0], NULL)){
        if (msg) bu_vls_sprintf(msg, "Error - file %s already exists!\n", 
argv[0]);
        return -1;
@@ -284,9 +341,9 @@
     int type_int;
     mime_model_t type = MIME_MODEL_UNKNOWN;
     mime_model_t *set_type = (mime_model_t *)set_mime;
-    if (!argv || argc == 0) {
-       return 0;
-    }
+
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "mime format");
+
     type_int = bu_file_mime(argv[0], MIME_MODEL);
     type = (type_int < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)type_int;
     if (type == MIME_MODEL_UNKNOWN) {
@@ -319,12 +376,13 @@
 
 #define gcv_help_str "Print help and exit.  If a format is specified to 
--help, print help specific to that format"
 
-#define gcv_inopt_str "Options to apply only while processing input file.  
Quotes around the opts are always necessary, but brackets are only necessary 
when supplying a single option without arguments that would otherwise be 
interpreted as an argv entry by the shell, even with quotes.  Brackets will 
never hurt, and for robustness when scripting they should always be used."
+#define gcv_inopt_str "Options to apply only while processing input file.  
Accepts options until another toplevel option is encountered."
 
-#define gcv_outopt_str "Options to apply only while preparing output file.  
Quotes around the opts are always necessary, but brackets are only necessary 
when supplying a single option without arguments that would otherwise be 
interpreted as an argv entry by the shell, even with quotes.  Brackets will 
never hurt, and for robustness when scripting they should always be used."
+#define gcv_outopt_str "Options to apply only while preparing output file.  
Accepts options until another toplevel option is encountered."
+#define gcv_both_str "Options to apply both during input and output handling.  
Accepts options until another toplevel option is encountered."
 
 int
-main(int ac, char **av)
+main(int ac, const char **av)
 {
     size_t i;
     int fmt = 0;
@@ -337,8 +395,9 @@
     static mime_model_t out_type = MIME_MODEL_UNKNOWN;
     static char *in_path_str = NULL;
     static char *out_path_str = NULL;
-    static struct bu_vls in_only_opts = BU_VLS_INIT_ZERO;
-    static struct bu_vls out_only_opts = BU_VLS_INIT_ZERO;
+    static struct gcv_fmt_opts in_only_opts;
+    static struct gcv_fmt_opts out_only_opts;
+    static struct gcv_fmt_opts both_opts;
     static struct gcv_help_state hs;
 
     struct bu_vls in_format = BU_VLS_INIT_ZERO;
@@ -348,24 +407,30 @@
     struct bu_vls out_path_raw = BU_VLS_INIT_ZERO;
     struct bu_vls out_path = BU_VLS_INIT_ZERO;
     struct bu_vls log = BU_VLS_INIT_ZERO;
-    struct bu_vls input_opts = BU_VLS_INIT_ZERO;
-    struct bu_vls output_opts = BU_VLS_INIT_ZERO;
+
+    struct bu_ptbl input_opts = BU_PTBL_INIT_ZERO;
+    struct bu_ptbl output_opts = BU_PTBL_INIT_ZERO;
     struct bu_vls parse_msgs = BU_VLS_INIT_ZERO;
     int uac = 0;
-    const char **uav = (const char **)bu_calloc(ac, sizeof(char *), "unknown 
results");
+    int io_opt_cnt = io_opt_files(ac, av);
 
-    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,               },
+    struct bu_opt_desc gcv_opt_desc[] = {
+       {"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",       &gcv_fmt_fun, (void 
*)&in_only_opts,  gcv_inopt_str,                },
+       {"O", "output-only-opts", "opts",       &gcv_fmt_fun, (void 
*)&out_only_opts, gcv_outopt_str,               },
+       {"B", "input-and-output-opts", "opts",  &gcv_fmt_fun, (void 
*)&both_opts,     gcv_both_str,                 },
        BU_OPT_DESC_NULL
     };
 
+    gcv_fmt_opts_init(&in_only_opts, gcv_opt_desc);
+    gcv_fmt_opts_init(&out_only_opts, gcv_opt_desc);
+    gcv_fmt_opts_init(&both_opts, gcv_opt_desc);
+
     hs.flag = 0;
     hs.format = NULL;
 
@@ -379,8 +444,13 @@
        goto cleanup;
     }
 
-    uac = bu_opt_parse(&uav, ac, &parse_msgs, ac, (const char **)av, 
gcv_opt_desc);
+    uac = bu_opt_parse(&parse_msgs, ac - 2 + io_opt_cnt, av, gcv_opt_desc);
 
+    if (uac == -1) {
+       bu_log("Parsing error: %s\n", bu_vls_addr(&parse_msgs));
+       goto cleanup;
+    }
+
     /* First, see if help was supplied */
     if (hs.flag) {
        if (hs.format) {
@@ -431,23 +501,19 @@
 
     /* If not specified explicitly with -i or -o, the input and output paths 
must always
      * be the last two arguments supplied */
-    if (uac > 0 && !(skip_in && skip_out)) {
+    if (!(skip_in && skip_out)) {
        if (skip_in && !skip_out) {
-           bu_vls_sprintf(&out_path_raw, "%s", uav[uac - 1]);
-           uac--;
+           bu_vls_sprintf(&out_path_raw, "%s", av[ac - 1]);
        }
        if (!skip_in && skip_out) {
-           bu_vls_sprintf(&in_path_raw, "%s", uav[uac - 1]);
-           uac--;
+           bu_vls_sprintf(&in_path_raw, "%s", av[ac - 1]);
        }
        if (!skip_in && !skip_out) {
-           if (uac > 1) {
-               bu_vls_sprintf(&in_path_raw, "%s", uav[uac - 2]);
-               bu_vls_sprintf(&out_path_raw, "%s", uav[uac - 1]);
-               uac = uac -2;
+           if (ac > 1) {
+               bu_vls_sprintf(&in_path_raw, "%s", av[ac - 2]);
+               bu_vls_sprintf(&out_path_raw, "%s", av[ac - 1]);
            } else {
-               bu_vls_sprintf(&in_path_raw, "%s", uav[uac - 1]);
-               uac--;
+               bu_vls_sprintf(&in_path_raw, "%s", av[ac - 1]);
            }
        }
     }
@@ -457,44 +523,24 @@
      * input/output specific options have a chance to override them. */
     if (uac) {
        for (i = 0; i < (size_t)uac; i++) {
-           if (i != 0) {
-               bu_vls_printf(&input_opts, " ");
-               bu_vls_printf(&output_opts, " ");
-           }
-           bu_vls_printf(&input_opts, "%s", uav[i]);
-           bu_vls_printf(&output_opts, "%s", uav[i]);
+           bu_ptbl_ins(&input_opts, (long *)av[i]);
+           bu_ptbl_ins(&output_opts, (long *)av[i]);
        }
-       if (bu_vls_strlen(&input_opts) > 0) bu_log("Unknown options (input): 
%s\n", bu_vls_addr(&input_opts));
-       if (bu_vls_strlen(&output_opts) > 0) bu_log("Unknown options (output): 
%s\n", bu_vls_addr(&output_opts));
     }
+    /* Same for any options that were supplied explicitly to go to both input 
and output */
+    if (BU_PTBL_LEN(both_opts.args) > 0) {
+       bu_ptbl_cat(&input_opts, both_opts.args);
+       bu_ptbl_cat(&output_opts, both_opts.args);
+    }
 
     /* If we have input and/or output specific options, append them now */
-    if (bu_vls_strlen(&in_only_opts) > 0) {
-       struct bu_vls o_tmp = BU_VLS_INIT_ZERO;
-       if (bu_vls_strlen(&input_opts) > 0)
-           bu_vls_printf(&input_opts, " ");
-
-       bu_vls_sprintf(&o_tmp, "%s", bu_vls_addr(&in_only_opts));
-       if (bu_vls_addr(&o_tmp)[0] == '[') bu_vls_nibble(&o_tmp, 1);
-       if (bu_vls_addr(&o_tmp)[strlen(bu_vls_addr(&o_tmp)) - 1] == ']') 
bu_vls_trunc(&o_tmp, -1);
-       bu_vls_printf(&input_opts, "%s", bu_vls_addr(&o_tmp));
-       if (bu_vls_strlen(&input_opts) > 0) bu_log("Input only opts: %s\n", 
bu_vls_addr(&o_tmp));
-       bu_vls_free(&o_tmp);
+    if (BU_PTBL_LEN(in_only_opts.args) > 0) {
+       bu_ptbl_cat(&input_opts, in_only_opts.args);
     }
-    if (bu_vls_strlen(&out_only_opts) > 0) {
-       struct bu_vls o_tmp = BU_VLS_INIT_ZERO;
-       if (bu_vls_strlen(&output_opts) > 0)
-           bu_vls_printf(&output_opts, " ");
-
-       bu_vls_sprintf(&o_tmp, "%s", &out_only_opts);
-       if (bu_vls_addr(&o_tmp)[0] == '[') bu_vls_nibble(&o_tmp, 1);
-       if (bu_vls_addr(&o_tmp)[strlen(bu_vls_addr(&o_tmp)) - 1] == ']') 
bu_vls_trunc(&o_tmp, -1);
-       bu_vls_printf(&output_opts, "%s", bu_vls_addr(&o_tmp));
-       if (bu_vls_strlen(&output_opts) > 0) bu_log("Output only opts: %s\n", 
bu_vls_addr(&o_tmp));
-       bu_vls_free(&o_tmp);
+    if (BU_PTBL_LEN(out_only_opts.args) > 0) {
+       bu_ptbl_cat(&output_opts, out_only_opts.args);
     }
 
-
     /* See if we have input and output files specified */
     if (!extract_path(&in_path, bu_vls_addr(&in_path_raw))) {
        if (bu_vls_strlen(&in_path_raw) > 0) {
@@ -565,20 +611,20 @@
 
     switch (in_type) {
        case MIME_MODEL_VND_FASTGEN:
-           fast4_arg_process(bu_vls_addr(&input_opts));
+           fast4_arg_process(BU_PTBL_LEN(&input_opts), (const char 
**)input_opts.buffer);
            break;
        case MIME_MODEL_STL:
-           stl_arg_process(bu_vls_addr(&input_opts));
+           stl_arg_process(BU_PTBL_LEN(&input_opts), (const char 
**)input_opts.buffer);
        default:
            break;
     }
 
     switch (out_type) {
        case MIME_MODEL_VND_FASTGEN:
-           fast4_arg_process(bu_vls_addr(&output_opts));
+           fast4_arg_process(BU_PTBL_LEN(&output_opts), (const char 
**)output_opts.buffer);
            break;
        case MIME_MODEL_STL:
-           stl_arg_process(bu_vls_addr(&output_opts));
+           stl_arg_process(BU_PTBL_LEN(&output_opts), (const char 
**)output_opts.buffer);
        default:
            break;
     }
@@ -595,10 +641,11 @@
     bu_vls_free(&out_format);
     bu_vls_free(&out_path);
     bu_vls_free(&log);
-    bu_vls_free(&input_opts);
-    bu_vls_free(&output_opts);
-    bu_vls_free(&in_only_opts);
-    bu_vls_free(&out_only_opts);
+    bu_ptbl_free(&input_opts);
+    bu_ptbl_free(&output_opts);
+    gcv_fmt_opts_free(&in_only_opts);
+    gcv_fmt_opts_free(&out_only_opts);
+    gcv_fmt_opts_free(&both_opts);
     return ret;
 }
 

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/Axis2Placement.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/Axis2Placement.cpp  
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/Axis2Placement.cpp  
2015-06-16 19:53:24 UTC (rev 65334)
@@ -88,7 +88,7 @@
 }
 
 bool
-Axis2Placement::Load(STEPWrapper *sw, SDAI_Select *sse)
+Axis2Placement::Load(STEPWrapper *sw, SDAI_Application_instance *sse)
 {
     step = sw;
 

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/Axis2Placement.h
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/Axis2Placement.h    
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/Axis2Placement.h    
2015-06-16 19:53:24 UTC (rev 65334)
@@ -56,7 +56,7 @@
     const double *GetNormal();
     const double *GetXAxis();
     const double *GetYAxis();
-    bool Load(STEPWrapper *sw, SDAI_Select *sse);
+    bool Load(STEPWrapper *sw, SDAI_Application_instance *sse);
     virtual void Print(int level);
 
     //static methods

Modified: 
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedDefinition.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedDefinition.cpp 
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedDefinition.cpp 
2015-06-16 19:53:24 UTC (rev 65334)
@@ -129,7 +129,7 @@
 }
 
 bool
-CharacterizedDefinition::Load(STEPWrapper *sw,SDAI_Select *sse) {
+CharacterizedDefinition::Load(STEPWrapper *sw,SDAI_Application_instance *sse) {
     step=sw;
 
     if (definition == NULL) {
@@ -141,7 +141,7 @@
 
            type = CharacterizedDefinition::CHARACTERIZED_PRODUCT_DEFINITION;
            definition = aCPD;
-           if (!aCPD->Load(step, cpd_select)) {
+           if (!aCPD->Load(step, (SDAI_Application_instance *)cpd_select)) {
                std::cout << CLASSNAME << ":Error loading select attribute 
'definition' as CharacterizedProductDefinition from CharacterizedDefinition." 
<< std::endl;
                return false;
            }
@@ -151,7 +151,7 @@
 
            type = CharacterizedDefinition::SHAPE_DEFINITION;
            definition = aSD;
-           if (!aSD->Load(step, sd_select)) {
+           if (!aSD->Load(step, (SDAI_Application_instance *)sd_select)) {
                std::cout << CLASSNAME << ":Error loading select attribute 
'definition' as CharacterizedProductDefinition from CharacterizedDefinition." 
<< std::endl;
                return false;
            }

Modified: 
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedDefinition.h
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedDefinition.h   
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedDefinition.h   
2015-06-16 19:53:24 UTC (rev 65334)
@@ -65,7 +65,7 @@
     int GetProductId();
     ProductDefinition *GetRelatingProductDefinition();
     ProductDefinition *GetRelatedProductDefinition();
-    bool Load(STEPWrapper *sw, SDAI_Select *sse);
+    bool Load(STEPWrapper *sw, SDAI_Application_instance *sse);
     virtual bool LoadONBrep(ON_Brep *brep);
     virtual void Print(int level);
     virtual CharacterizedDefinition_type CharacterizedDefinitionType()

Modified: 
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedProductDefinition.cpp
===================================================================
--- 
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedProductDefinition.cpp
  2015-06-16 19:37:48 UTC (rev 65333)
+++ 
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedProductDefinition.cpp
  2015-06-16 19:53:24 UTC (rev 65334)
@@ -120,7 +120,7 @@
 }
 
 bool
-CharacterizedProductDefinition::Load(STEPWrapper *sw,SDAI_Select *sse) {
+CharacterizedProductDefinition::Load(STEPWrapper *sw, 
SDAI_Application_instance *sse) {
     step=sw;
 
     if (definition == NULL) {

Modified: 
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedProductDefinition.h
===================================================================
--- 
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedProductDefinition.h
    2015-06-16 19:37:48 UTC (rev 65333)
+++ 
brlcad/branches/brep-debug/src/conv/step/step-g/CharacterizedProductDefinition.h
    2015-06-16 19:53:24 UTC (rev 65334)
@@ -63,7 +63,7 @@
     int GetProductId();
     ProductDefinition *GetRelatingProductDefinition();
     ProductDefinition *GetRelatedProductDefinition();
-    bool Load(STEPWrapper *sw, SDAI_Select *sse);
+    bool Load(STEPWrapper *sw, SDAI_Application_instance *sse);
     virtual bool LoadONBrep(ON_Brep *brep);
     virtual void Print(int level);
     virtual CharacterizedProductDefinition_type 
CharacterizedProductDefinitionType()

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/Conic.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/Conic.cpp   2015-06-16 
19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/Conic.cpp   2015-06-16 
19:53:24 UTC (rev 65334)
@@ -102,7 +102,7 @@
            Axis2Placement *aA2P = new Axis2Placement();
 
            position = aA2P;
-           if (!aA2P->Load(step, select)) {
+           if (!aA2P->Load(step, (SDAI_Application_instance *)select)) {
                std::cout << CLASSNAME << ":Error loading select Axis2Placement 
from Conic." << std::endl;
                sw->entity_status[id] = STEP_LOAD_ERROR;
                return false;

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSet.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSet.cpp    
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSet.cpp    
2015-06-16 19:53:24 UTC (rev 65334)
@@ -78,7 +78,7 @@
                if (aGSS) {
                    elements.push_back(aGSS);
 
-                   if (!aGSS->Load(step, select)) {
+                   if (!aGSS->Load(step, (SDAI_Application_instance *)select)) 
{
                        std::cout << CLASSNAME << ":Error loading select 
attribute list 'elements' as GeometricSetSelect from GeometricSet." << 
std::endl;
                        return false;
                    }

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSetSelect.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSetSelect.cpp      
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSetSelect.cpp      
2015-06-16 19:53:24 UTC (rev 65334)
@@ -70,11 +70,11 @@
 }
 
 bool
-GeometricSetSelect::Load(STEPWrapper *sw,SDAI_Select *sse) {
+GeometricSetSelect::Load(STEPWrapper *sw, SDAI_Application_instance *sse) {
     step=sw;
 
     if (element == NULL) {
-       SdaiGeometric_set_select *v = (SdaiGeometric_set_select *) sse;
+       SdaiGeometric_set_select *v = (SdaiGeometric_set_select *)sse;
 
        if (v->IsPoint()) {
            SdaiPoint *point_select = *v;

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSetSelect.h
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSetSelect.h        
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/GeometricSetSelect.h        
2015-06-16 19:53:24 UTC (rev 65334)
@@ -60,7 +60,7 @@
     Point *GetPointElement();
     Curve *GetCurveElement();
     Surface *GetSurfaceElement();
-    bool Load(STEPWrapper *sw, SDAI_Select *sse);
+    bool Load(STEPWrapper *sw, SDAI_Application_instance *sse);
     virtual bool LoadONBrep(ON_Brep *brep);
     virtual void Print(int level);
     virtual GeometricSetSelect_type GeometricSetSelectType()

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/PCurveOrSurface.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/PCurveOrSurface.cpp 
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/PCurveOrSurface.cpp 
2015-06-16 19:53:24 UTC (rev 65334)
@@ -70,7 +70,7 @@
 }
 
 bool
-PCurveOrSurface::Load(STEPWrapper *sw, SDAI_Select *sse)
+PCurveOrSurface::Load(STEPWrapper *sw, SDAI_Application_instance *sse)
 {
     step = sw;
 

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/PCurveOrSurface.h
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/PCurveOrSurface.h   
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/PCurveOrSurface.h   
2015-06-16 19:53:24 UTC (rev 65334)
@@ -54,7 +54,7 @@
     PCurveOrSurface();
     virtual ~PCurveOrSurface();
     PCurveOrSurface(STEPWrapper *sw, int step_id);
-    bool Load(STEPWrapper *sw, SDAI_Select *sse);
+    bool Load(STEPWrapper *sw, SDAI_Application_instance *sse);
     virtual void Print(int level);
 
     //static methods

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/PropertyDefinition.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/PropertyDefinition.cpp      
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/PropertyDefinition.cpp      
2015-06-16 19:53:24 UTC (rev 65334)
@@ -106,7 +106,7 @@
            CharacterizedDefinition *aCD = new CharacterizedDefinition();
 
            definition = aCD;
-           if (!aCD->Load(step, select)) {
+           if (!aCD->Load(step, (SDAI_Application_instance *)select)) {
                std::cout << CLASSNAME << ":Error loading select attribute 
'definition' as CharacterizedDefinition from PropertyDefinition." << std::endl;
                sw->entity_status[id] = STEP_LOAD_ERROR;
                return false;

Modified: 
brlcad/branches/brep-debug/src/conv/step/step-g/RepresentedDefinition.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/RepresentedDefinition.cpp   
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/RepresentedDefinition.cpp   
2015-06-16 19:53:24 UTC (rev 65334)
@@ -60,7 +60,7 @@
 }
 
 bool
-RepresentedDefinition::Load(STEPWrapper *sw,SDAI_Select *sse) {
+RepresentedDefinition::Load(STEPWrapper *sw, SDAI_Application_instance *sse) {
     step=sw;
 
     //TODO: Need to complete for AP203e2

Modified: 
brlcad/branches/brep-debug/src/conv/step/step-g/RepresentedDefinition.h
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/RepresentedDefinition.h     
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/RepresentedDefinition.h     
2015-06-16 19:53:24 UTC (rev 65334)
@@ -54,7 +54,7 @@
     RepresentedDefinition();
     virtual ~RepresentedDefinition();
     RepresentedDefinition(STEPWrapper *sw, int step_id);
-    bool Load(STEPWrapper *sw, SDAI_Select *sse);
+    bool Load(STEPWrapper *sw, SDAI_Application_instance *sse);
     virtual void Print(int level);
 
     //static methods

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/ShapeDefinition.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/ShapeDefinition.cpp 
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/ShapeDefinition.cpp 
2015-06-16 19:53:24 UTC (rev 65334)
@@ -66,7 +66,7 @@
 }
 */
 bool
-ShapeDefinition::Load(STEPWrapper *sw,SDAI_Select *sse) {
+ShapeDefinition::Load(STEPWrapper *sw, SDAI_Application_instance *sse) {
     step=sw;
 
     if (definition == NULL) {

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/ShapeDefinition.h
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/ShapeDefinition.h   
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/ShapeDefinition.h   
2015-06-16 19:53:24 UTC (rev 65334)
@@ -60,7 +60,7 @@
     ProductDefinitionShape *GetProductDefinitionShape();
     ShapeAspect *GetShapeAspect();
     ShapeAspectRelationship *GetShapeAspectRelationship();
-    bool Load(STEPWrapper *sw, SDAI_Select *sse);
+    bool Load(STEPWrapper *sw, SDAI_Application_instance *sse);
     virtual bool LoadONBrep(ON_Brep *brep);
     virtual void Print(int level);
     virtual ShapeDefinition_type ShapeDefinitionType()

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/SurfaceCurve.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/SurfaceCurve.cpp    
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/SurfaceCurve.cpp    
2015-06-16 19:53:24 UTC (rev 65334)
@@ -134,7 +134,7 @@
                {
                    PCurveOrSurface *aPCOS = new PCurveOrSurface();
 
-                   if (!aPCOS->Load(step, p_or_s)) {
+                   if (!aPCOS->Load(step, (SDAI_Application_instance 
*)p_or_s)) {
                        std::cout << CLASSNAME << ":Error loading 
PCurveOrSurface select." << std::endl;
                        delete aPCOS;
                        goto step_error;

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/TrimmedCurve.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/TrimmedCurve.cpp    
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/TrimmedCurve.cpp    
2015-06-16 19:53:24 UTC (rev 65334)
@@ -114,7 +114,7 @@
                p = static_cast<SDAI_Select *>(sn->node);
                TrimmingSelect *aTS = new TrimmingSelect();
 
-               if (p && !aTS->Load(step, p)) {
+               if (p && !aTS->Load(step, (SDAI_Application_instance *)p)) {
                    std::cout << CLASSNAME << ":Error loading TrimmingSelect 
from list." << std::endl;
                    delete aTS;
                    goto step_error;
@@ -135,7 +135,7 @@
                p = static_cast<SDAI_Select *>(sn->node);
                TrimmingSelect *aTS = new TrimmingSelect();
 
-               if (p && !aTS->Load(step, p)) {
+               if (p && !aTS->Load(step, (SDAI_Application_instance *)p)) {
                    std::cout << CLASSNAME << ":Error loading TrimmingSelect 
from list." << std::endl;
                    delete aTS;
                    goto step_error;

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/TrimmingSelect.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/TrimmingSelect.cpp  
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/TrimmingSelect.cpp  
2015-06-16 19:53:24 UTC (rev 65334)
@@ -87,7 +87,7 @@
 }
 
 bool
-TrimmingSelect::Load(STEPWrapper *sw, SDAI_Select *sse)
+TrimmingSelect::Load(STEPWrapper *sw, SDAI_Application_instance *sse)
 {
     step = sw;
 

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/TrimmingSelect.h
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/TrimmingSelect.h    
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/TrimmingSelect.h    
2015-06-16 19:53:24 UTC (rev 65334)
@@ -56,7 +56,7 @@
     double GetParameterTrim();
     const double *GetPointTrim();
     bool IsParameterTrim();
-    bool Load(STEPWrapper *sw, SDAI_Select *sse);
+    bool Load(STEPWrapper *sw, SDAI_Application_instance *sse);
     virtual void Print(int level);
 
     //static methods

Modified: brlcad/branches/brep-debug/src/conv/step/step-g/step-g.cpp
===================================================================
--- brlcad/branches/brep-debug/src/conv/step/step-g/step-g.cpp  2015-06-16 
19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/conv/step/step-g/step-g.cpp  2015-06-16 
19:53:24 UTC (rev 65334)
@@ -27,10 +27,10 @@
 
 #include <iostream>
 
-#include "bu/getopt.h"
 #include "bu/time.h"
 #include "bu/file.h"
 #include "bu/log.h"
+#include "bu/opt.h"
 #include "bu/vls.h"
 
 //
@@ -53,12 +53,28 @@
     std::cerr << "Usage: step-g [-v] -o outfile.g infile.stp \n" << std::endl;
 }
 
+struct OutputFile {
+    char *filename;
+    bool overwrite;
+};
 
+static int
+parse_opt_O(struct bu_vls *error_msg, int argc, const char **argv, void 
*set_var)
+{
+    int ret;
+    OutputFile *ofile = (OutputFile *)set_var;
+
+    BU_OPT_CHECK_ARGV0(error_msg, argc, argv, "-O");
+
+    ofile->overwrite = true;
+    ret = bu_opt_str(error_msg, argc, argv, &ofile->filename);
+    return ret;
+}
+
 int
-main(int argc, char *argv[])
+main(int argc, const char *argv[])
 {
     int ret = 0;
-    int overwrite_existing = 0;
     int64_t elapsedtime;
 
     elapsedtime = bu_gettime();
@@ -77,57 +93,45 @@
     // STEPfile sfile (registry, instance_list);
 
     // process command line arguments
-    int c;
-    char *output_file = (char *)NULL;
-    bool verbose = false;
-    int dry_run = 0;
-    char *summary_log_file = (char *)NULL;
-    while ((c = bu_getopt(argc, argv, "DS:vO:o:")) != -1) {
-       switch (c) {
-           case 'D':
-               dry_run = 1;
-               break;
-           case 'S':
-               summary_log_file = bu_optarg;
-               break;
-           case 'O':
-               overwrite_existing = 1;
-               output_file = bu_optarg;
-               break;
-           case 'o':
-               output_file = bu_optarg;
-               break;
-           case 'v':
-               verbose = true;
-               break;
-           default:
-               usage();
-               bu_exit(1, NULL);
-               break;
-       }
+    static OutputFile ofile = {NULL, false};
+    static bool verbose = false;
+    static int dry_run = 0;
+    static char *summary_log_file = (char *)NULL;
+    struct bu_vls parse_msgs = BU_VLS_INIT_ZERO;
+    struct bu_opt_desc options[] = {
+       {"D", "", "",         NULL,        &dry_run,          "dry run (output 
file not written)"},
+       {"v", "", "",         NULL,        &verbose,          "verbose"},
+       {"O", "", "filename", parse_opt_O, &ofile,            "output file 
(overwrite)"},
+       {"o", "", "filename", bu_opt_str,  &ofile.filename,   "output file"},
+       {"S", "", "filename", bu_opt_str,  &summary_log_file, "summary file"},
+       BU_OPT_DESC_NULL
+    };
+
+    ++argv; --argc;
+    argc = bu_opt_parse(&parse_msgs, argc, argv, options);
+
+    if (bu_vls_strlen(&parse_msgs) > 0) {
+       bu_log("%s\n", bu_vls_cstr(&parse_msgs));
     }
-
-    if (bu_optind >= argc || output_file == (char *)NULL) {
+    if (argc != 1 || BU_STR_EMPTY(ofile.filename)) {
        usage();
        bu_exit(1, NULL);
     }
-
-    argc -= bu_optind;
-    argv += bu_optind;
-
-    if (!overwrite_existing) {
+    if (!ofile.overwrite) {
        /* check our inputs/outputs */
-       if (bu_file_exists(output_file, NULL)) {
-           bu_exit(1, "ERROR: refusing to overwrite existing output 
file:\"%s\". Please remove file or change output file name and try again.", 
output_file);
+       if (bu_file_exists(ofile.filename, NULL)) {
+           bu_exit(1, "ERROR: refusing to overwrite existing output file:"
+                       "\"%s\". Please remove the existing file, change the "
+                       "output file name, or use the '-O' option to force an"
+                       " overwrite.", ofile.filename);
        }
     }
-
     if (!bu_file_exists(argv[0], NULL) && !BU_STR_EQUAL(argv[0], "-")) {
        bu_exit(2, "ERROR: unable to read input \"%s\" STEP file", argv[0]);
     }
 
     std::string iflnm = argv[0];
-    std::string oflnm = output_file;
+    std::string oflnm = ofile.filename;
 
     STEPWrapper *step = new STEPWrapper();
 

Modified: brlcad/branches/brep-debug/src/libanalyze/raydiff.c
===================================================================
--- brlcad/branches/brep-debug/src/libanalyze/raydiff.c 2015-06-16 19:37:48 UTC 
(rev 65333)
+++ brlcad/branches/brep-debug/src/libanalyze/raydiff.c 2015-06-16 19:53:24 UTC 
(rev 65334)
@@ -240,16 +240,16 @@
     VSET(mid, (max[0] + min[0])/2, (max[1] + min[1])/2, (max[2] + min[2])/2);
 
     BU_GET(xdata, struct rt_pattern_data);
-    VSET(xdata->center_pt, min[0] - 0.1 * min[0], mid[1], mid[2]);
+    VSET(xdata->center_pt, min[0] - 0.1 * fabs(min[0]), mid[1], mid[2]);
     VSET(xdata->center_dir, 1, 0, 0);
     xdata->vn = 2;
     xdata->pn = 2;
     xdata->n_vec = (vect_t *)bu_calloc(xdata->vn + 1, sizeof(vect_t), "vects 
array");
     xdata->n_p = (fastf_t *)bu_calloc(xdata->pn + 1, sizeof(fastf_t), "params 
array");
-    xdata->n_p[0] = 50; /* TODO - get tolerances from caller */
-    xdata->n_p[1] = 50;
-    VSET(xdata->n_vec[0], 0, max[1], 0);
-    VSET(xdata->n_vec[1], 0, 0, max[2]);
+    xdata->n_p[0] = tol->dist;
+    xdata->n_p[1] = tol->dist;
+    VSET(xdata->n_vec[0], 0, max[1] - mid[1], 0);
+    VSET(xdata->n_vec[1], 0, 0, max[2] - mid[2]);
     ret = rt_pattern(xdata, RT_PATTERN_RECT_ORTHOGRID);
     bu_free(xdata->n_vec, "x vec inputs");
     bu_free(xdata->n_p, "x p inputs");
@@ -257,32 +257,49 @@
 
 
     BU_GET(ydata, struct rt_pattern_data);
-    VSET(ydata->center_pt, mid[0], min[1] - 0.1 * min[1], mid[2]);
+    VSET(ydata->center_pt, mid[0], min[1] - 0.1 * fabs(min[1]), mid[2]);
     VSET(ydata->center_dir, 0, 1, 0);
     ydata->vn = 2;
     ydata->pn = 2;
     ydata->n_vec = (vect_t *)bu_calloc(ydata->vn + 1, sizeof(vect_t), "vects 
array");
     ydata->n_p = (fastf_t *)bu_calloc(ydata->pn + 1, sizeof(fastf_t), "params 
array");
-    ydata->n_p[0] = 50; /* TODO - get tolerances from caller */
-    ydata->n_p[1] = 50;
-    VSET(ydata->n_vec[0], max[0], 0, 0);
-    VSET(ydata->n_vec[1], 0, 0, max[2]);
+    ydata->n_p[0] = tol->dist;
+    ydata->n_p[1] = tol->dist;
+    VSET(ydata->n_vec[0], max[0] - mid[0], 0, 0);
+    VSET(ydata->n_vec[1], 0, 0, max[2] - mid[2]);
     ret = rt_pattern(ydata, RT_PATTERN_RECT_ORTHOGRID);
     bu_free(ydata->n_vec, "y vec inputs");
     bu_free(ydata->n_p, "y p inputs");
     if (ret < 0) return -1;
 
+#if 0
+    {
+       size_t i = 0;
+       FILE fp = fopen("ydata.plot3", "wb");
+       for (i=0; i <= ydata->ray_cnt; i++) {
+           point_t base;
+           vect_t dir;
+           point_t tip;
+           VSET(base, ydata->rays[6*i], ydata->rays[6*i+1], 
ydata->rays[6*i+2]);
+           VSET(dir, ydata->rays[6*i+3], ydata->rays[6*i+4], 
ydata->rays[6*i+5]);
+           VJOIN1(tip, base, 500, dir);
+           pdv_3line(fp, base, tip);
+       }
+       fclose(fp);
+    }
+#endif
+
     BU_GET(zdata, struct rt_pattern_data);
-    VSET(zdata->center_pt, mid[0], mid[1], min[2] - 0.1 * min[2]);
+    VSET(zdata->center_pt, mid[0], mid[1], min[2] - 0.1 * fabs(min[2]));
     VSET(zdata->center_dir, 0, 0, 1);
     zdata->vn = 2;
     zdata->pn = 2;
     zdata->n_vec = (vect_t *)bu_calloc(zdata->vn + 1, sizeof(vect_t), "vects 
array");
     zdata->n_p = (fastf_t *)bu_calloc(zdata->pn + 1, sizeof(fastf_t), "params 
array");
-    zdata->n_p[0] = 50; /* TODO - get tolerances from caller */
-    zdata->n_p[1] = 50;
-    VSET(zdata->n_vec[0], max[0], 0, 0);
-    VSET(zdata->n_vec[1], 0, max[1], 0);
+    zdata->n_p[0] = tol->dist;
+    zdata->n_p[1] = tol->dist;
+    VSET(zdata->n_vec[0], max[0] - mid[0], 0, 0);
+    VSET(zdata->n_vec[1], 0, max[1] - mid[1], 0);
     ret = rt_pattern(zdata, RT_PATTERN_RECT_ORTHOGRID);
     bu_free(zdata->n_vec, "x vec inputs");
     bu_free(zdata->n_p, "x p inputs");
@@ -324,7 +341,7 @@
 */
     {
        int i, j;
-       ncpus = 2;
+       /*ncpus = 2;*/
        state = (struct raydiff_container *)bu_calloc(ncpus+1, sizeof(struct 
raydiff_container), "resources");
        for (i = 0; i < ncpus+1; i++) {
            state[i].rtip = rtip;

Modified: brlcad/branches/brep-debug/src/libanalyze/tests/CMakeLists.txt
===================================================================
--- brlcad/branches/brep-debug/src/libanalyze/tests/CMakeLists.txt      
2015-06-16 19:37:48 UTC (rev 65333)
+++ brlcad/branches/brep-debug/src/libanalyze/tests/CMakeLists.txt      
2015-06-16 19:53:24 UTC (rev 65334)
@@ -1,6 +1,8 @@
 BRLCAD_ADDEXEC(tester_density density.c "libanalyze;libbu" NO_INSTALL)
 BRLCAD_ADDEXEC(tester_raydiff raydiff.c "libanalyze;libbu" NO_INSTALL)
 
+CMAKEFILES(raydiff.g)
+
 # Local Variables:
 # tab-width: 8
 # mode: cmake

Modified: brlcad/branches/brep-debug/src/libbu/opt.c
===================================================================
--- brlcad/branches/brep-debug/src/libbu/opt.c  2015-06-16 19:37:48 UTC (rev 
65333)
+++ brlcad/branches/brep-debug/src/libbu/opt.c  2015-06-16 19:53:24 UTC (rev 
65334)
@@ -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));
@@ -333,11 +299,12 @@
 
 
 int
-bu_opt_parse(const char ***unused, size_t sizeof_unused, struct bu_vls *msgs, 
int argc, const char **argv, struct bu_opt_desc *ds)
+bu_opt_parse(struct bu_vls *msgs, int argc, const char **argv, struct 
bu_opt_desc *ds)
 {
     int i = 0;
     int offset = 0;
     int ret_argc = 0;
+    struct bu_ptbl known_args = BU_PTBL_INIT_ZERO;
     struct bu_ptbl unknown_args = BU_PTBL_INIT_ZERO;
     if (!argv || !ds) return -1;
 
@@ -345,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;
@@ -394,99 +360,97 @@
            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*/
+       /* 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 - halting.\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;
-                       }
-                   }
-                   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 {
-               while (arg_cnt < desc->arg_cnt_max && i < argc && 
!can_be_opt(argv[i])) {
-                   i++;
-                   arg_cnt++;
-               }
-               if (arg_cnt < desc->arg_cnt_min) {
-                   if (msgs) bu_vls_printf(msgs, "Option %s requires at least 
%d arguments but only %d were found - halting.\n", argv[i-1], 
desc->arg_cnt_min, arg_cnt);
-                   return -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 - halting.\n", argv[i-1], eq_arg);
+               return -1;
+           }
        }
     }
 
-    /* Copy as many of the unknown args as we can fit into the provided argv 
array.
-     * Program must check return value to see if any were lost due to the 
provided
-     * array being too small. */
+    /* Rearrange argv so the unused options are ordered at the front of the 
array. */
     ret_argc = BU_PTBL_LEN(&unknown_args);
-    if (ret_argc > 0 && sizeof_unused > 0 && unused) {
+    if (ret_argc > 0) {
        int avc = 0;
-       int max_avc_cnt = (BU_PTBL_LEN(&unknown_args) < sizeof_unused) ? 
BU_PTBL_LEN(&unknown_args) : sizeof_unused;
-       for (avc = 0; avc < max_avc_cnt; avc++) {
-           (*unused)[avc] = (const char *)BU_PTBL_GET(&unknown_args, avc);
+       int akc = BU_PTBL_LEN(&known_args);
+       for (avc = 0; avc < ret_argc; avc++) {
+           argv[avc] = (const char *)BU_PTBL_GET(&unknown_args, avc);
        }
+       /* Put the option argv pointers at the end of the array, in case they
+        * are still needed for memory freeing by the caller */
+       for (avc = ret_argc; avc < akc + ret_argc; avc++) {
+           argv[avc] = (const char *)BU_PTBL_GET(&unknown_args, avc);
+       }
     }
     bu_ptbl_free(&unknown_args);
+    bu_ptbl_free(&known_args);
 
     return ret_argc;
 }
@@ -499,9 +463,7 @@
     char *endptr = NULL;
     int *int_set = (int *)set_var;
 
-    if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
-       return 0;
-    }
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "bu_opt_int");
 
     l = strtol(argv[0], &endptr, 0);
 
@@ -521,7 +483,7 @@
        i = (int)l;
     } else {
        /* Too big or too small, fail */
-       if (msg) bu_vls_printf(msg, "String specifies number too large for int 
data type: %l\n", l);
+       if (msg) bu_vls_printf(msg, "String specifies number too large for int 
data type: %ld\n", l);
        return -1;
     }
 
@@ -536,9 +498,7 @@
     char *endptr = NULL;
     long *long_set = (long *)set_var;
 
-    if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
-       return 0;
-    }
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "bu_opt_long");
 
     l = strtol(argv[0], &endptr, 0);
 
@@ -564,9 +524,7 @@
     fastf_t *f_set = (fastf_t *)set_var;
     char *endptr = NULL;
 
-    if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
-       return 0;
-    }
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "bu_opt_fastf_t");
 
     if (sizeof(fastf_t) == sizeof(float)) {
        f = strtof(argv[0], &endptr);
@@ -592,29 +550,29 @@
 }
 
 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;
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "bu_opt_str");
 
     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;
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "bu_opt_vls");
 
     if (s_set) {
-       int i = 0;
-       for (i = 0; i < argc - 1; i++) {
-           bu_vls_printf(s_set, "%s ", argv[i]);
+       if (bu_vls_strlen(s_set) > 0) {
+           bu_vls_printf(s_set, " %s", argv[0]);
+       } else {
+           bu_vls_printf(s_set, "%s", argv[0]);
        }
-       bu_vls_printf(s_set, "%s", argv[argc - 1]);
     }
     return 1;
 }
@@ -625,9 +583,7 @@
     int *b_set = (int *)set_var;
     int bool_val;
 
-    if (!argv || !argv[0] || strlen(argv[0]) == 0 || argc != 1 ) {
-       return 0;
-    }
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "bu_opt_bool");
 
     bool_val = bu_str_true(argv[0]);
 
@@ -640,12 +596,6 @@
     return 1;
 }
 
-
-
-
-
-
-
 /*
  * Local Variables:
  * mode: C

Modified: brlcad/branches/brep-debug/src/libbu/tests/opt.c
===================================================================
--- brlcad/branches/brep-debug/src/libbu/tests/opt.c    2015-06-16 19:37:48 UTC 
(rev 65333)
+++ brlcad/branches/brep-debug/src/libbu/tests/opt.c    2015-06-16 19:53:24 UTC 
(rev 65334)
@@ -67,6 +67,8 @@
 }
 
 #define EXPECT_SUCCESS_INT(_name, _var, _exp) { \
+    set_msg_str(&parse_msgs, ac, av); \
+    ret = bu_opt_parse(&parse_msgs, ac, av, d); \
     if (ret || _var != _exp) { \
        bu_vls_printf(&parse_msgs, "\nError - expected value \"%d\" and got 
value %d\n", _exp, _var); \
        val_ok = 0; \
@@ -76,19 +78,23 @@
 }
 
 #define EXPECT_SUCCESS_INT_UNKNOWN(_name, _var, _exp) { \
+    set_msg_str(&parse_msgs, ac, av); \
+    ret = bu_opt_parse(&parse_msgs, ac, av, d); \
     if (ret <= 0) { \
        bu_vls_printf(&parse_msgs, "\nError - extra args but none found.\n"); \
        val_ok = 0; \
     } else { \
-    if ( _var != _exp) { \
-       bu_vls_printf(&parse_msgs, "\nError - expected value \"%d\" and got 
value %d\n", _exp, _var); \
-       val_ok = 0; \
-    } else { \
-       bu_vls_printf(&parse_msgs, "  \nGot expected value: %s = %d\n", _name, 
_var); \
-    }} \
+       if ( _var != _exp) { \
+           bu_vls_printf(&parse_msgs, "\nError - expected value \"%d\" and got 
value %d\n", _exp, _var); \
+           val_ok = 0; \
+       } else { \
+           bu_vls_printf(&parse_msgs, "  \nGot expected value: %s = %d\n", 
_name, _var); \
+       }} \
 }
 
 #define EXPECT_FAILURE_INT_UNKNOWN(_name, _var, _exp) { \
+    set_msg_str(&parse_msgs, ac, av); \
+    ret = bu_opt_parse(&parse_msgs, ac, av, d); \
     if (ret <= 0 || _var == _exp) { \
        bu_vls_printf(&parse_msgs, "\nError - expected failure (%s) but no 
error returned\n", _name); \
        val_ok = 0; \
@@ -98,6 +104,8 @@
 }
 
 #define EXPECT_SUCCESS_FLOAT(_name, _var, _exp) { \
+    set_msg_str(&parse_msgs, ac, av); \
+    ret = bu_opt_parse(&parse_msgs, ac, av, d); \
     if (ret || !NEAR_EQUAL(_var, _exp, SMALL_FASTF)) { \
        bu_vls_printf(&parse_msgs, "\nError - expected value \"%f\" and got 
value %f\n", _exp, _var); \
        val_ok = 0; \
@@ -107,6 +115,8 @@
 }
 
 #define EXPECT_SUCCESS_STRING(_name, _var, _exp) { \
+    set_msg_str(&parse_msgs, ac, av); \
+    ret = bu_opt_parse(&parse_msgs, ac, av, d); \
     if (ret || !BU_STR_EQUAL(_var, _exp)) { \
        bu_vls_printf(&parse_msgs, "\nError - expected value \"%s\" and got 
value %s\n", _exp, _var); \
        val_ok = 0; \
@@ -116,29 +126,35 @@
 }
 
 #define EXPECT_SUCCESS_COLOR(_name, _color, _r, _g, _b) { \
+    set_msg_str(&parse_msgs, ac, av); \
+    ret = bu_opt_parse(&parse_msgs, ac, av, d); \
     if (ret || (!NEAR_EQUAL(_color.buc_rgb[0], _r, SMALL_FASTF) || 
!NEAR_EQUAL(_color.buc_rgb[1], _g, SMALL_FASTF) || 
!NEAR_EQUAL(_color.buc_rgb[2], _b, SMALL_FASTF))) { \
        bu_vls_printf(&parse_msgs, "\nError - expected value \"%d/%d/%d\" and 
got value %.0f/%.0f/%.0f\n", _r, _g, _b, _color.buc_rgb[0], _color.buc_rgb[1], 
_color.buc_rgb[2]); \
        val_ok = 0; \
     } else { \
-       bu_vls_printf(&parse_msgs, "  \nGot expected value: %s == 
%.0f/%.0f/%.0f)\n", _name,  _color.buc_rgb[0], _color.buc_rgb[1], 
_color.buc_rgb[2]); \
+       bu_vls_printf(&parse_msgs, "  \nGot expected value: %s == 
%.0f/%.0f/%.0f\n", _name,  _color.buc_rgb[0], _color.buc_rgb[1], 
_color.buc_rgb[2]); \
     } \
 }
 
 #define EXPECT_SUCCESS_COLOR_UNKNOWN(_name, _color, _r, _g, _b) { \
+    set_msg_str(&parse_msgs, ac, av); \
+    ret = bu_opt_parse(&parse_msgs, ac, av, d); \
     if (ret <= 0) { \
        bu_vls_printf(&parse_msgs, "\nError - extra args expected but not 
found\n"); \
        val_ok = 0; \
     } else { \
-    if ((!NEAR_EQUAL(_color.buc_rgb[0], _r, SMALL_FASTF) || 
!NEAR_EQUAL(_color.buc_rgb[1], _g, SMALL_FASTF) || 
!NEAR_EQUAL(_color.buc_rgb[2], _b, SMALL_FASTF))) { \
-       bu_vls_printf(&parse_msgs, "\nError - expected value \"%d/%d/%d\" and 
got value %.0f/%.0f/%.0f\n", _r, _g, _b, _color.buc_rgb[0], _color.buc_rgb[1], 
_color.buc_rgb[2]); \
-       val_ok = 0; \
-    } else { \
-       bu_vls_printf(&parse_msgs, "  \nGot expected value: %s == 
%.0f/%.0f/%.0f)\n", _name,  _color.buc_rgb[0], _color.buc_rgb[1], 
_color.buc_rgb[2]); \
-    }} \
+       if ((!NEAR_EQUAL(_color.buc_rgb[0], _r, SMALL_FASTF) || 
!NEAR_EQUAL(_color.buc_rgb[1], _g, SMALL_FASTF) || 
!NEAR_EQUAL(_color.buc_rgb[2], _b, SMALL_FASTF))) { \
+           bu_vls_printf(&parse_msgs, "\nError - expected value \"%d/%d/%d\" 
and got value %.0f/%.0f/%.0f\n", _r, _g, _b, _color.buc_rgb[0], 
_color.buc_rgb[1], _color.buc_rgb[2]); \
+           val_ok = 0; \
+       } else { \
+           bu_vls_printf(&parse_msgs, "  \nGot expected value: %s == 
%.0f/%.0f/%.0f\n", _name,  _color.buc_rgb[0], _color.buc_rgb[1], 
_color.buc_rgb[2]); \
+       }} \
 }
 
 
 #define EXPECT_FAILURE(_name, _reason) { \
+    set_msg_str(&parse_msgs, ac, av); \
+    ret = bu_opt_parse(&parse_msgs, ac, av, d); \
     if (!ret==-1) { \
        bu_vls_printf(&parse_msgs, "\nError - expected parser to fail with 
error and it didn't\n"); \
        val_ok = 0; \
@@ -160,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
     };
 
@@ -177,121 +193,91 @@
     int ret = -1;
     int containers = 6;
     const char **av;
-    const char **unknown;
     struct bu_vls parse_msgs = BU_VLS_INIT_ZERO;
 
     av = (const char **)bu_calloc(containers, sizeof(char *), "Input array");
-    unknown = (const char **)bu_calloc(containers, sizeof(char *), "unknown 
results");
 
     if (cgy[0] == 'v') {
        switch (test_num) {
            /* Verbosity option tests */
            case 0:
-               ret = bu_opt_parse(&unknown, 0, &parse_msgs, 0, NULL, d);
+               ret = bu_opt_parse(&parse_msgs, 0, NULL, d);
                ret = (ret == -1) ? 0 : -1;
                break;
            case 1:
                ac = 1;
                av[0] = "-v";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 1);
                break;
            case 2:
                ac = 1;
                av[0] = "-v1";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 1);
                break;
            case 3:
                ac = 2;
                av[0] = "-v";
                av[1] = "1";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 1);
                break;
            case 4:
                ac = 1;
                av[0] = "-v=1";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 1);
                break;
            case 5:
                ac = 2;
                av[0] = "--v";
                av[1] = "1";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 1);
                break;
            case 6:
                ac = 1;
                av[0] = "--v=1";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 1);
                break;
            case 7:
                ac = 2;
                av[0] = "-v";
                av[1] = "2";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 2);
                break;
            case 8:
                ac = 2;
                av[0] = "-v";
                av[1] = "4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("verbosity", "4 > 3");
                break;
            case 9:
                ac = 2;
                av[0] = "--verb";
                av[1] = "2";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 2);
                break;
            case 10:
                ac = 2;
                av[0] = "--verb";
                av[1] = "4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("verbosity", "4 > 3");
                break;
            case 11:
                ac = 1;
                av[0] = "--verb=2";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 2);
                break;
            case 12:
                ac = 1;
                av[0] = "--verb=4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("verbosity", "4 > 3");
                break;
            case 13:
                ac = 1;
                av[0] = "--v";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 1);
                break;
            case 14:
                ac = 1;
                av[0] = "--verb";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("verbosity", verbosity, 1);
                break;
            default:
@@ -305,73 +291,53 @@
            case 1:
                ac = 1;
                av[0] = "-h";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("print_help", print_help, 1);
                break;
            case 2:
                ac = 1;
                av[0] = "-?";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("print_help", print_help, 1);
                break;
            case 3:
                ac = 1;
                av[0] = "--help";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("print_help", print_help, 1);
                break;
            case 4:
                ac = 1;
                av[0] = "--help=4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("print_help", "extra arg");
                break;
            case 5:
                ac = 1;
                av[0] = "-?4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("print_help", "extra arg");
                break;
            case 6:
                ac = 2;
                av[0] = "-?";
                av[1] = "4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT_UNKNOWN("print_help", print_help, 1);
                break;
            case 7:
                ac = 1;
                av[0] = "-?=4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("print_help", "extra arg");
                break;
            case 8:
                ac = 1;
                av[0] = "--?4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE_INT_UNKNOWN("print_help", print_help, 1);
                break;
            case 9:
                ac = 2;
                av[0] = "--?";
                av[1] = "4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT_UNKNOWN("print_help", print_help, 1);
                break;
            case 10:
                ac = 1;
                av[0] = "--?=4";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("print_help", "extra arg");
                break;
            default:
@@ -386,32 +352,24 @@
                ac = 2;
                av[0] = "-b";
                av[1] = "true";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("bool", b, 1);
                break;
            case 2:
                ac = 2;
                av[0] = "-b";
                av[1] = "false";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("bool", b, 0);
                break;
            case 3:
                ac = 2;
                av[0] = "--bool";
                av[1] = "1";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("bool", b, 1);
                break;
            case 4:
                ac = 2;
                av[0] = "--bool";
                av[1] = "0";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("bool", b, 0);
                break;
            default:
@@ -425,16 +383,12 @@
            case 1:
                ac = 1;
                av[0] = "-s";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("string", "missing argument");
                break;
            case 2:
                ac = 2;
                av[0] = "-s";
                av[1] = "test_str";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_STRING("string", str, "test_str");
                break;
            default:
@@ -448,40 +402,30 @@
            case 1:
                ac = 1;
                av[0] = "-i";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("int_num", "missing arg");
                break;
            case 2:
                ac = 2;
                av[0] = "-i";
                av[1] = "-f";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("int_num", "invalid arg");
                break;
            case 3:
                ac = 2;
                av[0] = "-i";
                av[1] = "1";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("int_num", i, 1);
                break;
            case 4:
                ac = 2;
                av[0] = "-i";
                av[1] = "-1";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_INT("int_num", i, -1);
                break;
            case 5:
                ac = 2;
                av[0] = "-i";
                av[1] = "214748364700";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_FAILURE("int_num", "number too large for int container");
                break;
 
@@ -499,16 +443,12 @@
                    ac = 2;
                    av[0] = "-l";
                    av[1] = "214748364800";
-                   set_msg_str(&parse_msgs, ac, av);
-                   ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, 
av, d);
                    EXPECT_SUCCESS_INT("long_num", l, 214748364800);
                    break;
                case 2:
                    ac = 2;
                    av[0] = "-l";
                    av[1] = "-214748364800";
-                   set_msg_str(&parse_msgs, ac, av);
-                   ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, 
av, d);
                    EXPECT_SUCCESS_INT("long_num", l, -214748364800);
                    break;
                default:
@@ -522,16 +462,12 @@
                    ac = 2;
                    av[0] = "-l";
                    av[1] = "21474836";
-                   set_msg_str(&parse_msgs, ac, av);
-                   ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, 
av, d);
                    EXPECT_SUCCESS_INT("long_num", l, 21474836);
                    break;
                case 2:
                    ac = 2;
                    av[0] = "-l";
                    av[1] = "-21474836";
-                   set_msg_str(&parse_msgs, ac, av);
-                   ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, 
av, d);
                    EXPECT_SUCCESS_INT("long_num", l, -21474836);
                    break;
                default:
@@ -548,24 +484,18 @@
                ac = 2;
                av[0] = "-f";
                av[1] = "1.234";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_FLOAT("float_num", f, 1.234);
                break;
            case 2:
                ac = 2;
                av[0] = "-f";
                av[1] = "-1.234";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_FLOAT("float_num", f, -1.234);
                break;
            case 3:
                ac = 2;
                av[0] = "-f";
                av[1] = "-3.0e-3";
-               set_msg_str(&parse_msgs, ac, av);
-               ret = bu_opt_parse(&unknown, containers, &parse_msgs, ac, av, 
d);
                EXPECT_SUCCESS_FLOAT("float_num", f, -0.003);
                break;
            default:
@@ -578,9 +508,9 @@
        int u = 0;
        bu_vls_printf(&parse_msgs, "\nUnknown args: ");
        for (u = 0; u < ret - 1; u++) {
-           bu_vls_printf(&parse_msgs, "%s, ", unknown[u]);
+           bu_vls_printf(&parse_msgs, "%s, ", av[u]);
        }
-       bu_vls_printf(&parse_msgs, "%s\n", unknown[ret - 1]);
+       bu_vls_printf(&parse_msgs, "%s\n", av[ret - 1]);
     }
 
     ret = (!val_ok) ? -1 : 0;
@@ -590,7 +520,6 @@
     }
     bu_vls_free(&parse_msgs);
     bu_free(av, "free av");
-    bu_free(unknown, "free av");
     return ret;
 }
 
@@ -610,14 +539,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;
-    }
 
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "color");
+
     /* 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)) 
{
@@ -643,7 +571,7 @@
        return 1;
     }
 
-    return 0;
+    return -1;
 }
 
 int desc_2(int test_num)
@@ -655,28 +583,24 @@
     int containers = 7;
     int ac = 0;
     const char **av;
-    const char **unknown;
     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");

@@ Diff output truncated at 100000 characters. @@
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