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