int unregister_command(command_context_t *context, char *name)
{
- unique_length_dirty = 1;
-
command_t *c, *p = NULL, *c2;
+ unique_length_dirty = 1;
+
if ((!context) || (!name))
return ERROR_INVALID_ARGUMENTS;
return nwords;
}
-void command_print(command_context_t *context, char *format, ...)
+void command_print_n(command_context_t *context, char *format, ...)
{
- char *buffer = NULL;
- int n, size = 0;
- char *p;
-
- /* process format string */
- for (;;)
- {
- va_list ap;
- va_start(ap, format);
- if (!buffer || (n = vsnprintf(buffer, size, format, ap)) >= size)
- {
- /* increase buffer until it fits the whole string */
- if (!(p = realloc(buffer, size += 4096)))
- {
- /* gotta free up */
- if (buffer)
- free(buffer);
- va_end(ap);
- return;
- }
-
- buffer = p;
-
- va_end(ap);
- continue;
- }
- va_end(ap);
- break;
- }
+ char *string;
- /* vsnprintf failed */
- if (n < 0)
+ va_list ap;
+ va_start(ap, format);
+
+ string = alloc_vprintf(format, ap);
+ if (string != NULL)
{
- if (buffer)
- free(buffer);
- return;
+ context->output_handler(context, string);
+ free(string);
}
- p = buffer;
-
- /* process lines in buffer */
- do {
- char *next = strchr(p, '\n');
-
- if (next)
- *next++ = 0;
+ va_end(ap);
+}
- if (context->output_handler)
- context->output_handler(context, p);
+void command_print(command_context_t *context, char *format, ...)
+{
+ char *string;
- p = next;
- } while (p);
-
- if (buffer)
- free(buffer);
+ va_list ap;
+ va_start(ap, format);
+
+ string = alloc_vprintf(format, ap);
+ if (string != NULL)
+ {
+ strcat(string, "\n"); /* alloc_vprintf guaranteed the buffer to be at least one char longer */
+ context->output_handler(context, string);
+ free(string);
+ }
+
+ va_end(ap);
}
int find_and_run_command(command_context_t *context, command_t *commands, char *words[], int num_words, int start_word)
{
command_t *c;
+ int retval = ERROR_COMMAND_SYNTAX_ERROR;
if (unique_length_dirty)
{
if (!c->handler)
{
command_print(context, "No handler for command");
+ retval = ERROR_COMMAND_SYNTAX_ERROR;
break;
}
else
{
command_print(context, "Syntax error:");
command_print_help_line(context, c, 0);
+ } else if (retval != ERROR_OK)
+ {
+ /* we do not print out an error message because the command *should*
+ * have printed out an error
+ */
+ LOG_DEBUG("Command failed with error code %d", retval);
}
return retval;
}
}
command_print(context, "Command %s not found", words[start_word]);
- return ERROR_OK;
+ return retval;
}
-static int command_run_line_inner(command_context_t *context, char *line)
+int command_run_line(command_context_t *context, char *line)
{
int nwords;
char *words[128] = {0};
if (*line && (line[0] == '#'))
return ERROR_OK;
- if (context->echo)
- {
- command_print(context, "%s", line);
- }
+ LOG_DEBUG("%s", line);
nwords = parse_line(line, words, sizeof(words) / sizeof(words[0]));
return retval;
}
-int command_run_line(command_context_t *context, char *line)
-{
- int retval=command_run_line_inner(context, line);
- // we don't want any dangling callbacks!
- //
- // Capturing output from logging is *very* loosly modeled on C/C++ exceptions.
- // the capture must be set up at function entry and
- // stops when the function call returns
- log_setCallback(NULL, NULL);
- return retval;
-}
int command_run_file(command_context_t *context, FILE *file, enum command_mode mode)
{
int retval = ERROR_OK;
break;
/* run line */
- if ((retval = command_run_line_inner(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION)
+ if ((retval = command_run_line(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION)
break;
}
void command_print_help_line(command_context_t* context, struct command_s *command, int indent)
{
command_t *c;
- char indents[32] = {0};
+ char *indent_text=malloc(indent + 2);
+
char *help = "no help available";
char name_buf[64];
- int i;
- for (i = 0; i < indent; i+=2)
+ if (indent)
{
- indents[i*2] = ' ';
- indents[i*2+1] = '-';
+ indent_text[0] = ' ';
+ memset(indent_text + 1, '-', indent);
+ indent_text[indent + 1] = 0;
}
- indents[i*2] = 0;
if (command->help)
help = command->help;
snprintf(name_buf, 64, command->name);
- strncat(name_buf, indents, 64);
- command_print(context, "%20s\t%s", name_buf, help);
+
+ if (indent)
+ strncat(name_buf, indent_text, 64);
+
+ command_print(context, "%20s\t%s", name_buf, help, indent);
if (command->children)
{
command_print_help_line(context, c, indent + 1);
}
}
+ free(indent_text);
}
-int command_print_help(command_context_t* context, char* name, char** args, int argc)
+int command_print_help_match(command_context_t* context, command_t* c_first, char* name, char** args, int argc)
{
- command_t *c;
+ command_t * c;
- for (c = context->commands; c; c = c->next)
+ for (c = c_first; c; c = c->next)
{
- if (argc == 1)
+ if (argc > 0)
{
- if (strncasecmp(c->name, args[0], c->unique_len))
- continue;
+ if (strncasecmp(c->name, args[0], c->unique_len))
+ continue;
- if (strncasecmp(c->name, args[0], strlen(args[0])))
- continue;
- }
+ if (strncasecmp(c->name, args[0], strlen(args[0])))
+ continue;
+
+ if (argc > 1)
+ {
+ command_print_help_match(context, c->children, name, args + 1, argc - 1);
+ continue;
+ }
+ }
command_print_help_line(context, c, 0);
}
return ERROR_OK;
}
+int command_print_help(command_context_t* context, char* name, char** args, int argc)
+{
+ return command_print_help_match(context, context->commands, name, args, argc);
+}
+
+
void command_set_output_handler(command_context_t* context, int (*output_handler)(struct command_context_s *context, char* line), void *priv)
{
context->output_handler = output_handler;
context->mode = COMMAND_EXEC;
context->commands = NULL;
context->current_target = 0;
- context->echo = 0;
context->output_handler = NULL;
context->output_handler_priv = NULL;
int handle_time_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
- if (argc<1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
duration_t duration;
char *duration_text;
int retval;
+ float t;
+
+ if (argc<1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
duration_start_measure(&duration);
duration_stop_measure(&duration, &duration_text);
- float t=duration.duration.tv_sec;
+ t=duration.duration.tv_sec;
t+=((float)duration.duration.tv_usec / 1000000.0);
command_print(cmd_ctx, "%s took %fs", args[0], t);