Revision: 45731
          http://brlcad.svn.sourceforge.net/brlcad/?rev=45731&view=rev
Author:   bhinesley
Date:     2011-07-29 09:33:17 +0000 (Fri, 29 Jul 2011)

Log Message:
-----------
Updated several helper functions to work with a recent change from automatic 
arguments in union edit_cmd to pointers. Added command-specific functions to 
initialize the needed argument pointers. Fixed a problem with the help 
subsystem, and eliminated a bit of redundancy. More edit() testing, but not a 
whole heck of lot of foreward progress yet.

Modified Paths:
--------------
    brlcad/trunk/src/libged/edit.c

Modified: brlcad/trunk/src/libged/edit.c
===================================================================
--- brlcad/trunk/src/libged/edit.c      2011-07-29 01:08:44 UTC (rev 45730)
+++ brlcad/trunk/src/libged/edit.c      2011-07-29 09:33:17 UTC (rev 45731)
@@ -910,16 +910,18 @@
 /**
  * Command specific information, for a table of available commands.
  */
+typedef void (*init_handler)(union edit_cmd *const cmd);
 typedef int (*exec_handler)(struct ged *gedp, const union edit_cmd *const cmd);
 typedef int (*add_args_handler)(struct ged *gedp, union edit_cmd *const cmd,
                                struct edit_arg *args, const int flags);
 typedef struct edit_arg * (*get_next_arg_head_handler)(
-       union edit_cmd *const cmd, struct edit_arg *prev_arg_head);
+       const union edit_cmd *const cmd);
 struct edit_cmd_tab {
     char *name;
     char *opt_global;
     char *usage;
     char *help;
+    init_handler init;
     exec_handler exec;
     add_args_handler add_args;
     get_next_arg_head_handler get_next_arg_head;
@@ -1027,35 +1029,32 @@
  * Free any dynamically allocated arg that may exist
  */
 HIDDEN void
-edit_cmd_free(union edit_cmd *const args)
+edit_cmd_free(union edit_cmd *const subcmd)
 {
-    /* first object is automatic */
-    if (args->common.objects->next)
-       edit_arg_free_all(args->common.objects->next);
+    struct edit_arg *cur_arg_head = subcmd->common.objects;
+    struct edit_arg *prev_arg_head = cur_arg_head;
+    while (prev_arg_head) {
+       cur_arg_head = subcmd->cmd->get_next_arg_head(subcmd);
+       edit_arg_free_all(prev_arg_head);
+       prev_arg_head = cur_arg_head;
+    }
 }
 
-
 /**
  * Provide an array of arguments and the current argument,
  * and this function will return the next argument. Returns
- * the same argument that you passed in if there are no more argument
- * heads left, or NULL if there was no match.
+ * the NULL if there are no more argument heads left.
  */
 HIDDEN struct edit_arg *
-edit_cmd_get_next_arg_head(struct edit_arg *arg_heads[],
-                          struct edit_arg *prev_arg_head)
+edit_cmd_get_next_arg_head(struct edit_arg *const arg_heads[],
+                          const int len, int *const idx)
 {
-    int i;
-    for (i = 0; arg_heads[i]; ++i) {
-       if (arg_heads[i] == prev_arg_head)
-           break;
+    if ((*idx + 1) >= len) {
+       *idx = 0;
+       return (struct edit_arg *)NULL;
     }
-    if (!arg_heads[i])
-       return (struct edit_arg *)NULL;
-    ++i;
-    if (!arg_heads[i])
-       return prev_arg_head;
-    return arg_heads[i];
+    ++(*idx);
+    return arg_heads[*idx];
 }
 
 /* 
@@ -1069,11 +1068,12 @@
  * To add a new command, so far, you need to:
  *     1) add a struct to the union edit_cmd
  *     2) add command data/function pointers to the command table
- *     3) create 4 functions that
- *             a) add args to build the command
- *             b) get the next arg head in union edit_cmd
- *             c) perform the command
- *             d) wrap the command, to alternatively accept a union
+ *     3) create 5 functions that
+ *             a) initialize the command's struct in union edit_cmd
+ *             b) add args to build the command
+ *             c) get the next arg head in union edit_cmd
+ *             d) perform the command
+ *             e) wrap the command, to alternatively accept a union
  *                edit_cmd
  *
  */
@@ -1099,6 +1099,21 @@
 }
 
 /**
+ * Initialize command argument-pointer members to NULL.
+ */
+HIDDEN void
+edit_rotate_init(union edit_cmd *const subcmd)
+{
+    subcmd->rotate.objects =
+    subcmd->rotate.center =
+    subcmd->rotate.ref_angle.from =
+    subcmd->rotate.ref_angle.to =
+    subcmd->rotate.ref_axis.from =
+    subcmd->rotate.ref_axis.to =
+    (struct edit_arg *)NULL;
+}
+
+/**
  * Maps edit_arg fields to the subcommand function's arguments and
  * calls it.  Provides an common interface, so that all subcommands
  * can use the same function pointer type. Ignores all edit_arg fields
@@ -1145,9 +1160,11 @@
  * FIXME: Kind of dirty; haven't found a better way yet, though.
  */
 struct edit_arg *
-edit_rotate_get_next_arg_head(union edit_cmd *const cmd, struct edit_arg 
*prev_arg_head)
+edit_rotate_get_next_arg_head(const union edit_cmd *const cmd)
 {
-    struct edit_arg *arg_heads[8];
+    static int idx = 0;
+    const int len = 8;
+    struct edit_arg *arg_heads[len];
 
     arg_heads[0] = cmd->rotate.objects;
     arg_heads[1] = cmd->rotate.ref_axis.from;
@@ -1158,7 +1175,7 @@
     arg_heads[6] = cmd->rotate.ref_angle.to;
     arg_heads[7] = (struct edit_arg *)NULL;
 
-    return edit_cmd_get_next_arg_head(arg_heads, prev_arg_head);
+    return edit_cmd_get_next_arg_head(arg_heads, len, &idx);
 }
 
 /**
@@ -1179,6 +1196,18 @@
     return GED_OK;
 }
 
+HIDDEN void
+edit_scale_init(union edit_cmd *const subcmd)
+{
+    subcmd->scale.objects =
+    subcmd->scale.center =
+    subcmd->scale.ref_factor.from =
+    subcmd->scale.ref_factor.to =
+    subcmd->scale.ref_scale.from =
+    subcmd->scale.ref_scale.to =
+    (struct edit_arg *)NULL;
+}
+
 /**
  * Maps edit_arg fields to the subcommand function's arguments and
  * calls it.  Provides an common interface, so that all subcommands
@@ -1210,9 +1239,11 @@
 }
 
 struct edit_arg *
-edit_scale_get_next_arg_head(union edit_cmd *const cmd, struct edit_arg 
*prev_arg_head)
+edit_scale_get_next_arg_head(const union edit_cmd *const cmd)
 {
-    struct edit_arg *arg_heads[7];
+    static int idx = 0;
+    const int len = 7;
+    struct edit_arg *arg_heads[len];
 
     arg_heads[0] = cmd->scale.objects;
     arg_heads[1] = cmd->scale.ref_scale.from;
@@ -1222,7 +1253,7 @@
     arg_heads[5] = cmd->scale.ref_factor.to;
     arg_heads[6] = (struct edit_arg *)NULL;
 
-    return edit_cmd_get_next_arg_head(arg_heads, prev_arg_head);
+    return edit_cmd_get_next_arg_head(arg_heads, len, &idx);
 }
 
 /**
@@ -1239,6 +1270,15 @@
     return GED_OK;
 }
 
+HIDDEN void
+edit_translate_init(union edit_cmd *const subcmd)
+{
+    subcmd->translate.objects =
+    subcmd->translate.ref_vector.from =
+    subcmd->translate.ref_vector.to =
+    (struct edit_arg *)NULL;
+}
+
 /**
  * Maps edit_arg fields to the subcommand function's arguments and
  * calls it.  Provides an common interface, so that all subcommands
@@ -1256,7 +1296,7 @@
 }
 
 int
-edit_translate_add_args(struct ged *gedp,  union edit_cmd *const cmd,
+edit_translate_add_args(struct ged *gedp, union edit_cmd *const cmd,
                        struct edit_arg *args, const int flags)
 {
     (void)gedp;
@@ -1287,23 +1327,25 @@
 }
 
 struct edit_arg *
-edit_translate_get_next_arg_head(union edit_cmd *const cmd, struct edit_arg 
*prev_arg_head)
+edit_translate_get_next_arg_head(const union edit_cmd *const cmd)
 {
-    struct edit_arg *arg_heads[4];
+    static int idx = 0;
+    const int len = 4;
+    struct edit_arg *arg_heads[len];
 
     arg_heads[0] = cmd->translate.objects;
     arg_heads[1] = cmd->translate.ref_vector.from;
     arg_heads[2] = cmd->translate.ref_vector.to;
     arg_heads[3] = (struct edit_arg *)NULL;
 
-    return edit_cmd_get_next_arg_head(arg_heads, prev_arg_head);
+    return edit_cmd_get_next_arg_head(arg_heads, len, &idx);
 }
 
 /* 
  * Table of edit command data/functions
  */
 static const struct edit_cmd_tab edit_cmds[] = {
-    {"help", (char *)NULL, "[subcmd]", (char *)NULL, NULL, NULL, NULL},
+    {"help", (char *)NULL, "[subcmd]", (char *)NULL, NULL, NULL, NULL, NULL},
 #define EDIT_CMD_HELP 0 /* idx of "help" in edit_cmds */
     {"rotate",         "R",
        "[-R] [AXIS] [CENTER] ANGLE OBJECT ...",
@@ -1314,6 +1356,7 @@
            "[[-n] -k {ANGLE_FROM_OBJECT | ANGLE_FROM_POS}]\n"
            "[-n | -o] [-a | -r | -d]"
                "{ANGLE_TO_OBJECT | ANGLE_TO_POS}} OBJECT ...",
+       &edit_rotate_init,
        &edit_rotate_wrapper,
        &edit_rotate_add_args,
        &edit_rotate_get_next_arg_head
@@ -1326,6 +1369,7 @@
            "[[-n] -k {FACTOR_FROM_OBJECT | FACTOR_FROM_POS}]\n"
            "[-n] [-a | -r] {FACTOR_TO_OBJECT | FACTOR_TO_POS}"
                " OBJECT ...",
+       &edit_scale_init,
        &edit_scale_wrapper,
        &edit_scale_add_args,
        &edit_scale_get_next_arg_head
@@ -1334,11 +1378,13 @@
        "[FROM] TO OBJECT ...",
        "[[-n] -k {FROM_OBJECT | FROM_POS}]\n"
            "[-n] [-a | -r] {TO_OBJECT | TO_POS} OBJECT ...",
+       &edit_translate_init,
        &edit_translate_wrapper,
        &edit_translate_add_args,
        &edit_translate_get_next_arg_head
     },
-    {(char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, NULL, NULL, NULL}
+    {(char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, NULL, NULL, NULL,
+       NULL}
 };
 
 
@@ -1370,22 +1416,22 @@
  * Returns GED_ERROR on failure, and GED_OK on success.
  */
 int
-edit(struct ged *gedp, union edit_cmd *const cmd, const int flags)
+edit(struct ged *gedp, union edit_cmd *const subcmd, const int flags)
 {
     (void)gedp;
-    (void)cmd;
+    (void)subcmd;
     (void)flags;
+    struct edit_arg *arg_head = subcmd->cmd_line.args;;
+    struct edit_arg *cur_arg = arg_head;
+    /* struct edit_arg *prev_arg = NULL; */
+    int i;
 #if 0
     int noisy;
-    struct edit_arg *args = &cmd->cmd_line.args;
-    struct edit_arg *cur_arg = args;
-    struct edit_arg *prev_arg = NULL;
 
-
     /* if flags conflict (GED_ERROR/GED_QUIET), side with verbosity */
     noisy = (flags & GED_ERROR); 
+#endif
 
-#endif
     /*
      * TODO: write one edit_*_add_args() function, for testing
      */
@@ -1395,7 +1441,18 @@
      * all batch operators ("."), and do any other processing that is
      * not specific to a command. 
      */
-    /*  */
+    for (; arg_head; arg_head = subcmd->cmd->get_next_arg_head(subcmd)) {
+       for (cur_arg = arg_head; cur_arg; cur_arg = cur_arg->next) {
+           /* turn character options into flags */
+           /* XXX testing */
+           bu_vls_printf(gedp->ged_result_str, "options:");
+           for (i = 0; i < EDIT_MAX_ARG_OPTIONS; ++i) {
+               bu_vls_printf(gedp->ged_result_str, "%c",
+                             cur_arg->cl_options[i]);
+           }
+           return GED_ERROR;
+       }
+    }
 
     /* 
      * TODO: Second pass: command specific processing. Simultaneously
@@ -1733,16 +1790,12 @@
                                      edit_cmds[i].name);
                    return GED_ERROR;
                }
-
-               bu_vls_printf(gedp->ged_result_str, "Usage: %s %s\n\n%s %s",
-                             edit_cmds[i].name, edit_cmds[i].usage,
-                             edit_cmds[i].name, edit_cmds[i].help);
-               return GED_HELP;
+               goto get_full_help;
            }
        default:
            if (argc == 0) { 
                /* no args to subcommand; must want usage */
-               bu_vls_printf(gedp->ged_result_str, "Usage: %s %s",
+               bu_vls_printf(gedp->ged_result_str, "Usage: %s [help] | %s",
                              subcmd.cmd->name, subcmd.cmd->usage);
                return GED_HELP;
            }
@@ -1756,12 +1809,9 @@
            if (argc == 1 &&
                BU_STR_EQUAL(edit_cmds[EDIT_CMD_HELP].name,
                argv[0])) {
-               bu_vls_printf(gedp->ged_result_str,
-                             "Usage: %s %s\n\n%s %s",
-                             subcmd.cmd->name, subcmd.cmd->usage,
-                             subcmd.cmd->name, subcmd.cmd->help);
-               return GED_HELP;
+               goto get_full_help;
            }
+           break;
     }
 
     /*
@@ -1769,6 +1819,8 @@
      */
 
     /*
+     * FIXME: this isn't fully implemented, and it should be.
+     *
      * The object of the game is to remain agnostic of unique aspects
      * of argument structures of subcommands (i.e. inside the edit_cmd
      * union). Therefore, we will simply chain all of the arguments
@@ -1935,13 +1987,12 @@
            edit_cmd_free(&subcmd);
            return GED_ERROR;
        }
-       /* BU_ASSERT(argc == 0); */
     }
 
     /* remove command line arguments, and let command specific
      * funtions reattach them in the proper locations */
     cur_arg = subcmd.cmd_line.args;
-    subcmd.cmd_line.args = NULL;
+    subcmd.cmd->init(&subcmd);
     if (subcmd.cmd->add_args(gedp, &subcmd, cur_arg, GED_ERROR) == GED_ERROR)
        return GED_ERROR;
 
@@ -1950,6 +2001,14 @@
     edit_cmd_free(&subcmd);
     return ret;
 
+get_full_help:
+    bu_vls_printf(gedp->ged_result_str,
+                 "Usage: %s [help] | %s\n\n%s [help] | %s",
+                 subcmd.cmd->name, subcmd.cmd->usage,
+                 subcmd.cmd->name, subcmd.cmd->help);
+    edit_cmd_free(&subcmd);
+    return GED_HELP;
+
 err_missing_arg:
     bu_vls_printf(gedp->ged_result_str, "Missing argument for option -%c",
        bu_optopt);


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

------------------------------------------------------------------------------
Got Input?   Slashdot Needs You.
Take our quick survey online.  Come on, we don't ask for help often.
Plus, you'll get a chance to win $100 to spend on ThinkGeek.
http://p.sf.net/sfu/slashdot-survey
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to