From bc9ae740730efacc2daa3ecbdb0ee75601ec18df Mon Sep 17 00:00:00 2001 From: Zachary T Welch Date: Sun, 29 Nov 2009 15:58:16 -0800 Subject: [PATCH] improve command_done() API and docs command_done() does not need to return an error, but it needed Doxygen comment. Provide some for copy_command_context as well. Note: this audit revealed some potential bugs with the command context implementation. There was a reason that commands were added at the end of the list. Shallow copying of command_context means that the list is shared between them. And commands added at the top-level before the pre-existing commands will not be available in the shared context as they were before. Yikes! Fortunately, this does not seem to occur in general use, as 'add_help_text' gets registered in startup.tcl and claims the first slot in my own test cases. Thus, it seems that we have been masking the issue for now, but it shows the need for further architectural improvement in the core command module. --- src/helper/command.c | 8 ++++---- src/helper/command.h | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index ac7c8d88b..6031ce6a4 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -683,12 +683,12 @@ struct command_context* copy_command_context(struct command_context* context) return copy_context; } -int command_done(struct command_context *context) +void command_done(struct command_context *cmd_ctx) { - free(context); - context = NULL; + if (NULL == cmd_ctx) + return; - return ERROR_OK; + free(cmd_ctx); } /* find full path to file */ diff --git a/src/helper/command.h b/src/helper/command.h index 2d3348468..72c564756 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -316,7 +316,6 @@ void command_set_handler_data(struct command *c, void *p); void command_set_output_handler(struct command_context* context, command_output_handler_t output_handler, void *priv); -struct command_context* copy_command_context(struct command_context* context); int command_context_mode(struct command_context *context, enum command_mode mode); @@ -324,7 +323,21 @@ int command_context_mode(struct command_context *context, enum command_mode mode * Creates a new command context using the startup TCL provided. */ struct command_context* command_init(const char *startup_tcl); -int command_done(struct command_context *context); +/** + * Creates a copy of an existing command context. This does not create + * a deep copy of the command list, so modifications in one context will + * affect all shared contexts. The caller must track reference counting + * and ensure the commands are freed before destroying the last instance. + * @param cmd_ctx The command_context that will be copied. + * @returns A new command_context with the same state as the original. + */ +struct command_context* copy_command_context(struct command_context* cmd_ctx); +/** + * Frees the resources associated with a command context. The commands + * are not removed, so unregister_all_commands() must be called first. + * @param cmd_ctx The command_context that will be destroyed. + */ +void command_done(struct command_context *context); void command_print(struct command_context *context, const char *format, ...) __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));