X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fcommand.c;h=d2abb0c2ab43de4900667606f523f6d14785a6d6;hp=8a736686a61d46a498b8b347055623f6b198831f;hb=c5b718f5e85c7a884f7610fea46ceea2c3fbd4a7;hpb=269c6d8385c1183819dfef18c811aad76699e6fc diff --git a/src/helper/command.c b/src/helper/command.c index 8a736686a6..d2abb0c2ab 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -46,52 +46,14 @@ int handle_sleep_command(struct command_context_s *cmd_ctx, char *cmd, char **ar int handle_time_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_fast_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int build_unique_lengths(command_context_t *context, command_t *commands) -{ - command_t *c, *p; +/* forward declaration of jim_command */ +extern int jim_command(command_context_t *context, char *line); - /* iterate through all commands */ - for (c = commands; c; c = c->next) - { - /* find out how many characters are required to uniquely identify a command */ - for (c->unique_len = 1; c->unique_len <= strlen(c->name); c->unique_len++) - { - int foundmatch = 0; - - /* for every command, see if the current length is enough */ - for (p = commands; p; p = p->next) - { - /* ignore the command itself */ - if (c == p) - continue; - - /* compare commands up to the current length */ - if (strncmp(p->name, c->name, c->unique_len) == 0) - foundmatch++; - } - - /* when none of the commands matched, we've found the minimum length required */ - if (!foundmatch) - break; - } - - /* if the current command has children, build the unique lengths for them */ - if (c->children) - build_unique_lengths(context, c->children); - } - - return ERROR_OK; -} -/* Avoid evaluating this each time we add a command. Reduces overhead from O(n^2) to O(n). - * Makes a difference on ARM7 types machines and is not observable on GHz machines. - */ -static int unique_length_dirty = 1; command_t* register_command(command_context_t *context, command_t *parent, char *name, int (*handler)(struct command_context_s *context, char* name, char** args, int argc), enum command_mode mode, char *help) { command_t *c, *p; - unique_length_dirty = 1; if (!context || !name) return NULL; @@ -107,7 +69,6 @@ command_t* register_command(command_context_t *context, command_t *parent, char c->help = strdup(help); else c->help = NULL; - c->unique_len = 0; c->next = NULL; /* place command in tree */ @@ -147,8 +108,6 @@ int unregister_all_commands(command_context_t *context) { command_t *c, *c2; - unique_length_dirty = 1; - if (context == NULL) return ERROR_OK; @@ -186,8 +145,6 @@ int unregister_command(command_context_t *context, char *name) { command_t *c, *p = NULL, *c2; - unique_length_dirty = 1; - if ((!context) || (!name)) return ERROR_INVALID_ARGUMENTS; @@ -302,6 +259,13 @@ int parse_line(char *line, char *words[], int max_words) return nwords; } +void command_output_text(command_context_t *context, const char *data) +{ + if( context && context->output_handler && data ){ + context->output_handler( context, data ); + } +} + void command_print_n(command_context_t *context, char *format, ...) { char *string; @@ -341,21 +305,11 @@ command_t *find_command(command_context_t *context, command_t *commands, char *w { command_t *c; - if (unique_length_dirty) - { - unique_length_dirty = 0; - /* update unique lengths */ - build_unique_lengths(context, context->commands); - } - for (c = commands; c; c = c->next) { - if (strncasecmp(c->name, words[start_word], c->unique_len)) + if (strcasecmp(c->name, words[start_word])) continue; - if (strncasecmp(c->name, words[start_word], strlen(words[start_word]))) - continue; - if ((context->mode == COMMAND_CONFIG) || (c->mode == COMMAND_ANY) || (c->mode == context->mode) ) { if (!c->children) @@ -387,11 +341,11 @@ int find_and_run_command(command_context_t *context, command_t *commands, char * { int start_word=0; command_t *c; - c=find_command(context, commands, words, num_words, start_word, &start_word); - if (c==NULL) + c = find_command(context, commands, words, num_words, start_word, &start_word); + if (c == NULL) { - command_print(context, "Command %s not found", words[start_word]); - return ERROR_COMMAND_SYNTAX_ERROR; + /* just return command not found */ + return ERROR_COMMAND_NOTFOUND; } int retval = c->handler(context, c->name, words + start_word + 1, num_words - start_word - 1); @@ -411,10 +365,11 @@ int find_and_run_command(command_context_t *context, command_t *commands, char * */ LOG_DEBUG("Command failed with error code %d", retval); } + return retval; } -int command_run_line_internal_op(command_context_t *context, char *line, int run) +int command_run_line_internal(command_context_t *context, char *line) { LOG_USER_N("%s", ""); /* Keep GDB connection alive*/ @@ -440,14 +395,9 @@ int command_run_line_internal_op(command_context_t *context, char *line, int run nwords = parse_line(line, words, sizeof(words) / sizeof(words[0])); if (nwords > 0) - if (run) - { - retval = find_and_run_command(context, context->commands, words, nwords); - } else - { - int t; - return (find_command(context, context->commands, words, nwords, 0, &t)!=NULL)?ERROR_OK:ERROR_FAIL; - } + { + retval = find_and_run_command(context, context->commands, words, nwords); + } else return ERROR_INVALID_ARGUMENTS; @@ -457,85 +407,17 @@ int command_run_line_internal_op(command_context_t *context, char *line, int run return retval; } -int command_run_line_internal(command_context_t *context, char *line) -{ - return command_run_line_internal_op(context, line, 1); -} - int command_run_line(command_context_t *context, char *line) { - int retval; - if ((!context) || (!line)) - return ERROR_INVALID_ARGUMENTS; - - if (command_run_line_internal_op(context, line, 0)!=ERROR_OK) - { - /* If we can't find a command, then try the interpreter. - * If there is no interpreter implemented, then this will - * simply print a syntax error. - * - * These hooks were left in to reduce patch size for - * wip to add scripting language. - */ - return jim_command(context, line); - } - - return command_run_line_internal(context, line); + /* if a command is unknown to the "unknown" proc in tcl/commands.tcl will + * redirect it to OpenOCD. + * + * This avoids having to type the "openocd" prefix and makes OpenOCD + * commands "native" to Tcl. + */ + return jim_command(context, line); } -int command_run_file(command_context_t *context, FILE *file, enum command_mode mode) -{ - int retval = ERROR_OK; - int old_command_mode; - char *buffer=malloc(4096); - if (buffer==NULL) - { - return ERROR_INVALID_ARGUMENTS; - } - - old_command_mode = context->mode; - context->mode = mode; - - while (fgets(buffer, 4096, file)) - { - char *p; - char *cmd, *end; - - /* stop processing line after a comment (#, !) or a LF, CR were encountered */ - if ((p = strpbrk(buffer, "#!\r\n"))) - *p = 0; - - /* skip over leading whitespace */ - cmd = buffer; - while (isspace(*cmd)) - cmd++; - - /* empty (all whitespace) line? */ - if (!*cmd) - continue; - - /* search the end of the current line, ignore trailing whitespace */ - for (p = end = cmd; *p; p++) - if (!isspace(*p)) - end = p; - - /* terminate end */ - *++end = 0; - if (strcasecmp(cmd, "quit") == 0) - break; - - /* run line */ - if ((retval = command_run_line(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION) - break; - } - - context->mode = old_command_mode; - - - free(buffer); - - return retval; -} int command_run_linef(command_context_t *context, char *format, ...) { @@ -595,10 +477,7 @@ int command_print_help_match(command_context_t* context, command_t* c_first, cha { if (argc > 0) { - if (strncasecmp(c->name, args[0], c->unique_len)) - continue; - - if (strncasecmp(c->name, args[0], strlen(args[0]))) + if (strcasecmp(c->name, args[0])) continue; if (argc > 1) @@ -619,7 +498,7 @@ int command_print_help(command_context_t* context, char* name, char** args, int 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) +void command_set_output_handler(command_context_t* context, int (*output_handler)(struct command_context_s *context, const char* line), void *priv) { context->output_handler = output_handler; context->output_handler_priv = priv; @@ -707,6 +586,10 @@ int handle_time_command(struct command_context_s *cmd_ctx, char *cmd, char **arg duration_start_measure(&duration); retval = find_and_run_command(cmd_ctx, cmd_ctx->commands, args, argc); + if (retval == ERROR_COMMAND_NOTFOUND) + { + command_print(cmd_ctx, "Command %s not found", args[0]); + } duration_stop_measure(&duration, &duration_text);