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