OpenOCD
command.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2005 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  * *
7  * Copyright (C) 2007,2008 Øyvind Harboe *
8  * oyvind.harboe@zylin.com *
9  * *
10  * Copyright (C) 2008, Duane Ellis *
11  * openocd@duaneeellis.com *
12  * *
13  * part of this file is taken from libcli (libcli.sourceforge.net) *
14  * Copyright (C) David Parrish (david@dparrish.com) *
15  ***************************************************************************/
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 /* see Embedded-HOWTO.txt in Jim Tcl project hosted on BerliOS*/
22 #define JIM_EMBEDDED
23 
24 /* @todo the inclusion of target.h here is a layering violation */
25 #include <jtag/jtag.h>
26 #include <target/target.h>
27 #include "command.h"
28 #include "configuration.h"
29 #include "log.h"
30 #include "time_support.h"
31 #include "jim-eventloop.h"
32 
33 /* nice short description of source file */
34 #define __THIS__FILE__ "command.c"
35 
37  Jim_Interp *interp;
38  Jim_Obj *output;
39 };
40 
41 static int unregister_command(struct command_context *context,
42  const char *cmd_prefix, const char *name);
43 static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *argv);
44 static int help_add_command(struct command_context *cmd_ctx,
45  const char *cmd_name, const char *help_text, const char *usage_text);
46 static int help_del_command(struct command_context *cmd_ctx, const char *cmd_name);
47 
48 /* set of functions to wrap jimtcl internal data */
49 static inline bool jimcmd_is_proc(Jim_Cmd *cmd)
50 {
51  return cmd->isproc;
52 }
53 
55 {
56  return !cmd->isproc && cmd->u.native.cmdProc == jim_command_dispatch;
57 }
58 
59 void *jimcmd_privdata(Jim_Cmd *cmd)
60 {
61  return cmd->isproc ? NULL : cmd->u.native.privData;
62 }
63 
64 static void tcl_output(void *privData, const char *file, unsigned line,
65  const char *function, const char *string)
66 {
67  struct log_capture_state *state = privData;
68  Jim_AppendString(state->interp, state->output, string, strlen(string));
69 }
70 
72 {
73  /* capture log output and return it. A garbage collect can
74  * happen, so we need a reference count to this object */
75  Jim_Obj *jim_output = Jim_NewStringObj(interp, "", 0);
76  if (!jim_output)
77  return NULL;
78 
79  Jim_IncrRefCount(jim_output);
80 
81  struct log_capture_state *state = malloc(sizeof(*state));
82  if (!state) {
83  LOG_ERROR("Out of memory");
84  Jim_DecrRefCount(interp, jim_output);
85  return NULL;
86  }
87 
88  state->interp = interp;
89  state->output = jim_output;
90 
92 
93  return state;
94 }
95 
96 /* Classic openocd commands provide progress output which we
97  * will capture and return as a Tcl return value.
98  *
99  * However, if a non-openocd command has been invoked, then it
100  * makes sense to return the tcl return value from that command.
101  *
102  * The tcl return value is empty for openocd commands that provide
103  * progress output.
104  *
105  * Therefore we set the tcl return value only if we actually
106  * captured output.
107  */
109 {
110  if (!state)
111  return;
112 
114 
115  int length;
116  Jim_GetString(state->output, &length);
117 
118  if (length > 0)
119  Jim_SetResult(state->interp, state->output);
120  else {
121  /* No output captured, use tcl return value (which could
122  * be empty too). */
123  }
124  Jim_DecrRefCount(state->interp, state->output);
125 
126  free(state);
127 }
128 
129 static int command_retval_set(Jim_Interp *interp, int retval)
130 {
131  int *return_retval = Jim_GetAssocData(interp, "retval");
132  if (return_retval)
133  *return_retval = retval;
134 
135  return (retval == ERROR_OK) ? JIM_OK : retval;
136 }
137 
138 extern struct command_context *global_cmd_ctx;
139 
140 /* dump a single line to the log for the command.
141  * Do nothing in case we are not at debug level 3 */
142 static void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv)
143 {
145  return;
146 
147  char *dbg = alloc_printf("command -");
148  for (unsigned i = 0; i < argc; i++) {
149  int len;
150  const char *w = Jim_GetString(argv[i], &len);
151  char *t = alloc_printf("%s %s", dbg, w);
152  free(dbg);
153  dbg = t;
154  }
155  LOG_DEBUG("%s", dbg);
156  free(dbg);
157 }
158 
159 static void script_command_args_free(char **words, unsigned nwords)
160 {
161  for (unsigned i = 0; i < nwords; i++)
162  free(words[i]);
163  free(words);
164 }
165 
167  unsigned argc, Jim_Obj * const *argv, unsigned *nwords)
168 {
169  char **words = malloc(argc * sizeof(char *));
170  if (!words)
171  return NULL;
172 
173  unsigned i;
174  for (i = 0; i < argc; i++) {
175  int len;
176  const char *w = Jim_GetString(argv[i], &len);
177  words[i] = strdup(w);
178  if (!words[i]) {
179  script_command_args_free(words, i);
180  return NULL;
181  }
182  }
183  *nwords = i;
184  return words;
185 }
186 
188 {
189  /* grab the command context from the associated data */
190  struct command_context *cmd_ctx = Jim_GetAssocData(interp, "context");
191  if (!cmd_ctx) {
192  /* Tcl can invoke commands directly instead of via command_run_line(). This would
193  * happen when the Jim Tcl interpreter is provided by eCos or if we are running
194  * commands in a startup script.
195  *
196  * A telnet or gdb server would provide a non-default command context to
197  * handle piping of error output, have a separate current target, etc.
198  */
199  cmd_ctx = global_cmd_ctx;
200  }
201  return cmd_ctx;
202 }
203 
209 static struct command *command_find_from_name(Jim_Interp *interp, const char *name)
210 {
211  if (!name)
212  return NULL;
213 
214  Jim_Obj *jim_name = Jim_NewStringObj(interp, name, -1);
215  Jim_IncrRefCount(jim_name);
216  Jim_Cmd *cmd = Jim_GetCommand(interp, jim_name, JIM_NONE);
217  Jim_DecrRefCount(interp, jim_name);
219  return NULL;
220 
221  return jimcmd_privdata(cmd);
222 }
223 
224 static struct command *command_new(struct command_context *cmd_ctx,
225  const char *full_name, const struct command_registration *cr)
226 {
227  assert(cr->name);
228 
229  /*
230  * If it is a non-jim command with no .usage specified,
231  * log an error.
232  *
233  * strlen(.usage) == 0 means that the command takes no
234  * arguments.
235  */
236  if (!cr->jim_handler && !cr->usage)
237  LOG_ERROR("BUG: command '%s' does not have the "
238  "'.usage' field filled out",
239  full_name);
240 
241  struct command *c = calloc(1, sizeof(struct command));
242  if (!c)
243  return NULL;
244 
245  c->name = strdup(cr->name);
246  if (!c->name) {
247  free(c);
248  return NULL;
249  }
250 
251  c->handler = cr->handler;
252  c->jim_handler = cr->jim_handler;
253  c->mode = cr->mode;
254 
255  if (cr->help || cr->usage)
256  help_add_command(cmd_ctx, full_name, cr->help, cr->usage);
257 
258  return c;
259 }
260 
261 static void command_free(struct Jim_Interp *interp, void *priv)
262 {
263  struct command *c = priv;
264 
265  free(c->name);
266  free(c);
267 }
268 
269 static struct command *register_command(struct command_context *context,
270  const char *cmd_prefix, const struct command_registration *cr)
271 {
272  char *full_name;
273 
274  if (!context || !cr->name)
275  return NULL;
276 
277  if (cmd_prefix)
278  full_name = alloc_printf("%s %s", cmd_prefix, cr->name);
279  else
280  full_name = strdup(cr->name);
281  if (!full_name)
282  return NULL;
283 
284  struct command *c = command_find_from_name(context->interp, full_name);
285  if (c) {
286  /* TODO: originally we treated attempting to register a cmd twice as an error
287  * Sometimes we need this behaviour, such as with flash banks.
288  * http://www.mail-archive.com/openocd-development@lists.berlios.de/msg11152.html */
289  LOG_DEBUG("command '%s' is already registered", full_name);
290  free(full_name);
291  return c;
292  }
293 
294  c = command_new(context, full_name, cr);
295  if (!c) {
296  free(full_name);
297  return NULL;
298  }
299 
300  if (false) /* too noisy with debug_level 3 */
301  LOG_DEBUG("registering '%s'...", full_name);
302  int retval = Jim_CreateCommand(context->interp, full_name,
304  if (retval != JIM_OK) {
305  command_run_linef(context, "del_help_text {%s}", full_name);
306  command_run_linef(context, "del_usage_text {%s}", full_name);
307  free(c);
308  free(full_name);
309  return NULL;
310  }
311 
312  free(full_name);
313  return c;
314 }
315 
316 int __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix,
317  const struct command_registration *cmds, void *data,
318  struct target *override_target)
319 {
320  int retval = ERROR_OK;
321  unsigned i;
322  for (i = 0; cmds[i].name || cmds[i].chain; i++) {
323  const struct command_registration *cr = cmds + i;
324 
325  struct command *c = NULL;
326  if (cr->name) {
327  c = register_command(cmd_ctx, cmd_prefix, cr);
328  if (!c) {
329  retval = ERROR_FAIL;
330  break;
331  }
332  c->jim_handler_data = data;
333  c->jim_override_target = override_target;
334  }
335  if (cr->chain) {
336  if (cr->name) {
337  if (cmd_prefix) {
338  char *new_prefix = alloc_printf("%s %s", cmd_prefix, cr->name);
339  if (!new_prefix) {
340  retval = ERROR_FAIL;
341  break;
342  }
343  retval = __register_commands(cmd_ctx, new_prefix, cr->chain, data, override_target);
344  free(new_prefix);
345  } else {
346  retval = __register_commands(cmd_ctx, cr->name, cr->chain, data, override_target);
347  }
348  } else {
349  retval = __register_commands(cmd_ctx, cmd_prefix, cr->chain, data, override_target);
350  }
351  if (retval != ERROR_OK)
352  break;
353  }
354  }
355  if (retval != ERROR_OK) {
356  for (unsigned j = 0; j < i; j++)
357  unregister_command(cmd_ctx, cmd_prefix, cmds[j].name);
358  }
359  return retval;
360 }
361 
362 static __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)))
363 int unregister_commands_match(struct command_context *cmd_ctx, const char *format, ...)
364 {
365  Jim_Interp *interp = cmd_ctx->interp;
366  va_list ap;
367 
368  va_start(ap, format);
369  char *query = alloc_vprintf(format, ap);
370  va_end(ap);
371  if (!query)
372  return ERROR_FAIL;
373 
374  char *query_cmd = alloc_printf("info commands {%s}", query);
375  free(query);
376  if (!query_cmd)
377  return ERROR_FAIL;
378 
379  int retval = Jim_EvalSource(interp, __THIS__FILE__, __LINE__, query_cmd);
380  free(query_cmd);
381  if (retval != JIM_OK)
382  return ERROR_FAIL;
383 
384  Jim_Obj *list = Jim_GetResult(interp);
385  Jim_IncrRefCount(list);
386 
387  int len = Jim_ListLength(interp, list);
388  for (int i = 0; i < len; i++) {
389  Jim_Obj *elem = Jim_ListGetIndex(interp, list, i);
390  Jim_IncrRefCount(elem);
391 
392  const char *name = Jim_GetString(elem, NULL);
393  struct command *c = command_find_from_name(interp, name);
394  if (!c) {
395  /* not openocd command */
396  Jim_DecrRefCount(interp, elem);
397  continue;
398  }
399  if (false) /* too noisy with debug_level 3 */
400  LOG_DEBUG("delete command \"%s\"", name);
401 #if JIM_VERSION >= 80
402  Jim_DeleteCommand(interp, elem);
403 #else
404  Jim_DeleteCommand(interp, name);
405 #endif
406 
407  help_del_command(cmd_ctx, name);
408 
409  Jim_DecrRefCount(interp, elem);
410  }
411 
412  Jim_DecrRefCount(interp, list);
413  return ERROR_OK;
414 }
415 
417  const char *cmd_prefix)
418 {
419  if (!context)
420  return ERROR_OK;
421 
422  if (!cmd_prefix || !*cmd_prefix)
423  return unregister_commands_match(context, "*");
424 
425  int retval = unregister_commands_match(context, "%s *", cmd_prefix);
426  if (retval != ERROR_OK)
427  return retval;
428 
429  return unregister_commands_match(context, "%s", cmd_prefix);
430 }
431 
432 static int unregister_command(struct command_context *context,
433  const char *cmd_prefix, const char *name)
434 {
435  if (!context || !name)
437 
438  if (!cmd_prefix || !*cmd_prefix)
439  return unregister_commands_match(context, "%s", name);
440 
441  return unregister_commands_match(context, "%s %s", cmd_prefix, name);
442 }
443 
444 void command_output_text(struct command_context *context, const char *data)
445 {
446  if (context && context->output_handler && data)
447  context->output_handler(context, data);
448 }
449 
450 void command_print_sameline(struct command_invocation *cmd, const char *format, ...)
451 {
452  char *string;
453 
454  va_list ap;
455  va_start(ap, format);
456 
457  string = alloc_vprintf(format, ap);
458  if (string && cmd) {
459  /* we want this collected in the log + we also want to pick it up as a tcl return
460  * value.
461  *
462  * The latter bit isn't precisely neat, but will do for now.
463  */
464  Jim_AppendString(cmd->ctx->interp, cmd->output, string, -1);
465  /* We already printed it above
466  * command_output_text(context, string); */
467  free(string);
468  }
469 
470  va_end(ap);
471 }
472 
473 void command_print(struct command_invocation *cmd, const char *format, ...)
474 {
475  char *string;
476 
477  va_list ap;
478  va_start(ap, format);
479 
480  string = alloc_vprintf(format, ap);
481  if (string && cmd) {
482  strcat(string, "\n"); /* alloc_vprintf guaranteed the buffer to be at least one
483  *char longer */
484  /* we want this collected in the log + we also want to pick it up as a tcl return
485  * value.
486  *
487  * The latter bit isn't precisely neat, but will do for now.
488  */
489  Jim_AppendString(cmd->ctx->interp, cmd->output, string, -1);
490  /* We already printed it above
491  * command_output_text(context, string); */
492  free(string);
493  }
494 
495  va_end(ap);
496 }
497 
498 static bool command_can_run(struct command_context *cmd_ctx, struct command *c, const char *full_name)
499 {
500  if (c->mode == COMMAND_ANY || c->mode == cmd_ctx->mode)
501  return true;
502 
503  /* Many commands may be run only before/after 'init' */
504  const char *when;
505  switch (c->mode) {
506  case COMMAND_CONFIG:
507  when = "before";
508  break;
509  case COMMAND_EXEC:
510  when = "after";
511  break;
512  /* handle the impossible with humor; it guarantees a bug report! */
513  default:
514  when = "if Cthulhu is summoned by";
515  break;
516  }
517  LOG_ERROR("The '%s' command must be used %s 'init'.",
518  full_name ? full_name : c->name, when);
519  return false;
520 }
521 
522 static int run_command(struct command_context *context,
523  struct command *c, const char **words, unsigned num_words)
524 {
525  struct command_invocation cmd = {
526  .ctx = context,
527  .current = c,
528  .name = c->name,
529  .argc = num_words - 1,
530  .argv = words + 1,
531  };
532 
533  cmd.output = Jim_NewEmptyStringObj(context->interp);
534  Jim_IncrRefCount(cmd.output);
535 
536  int retval = c->handler(&cmd);
537  if (retval == ERROR_COMMAND_SYNTAX_ERROR) {
538  /* Print help for command */
539  command_run_linef(context, "usage %s", words[0]);
540  } else if (retval == ERROR_COMMAND_CLOSE_CONNECTION) {
541  /* just fall through for a shutdown request */
542  } else {
543  if (retval != ERROR_OK)
544  LOG_DEBUG("Command '%s' failed with error code %d",
545  words[0], retval);
546  /* Use the command output as the Tcl result */
547  Jim_SetResult(context->interp, cmd.output);
548  }
549  Jim_DecrRefCount(context->interp, cmd.output);
550 
551  return retval;
552 }
553 
554 int command_run_line(struct command_context *context, char *line)
555 {
556  /* all the parent commands have been registered with the interpreter
557  * so, can just evaluate the line as a script and check for
558  * results
559  */
560  /* run the line thru a script engine */
561  int retval = ERROR_FAIL;
562  int retcode;
563  /* Beware! This code needs to be reentrant. It is also possible
564  * for OpenOCD commands to be invoked directly from Tcl. This would
565  * happen when the Jim Tcl interpreter is provided by eCos for
566  * instance.
567  */
568  struct target *saved_target_override = context->current_target_override;
569  context->current_target_override = NULL;
570 
571  Jim_Interp *interp = context->interp;
572  struct command_context *old_context = Jim_GetAssocData(interp, "context");
573  Jim_DeleteAssocData(interp, "context");
574  retcode = Jim_SetAssocData(interp, "context", NULL, context);
575  if (retcode == JIM_OK) {
576  /* associated the return value */
577  Jim_DeleteAssocData(interp, "retval");
578  retcode = Jim_SetAssocData(interp, "retval", NULL, &retval);
579  if (retcode == JIM_OK) {
580  retcode = Jim_Eval_Named(interp, line, 0, 0);
581 
582  Jim_DeleteAssocData(interp, "retval");
583  }
584  Jim_DeleteAssocData(interp, "context");
585  int inner_retcode = Jim_SetAssocData(interp, "context", NULL, old_context);
586  if (retcode == JIM_OK)
587  retcode = inner_retcode;
588  }
589  context->current_target_override = saved_target_override;
590  if (retcode == JIM_OK) {
591  const char *result;
592  int reslen;
593 
594  result = Jim_GetString(Jim_GetResult(interp), &reslen);
595  if (reslen > 0) {
596  command_output_text(context, result);
597  command_output_text(context, "\n");
598  }
599  retval = ERROR_OK;
600  } else if (retcode == JIM_EXIT) {
601  /* ignore.
602  * exit(Jim_GetExitCode(interp)); */
603  } else if (retcode == ERROR_COMMAND_CLOSE_CONNECTION) {
604  return retcode;
605  } else {
606  Jim_MakeErrorMessage(interp);
607  /* error is broadcast */
608  LOG_USER("%s", Jim_GetString(Jim_GetResult(interp), NULL));
609 
610  if (retval == ERROR_OK) {
611  /* It wasn't a low level OpenOCD command that failed */
612  return ERROR_FAIL;
613  }
614  return retval;
615  }
616 
617  return retval;
618 }
619 
620 int command_run_linef(struct command_context *context, const char *format, ...)
621 {
622  int retval = ERROR_FAIL;
623  char *string;
624  va_list ap;
625  va_start(ap, format);
626  string = alloc_vprintf(format, ap);
627  if (string) {
628  retval = command_run_line(context, string);
629  free(string);
630  }
631  va_end(ap);
632  return retval;
633 }
634 
637 {
638  context->output_handler = output_handler;
639  context->output_handler_priv = priv;
640 }
641 
643 {
644  struct command_context *copy_context = malloc(sizeof(struct command_context));
645 
646  *copy_context = *context;
647 
648  return copy_context;
649 }
650 
651 void command_done(struct command_context *cmd_ctx)
652 {
653  if (!cmd_ctx)
654  return;
655 
656  free(cmd_ctx);
657 }
658 
659 /* find full path to file */
660 static int jim_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
661 {
662  if (argc != 2)
663  return JIM_ERR;
664  const char *file = Jim_GetString(argv[1], NULL);
665  char *full_path = find_file(file);
666  if (!full_path)
667  return JIM_ERR;
668  Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
669  free(full_path);
670 
671  Jim_SetResult(interp, result);
672  return JIM_OK;
673 }
674 
675 COMMAND_HANDLER(handle_echo)
676 {
677  if (CMD_ARGC == 2 && !strcmp(CMD_ARGV[0], "-n")) {
678  LOG_USER_N("%s", CMD_ARGV[1]);
679  return ERROR_OK;
680  }
681 
682  if (CMD_ARGC != 1)
683  return ERROR_FAIL;
684 
685  LOG_USER("%s", CMD_ARGV[0]);
686  return ERROR_OK;
687 }
688 
689 /* Capture progress output and return as tcl return value. If the
690  * progress output was empty, return tcl return value.
691  */
692 static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
693 {
694  if (argc != 2)
695  return JIM_ERR;
696 
698 
699  /* disable polling during capture. This avoids capturing output
700  * from polling.
701  *
702  * This is necessary in order to avoid accidentally getting a non-empty
703  * string for tcl fn's.
704  */
705  bool save_poll_mask = jtag_poll_mask();
706 
707  const char *str = Jim_GetString(argv[1], NULL);
708  int retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__);
709 
710  jtag_poll_unmask(save_poll_mask);
711 
713 
714  return retcode;
715 }
716 
717 struct help_entry {
718  struct list_head lh;
719  char *cmd_name;
720  char *help;
721  char *usage;
722 };
723 
724 static COMMAND_HELPER(command_help_show, struct help_entry *c,
725  bool show_help, const char *cmd_match);
726 
727 static COMMAND_HELPER(command_help_show_list, bool show_help, const char *cmd_match)
728 {
729  struct help_entry *entry;
730 
731  list_for_each_entry(entry, CMD_CTX->help_list, lh)
732  CALL_COMMAND_HANDLER(command_help_show, entry, show_help, cmd_match);
733  return ERROR_OK;
734 }
735 
736 #define HELP_LINE_WIDTH(_n) (int)(76 - (2 * _n))
737 
738 static void command_help_show_indent(unsigned n)
739 {
740  for (unsigned i = 0; i < n; i++)
741  LOG_USER_N(" ");
742 }
743 static void command_help_show_wrap(const char *str, unsigned n, unsigned n2)
744 {
745  const char *cp = str, *last = str;
746  while (*cp) {
747  const char *next = last;
748  do {
749  cp = next;
750  do {
751  next++;
752  } while (*next != ' ' && *next != '\t' && *next != '\0');
753  } while ((next - last < HELP_LINE_WIDTH(n)) && *next != '\0');
754  if (next - last < HELP_LINE_WIDTH(n))
755  cp = next;
757  LOG_USER("%.*s", (int)(cp - last), last);
758  last = cp + 1;
759  n = n2;
760  }
761 }
762 
763 static COMMAND_HELPER(command_help_show, struct help_entry *c,
764  bool show_help, const char *cmd_match)
765 {
766  unsigned int n = 0;
767  for (const char *s = strchr(c->cmd_name, ' '); s; s = strchr(s + 1, ' '))
768  n++;
769 
770  /* If the match string occurs anywhere, we print out
771  * stuff for this command. */
772  bool is_match = strstr(c->cmd_name, cmd_match) ||
773  (c->usage && strstr(c->usage, cmd_match)) ||
774  (c->help && strstr(c->help, cmd_match));
775 
776  if (is_match) {
777  if (c->usage && strlen(c->usage) > 0) {
778  char *msg = alloc_printf("%s %s", c->cmd_name, c->usage);
779  command_help_show_wrap(msg, n, n + 5);
780  free(msg);
781  } else {
782  command_help_show_wrap(c->cmd_name, n, n + 5);
783  }
784  }
785 
786  if (is_match && show_help) {
787  char *msg;
788 
789  /* TODO: factorize jim_command_mode() to avoid running jim command here */
790  char *request = alloc_printf("command mode %s", c->cmd_name);
791  if (!request) {
792  LOG_ERROR("Out of memory");
793  return ERROR_FAIL;
794  }
795  int retval = Jim_Eval(CMD_CTX->interp, request);
796  free(request);
798  if (retval != JIM_ERR) {
799  const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL);
800  if (!strcmp(result, "any"))
801  mode = COMMAND_ANY;
802  else if (!strcmp(result, "config"))
804  else if (!strcmp(result, "exec"))
805  mode = COMMAND_EXEC;
806  }
807 
808  /* Normal commands are runtime-only; highlight exceptions */
809  if (mode != COMMAND_EXEC) {
810  const char *stage_msg = "";
811 
812  switch (mode) {
813  case COMMAND_CONFIG:
814  stage_msg = " (configuration command)";
815  break;
816  case COMMAND_ANY:
817  stage_msg = " (command valid any time)";
818  break;
819  default:
820  stage_msg = " (?mode error?)";
821  break;
822  }
823  msg = alloc_printf("%s%s", c->help ? c->help : "", stage_msg);
824  } else
825  msg = alloc_printf("%s", c->help ? c->help : "");
826 
827  if (msg) {
828  command_help_show_wrap(msg, n + 3, n + 3);
829  free(msg);
830  } else
831  return -ENOMEM;
832  }
833 
834  return ERROR_OK;
835 }
836 
837 COMMAND_HANDLER(handle_help_command)
838 {
839  bool full = strcmp(CMD_NAME, "help") == 0;
840  int retval;
841  char *cmd_match;
842 
843  if (CMD_ARGC <= 0)
844  cmd_match = strdup("");
845 
846  else {
847  cmd_match = strdup(CMD_ARGV[0]);
848 
849  for (unsigned int i = 1; i < CMD_ARGC && cmd_match; ++i) {
850  char *prev = cmd_match;
851  cmd_match = alloc_printf("%s %s", prev, CMD_ARGV[i]);
852  free(prev);
853  }
854  }
855 
856  if (!cmd_match) {
857  LOG_ERROR("unable to build search string");
858  return -ENOMEM;
859  }
860  retval = CALL_COMMAND_HANDLER(command_help_show_list, full, cmd_match);
861 
862  free(cmd_match);
863  return retval;
864 }
865 
866 static char *alloc_concatenate_strings(int argc, Jim_Obj * const *argv)
867 {
868  char *prev, *all;
869  int i;
870 
871  assert(argc >= 1);
872 
873  all = strdup(Jim_GetString(argv[0], NULL));
874  if (!all) {
875  LOG_ERROR("Out of memory");
876  return NULL;
877  }
878 
879  for (i = 1; i < argc; ++i) {
880  prev = all;
881  all = alloc_printf("%s %s", all, Jim_GetString(argv[i], NULL));
882  free(prev);
883  if (!all) {
884  LOG_ERROR("Out of memory");
885  return NULL;
886  }
887  }
888 
889  return all;
890 }
891 
892 static int exec_command(Jim_Interp *interp, struct command_context *cmd_ctx,
893  struct command *c, int argc, Jim_Obj * const *argv)
894 {
895  if (c->jim_handler)
896  return c->jim_handler(interp, argc, argv);
897 
898  /* use c->handler */
899  unsigned int nwords;
900  char **words = script_command_args_alloc(argc, argv, &nwords);
901  if (!words)
902  return JIM_ERR;
903 
904  int retval = run_command(cmd_ctx, c, (const char **)words, nwords);
905  script_command_args_free(words, nwords);
906  return command_retval_set(interp, retval);
907 }
908 
909 static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
910 {
911  /* check subcommands */
912  if (argc > 1) {
913  char *s = alloc_printf("%s %s", Jim_GetString(argv[0], NULL), Jim_GetString(argv[1], NULL));
914  Jim_Obj *js = Jim_NewStringObj(interp, s, -1);
915  Jim_IncrRefCount(js);
916  free(s);
917  Jim_Cmd *cmd = Jim_GetCommand(interp, js, JIM_NONE);
918  if (cmd) {
919  int retval = Jim_EvalObjPrefix(interp, js, argc - 2, argv + 2);
920  Jim_DecrRefCount(interp, js);
921  return retval;
922  }
923  Jim_DecrRefCount(interp, js);
924  }
925 
926  script_debug(interp, argc, argv);
927 
928  struct command *c = jim_to_command(interp);
929  if (!c->jim_handler && !c->handler) {
930  Jim_EvalObjPrefix(interp, Jim_NewStringObj(interp, "usage", -1), 1, argv);
931  return JIM_ERR;
932  }
933 
935 
936  if (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL)))
937  return JIM_ERR;
938 
939  /*
940  * TODO: to be removed after v0.12.0
941  * workaround for https://sourceforge.net/p/openocd/tickets/362/
942  * After syntax change of "expr" in jimtcl 0.81
943  * the replacement of jimtcl "expr" with openocd version in
944  * https://review.openocd.org/6510/
945  * introduces too many target polling during math expressions with
946  * "expr" commands.
947  * After v0.12.0 replace the following two lines with
948  * target_call_timer_callbacks();
949  */
950  if (strcmp(c->name, "expr"))
952 
953  /*
954  * Black magic of overridden current target:
955  * If the command we are going to handle has a target prefix,
956  * override the current target temporarily for the time
957  * of processing the command.
958  * current_target_override is used also for event handlers
959  * therefore we prevent touching it if command has no prefix.
960  * Previous override is saved and restored back to ensure
961  * correct work when jim_command_dispatch() is re-entered.
962  */
963  struct target *saved_target_override = cmd_ctx->current_target_override;
964  if (c->jim_override_target)
966 
967  int retval = exec_command(interp, cmd_ctx, c, argc, argv);
968 
969  if (c->jim_override_target)
970  cmd_ctx->current_target_override = saved_target_override;
971 
972  return retval;
973 }
974 
975 static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
976 {
978  enum command_mode mode;
979 
980  if (argc > 1) {
981  char *full_name = alloc_concatenate_strings(argc - 1, argv + 1);
982  if (!full_name)
983  return JIM_ERR;
984  Jim_Obj *s = Jim_NewStringObj(interp, full_name, -1);
985  Jim_IncrRefCount(s);
986  Jim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE);
987  Jim_DecrRefCount(interp, s);
988  free(full_name);
989  if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_oocd_command(cmd))) {
990  Jim_SetResultString(interp, "unknown", -1);
991  return JIM_OK;
992  }
993 
994  if (jimcmd_is_proc(cmd)) {
995  /* tcl proc */
996  mode = COMMAND_ANY;
997  } else {
998  struct command *c = jimcmd_privdata(cmd);
999 
1000  mode = c->mode;
1001  }
1002  } else
1003  mode = cmd_ctx->mode;
1004 
1005  const char *mode_str;
1006  switch (mode) {
1007  case COMMAND_ANY:
1008  mode_str = "any";
1009  break;
1010  case COMMAND_CONFIG:
1011  mode_str = "config";
1012  break;
1013  case COMMAND_EXEC:
1014  mode_str = "exec";
1015  break;
1016  default:
1017  mode_str = "unknown";
1018  break;
1019  }
1020  Jim_SetResultString(interp, mode_str, -1);
1021  return JIM_OK;
1022 }
1023 
1025 {
1026  struct help_entry *curr, *n;
1027 
1028  list_for_each_entry_safe(curr, n, cmd_ctx->help_list, lh) {
1029  list_del(&curr->lh);
1030  free(curr->cmd_name);
1031  free(curr->help);
1032  free(curr->usage);
1033  free(curr);
1034  }
1035  return ERROR_OK;
1036 }
1037 
1038 static int help_del_command(struct command_context *cmd_ctx, const char *cmd_name)
1039 {
1040  struct help_entry *curr;
1041 
1042  list_for_each_entry(curr, cmd_ctx->help_list, lh) {
1043  if (!strcmp(cmd_name, curr->cmd_name)) {
1044  list_del(&curr->lh);
1045  free(curr->cmd_name);
1046  free(curr->help);
1047  free(curr->usage);
1048  free(curr);
1049  break;
1050  }
1051  }
1052 
1053  return ERROR_OK;
1054 }
1055 
1056 static int help_add_command(struct command_context *cmd_ctx,
1057  const char *cmd_name, const char *help_text, const char *usage_text)
1058 {
1059  int cmp = -1; /* add after curr */
1060  struct help_entry *curr;
1061 
1062  list_for_each_entry_reverse(curr, cmd_ctx->help_list, lh) {
1063  cmp = strcmp(cmd_name, curr->cmd_name);
1064  if (cmp >= 0)
1065  break;
1066  }
1067 
1068  struct help_entry *entry;
1069  if (cmp) {
1070  entry = calloc(1, sizeof(*entry));
1071  if (!entry) {
1072  LOG_ERROR("Out of memory");
1073  return ERROR_FAIL;
1074  }
1075  entry->cmd_name = strdup(cmd_name);
1076  if (!entry->cmd_name) {
1077  LOG_ERROR("Out of memory");
1078  free(entry);
1079  return ERROR_FAIL;
1080  }
1081  list_add(&entry->lh, &curr->lh);
1082  } else {
1083  entry = curr;
1084  }
1085 
1086  if (help_text) {
1087  char *text = strdup(help_text);
1088  if (!text) {
1089  LOG_ERROR("Out of memory");
1090  return ERROR_FAIL;
1091  }
1092  free(entry->help);
1093  entry->help = text;
1094  }
1095 
1096  if (usage_text) {
1097  char *text = strdup(usage_text);
1098  if (!text) {
1099  LOG_ERROR("Out of memory");
1100  return ERROR_FAIL;
1101  }
1102  free(entry->usage);
1103  entry->usage = text;
1104  }
1105 
1106  return ERROR_OK;
1107 }
1108 
1109 COMMAND_HANDLER(handle_help_add_command)
1110 {
1111  if (CMD_ARGC != 2)
1113 
1114  const char *help = !strcmp(CMD_NAME, "add_help_text") ? CMD_ARGV[1] : NULL;
1115  const char *usage = !strcmp(CMD_NAME, "add_usage_text") ? CMD_ARGV[1] : NULL;
1116  if (!help && !usage) {
1117  LOG_ERROR("command name '%s' is unknown", CMD_NAME);
1119  }
1120  const char *cmd_name = CMD_ARGV[0];
1122 }
1123 
1124 /* sleep command sleeps for <n> milliseconds
1125  * this is useful in target startup scripts
1126  */
1127 COMMAND_HANDLER(handle_sleep_command)
1128 {
1129  bool busy = false;
1130  if (CMD_ARGC == 2) {
1131  if (strcmp(CMD_ARGV[1], "busy") == 0)
1132  busy = true;
1133  else
1135  } else if (CMD_ARGC < 1 || CMD_ARGC > 2)
1137 
1138  unsigned long duration = 0;
1139  int retval = parse_ulong(CMD_ARGV[0], &duration);
1140  if (retval != ERROR_OK)
1141  return retval;
1142 
1143  if (!busy) {
1144  int64_t then = timeval_ms();
1145  while (timeval_ms() - then < (int64_t)duration) {
1147  keep_alive();
1148  usleep(1000);
1149  }
1150  } else
1152 
1153  return ERROR_OK;
1154 }
1155 
1156 static const struct command_registration command_subcommand_handlers[] = {
1157  {
1158  .name = "mode",
1159  .mode = COMMAND_ANY,
1160  .jim_handler = jim_command_mode,
1161  .usage = "[command_name ...]",
1162  .help = "Returns the command modes allowed by a command: "
1163  "'any', 'config', or 'exec'. If no command is "
1164  "specified, returns the current command mode. "
1165  "Returns 'unknown' if an unknown command is given. "
1166  "Command can be multiple tokens.",
1167  },
1169 };
1170 
1171 static const struct command_registration command_builtin_handlers[] = {
1172  {
1173  .name = "ocd_find",
1174  .mode = COMMAND_ANY,
1175  .jim_handler = jim_find,
1176  .help = "find full path to file",
1177  .usage = "file",
1178  },
1179  {
1180  .name = "capture",
1181  .mode = COMMAND_ANY,
1182  .jim_handler = jim_capture,
1183  .help = "Capture progress output and return as tcl return value. If the "
1184  "progress output was empty, return tcl return value.",
1185  .usage = "command",
1186  },
1187  {
1188  .name = "echo",
1189  .handler = handle_echo,
1190  .mode = COMMAND_ANY,
1191  .help = "Logs a message at \"user\" priority. "
1192  "Option \"-n\" suppresses trailing newline",
1193  .usage = "[-n] string",
1194  },
1195  {
1196  .name = "add_help_text",
1197  .handler = handle_help_add_command,
1198  .mode = COMMAND_ANY,
1199  .help = "Add new command help text; "
1200  "Command can be multiple tokens.",
1201  .usage = "command_name helptext_string",
1202  },
1203  {
1204  .name = "add_usage_text",
1205  .handler = handle_help_add_command,
1206  .mode = COMMAND_ANY,
1207  .help = "Add new command usage text; "
1208  "command can be multiple tokens.",
1209  .usage = "command_name usage_string",
1210  },
1211  {
1212  .name = "sleep",
1213  .handler = handle_sleep_command,
1214  .mode = COMMAND_ANY,
1215  .help = "Sleep for specified number of milliseconds. "
1216  "\"busy\" will busy wait instead (avoid this).",
1217  .usage = "milliseconds ['busy']",
1218  },
1219  {
1220  .name = "help",
1221  .handler = handle_help_command,
1222  .mode = COMMAND_ANY,
1223  .help = "Show full command help; "
1224  "command can be multiple tokens.",
1225  .usage = "[command_name]",
1226  },
1227  {
1228  .name = "usage",
1229  .handler = handle_help_command,
1230  .mode = COMMAND_ANY,
1231  .help = "Show basic command usage; "
1232  "command can be multiple tokens.",
1233  .usage = "[command_name]",
1234  },
1235  {
1236  .name = "command",
1237  .mode = COMMAND_ANY,
1238  .help = "core command group (introspection)",
1239  .chain = command_subcommand_handlers,
1240  .usage = "",
1241  },
1243 };
1244 
1245 struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp)
1246 {
1247  struct command_context *context = calloc(1, sizeof(struct command_context));
1248 
1249  context->mode = COMMAND_EXEC;
1250 
1251  /* context can be duplicated. Put list head on separate mem-chunk to keep list consistent */
1252  context->help_list = malloc(sizeof(*context->help_list));
1253  INIT_LIST_HEAD(context->help_list);
1254 
1255  /* Create a jim interpreter if we were not handed one */
1256  if (!interp) {
1257  /* Create an interpreter */
1258  interp = Jim_CreateInterp();
1259  /* Add all the Jim core commands */
1260  Jim_RegisterCoreCommands(interp);
1261  Jim_InitStaticExtensions(interp);
1262  }
1263 
1264  context->interp = interp;
1265 
1267 
1268  Jim_SetAssocData(interp, "context", NULL, context);
1269  if (Jim_Eval_Named(interp, startup_tcl, "embedded:startup.tcl", 1) == JIM_ERR) {
1270  LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD)");
1271  Jim_MakeErrorMessage(interp);
1272  LOG_USER_N("%s", Jim_GetString(Jim_GetResult(interp), NULL));
1273  exit(-1);
1274  }
1275  Jim_DeleteAssocData(interp, "context");
1276 
1277  return context;
1278 }
1279 
1280 void command_exit(struct command_context *context)
1281 {
1282  if (!context)
1283  return;
1284 
1285  Jim_FreeInterp(context->interp);
1286  free(context->help_list);
1287  command_done(context);
1288 }
1289 
1291 {
1292  if (!cmd_ctx)
1294 
1295  cmd_ctx->mode = mode;
1296  return ERROR_OK;
1297 }
1298 
1300 {
1301  static int recursion;
1302  if (recursion)
1303  return;
1304 
1305  recursion++;
1306  Jim_ProcessEvents(cmd_ctx->interp, JIM_ALL_EVENTS | JIM_DONT_WAIT);
1307  recursion--;
1308 }
1309 
1310 #define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max) \
1311  int parse ## name(const char *str, type * ul) \
1312  { \
1313  if (!*str) { \
1314  LOG_ERROR("Invalid command argument"); \
1315  return ERROR_COMMAND_ARGUMENT_INVALID; \
1316  } \
1317  char *end; \
1318  errno = 0; \
1319  *ul = func(str, &end, 0); \
1320  if (*end) { \
1321  LOG_ERROR("Invalid command argument"); \
1322  return ERROR_COMMAND_ARGUMENT_INVALID; \
1323  } \
1324  if ((max == *ul) && (errno == ERANGE)) { \
1325  LOG_ERROR("Argument overflow"); \
1326  return ERROR_COMMAND_ARGUMENT_OVERFLOW; \
1327  } \
1328  if (min && (min == *ul) && (errno == ERANGE)) { \
1329  LOG_ERROR("Argument underflow"); \
1330  return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \
1331  } \
1332  return ERROR_OK; \
1333  }
1334 DEFINE_PARSE_NUM_TYPE(_ulong, unsigned long, strtoul, 0, ULONG_MAX)
1335 DEFINE_PARSE_NUM_TYPE(_ullong, unsigned long long, strtoull, 0, ULLONG_MAX)
1336 DEFINE_PARSE_NUM_TYPE(_long, long, strtol, LONG_MIN, LONG_MAX)
1337 DEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX)
1338 
1339 #define DEFINE_PARSE_WRAPPER(name, type, min, max, functype, funcname) \
1340  int parse ## name(const char *str, type * ul) \
1341  { \
1342  functype n; \
1343  int retval = parse ## funcname(str, &n); \
1344  if (retval != ERROR_OK) \
1345  return retval; \
1346  if (n > max) \
1347  return ERROR_COMMAND_ARGUMENT_OVERFLOW; \
1348  if (min) \
1349  return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \
1350  *ul = n; \
1351  return ERROR_OK; \
1352  }
1353 
1354 #define DEFINE_PARSE_ULONGLONG(name, type, min, max) \
1355  DEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long long, _ullong)
1356 DEFINE_PARSE_ULONGLONG(_uint, unsigned, 0, UINT_MAX)
1357 DEFINE_PARSE_ULONGLONG(_u64, uint64_t, 0, UINT64_MAX)
1358 DEFINE_PARSE_ULONGLONG(_u32, uint32_t, 0, UINT32_MAX)
1359 DEFINE_PARSE_ULONGLONG(_u16, uint16_t, 0, UINT16_MAX)
1360 DEFINE_PARSE_ULONGLONG(_u8, uint8_t, 0, UINT8_MAX)
1361 
1363 
1364 #define DEFINE_PARSE_LONGLONG(name, type, min, max) \
1365  DEFINE_PARSE_WRAPPER(name, type, min, max, long long, _llong)
1366 DEFINE_PARSE_LONGLONG(_int, int, n < INT_MIN, INT_MAX)
1367 DEFINE_PARSE_LONGLONG(_s64, int64_t, n < INT64_MIN, INT64_MAX)
1368 DEFINE_PARSE_LONGLONG(_s32, int32_t, n < INT32_MIN, INT32_MAX)
1369 DEFINE_PARSE_LONGLONG(_s16, int16_t, n < INT16_MIN, INT16_MAX)
1370 DEFINE_PARSE_LONGLONG(_s8, int8_t, n < INT8_MIN, INT8_MAX)
1371 
1372 static int command_parse_bool(const char *in, bool *out,
1373  const char *on, const char *off)
1374 {
1375  if (strcasecmp(in, on) == 0)
1376  *out = true;
1377  else if (strcasecmp(in, off) == 0)
1378  *out = false;
1379  else
1381  return ERROR_OK;
1382 }
1383 
1384 int command_parse_bool_arg(const char *in, bool *out)
1385 {
1386  if (command_parse_bool(in, out, "on", "off") == ERROR_OK)
1387  return ERROR_OK;
1388  if (command_parse_bool(in, out, "enable", "disable") == ERROR_OK)
1389  return ERROR_OK;
1390  if (command_parse_bool(in, out, "true", "false") == ERROR_OK)
1391  return ERROR_OK;
1392  if (command_parse_bool(in, out, "yes", "no") == ERROR_OK)
1393  return ERROR_OK;
1394  if (command_parse_bool(in, out, "1", "0") == ERROR_OK)
1395  return ERROR_OK;
1397 }
1398 
1399 COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label)
1400 {
1401  switch (CMD_ARGC) {
1402  case 1: {
1403  const char *in = CMD_ARGV[0];
1404  if (command_parse_bool_arg(in, out) != ERROR_OK) {
1405  LOG_ERROR("%s: argument '%s' is not valid", CMD_NAME, in);
1407  }
1408  }
1409  /* fallthrough */
1410  case 0:
1411  LOG_INFO("%s is %s", label, *out ? "enabled" : "disabled");
1412  break;
1413  default:
1415  }
1416  return ERROR_OK;
1417 }
const char * label
Definition: arm_cti.c:164
enum arm_mode mode
Definition: armv4_5.c:277
const char * name
Definition: armv4_5.c:76
static struct log_capture_state * command_log_capture_start(Jim_Interp *interp)
Definition: command.c:71
struct command_context * current_command_context(Jim_Interp *interp)
Definition: command.c:187
static void command_free(struct Jim_Interp *interp, void *priv)
Definition: command.c:261
int command_parse_bool_arg(const char *in, bool *out)
Definition: command.c:1384
static void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj *const *argv)
Definition: command.c:142
int help_del_all_commands(struct command_context *cmd_ctx)
Unregisters the help for all commands.
Definition: command.c:1024
static bool command_can_run(struct command_context *cmd_ctx, struct command *c, const char *full_name)
Definition: command.c:498
static int jim_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Definition: command.c:660
bool jimcmd_is_oocd_command(Jim_Cmd *cmd)
Return true if the command cmd is registered by OpenOCD.
Definition: command.c:54
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:450
static int command_parse_bool(const char *in, bool *out, const char *on, const char *off)
Definition: command.c:1372
static struct command * register_command(struct command_context *context, const char *cmd_prefix, const struct command_registration *cr)
Definition: command.c:269
struct command_context * global_cmd_ctx
Definition: openocd.c:292
static int help_add_command(struct command_context *cmd_ctx, const char *cmd_name, const char *help_text, const char *usage_text)
Definition: command.c:1056
static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Definition: command.c:975
static struct command * command_new(struct command_context *cmd_ctx, const char *full_name, const struct command_registration *cr)
Definition: command.c:224
static COMMAND_HELPER(command_help_show, struct help_entry *c, bool show_help, const char *cmd_match)
Definition: command.c:763
static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Definition: command.c:909
void command_done(struct command_context *cmd_ctx)
Frees the resources associated with a command context.
Definition: command.c:651
void * jimcmd_privdata(Jim_Cmd *cmd)
Return the pointer to the command's private data specified during the registration of command cmd .
Definition: command.c:59
static void command_help_show_indent(unsigned n)
Definition: command.c:738
static bool jimcmd_is_proc(Jim_Cmd *cmd)
Definition: command.c:49
#define HELP_LINE_WIDTH(_n)
Definition: command.c:736
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:473
static void command_help_show_wrap(const char *str, unsigned n, unsigned n2)
Definition: command.c:743
static int unregister_command(struct command_context *context, const char *cmd_prefix, const char *name)
Definition: command.c:432
COMMAND_HANDLER(handle_echo)
Definition: command.c:675
static void command_log_capture_finish(struct log_capture_state *state)
Definition: command.c:108
void process_jim_events(struct command_context *cmd_ctx)
Definition: command.c:1299
static const struct command_registration command_subcommand_handlers[]
Definition: command.c:1156
struct command_context * copy_command_context(struct command_context *context)
Creates a copy of an existing command context.
Definition: command.c:642
void command_exit(struct command_context *context)
Shutdown a command context.
Definition: command.c:1280
static struct command * command_find_from_name(Jim_Interp *interp, const char *name)
Find a openocd command from fullname.
Definition: command.c:209
static char ** script_command_args_alloc(unsigned argc, Jim_Obj *const *argv, unsigned *nwords)
Definition: command.c:166
static int run_command(struct command_context *context, struct command *c, const char **words, unsigned num_words)
Definition: command.c:522
#define __THIS__FILE__
Definition: command.c:34
static __attribute__((format(PRINTF_ATTRIBUTE_FORMAT, 2, 3)))
Definition: command.c:362
void command_output_text(struct command_context *context, const char *data)
Definition: command.c:444
#define DEFINE_PARSE_LONGLONG(name, type, min, max)
Definition: command.c:1364
static void script_command_args_free(char **words, unsigned nwords)
Definition: command.c:159
static int help_del_command(struct command_context *cmd_ctx, const char *cmd_name)
Definition: command.c:1038
struct command_context * command_init(const char *startup_tcl, Jim_Interp *interp)
Creates a new command context using the startup TCL provided and the existing Jim interpreter,...
Definition: command.c:1245
int command_context_mode(struct command_context *cmd_ctx, enum command_mode mode)
Definition: command.c:1290
static char * alloc_concatenate_strings(int argc, Jim_Obj *const *argv)
Definition: command.c:866
static int exec_command(Jim_Interp *interp, struct command_context *cmd_ctx, struct command *c, int argc, Jim_Obj *const *argv)
Definition: command.c:892
static void tcl_output(void *privData, const char *file, unsigned line, const char *function, const char *string)
Definition: command.c:64
int command_run_linef(struct command_context *context, const char *format,...)
Definition: command.c:620
int __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds, void *data, struct target *override_target)
Definition: command.c:316
static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Definition: command.c:692
void command_set_output_handler(struct command_context *context, command_output_handler_t output_handler, void *priv)
Definition: command.c:635
static const struct command_registration command_builtin_handlers[]
Definition: command.c:1171
int unregister_all_commands(struct command_context *context, const char *cmd_prefix)
Unregisters all commands from the specified context.
Definition: command.c:416
#define DEFINE_PARSE_ULONGLONG(name, type, min, max)
Definition: command.c:1354
int command_run_line(struct command_context *context, char *line)
Definition: command.c:554
static int command_retval_set(Jim_Interp *interp, int retval)
Definition: command.c:129
#define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max)
Definition: command.c:1310
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:117
#define CMD_NAME
Use this macro to access the name of the command being handled, rather than accessing the variable di...
Definition: command.h:160
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:155
int parse_ulong(const char *str, unsigned long *ul)
#define PRINTF_ATTRIBUTE_FORMAT
Definition: command.h:27
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:385
#define ERROR_COMMAND_CLOSE_CONNECTION
Definition: command.h:384
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:150
int(* command_output_handler_t)(struct command_context *context, const char *line)
The type signature for command context's output handler.
Definition: command.h:49
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:145
static struct command * jim_to_command(Jim_Interp *interp)
Definition: command.h:206
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:247
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
Definition: command.h:268
command_mode
OpenOCD command mode is COMMAND_CONFIG at start, then switches to COMMAND_EXEC during the execution o...
Definition: command.h:39
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_UNKNOWN
Definition: command.h:43
@ COMMAND_EXEC
Definition: command.h:40
char * find_file(const char *file)
Definition: configuration.c:61
static struct esp_usb_jtag * priv
Definition: esp_usb_jtag.c:219
uint8_t length
Definition: esp_usb_jtag.c:1
void jtag_poll_unmask(bool saved)
Restore saved mask for polling.
Definition: jtag/core.c:177
bool jtag_poll_mask(void)
Mask (disable) polling and return the current mask status that should be feed to jtag_poll_unmask() t...
Definition: jtag/core.c:170
The JTAG interface can be implemented with a software or hardware fifo.
static void list_add(struct list_head *new, struct list_head *head)
list_add - add a new entry
Definition: list.h:112
#define list_for_each_entry(pos, head, member)
list_for_each_entry - iterate over list of given type
Definition: list.h:643
static void list_del(struct list_head *entry)
list_del - deletes entry from list.
Definition: list.h:160
#define list_for_each_entry_safe(pos, n, head, member)
list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
Definition: list.h:744
#define list_for_each_entry_reverse(pos, head, member)
list_for_each_entry_reverse - iterate backwards over list of given type.
Definition: list.h:654
static void INIT_LIST_HEAD(struct list_head *list)
INIT_LIST_HEAD - Initialize a list_head structure.
Definition: list.h:61
int log_remove_callback(log_callback_fn fn, void *priv)
Definition: log.c:324
int log_add_callback(log_callback_fn fn, void *priv)
Definition: log.c:299
char * alloc_vprintf(const char *fmt, va_list ap)
Definition: log.c:341
int debug_level
Definition: log.c:34
void busy_sleep(uint64_t ms)
Definition: log.c:473
void keep_alive(void)
Definition: log.c:419
char * alloc_printf(const char *format,...)
Definition: log.c:366
#define LOG_USER(expr ...)
Definition: log.h:126
#define ERROR_FAIL
Definition: log.h:161
#define LOG_USER_N(expr ...)
Definition: log.h:129
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_INFO(expr ...)
Definition: log.h:117
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:155
@ LOG_LVL_DEBUG
Definition: log.h:47
static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:117
enum command_mode mode
Definition: command.h:54
Jim_Interp * interp
Definition: command.h:53
struct list_head * help_list
Definition: command.h:66
void * output_handler_priv
Definition: command.h:65
struct target * current_target_override
Definition: command.h:57
command_output_handler_t output_handler
Definition: command.h:64
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
const char * name
Definition: command.h:229
command_handler_t handler
Definition: command.h:230
enum command_mode mode
Definition: command.h:232
Jim_CmdProc * jim_handler
Definition: command.h:231
const struct command_registration * chain
If non-NULL, the commands in chain will be registered in the same context and scope of this registrat...
Definition: command.h:243
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:235
const char * help
Definition: command.h:233
void * jim_handler_data
Definition: command.h:195
Jim_CmdProc * jim_handler
Definition: command.h:194
command_handler_t handler
Definition: command.h:193
struct target * jim_override_target
Definition: command.h:197
enum command_mode mode
Definition: command.h:199
char * name
Definition: command.h:192
Definition: command.c:717
char * cmd_name
Definition: command.c:719
char * usage
Definition: command.c:721
struct list_head lh
Definition: command.c:718
char * help
Definition: command.c:720
Definition: list.h:26
Jim_Obj * output
Definition: command.c:38
Jim_Interp * interp
Definition: command.c:37
Definition: target.h:120
int target_call_timer_callbacks_now()
Invoke this to ensure that e.g.
Definition: target.c:1953
int64_t timeval_ms(void)
uint64_t target_addr_t
Definition: types.h:335
#define TARGET_ADDR_MAX
Definition: types.h:336
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t state[4]
Definition: vdebug.c:21