Revision: 65121
          http://sourceforge.net/p/brlcad/code/65121
Author:   starseeker
Date:     2015-05-31 16:19:26 +0000 (Sun, 31 May 2015)
Log Message:
-----------
Get dynamic option handling working, and add a demonstration in gcv

Modified Paths:
--------------
    brlcad/trunk/include/bu/opt.h
    brlcad/trunk/src/conv/gcv/gcv.cpp
    brlcad/trunk/src/libbu/opt.c

Modified: brlcad/trunk/include/bu/opt.h
===================================================================
--- brlcad/trunk/include/bu/opt.h       2015-05-30 19:42:02 UTC (rev 65120)
+++ brlcad/trunk/include/bu/opt.h       2015-05-31 16:19:26 UTC (rev 65121)
@@ -51,6 +51,8 @@
  */
 typedef int (*bu_opt_arg_process_t)(struct bu_vls *, struct bu_opt_data *);
 
+typedef struct bu_ptbl bu_opt_dtbl_t;
+
 /**
  * "Option description" structure
  */
@@ -67,20 +69,30 @@
 };
 #define BU_OPT_DESC_NULL {-1, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL}
 
-/** Set the values in a struct bu_opt_desc */
-BU_EXPORT extern void bu_opt_desc_add(struct bu_ptbl *dtbl, int ind,
+/**
+ * Initialize a bu_opt_desc ptbl.  If ds is not NULL, populate the table
+ * with the bu_opt_desc structs in the ds array. */
+BU_EXPORT extern void bu_opt_desc_init(bu_opt_dtbl_t **dtbl, struct 
bu_opt_desc *ds);
+
+/**
+ * Add an option description to a bu_opt_desc ptbl */
+BU_EXPORT extern void bu_opt_desc_add(bu_opt_dtbl_t *dtbl, int ind,
        size_t min, size_t max, const char *shortopt,
        const char *longopt, bu_opt_arg_process_t arg_process,
        const char *shortopt_doc, const char *longopt_doc, const char 
*help_str);
-
-BU_EXPORT extern void bu_opt_desc_del(struct bu_ptbl *dtbl, int ind);
-BU_EXPORT extern void bu_opt_desc_del_name(struct bu_ptbl *dtbl, const char 
*name);
 /**
+ * Remove option descriptions with index matching key from a bu_opt_desc ptbl 
*/
+BU_EXPORT extern void bu_opt_desc_del(bu_opt_dtbl_t *dtbl, int key);
+/**
+ * Remove option descriptions with either a shortopt or a longopt matching name
+ * from a bu_opt_desc ptbl */
+BU_EXPORT extern void bu_opt_desc_del_name(bu_opt_dtbl_t *dtbl, const char 
*name);
+/**
  *  If bu_opt_desc instances aren't part of static arrays, they'll
  *  be inside a table.  This function frees them, but does not free
  *  the bu_ptbl container.
  */
-BU_EXPORT extern void bu_opt_desc_free(struct bu_ptbl *tbl);
+BU_EXPORT extern void bu_opt_desc_free(bu_opt_dtbl_t *tbl);
 
 
 /**
@@ -176,19 +188,19 @@
  *
  *  enum d1_opt_ind {D1_HELP, D1_VERBOSITY};
  *  struct bu_ptbl dtbl;
- *  BU_OPT_DESC_PTBL_INIT(4, &dtbl);
- *  bu_opt_desc_set(BU_OPT_DESC_GET_PTBL(0), D1_HELP, 0, 0, "h", "help", NULL, 
help_str);
- *  bu_opt_desc_set(BU_OPT_DESC_GET_PTBL(1), D1_HELP, 0, 0, "?", "", NULL, 
help_str);
- *  bu_opt_desc_set(BU_OPT_DESC_GET_PTBL(2), D1_VERBOSITY, 0, 1, "v", 
"verbosity", &(dtbl_verbosity), "Set verbosity");
+ *  bu_opt_desc_init(&dtbl, NULL);
+ *  bu_opt_desc_add(D1_HELP, 0, 0, "h", "help",    NULL,      "-h", "--help",  
  "Help");
+ *  bu_opt_desc_add(D1_HELP, 0, 0, "?", "",        NULL,      "-?", "",        
  "");
+ *  bu_opt_desc_add(D1_O1,   0, 1, "v", "verbose", &(dtbl_v), "-v", 
"--verbose", "Set verbosity");
  *  bu_opt_parse_ptbl(argc, argv, dtbl);
  */
-BU_EXPORT extern int bu_opt_parse_dtbl(struct bu_ptbl **tbl, struct bu_vls 
*msgs, int ac, const char **argv, struct bu_ptbl *dtbl);
+BU_EXPORT extern int bu_opt_parse_dtbl(struct bu_ptbl **tbl, struct bu_vls 
*msgs, int ac, const char **argv, bu_opt_dtbl_t *dtbl);
 
 /**
  * Option parse an argv array defined as a space separated string.  This
  * is a convenience function that calls bu_opt_parse_dtbl and also handles
  * breaking str down into a proper argv array. */
-BU_EXPORT extern int bu_opt_parse_str_dtbl(struct bu_ptbl **tbl, struct bu_vls 
*msgs, const char *str, struct bu_ptbl *dtbl);
+BU_EXPORT extern int bu_opt_parse_str_dtbl(struct bu_ptbl **tbl, struct bu_vls 
*msgs, const char *str, bu_opt_dtbl_t *dtbl);
 
 /**
  * In situations where multiple options are present, the general rule is that
@@ -292,7 +304,7 @@
 };
 
 BU_EXPORT extern const char *bu_opt_describe(struct bu_opt_desc *ds, struct 
bu_opt_desc_opts *settings);
-BU_EXPORT extern const char *bu_opt_describe_tbl(struct bu_ptbl *dtbl, struct 
bu_opt_desc_opts *settings);
+BU_EXPORT extern const char *bu_opt_describe_dtbl(bu_opt_dtbl_t *dtbl, struct 
bu_opt_desc_opts *settings);
 
 
 

Modified: brlcad/trunk/src/conv/gcv/gcv.cpp
===================================================================
--- brlcad/trunk/src/conv/gcv/gcv.cpp   2015-05-30 19:42:02 UTC (rev 65120)
+++ brlcad/trunk/src/conv/gcv/gcv.cpp   2015-05-31 16:19:26 UTC (rev 65121)
@@ -266,7 +266,7 @@
 
 
 #define gcv_help_str "Print help and exit.  If a format is specified to 
--help, print help specific to that format"
-enum gcv_opt_enums { GCV_HELP, IN_FILE, OUT_FILE, IN_FORMAT, OUT_FORMAT, 
IN_OPTS, OUT_OPTS };
+enum gcv_opt_enums { GCV_HELP, IN_FILE, OUT_FILE, IN_FORMAT, OUT_FORMAT, 
IN_OPTS, OUT_OPTS, GCV_OPTS_MAX };
 struct bu_opt_desc gcv_opt_desc[9] = {
     {GCV_HELP,    0, 1, "h", "help",             NULL,          "-h [format]", 
"--help [format]",             gcv_help_str},
     {GCV_HELP,    0, 1, "?", "",                 NULL,          "-? [format]", 
"",                            ""},
@@ -286,6 +286,7 @@
     size_t i;
     int fmt = 0;
     int ret = 0;
+    bu_opt_dtbl_t *top_opt_desc;
     const char *in_fmt = NULL;
     const char *out_fmt = NULL;
     mime_model_t in_type = MIME_MODEL_UNKNOWN;
@@ -305,15 +306,20 @@
 
     ac-=(ac>0); av+=(ac>0); // skip program name argv[0] if present
 
+    bu_opt_desc_init(&top_opt_desc, (struct bu_opt_desc *)&gcv_opt_desc);
+
     if (ac == 0) {
-       const char *help = bu_opt_describe(gcv_opt_desc, NULL);
+       const char *help = bu_opt_describe_dtbl(top_opt_desc, NULL);
        bu_log("%s\n", help);
-       bu_free((char *)help, "help str");
+       if (help) bu_free((char *)help, "help str");
        // TODO - print some help
        goto cleanup;
     }
 
+    /*
     (void)bu_opt_parse(&results, NULL, ac, (const char **)av, gcv_opt_desc);
+    */
+    (void)bu_opt_parse_dtbl(&results, NULL, ac, (const char **)av, 
top_opt_desc);
     bu_opt_compact(results);
 
     /* First, see if help was supplied */
@@ -324,7 +330,49 @@
            // TODO - generate some help based on format
        } else {
            // TODO - generate some generic gcv help
+           { /* Test static help print  */
+               bu_log("Static help printing:\n");
+               const char *help = bu_opt_describe(gcv_opt_desc, NULL);
+               bu_log("%s\n", help);
+               if (help) bu_free((char *)help, "help str");
+           }
 
+           { /* Test help print before dynamic opts */
+               bu_log("Dynamic help printing:\n");
+               const char *help = bu_opt_describe_dtbl(top_opt_desc, NULL);
+               bu_log("%s\n", help);
+               if (help) bu_free((char *)help, "help str");
+           }
+
+           /* Simulate a plug-in adding a new option to the toplevel options */
+
+           bu_opt_desc_add(top_opt_desc, BU_PTBL_LEN(top_opt_desc) + 1, 0, 1, 
"", "decimate", NULL, "", "--decimate [algorithm]",
+                   "Decimate output triangles.  If an algorithm is supplied 
use it, otherwise use FOO");
+
+           int parallel_key = BU_PTBL_LEN(top_opt_desc) + 1;
+           bu_opt_desc_add(top_opt_desc, parallel_key, 0, 0, "p", "parallel", 
NULL, "-p", "--parallel", "Enable parallel processing");
+           bu_opt_desc_add(top_opt_desc, parallel_key, 0, 0, "P", "", NULL, 
"-P", "", "");
+
+           { /* Test help print with dynamic opts added */
+               bu_log("Dynamic help printing with added opts:\n");
+               const char *help = bu_opt_describe_dtbl(top_opt_desc, NULL);
+               bu_log("%s\n", help);
+               if (help) bu_free((char *)help, "help str");
+           }
+
+           bu_opt_desc_del(top_opt_desc, IN_OPTS);
+           bu_opt_desc_del(top_opt_desc, OUT_OPTS);
+           bu_opt_desc_del_name(top_opt_desc, "P");
+
+           { /* Test help print with dynamic opts removed */
+               bu_log("Dynamic help printing with removed opts:\n");
+               const char *help = bu_opt_describe_dtbl(top_opt_desc, NULL);
+               bu_log("%s\n", help);
+               if (help) bu_free((char *)help, "help str");
+           }
+
+#if 0
+
            // TODO - figure out how to get this info from each plugin to 
construct this table
            // on the fly...
            bu_log("\nSupported formats:\n");
@@ -340,7 +388,7 @@
            bu_log(" |    iges    |   Initial Graphics        |   Yes  |   No   
|\n");
            bu_log(" |            |   Exchange Specification  |        |        
|\n");
            bu_log(" 
|----------------------------------------------------------|\n");
-
+#endif
        }
        goto cleanup;
     }
@@ -516,6 +564,7 @@
     bu_vls_free(&input_opts);
     bu_vls_free(&output_opts);
     bu_opt_data_free_tbl(results);
+    if (top_opt_desc) bu_opt_desc_free(top_opt_desc);
 
     return ret;
 }

Modified: brlcad/trunk/src/libbu/opt.c
===================================================================
--- brlcad/trunk/src/libbu/opt.c        2015-05-30 19:42:02 UTC (rev 65120)
+++ brlcad/trunk/src/libbu/opt.c        2015-05-31 16:19:26 UTC (rev 65121)
@@ -483,8 +483,56 @@
 }
 
 void
-bu_opt_desc_init(struct bu_opt_desc *d)
+bu_opt_data_print(const char *title, struct bu_ptbl *data)
 {
+    size_t i = 0;
+    size_t j = 0;
+    int offset_1 = 3;
+    struct bu_vls log = BU_VLS_INIT_ZERO;
+    if (!data || BU_PTBL_LEN(data) == 0) return;
+    if (title) {
+       bu_vls_sprintf(&log, "%s\n", title);
+    } else {
+       bu_vls_sprintf(&log, "Options:\n");
+    }
+    for (i = 0; i < BU_PTBL_LEN(data); i++) {
+       struct bu_opt_data *d = (struct bu_opt_data *)BU_PTBL_GET(data, i);
+       if (d->name) {
+           bu_vls_printf(&log, "%*s%s", offset_1, " ", d->name);
+           if (d->valid) {
+               bu_vls_printf(&log, "\t(valid)");
+           } else {
+               bu_vls_printf(&log, "\t(invalid)");
+           }
+           if (d->desc && d->desc->arg_cnt_max > 0) {
+               if (d->args && BU_PTBL_LEN(d->args) > 0) {
+                   bu_vls_printf(&log, ": ");
+                   for (j = 0; j < BU_PTBL_LEN(d->args) - 1; j++) {
+                       bu_vls_printf(&log, "%s, ", bu_opt_data_arg(d, j));
+                   }
+                   bu_vls_printf(&log, "%s\n", bu_opt_data_arg(d, 
BU_PTBL_LEN(d->args) - 1));
+               }
+           } else {
+               bu_vls_printf(&log, "\n");
+           }
+       } else {
+           bu_vls_printf(&log, "%*s(unknown): ", offset_1, " ", d->name);
+           if (d->args && BU_PTBL_LEN(d->args) > 0) {
+               for (j = 0; j < BU_PTBL_LEN(d->args) - 1; j++) {
+                   bu_vls_printf(&log, "%s ", bu_opt_data_arg(d, j));
+               }
+               bu_vls_printf(&log, "%s\n", bu_opt_data_arg(d, 
BU_PTBL_LEN(d->args) - 1));
+           }
+       }
+    }
+    bu_log("%s", bu_vls_addr(&log));
+    bu_vls_free(&log);
+}
+
+
+HIDDEN void
+bu_opt_desc_init_entry(struct bu_opt_desc *d)
+{
     if (!d) return;
     d->index = -1;
     d->arg_cnt_min = 0;
@@ -497,7 +545,7 @@
     d->help_string = NULL;
 }
 
-void
+HIDDEN void
 bu_opt_desc_set(struct bu_opt_desc *d, int ind,
        size_t min, size_t max, const char *shortopt,
        const char *longopt, bu_opt_arg_process_t arg_process,
@@ -507,12 +555,12 @@
     d->index = ind;
     d->arg_cnt_min = min;
     d->arg_cnt_max = max;
-    d->shortopt = shortopt;
-    d->longopt = longopt;
+    d->shortopt = (shortopt) ? bu_strdup(shortopt) : NULL;
+    d->longopt = (longopt) ? bu_strdup(longopt) : NULL;
     d->arg_process = arg_process;
-    d->shortopt_doc= shortopt_doc;
-    d->longopt_doc = longopt_doc;
-    d->help_string = help_str;
+    d->shortopt_doc = (shortopt_doc) ? bu_strdup(shortopt_doc) : NULL;
+    d->longopt_doc = (longopt_doc) ? bu_strdup(longopt_doc) : NULL;
+    d->help_string = (help_str) ? bu_strdup(help_str) : NULL;;
 }
 
 HIDDEN void
@@ -525,10 +573,97 @@
     if (d->longopt_doc) bu_free((char *)d->longopt_doc, "longopt_doc");
     if (d->help_string) bu_free((char *)d->help_string, "help_string");
 }
+void
+bu_opt_desc_init(bu_opt_dtbl_t **dtbl, struct bu_opt_desc *ds)
+{
+    size_t i;
+    size_t array_cnt = 0;
+    struct bu_opt_desc *cd;
+    struct bu_ptbl *tbl;
+    if (!dtbl) return;
+    BU_GET(tbl, struct bu_ptbl);
+    if (!(!ds || ds[0].index == -1)) {
+       while (ds[array_cnt].index != -1) array_cnt++;
+       bu_ptbl_init(tbl, array_cnt + 1, "new ptbl");
+       for (i = 0; i < array_cnt; i++) {
+           struct bu_opt_desc *d = &(ds[i]);
+           BU_GET(cd, struct bu_opt_desc);
+           bu_opt_desc_init_entry(cd);
+           bu_opt_desc_set(cd, d->index, d->arg_cnt_min, d->arg_cnt_max,
+                   d->shortopt, d->longopt, d->arg_process,
+                   d->shortopt_doc, d->longopt_doc,
+                   d->help_string);
+           bu_ptbl_ins(tbl, (long *)cd);
+       }
+    } else {
+       bu_ptbl_init(tbl, 8, "new ptbl");
+    }
+    BU_GET(cd, struct bu_opt_desc);
+    bu_opt_desc_init_entry(cd);
+    bu_ptbl_ins(tbl, (long *)cd);
+    (*dtbl) = tbl;
+}
 
 void
-bu_opt_desc_free(struct bu_ptbl *tbl)
+bu_opt_desc_add(bu_opt_dtbl_t *tbl, int ind, size_t min, size_t max, const 
char *shortopt,
+       const char *longopt, bu_opt_arg_process_t arg_process,
+       const char *shortopt_doc, const char *longopt_doc, const char *help_str)
 {
+    struct bu_opt_desc *d;
+    long *dn;
+    if (!tbl || (!shortopt && !longopt)) return;
+    dn = BU_PTBL_GET(tbl, BU_PTBL_LEN(tbl) - 1);
+    bu_ptbl_rm(tbl, dn);
+    BU_GET(d, struct bu_opt_desc);
+    bu_opt_desc_init_entry(d);
+    bu_opt_desc_set(d, ind, min, max, shortopt,
+           longopt, arg_process, shortopt_doc,
+           longopt_doc, help_str);
+    bu_ptbl_ins(tbl, (long *)d);
+    bu_ptbl_ins(tbl, dn);
+}
+
+void
+bu_opt_desc_del(bu_opt_dtbl_t *tbl, int key)
+{
+    size_t i = 0;
+    struct bu_ptbl tmp_tbl;
+    if (!tbl || key < 0) return;
+    bu_ptbl_init(&tmp_tbl, 64, "tmp tbl");
+    for (i = 0; i < BU_PTBL_LEN(tbl) - 1; i++) {
+       struct bu_opt_desc *d = (struct bu_opt_desc *)BU_PTBL_GET(tbl, i);
+       if (d->index == key) {
+           bu_ptbl_ins(&tmp_tbl, (long *)d);
+       }
+    }
+    for (i = 0; i < BU_PTBL_LEN(&tmp_tbl); i++) {
+       bu_ptbl_rm(tbl, BU_PTBL_GET(&tmp_tbl, i));
+    }
+    bu_ptbl_free(&tmp_tbl);
+}
+
+void
+bu_opt_desc_del_name(bu_opt_dtbl_t *tbl, const char *name)
+{
+    size_t i = 0;
+    struct bu_ptbl tmp_tbl;
+    if (!tbl || !name) return;
+    bu_ptbl_init(&tmp_tbl, 64, "tmp tbl");
+    for (i = 0; i < BU_PTBL_LEN(tbl) - 1; i++) {
+       struct bu_opt_desc *d = (struct bu_opt_desc *)BU_PTBL_GET(tbl, i);
+       if (BU_STR_EQUAL(d->shortopt, name) || BU_STR_EQUAL(d->longopt, name)) {
+           bu_ptbl_ins(&tmp_tbl, (long *)d);
+       }
+    }
+    for (i = 0; i < BU_PTBL_LEN(&tmp_tbl); i++) {
+       bu_ptbl_rm(tbl, BU_PTBL_GET(&tmp_tbl, i));
+    }
+    bu_ptbl_free(&tmp_tbl);
+}
+
+void
+bu_opt_desc_free(bu_opt_dtbl_t *tbl)
+{
     size_t i;
     if (!tbl) return;
     for (i = 0; i < BU_PTBL_LEN(tbl); i++) {
@@ -573,7 +708,7 @@
 }
 
 HIDDEN const char *
-bu_opt_describe(struct bu_opt_desc *ds, struct bu_opt_desc_opts *settings)
+bu_opt_describe_internal_ascii(struct bu_opt_desc *ds, bu_opt_dtbl_t *tbl, 
struct bu_opt_desc_opts *settings)
 {
     size_t i = 0;
     size_t j = 0;
@@ -588,7 +723,7 @@
     const char *finalized;
     struct bu_vls description = BU_VLS_INIT_ZERO;
     int *status;
-    if (!ds || ds[0].index == -1) return NULL;
+    if (((!ds || ds[0].index == -1) && !tbl) || (ds && tbl)) return NULL;
 
     if (settings) {
        offset = settings->offset;
@@ -596,12 +731,20 @@
        desc_cols = settings->description_columns;
     }
 
-    while (ds[i].index != -1) i++;
+    if (ds) {
+       while (ds[i].index != -1) i++;
+    } else {
+       int tbl_len = BU_PTBL_LEN(tbl) - 1;
+       i = (tbl_len < 0) ? 0 : tbl_len;
+    }
+    if (i == 0) return NULL;
     opt_cnt = i;
     status = (int *)bu_calloc(opt_cnt, sizeof(int), "opt status");
     i = 0;
     while (i < opt_cnt) {
-       struct bu_opt_desc *curr = &(ds[i]);
+       struct bu_opt_desc *curr;
+       struct bu_opt_desc *d;
+       curr = (ds) ? &(ds[i]) : (struct bu_opt_desc *)BU_PTBL_GET(tbl, i) ;
        if (!status[i]) {
            struct bu_vls opts = BU_VLS_INIT_ZERO;
            struct bu_vls help_str = BU_VLS_INIT_ZERO;
@@ -610,7 +753,7 @@
             * pass, so set the status flags accordingly */
            j = i;
            while (j < opt_cnt) {
-               struct bu_opt_desc *d = &(ds[j]);
+               d = (ds) ? &(ds[j]) : (struct bu_opt_desc *)BU_PTBL_GET(tbl, j);
                if (d->index == curr->index) {
                    status[j] = 1;
                }
@@ -621,7 +764,7 @@
             * the same index defining aliases, so accumulate all of them. */
            j = i;
            while (j < opt_cnt) {
-               struct bu_opt_desc *d = &(ds[j]);
+               d = (ds) ? &(ds[j]) : (struct bu_opt_desc *)BU_PTBL_GET(tbl, j);
                if (d->index == curr->index) {
                    int new_len = strlen(d->shortopt_doc);
                    if (new_len > 0) {
@@ -642,7 +785,7 @@
            /* Now do the long opts */
            j = i;
            while (j < opt_cnt) {
-               struct bu_opt_desc *d = &(ds[j]);
+               d = (ds) ? &(ds[j]) : (struct bu_opt_desc *)BU_PTBL_GET(tbl, j);
                if (d->index == curr->index) {
                    int new_len = strlen(d->longopt_doc);
                    if (new_len > 0) {
@@ -679,54 +822,24 @@
     return finalized;
 }
 
-void
-bu_opt_data_print(const char *title, struct bu_ptbl *data)
+const char *
+bu_opt_describe(struct bu_opt_desc *ds, struct bu_opt_desc_opts *settings)
 {
-    size_t i = 0;
-    size_t j = 0;
-    int offset_1 = 3;
-    struct bu_vls log = BU_VLS_INIT_ZERO;
-    if (!data || BU_PTBL_LEN(data) == 0) return;
-    if (title) {
-       bu_vls_sprintf(&log, "%s\n", title);
-    } else {
-       bu_vls_sprintf(&log, "Options:\n");
-    }
-    for (i = 0; i < BU_PTBL_LEN(data); i++) {
-       struct bu_opt_data *d = (struct bu_opt_data *)BU_PTBL_GET(data, i);
-       if (d->name) {
-           bu_vls_printf(&log, "%*s%s", offset_1, " ", d->name);
-           if (d->valid) {
-               bu_vls_printf(&log, "\t(valid)");
-           } else {
-               bu_vls_printf(&log, "\t(invalid)");
-           }
-           if (d->desc && d->desc->arg_cnt_max > 0) {
-               if (d->args && BU_PTBL_LEN(d->args) > 0) {
-                   bu_vls_printf(&log, ": ");
-                   for (j = 0; j < BU_PTBL_LEN(d->args) - 1; j++) {
-                       bu_vls_printf(&log, "%s, ", bu_opt_data_arg(d, j));
-                   }
-                   bu_vls_printf(&log, "%s\n", bu_opt_data_arg(d, 
BU_PTBL_LEN(d->args) - 1));
-               }
-           } else {
-               bu_vls_printf(&log, "\n");
-           }
-       } else {
-           bu_vls_printf(&log, "%*s(unknown): ", offset_1, " ", d->name);
-           if (d->args && BU_PTBL_LEN(d->args) > 0) {
-               for (j = 0; j < BU_PTBL_LEN(d->args) - 1; j++) {
-                   bu_vls_printf(&log, "%s ", bu_opt_data_arg(d, j));
-               }
-               bu_vls_printf(&log, "%s\n", bu_opt_data_arg(d, 
BU_PTBL_LEN(d->args) - 1));
-           }
-       }
-    }
-    bu_log("%s", bu_vls_addr(&log));
-    bu_vls_free(&log);
+    if (!ds) return NULL;
+    if (!settings) return bu_opt_describe_internal_ascii(ds, NULL, NULL);
+    return NULL;
 }
 
+const char *
+bu_opt_describe_dtbl(bu_opt_dtbl_t *dtbl, struct bu_opt_desc_opts *settings)
+{
+    if (!dtbl) return NULL;
+    if (!settings) return bu_opt_describe_internal_ascii(NULL, dtbl, NULL);
+    return NULL;
+}
 
+
+
 /*
  * Local Variables:
  * mode: C

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