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