Revision: 45735
http://brlcad.svn.sourceforge.net/brlcad/?rev=45735&view=rev
Author: bhinesley
Date: 2011-07-30 08:59:21 +0000 (Sat, 30 Jul 2011)
Log Message:
-----------
Due to some previous changes, an edit_arg was set to point at to something
before being 'initialized' to NULL, which was causing crashes later on. Also,
the natural origin option was still being saved as a character, and the target
object flag was not being set. Enabled support for multiple target object
arguments. Added helper function to free last arg in a list, broke common
functionality out to reduce redundancy. edit_translate_add_cl_args() is
improved, but there are still issues. Improved handling of multiple
leading/trailing arguments w/o options.
Modified Paths:
--------------
brlcad/trunk/src/libged/edit.c
Modified: brlcad/trunk/src/libged/edit.c
===================================================================
--- brlcad/trunk/src/libged/edit.c 2011-07-30 06:38:00 UTC (rev 45734)
+++ brlcad/trunk/src/libged/edit.c 2011-07-30 08:59:21 UTC (rev 45735)
@@ -971,13 +971,11 @@
}
/**
- * Free an argument node and all nodes down its list.
+ * Free an argument
*/
HIDDEN void
-edit_arg_free_all(struct edit_arg *arg)
+edit_arg_free(struct edit_arg *arg)
{
- if (arg->next)
- edit_arg_free_all(arg->next);
if (arg->object) {
db_free_full_path(arg->object);
bu_free((genptr_t)arg->object, "db_string_to_path");
@@ -988,6 +986,34 @@
}
/**
+ * Free the last argument node in the list.
+ */
+HIDDEN void
+edit_arg_free_last(struct edit_arg *arg)
+{
+ struct edit_arg *last_arg = arg;
+
+ while ((arg = arg->next)) {
+ if (!(arg->next))
+ break;
+ last_arg = arg;
+ }
+ last_arg->next = NULL;
+ edit_arg_free(arg);
+}
+
+/**
+ * Free an argument node and all nodes down its list.
+ */
+HIDDEN void
+edit_arg_free_all(struct edit_arg *arg)
+{
+ if (arg->next)
+ edit_arg_free_all(arg->next);
+ edit_arg_free(arg);
+}
+
+/**
* Free any dynamically allocated arg that may exist
*/
HIDDEN void
@@ -1301,7 +1327,7 @@
cmd->translate.ref_vector.from->next = NULL;
}
- if (cur_arg->type & EDIT_TO) {
+ if ((cur_arg->type & EDIT_TO) || (cur_arg->type == 0)) {
/* if there isn't an EDIT_TARGET_OBJECT, this func shouldn't
* be called */
BU_ASSERT_PTR(cur_arg->next, !=, NULL);
@@ -1471,7 +1497,7 @@
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:");
+ bu_vls_printf(gedp->ged_result_str, "(testing) options:");
for (i = 0; i < EDIT_MAX_ARG_OPTIONS; ++i) {
bu_vls_printf(gedp->ged_result_str, "%c",
cur_arg->cl_options[i]);
@@ -1731,20 +1757,17 @@
/* initialize the subcommand */
subcmd.cmd = (const struct edit_cmd_tab *)NULL;
- cur_arg = subcmd.common.objects = (struct edit_arg *)bu_malloc(
- sizeof(struct edit_arg),
- "edit_arg block for ged_edit()");
- edit_arg_init(cur_arg);
/*
* Validate command name
*/
-/* FIXME: usage/help messages for subcommands should contain the name
- * of the 'parent' command when necessary: i.e.: 'edit translate'
- * rather than just 'translate'. Also, the help option of subcommands
- * is not displayed properly; it should display when command is called
- * directly, i.e. 'translate', but not 'edit translate' */
+ /* FIXME: usage/help messages for subcommands should contain the
+ * name of the 'parent' command when necessary: i.e.: 'edit
+ * translate' rather than just 'translate'. Also, the help option
+ * of subcommands is not displayed properly; it should display
+ * when command is called directly, i.e. 'translate', but not
+ * 'edit translate' */
for (i = 0; edit_cmds[i].name; ++i) {
/* search for command name in the table */
@@ -1765,6 +1788,10 @@
/* now that the cmd type is known, we can init the subcmd args */
subcmd.cmd->init(&subcmd);
+ cur_arg = subcmd.cmd_line.args = (struct edit_arg *)bu_malloc(
+ sizeof(struct edit_arg),
+ "edit_arg block for ged_edit()");
+ edit_arg_init(cur_arg);
if (subcmd_name == cmd_name) { /* ptr cmp */
/* command name is serving as the subcommand */
@@ -1896,12 +1923,38 @@
*/
/* no options are required by default*/
- (void)edit_strs_to_arg(gedp, &argc, &argv, cur_arg, GED_QUIET);
-
- if (argc == 0) {
- ret = edit(gedp, &subcmd, GED_ERROR);
- edit_cmd_free(&subcmd);
- return ret;
+ while (edit_strs_to_arg(gedp, &argc, &argv, cur_arg, GED_QUIET) !=
GED_ERROR) {
+ if (argc == 0) {
+ /* free unused arg block */
+ edit_arg_free_last(subcmd.cmd_line.args);
+
+ cur_arg = subcmd.cmd_line.args;
+ if (cur_arg->next) {
+ cur_arg->type |= EDIT_TO;
+ cur_arg = cur_arg->next;
+ }
+
+ /* parsing is done and there were no options, so all args
+ * after the first arg should be a target obj */
+ for (; cur_arg; cur_arg = cur_arg->next) {
+ if (!(cur_arg->object)) {
+ bu_vls_printf(gedp->ged_result_str,
+ "expected only objects after first arg");
+ edit_cmd_free(&subcmd);
+ return GED_ERROR;
+ }
+ cur_arg->type |= EDIT_TARGET_OBJ;
+ }
+
+ /* let cmd specific func validate/move args to proper locations */
+ if (subcmd.cmd->add_cl_args(gedp, &subcmd, GED_ERROR) ==
+ GED_ERROR)
+ return GED_ERROR;
+ ret = edit(gedp, &subcmd, GED_ERROR);
+ edit_cmd_free(&subcmd);
+ return ret;
+ }
+ cur_arg = edit_arg_postfix_new(subcmd.cmd_line.args);
}
/* All leading args are parsed. If we're not not at an option,
@@ -1918,7 +1971,8 @@
bu_opterr = 0; /* suppress errors; accept unknown options */
++argc; /* bu_getopt doesn't expect first element to be an arg */
--argv;
- while ((c = bu_getopt(argc, (char * const *)argv, ":k:a:r:x:y:z:")) != -1)
{
+ while ((c = bu_getopt(argc, (char * const *)argv, ":n:k:a:r:x:y:z:"))
+ != -1) {
if (bu_optind >= argc)
/* last element is an option */
/* FIXME: this isn't enough; needs to detect all cases
@@ -2011,6 +2065,7 @@
break;
case 'n':
cur_arg->type |= EDIT_NATURAL_ORIGIN;
+ break;
default:
break;
}
@@ -2046,16 +2101,20 @@
/* get final/trailing args */
++argv;
--argc;
- if (argc > 0) {
+ while (argc > 0) {
if (edit_strs_to_arg(gedp, &argc, &argv, cur_arg, GED_ERROR) ==
GED_ERROR) {
edit_cmd_free(&subcmd);
return GED_ERROR;
}
+ cur_arg->type |= EDIT_TARGET_OBJ;
+ cur_arg = edit_arg_postfix_new(subcmd.cmd_line.args);
}
- /* let the cmd specific func validate/move args to the proper
- * locations */
+ /* free unused arg block */
+ edit_arg_free_last(subcmd.cmd_line.args);
+
+ /* let cmd specific func validate/move args to proper locations */
if (subcmd.cmd->add_cl_args(gedp, &subcmd, GED_ERROR) ==
GED_ERROR)
return GED_ERROR;
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