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 
348 void command_print_sameline(struct command_invocation *cmd, const char *format, ...)
349 {
350  char *string;
351 
352  va_list ap;
353  va_start(ap, format);
354 
355  string = alloc_vprintf(format, ap);
356  if (string && cmd) {
357  /* we want this collected in the log + we also want to pick it up as a tcl return
358  * value.
359  *
360  * The latter bit isn't precisely neat, but will do for now.
361  */
362  Jim_AppendString(cmd->ctx->interp, cmd->output, string, -1);
363  /* We already printed it above
364  * command_output_text(context, string); */
365  free(string);
366  }
367 
368  va_end(ap);
369 }
370 
371 void command_print(struct command_invocation *cmd, const char *format, ...)
372 {
373  char *string;
374 
375  va_list ap;
376  va_start(ap, format);
377 
378  string = alloc_vprintf(format, ap);
379  if (string && cmd) {
380  strcat(string, "\n"); /* alloc_vprintf guaranteed the buffer to be at least one
381  *char longer */
382  /* we want this collected in the log + we also want to pick it up as a tcl return
383  * value.
384  *
385  * The latter bit isn't precisely neat, but will do for now.
386  */
387  Jim_AppendString(cmd->ctx->interp, cmd->output, string, -1);
388  /* We already printed it above
389  * command_output_text(context, string); */
390  free(string);
391  }
392 
393  va_end(ap);
394 }
395 
396 static bool command_can_run(struct command_context *cmd_ctx, struct command *c, const char *full_name)
397 {
398  if (c->mode == COMMAND_ANY || c->mode == cmd_ctx->mode)
399  return true;
400 
401  /* Many commands may be run only before/after 'init' */
402  const char *when;
403  switch (c->mode) {
404  case COMMAND_CONFIG:
405  when = "before";
406  break;
407  case COMMAND_EXEC:
408  when = "after";
409  break;
410  /* handle the impossible with humor; it guarantees a bug report! */
411  default:
412  when = "if Cthulhu is summoned by";
413  break;
414  }
415  LOG_ERROR("The '%s' command must be used %s 'init'.",
416  full_name ? full_name : c->name, when);
417  return false;
418 }
419 
420 static int jim_exec_command(Jim_Interp *interp, struct command_context *context,
421  struct command *c, int argc, Jim_Obj * const *argv)
422 {
423  /* use c->handler */
424  const char **words = malloc(argc * sizeof(char *));
425  if (!words) {
426  LOG_ERROR("Out of memory");
427  return JIM_ERR;
428  }
429 
430  for (int i = 0; i < argc; i++)
431  words[i] = Jim_GetString(argv[i], NULL);
432 
433  struct command_invocation cmd = {
434  .ctx = context,
435  .current = c,
436  .name = c->name,
437  .argc = argc - 1,
438  .argv = words + 1,
439  .jimtcl_argv = argv + 1,
440  };
441 
442  cmd.output = Jim_NewEmptyStringObj(context->interp);
443  Jim_IncrRefCount(cmd.output);
444 
445  int retval = c->handler(&cmd);
446  if (retval == ERROR_COMMAND_SYNTAX_ERROR) {
447  // Print command syntax
448  Jim_EvalObjPrefix(context->interp, Jim_NewStringObj(context->interp, "usage", -1), 1, argv);
449  } else if (retval == ERROR_COMMAND_CLOSE_CONNECTION) {
450  /* just fall through for a shutdown request */
451  } else {
452  if (retval != ERROR_OK)
453  LOG_DEBUG("Command '%s' failed with error code %d",
454  words[0], retval);
455  /*
456  * Use the command output as the Tcl result.
457  * Drop last '\n' to allow command output concatenation
458  * while keep using command_print() everywhere.
459  */
460  const char *output_txt = Jim_String(cmd.output);
461  int len = strlen(output_txt);
462  if (len && output_txt[len - 1] == '\n')
463  --len;
464  Jim_SetResultString(context->interp, output_txt, len);
465  }
466  Jim_DecrRefCount(context->interp, cmd.output);
467 
468  free(words);
469 
470  if (retval == ERROR_OK)
471  return JIM_OK;
472 
473  // used by telnet server to close one connection
474  if (retval == ERROR_COMMAND_CLOSE_CONNECTION)
475  return JIM_EXIT;
476 
477  Jim_Obj *error_code = Jim_NewListObj(context->interp, NULL, 0);
478  Jim_ListAppendElement(context->interp, error_code, Jim_NewStringObj(context->interp, "OpenOCD", -1));
479  Jim_ListAppendElement(context->interp, error_code, Jim_NewIntObj(context->interp, retval));
480  Jim_SetGlobalVariableStr(context->interp, "errorCode", error_code);
481 
482  return JIM_ERR;
483 }
484 
485 int command_run_line(struct command_context *context, char *line)
486 {
487  /* all the parent commands have been registered with the interpreter
488  * so, can just evaluate the line as a script and check for
489  * results
490  */
491  /* run the line thru a script engine */
492  int retcode;
493  /* Beware! This code needs to be reentrant. It is also possible
494  * for OpenOCD commands to be invoked directly from Tcl. This would
495  * happen when the Jim Tcl interpreter is provided by eCos for
496  * instance.
497  */
498  struct target *saved_target_override = context->current_target_override;
499  context->current_target_override = NULL;
500 
501  Jim_Interp *interp = context->interp;
502  struct command_context *old_context = Jim_GetAssocData(interp, "context");
503  Jim_DeleteAssocData(interp, "context");
504  retcode = Jim_SetAssocData(interp, "context", NULL, context);
505  if (retcode == JIM_OK) {
506  retcode = Jim_Eval_Named(interp, line, NULL, 0);
507  Jim_DeleteAssocData(interp, "context");
508  int inner_retcode = Jim_SetAssocData(interp, "context", NULL, old_context);
509  if (retcode == JIM_OK)
510  retcode = inner_retcode;
511  }
512  context->current_target_override = saved_target_override;
513 
514  if (retcode == JIM_RETURN)
515  retcode = interp->returnCode;
516 
517  if (retcode == JIM_OK) {
518  const char *result;
519  int reslen;
520 
521  result = Jim_GetString(Jim_GetResult(interp), &reslen);
522  if (reslen > 0) {
523  command_output_text(context, result);
524  command_output_text(context, "\n");
525  }
526  return ERROR_OK;
527  }
528 
529  if (retcode == JIM_EXIT) {
530  // used by telnet server to close one connection
532  }
533 
534  Jim_MakeErrorMessage(interp);
535  /* error is broadcast */
536  LOG_USER("%s", Jim_GetString(Jim_GetResult(interp), NULL));
537 
538  return ERROR_FAIL;
539 }
540 
541 int command_run_linef(struct command_context *context, const char *format, ...)
542 {
543  int retval = ERROR_FAIL;
544  char *string;
545  va_list ap;
546  va_start(ap, format);
547  string = alloc_vprintf(format, ap);
548  if (string) {
549  retval = command_run_line(context, string);
550  free(string);
551  }
552  va_end(ap);
553  return retval;
554 }
555 
558 {
559  context->output_handler = output_handler;
560  context->output_handler_priv = priv;
561 }
562 
564 {
565  struct command_context *copy_context = malloc(sizeof(struct command_context));
566 
567  *copy_context = *context;
568 
569  return copy_context;
570 }
571 
572 void command_done(struct command_context *cmd_ctx)
573 {
574  if (!cmd_ctx)
575  return;
576 
577  free(cmd_ctx);
578 }
579 
580 /* find full path to file */
581 COMMAND_HANDLER(handle_find)
582 {
583  if (CMD_ARGC != 1)
585 
586  char *full_path = find_file(CMD_ARGV[0]);
587  if (!full_path)
589 
590  command_print(CMD, "%s", full_path);
591  free(full_path);
592 
593  return ERROR_OK;
594 }
595 
596 COMMAND_HANDLER(handle_echo)
597 {
598  if (CMD_ARGC == 2 && !strcmp(CMD_ARGV[0], "-n")) {
599  LOG_USER_N("%s", CMD_ARGV[1]);
600  return ERROR_OK;
601  }
602 
603  if (CMD_ARGC != 1)
605 
606  LOG_USER("%s", CMD_ARGV[0]);
607  return ERROR_OK;
608 }
609 
610 static void tcl_output(void *privData, const char *file, unsigned int line,
611  const char *function, const char *string)
612 {
613  struct log_capture_state *state = privData;
614  char *old = state->output;
615 
616  state->output = alloc_printf("%s%s", old ? old : "", string);
617  free(old);
618  if (!state->output)
619  LOG_ERROR("Out of memory");
620 }
621 
622 /*
623  * Return both the progress output (LOG_INFO and higher)
624  * and the tcl return value of a command.
625  */
626 COMMAND_HANDLER(handle_command_capture)
627 {
628  struct log_capture_state state = {NULL};
629 
630  if (CMD_ARGC != 1)
632 
633  /* disable polling during capture. This avoids capturing output
634  * from polling.
635  *
636  * This is necessary in order to avoid accidentally getting a non-empty
637  * string for tcl fn's.
638  */
639  bool save_poll_mask = jtag_poll_mask();
640 
642 
643  int jimretval = Jim_EvalObj(CMD_CTX->interp, CMD_JIMTCL_ARGV[0]);
644  const char *cmd_result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL);
645 
647 
648  jtag_poll_unmask(save_poll_mask);
649 
650  if (state.output && *state.output)
651  command_print(CMD, "%s", state.output);
652 
653  if (cmd_result && *cmd_result)
654  command_print(CMD, "%s", cmd_result);
655 
656  free(state.output);
657 
658  return (jimretval == JIM_OK) ? ERROR_OK : ERROR_FAIL;
659 }
660 
661 struct help_entry {
662  struct list_head lh;
663  char *cmd_name;
664  char *help;
665  char *usage;
666 };
667 
668 static COMMAND_HELPER(command_help_show, struct help_entry *c,
669  bool show_help, const char *cmd_match);
670 
671 static COMMAND_HELPER(command_help_show_list, bool show_help, const char *cmd_match)
672 {
673  struct help_entry *entry;
674 
675  list_for_each_entry(entry, CMD_CTX->help_list, lh)
676  CALL_COMMAND_HANDLER(command_help_show, entry, show_help, cmd_match);
677  return ERROR_OK;
678 }
679 
680 #define HELP_LINE_WIDTH(_n) (int)(76 - (2 * _n))
681 
682 static COMMAND_HELPER(command_help_show_indent, unsigned int n)
683 {
684  for (unsigned int i = 0; i < n; i++)
686 
687  return ERROR_OK;
688 }
689 
690 static COMMAND_HELPER(command_help_show_wrap,
691  const char *str, unsigned int n, unsigned int n2)
692 {
693  const char *cp = str, *last = str;
694  while (*cp) {
695  const char *next = last;
696  do {
697  cp = next;
698  do {
699  next++;
700  } while (*next != ' ' && *next != '\t' && *next != '\0');
701  } while ((next - last < HELP_LINE_WIDTH(n)) && *next != '\0');
702  if (next - last < HELP_LINE_WIDTH(n))
703  cp = next;
704  CALL_COMMAND_HANDLER(command_help_show_indent, n);
705  command_print(CMD, "%.*s", (int)(cp - last), last);
706  last = cp + 1;
707  n = n2;
708  }
709 
710  return ERROR_OK;
711 }
712 
713 static COMMAND_HELPER(command_help_show, struct help_entry *c,
714  bool show_help, const char *cmd_match)
715 {
716  unsigned int n = 0;
717  for (const char *s = strchr(c->cmd_name, ' '); s; s = strchr(s + 1, ' '))
718  n++;
719 
720  /* If the match string occurs anywhere, we print out
721  * stuff for this command. */
722  bool is_match = strstr(c->cmd_name, cmd_match) ||
723  (c->usage && strstr(c->usage, cmd_match)) ||
724  (c->help && strstr(c->help, cmd_match));
725 
726  if (is_match) {
727  if (c->usage && strlen(c->usage) > 0) {
728  char *msg = alloc_printf("%s %s", c->cmd_name, c->usage);
729  CALL_COMMAND_HANDLER(command_help_show_wrap, msg, n, n + 5);
730  free(msg);
731  } else {
732  CALL_COMMAND_HANDLER(command_help_show_wrap, c->cmd_name, n, n + 5);
733  }
734  }
735 
736  if (is_match && show_help) {
737  char *msg;
738 
739  enum command_mode mode = get_command_mode(CMD_CTX->interp, c->cmd_name);
740 
741  /* Normal commands are runtime-only; highlight exceptions */
742  if (mode != COMMAND_EXEC) {
743  const char *stage_msg = "";
744 
745  switch (mode) {
746  case COMMAND_CONFIG:
747  stage_msg = " (configuration command)";
748  break;
749  case COMMAND_ANY:
750  stage_msg = " (command valid any time)";
751  break;
752  case COMMAND_UNKNOWN:
753  default:
754  stage_msg = " (?mode error?)";
755  break;
756  }
757  msg = alloc_printf("%s%s", c->help ? c->help : "", stage_msg);
758  } else
759  msg = alloc_printf("%s", c->help ? c->help : "");
760 
761  if (!msg) {
762  LOG_ERROR("Out of memory");
763  return ERROR_FAIL;
764  }
765 
766  CALL_COMMAND_HANDLER(command_help_show_wrap, msg, n + 3, n + 3);
767  free(msg);
768  }
769 
770  return ERROR_OK;
771 }
772 
773 COMMAND_HANDLER(handle_help_command)
774 {
775  bool full = strcmp(CMD_NAME, "help") == 0;
776  int retval;
777  char *cmd_match;
778 
779  if (CMD_ARGC <= 0)
780  cmd_match = strdup("");
781 
782  else {
783  cmd_match = strdup(CMD_ARGV[0]);
784 
785  for (unsigned int i = 1; i < CMD_ARGC && cmd_match; ++i) {
786  char *prev = cmd_match;
787  cmd_match = alloc_printf("%s %s", prev, CMD_ARGV[i]);
788  free(prev);
789  }
790  }
791 
792  if (!cmd_match) {
793  LOG_ERROR("unable to build search string");
794  return -ENOMEM;
795  }
796  retval = CALL_COMMAND_HANDLER(command_help_show_list, full, cmd_match);
797 
798  free(cmd_match);
799  return retval;
800 }
801 
802 static char *alloc_concatenate_strings(int argc, const char **argv)
803 {
804  assert(argc >= 1);
805 
806  char *all = strdup(argv[0]);
807  if (!all) {
808  LOG_ERROR("Out of memory");
809  return NULL;
810  }
811 
812  for (int i = 1; i < argc; ++i) {
813  char *prev = all;
814  all = alloc_printf("%s %s", all, argv[i]);
815  free(prev);
816  if (!all) {
817  LOG_ERROR("Out of memory");
818  return NULL;
819  }
820  }
821 
822  return all;
823 }
824 
825 static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
826 {
827  /* check subcommands */
828  if (argc > 1) {
829  char *s = alloc_printf("%s %s", Jim_GetString(argv[0], NULL), Jim_GetString(argv[1], NULL));
830  Jim_Obj *js = Jim_NewStringObj(interp, s, -1);
831  Jim_IncrRefCount(js);
832  free(s);
833  Jim_Cmd *cmd = Jim_GetCommand(interp, js, JIM_NONE);
834  if (cmd) {
835  int retval = Jim_EvalObjPrefix(interp, js, argc - 2, argv + 2);
836  Jim_DecrRefCount(interp, js);
837  return retval;
838  }
839  Jim_DecrRefCount(interp, js);
840  }
841 
842  script_debug(interp, argc, argv);
843 
844  struct command *c = jim_to_command(interp);
845  if (!c->handler) {
846  Jim_EvalObjPrefix(interp, Jim_NewStringObj(interp, "usage", -1), 1, argv);
847  return JIM_ERR;
848  }
849 
851 
852  if (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL)))
853  return JIM_ERR;
854 
856 
857  /*
858  * Black magic of overridden current target:
859  * If the command we are going to handle has a target prefix,
860  * override the current target temporarily for the time
861  * of processing the command.
862  * current_target_override is used also for event handlers
863  * therefore we prevent touching it if command has no prefix.
864  * Previous override is saved and restored back to ensure
865  * correct work when jim_command_dispatch() is re-entered.
866  */
867  struct target *saved_target_override = cmd_ctx->current_target_override;
868  if (c->jim_override_target)
870 
871  int retval = jim_exec_command(interp, cmd_ctx, c, argc, argv);
872 
873  if (c->jim_override_target)
874  cmd_ctx->current_target_override = saved_target_override;
875 
876  return retval;
877 }
878 
879 static enum command_mode get_command_mode(Jim_Interp *interp, const char *cmd_name)
880 {
881  if (!cmd_name)
882  return COMMAND_UNKNOWN;
883 
884  Jim_Obj *s = Jim_NewStringObj(interp, cmd_name, -1);
885  Jim_IncrRefCount(s);
886  Jim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE);
887  Jim_DecrRefCount(interp, s);
888 
890  return COMMAND_UNKNOWN;
891 
892  /* tcl proc */
893  if (jimcmd_is_proc(cmd))
894  return COMMAND_ANY;
895 
896  struct command *c = jimcmd_privdata(cmd);
897  return c->mode;
898 }
899 
900 COMMAND_HANDLER(handle_command_mode)
901 {
902  enum command_mode mode = CMD_CTX->mode;
903 
904  if (CMD_ARGC) {
906  if (!full_name)
907  return ERROR_FAIL;
908 
910 
911  free(full_name);
912  }
913 
914  const char *mode_str;
915  switch (mode) {
916  case COMMAND_ANY:
917  mode_str = "any";
918  break;
919  case COMMAND_CONFIG:
920  mode_str = "config";
921  break;
922  case COMMAND_EXEC:
923  mode_str = "exec";
924  break;
925  case COMMAND_UNKNOWN:
926  default:
927  mode_str = "unknown";
928  break;
929  }
930  command_print(CMD, "%s", mode_str);
931  return ERROR_OK;
932 }
933 
935 {
936  struct help_entry *curr, *n;
937 
938  list_for_each_entry_safe(curr, n, cmd_ctx->help_list, lh) {
939  list_del(&curr->lh);
940  free(curr->cmd_name);
941  free(curr->help);
942  free(curr->usage);
943  free(curr);
944  }
945  return ERROR_OK;
946 }
947 
948 static int help_del_command(struct command_context *cmd_ctx, const char *cmd_name)
949 {
950  struct help_entry *curr;
951 
952  list_for_each_entry(curr, cmd_ctx->help_list, lh) {
953  if (!strcmp(cmd_name, curr->cmd_name)) {
954  list_del(&curr->lh);
955  free(curr->cmd_name);
956  free(curr->help);
957  free(curr->usage);
958  free(curr);
959  break;
960  }
961  }
962 
963  return ERROR_OK;
964 }
965 
966 static int help_add_command(struct command_context *cmd_ctx,
967  const char *cmd_name, const char *help_text, const char *usage_text)
968 {
969  int cmp = -1; /* add after curr */
970  struct help_entry *curr;
971 
972  list_for_each_entry_reverse(curr, cmd_ctx->help_list, lh) {
973  cmp = strcmp(cmd_name, curr->cmd_name);
974  if (cmp >= 0)
975  break;
976  }
977 
978  struct help_entry *entry;
979  if (cmp) {
980  entry = calloc(1, sizeof(*entry));
981  if (!entry) {
982  LOG_ERROR("Out of memory");
983  return ERROR_FAIL;
984  }
985  entry->cmd_name = strdup(cmd_name);
986  if (!entry->cmd_name) {
987  LOG_ERROR("Out of memory");
988  free(entry);
989  return ERROR_FAIL;
990  }
991  list_add(&entry->lh, &curr->lh);
992  } else {
993  entry = curr;
994  }
995 
996  if (help_text) {
997  char *text = strdup(help_text);
998  if (!text) {
999  LOG_ERROR("Out of memory");
1000  return ERROR_FAIL;
1001  }
1002  free(entry->help);
1003  entry->help = text;
1004  }
1005 
1006  if (usage_text) {
1007  char *text = strdup(usage_text);
1008  if (!text) {
1009  LOG_ERROR("Out of memory");
1010  return ERROR_FAIL;
1011  }
1012  free(entry->usage);
1013  entry->usage = text;
1014  }
1015 
1016  return ERROR_OK;
1017 }
1018 
1019 COMMAND_HANDLER(handle_help_add_command)
1020 {
1021  if (CMD_ARGC != 2)
1023 
1024  const char *help = !strcmp(CMD_NAME, "add_help_text") ? CMD_ARGV[1] : NULL;
1025  const char *usage = !strcmp(CMD_NAME, "add_usage_text") ? CMD_ARGV[1] : NULL;
1026  if (!help && !usage) {
1027  LOG_ERROR("command name '%s' is unknown", CMD_NAME);
1029  }
1030  const char *cmd_name = CMD_ARGV[0];
1032 }
1033 
1034 /* sleep command sleeps for <n> milliseconds
1035  * this is useful in target startup scripts
1036  */
1037 COMMAND_HANDLER(handle_sleep_command)
1038 {
1039  bool busy = false;
1040  if (CMD_ARGC == 2) {
1041  if (strcmp(CMD_ARGV[1], "busy") == 0)
1042  busy = true;
1043  else
1045  } else if (CMD_ARGC < 1 || CMD_ARGC > 2)
1047 
1048  unsigned long duration = 0;
1049  int retval = parse_ulong(CMD_ARGV[0], &duration);
1050  if (retval != ERROR_OK)
1051  return retval;
1052 
1053  if (!busy) {
1054  int64_t then = timeval_ms();
1055  while (timeval_ms() - then < (int64_t)duration) {
1057  keep_alive();
1058  usleep(1000);
1059  }
1060  } else
1062 
1063  return ERROR_OK;
1064 }
1065 
1066 static const struct command_registration command_subcommand_handlers[] = {
1067  {
1068  .name = "mode",
1069  .mode = COMMAND_ANY,
1070  .handler = handle_command_mode,
1071  .usage = "[command_name ...]",
1072  .help = "Returns the command modes allowed by a command: "
1073  "'any', 'config', or 'exec'. If no command is "
1074  "specified, returns the current command mode. "
1075  "Returns 'unknown' if an unknown command is given. "
1076  "Command can be multiple tokens.",
1077  },
1079 };
1080 
1081 static const struct command_registration command_builtin_handlers[] = {
1082  {
1083  .name = "ocd_find",
1084  .mode = COMMAND_ANY,
1085  .handler = handle_find,
1086  .help = "find full path to file",
1087  .usage = "file",
1088  },
1089  {
1090  .name = "capture",
1091  .mode = COMMAND_ANY,
1092  .handler = handle_command_capture,
1093  .help = "Capture progress output and return as tcl return value. If the "
1094  "progress output was empty, return tcl return value.",
1095  .usage = "command",
1096  },
1097  {
1098  .name = "echo",
1099  .handler = handle_echo,
1100  .mode = COMMAND_ANY,
1101  .help = "Logs a message at \"user\" priority. "
1102  "Option \"-n\" suppresses trailing newline",
1103  .usage = "[-n] string",
1104  },
1105  {
1106  .name = "add_help_text",
1107  .handler = handle_help_add_command,
1108  .mode = COMMAND_ANY,
1109  .help = "Add new command help text; "
1110  "Command can be multiple tokens.",
1111  .usage = "command_name helptext_string",
1112  },
1113  {
1114  .name = "add_usage_text",
1115  .handler = handle_help_add_command,
1116  .mode = COMMAND_ANY,
1117  .help = "Add new command usage text; "
1118  "command can be multiple tokens.",
1119  .usage = "command_name usage_string",
1120  },
1121  {
1122  .name = "sleep",
1123  .handler = handle_sleep_command,
1124  .mode = COMMAND_ANY,
1125  .help = "Sleep for specified number of milliseconds. "
1126  "\"busy\" will busy wait instead (avoid this).",
1127  .usage = "milliseconds ['busy']",
1128  },
1129  {
1130  .name = "help",
1131  .handler = handle_help_command,
1132  .mode = COMMAND_ANY,
1133  .help = "Show full command help; "
1134  "command can be multiple tokens.",
1135  .usage = "[command_name]",
1136  },
1137  {
1138  .name = "usage",
1139  .handler = handle_help_command,
1140  .mode = COMMAND_ANY,
1141  .help = "Show basic command usage; "
1142  "command can be multiple tokens.",
1143  .usage = "[command_name]",
1144  },
1145  {
1146  .name = "command",
1147  .mode = COMMAND_ANY,
1148  .help = "core command group (introspection)",
1149  .chain = command_subcommand_handlers,
1150  .usage = "",
1151  },
1153 };
1154 
1155 struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp)
1156 {
1157  struct command_context *context = calloc(1, sizeof(struct command_context));
1158 
1159  context->mode = COMMAND_EXEC;
1160 
1161  /* context can be duplicated. Put list head on separate mem-chunk to keep list consistent */
1162  context->help_list = malloc(sizeof(*context->help_list));
1163  INIT_LIST_HEAD(context->help_list);
1164 
1165  /* Create a jim interpreter if we were not handed one */
1166  if (!interp) {
1167  /* Create an interpreter */
1168  interp = Jim_CreateInterp();
1169  /* Add all the Jim core commands */
1170  Jim_RegisterCoreCommands(interp);
1171  Jim_InitStaticExtensions(interp);
1172  }
1173 
1174  context->interp = interp;
1175 
1177 
1178  Jim_SetAssocData(interp, "context", NULL, context);
1179  if (Jim_Eval_Named(interp, startup_tcl, "embedded:startup.tcl", 1) == JIM_ERR) {
1180  LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD)");
1181  Jim_MakeErrorMessage(interp);
1182  LOG_USER_N("%s", Jim_GetString(Jim_GetResult(interp), NULL));
1183  exit(-1);
1184  }
1185  Jim_DeleteAssocData(interp, "context");
1186 
1187  return context;
1188 }
1189 
1190 void command_exit(struct command_context *context)
1191 {
1192  if (!context)
1193  return;
1194 
1195  Jim_FreeInterp(context->interp);
1196  free(context->help_list);
1197  command_done(context);
1198 }
1199 
1201 {
1202  if (!cmd_ctx)
1204 
1205  cmd_ctx->mode = mode;
1206  return ERROR_OK;
1207 }
1208 
1210 {
1211  static int recursion;
1212  if (recursion)
1213  return;
1214 
1215  recursion++;
1216  Jim_ProcessEvents(cmd_ctx->interp, JIM_ALL_EVENTS | JIM_DONT_WAIT);
1217  recursion--;
1218 }
1219 
1220 #define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max) \
1221  int parse ## name(const char *str, type * ul) \
1222  { \
1223  if (!*str) { \
1224  LOG_ERROR("Invalid command argument"); \
1225  return ERROR_COMMAND_ARGUMENT_INVALID; \
1226  } \
1227  char *end; \
1228  errno = 0; \
1229  *ul = func(str, &end, 0); \
1230  if (*end) { \
1231  LOG_ERROR("Invalid command argument"); \
1232  return ERROR_COMMAND_ARGUMENT_INVALID; \
1233  } \
1234  if ((max == *ul) && (errno == ERANGE)) { \
1235  LOG_ERROR("Argument overflow"); \
1236  return ERROR_COMMAND_ARGUMENT_OVERFLOW; \
1237  } \
1238  if (min && (min == *ul) && (errno == ERANGE)) { \
1239  LOG_ERROR("Argument underflow"); \
1240  return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \
1241  } \
1242  return ERROR_OK; \
1243  }
1244 DEFINE_PARSE_NUM_TYPE(_ulong, unsigned long, strtoul, 0, ULONG_MAX)
1245 DEFINE_PARSE_NUM_TYPE(_ullong, unsigned long long, strtoull, 0, ULLONG_MAX)
1246 DEFINE_PARSE_NUM_TYPE(_long, long, strtol, LONG_MIN, LONG_MAX)
1247 DEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX)
1248 
1249 #define DEFINE_PARSE_WRAPPER(name, type, min, max, functype, funcname) \
1250  int parse ## name(const char *str, type * ul) \
1251  { \
1252  functype n; \
1253  int retval = parse ## funcname(str, &n); \
1254  if (retval != ERROR_OK) \
1255  return retval; \
1256  if (n > max) \
1257  return ERROR_COMMAND_ARGUMENT_OVERFLOW; \
1258  if (min) \
1259  return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \
1260  *ul = n; \
1261  return ERROR_OK; \
1262  }
1263 
1264 #define DEFINE_PARSE_ULONGLONG(name, type, min, max) \
1265  DEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long long, _ullong)
1266 DEFINE_PARSE_ULONGLONG(_uint, unsigned int, 0, UINT_MAX)
1267 DEFINE_PARSE_ULONGLONG(_u64, uint64_t, 0, UINT64_MAX)
1268 DEFINE_PARSE_ULONGLONG(_u32, uint32_t, 0, UINT32_MAX)
1269 DEFINE_PARSE_ULONGLONG(_u16, uint16_t, 0, UINT16_MAX)
1270 DEFINE_PARSE_ULONGLONG(_u8, uint8_t, 0, UINT8_MAX)
1271 
1273 
1274 #define DEFINE_PARSE_LONGLONG(name, type, min, max) \
1275  DEFINE_PARSE_WRAPPER(name, type, min, max, long long, _llong)
1276 DEFINE_PARSE_LONGLONG(_int, int, n < INT_MIN, INT_MAX)
1277 DEFINE_PARSE_LONGLONG(_s64, int64_t, n < INT64_MIN, INT64_MAX)
1278 DEFINE_PARSE_LONGLONG(_s32, int32_t, n < INT32_MIN, INT32_MAX)
1279 DEFINE_PARSE_LONGLONG(_s16, int16_t, n < INT16_MIN, INT16_MAX)
1280 DEFINE_PARSE_LONGLONG(_s8, int8_t, n < INT8_MIN, INT8_MAX)
1281 
1282 static int command_parse_bool(const char *in, bool *out,
1283  const char *on, const char *off)
1284 {
1285  if (strcasecmp(in, on) == 0)
1286  *out = true;
1287  else if (strcasecmp(in, off) == 0)
1288  *out = false;
1289  else
1291  return ERROR_OK;
1292 }
1293 
1294 int command_parse_bool_arg(const char *in, bool *out)
1295 {
1296  if (command_parse_bool(in, out, "on", "off") == ERROR_OK)
1297  return ERROR_OK;
1298  if (command_parse_bool(in, out, "enable", "disable") == ERROR_OK)
1299  return ERROR_OK;
1300  if (command_parse_bool(in, out, "true", "false") == ERROR_OK)
1301  return ERROR_OK;
1302  if (command_parse_bool(in, out, "yes", "no") == ERROR_OK)
1303  return ERROR_OK;
1304  if (command_parse_bool(in, out, "1", "0") == ERROR_OK)
1305  return ERROR_OK;
1307 }
1308 
1309 COMMAND_HELPER(command_parse_str_to_buf, const char *str, void *buf, unsigned int buf_len)
1310 {
1311  assert(str);
1312  assert(buf);
1313 
1314  int ret = str_to_buf(str, buf, buf_len);
1315  if (ret == ERROR_OK)
1316  return ret;
1317 
1318  /* Provide a clear error message to the user */
1319  if (ret == ERROR_INVALID_NUMBER) {
1320  command_print(CMD, "'%s' is not a valid number", str);
1321  } else if (ret == ERROR_NUMBER_EXCEEDS_BUFFER) {
1322  command_print(CMD, "Number %s exceeds %u bits", str, buf_len);
1323  } else {
1324  command_print(CMD, "Could not parse number '%s'", str);
1325  }
1326 
1328 }
1329 
1330 COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label)
1331 {
1332  switch (CMD_ARGC) {
1333  case 1: {
1334  const char *in = CMD_ARGV[0];
1335  if (command_parse_bool_arg(in, out) != ERROR_OK) {
1336  LOG_ERROR("%s: argument '%s' is not valid", CMD_NAME, in);
1338  }
1339  }
1340  /* fallthrough */
1341  case 0:
1342  LOG_INFO("%s is %s", label, *out ? "enabled" : "disabled");
1343  break;
1344  default:
1346  }
1347  return ERROR_OK;
1348 }
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:1294
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:934
static bool command_can_run(struct command_context *cmd_ctx, struct command *c, const char *full_name)
Definition: command.c:396
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:348
static int command_parse_bool(const char *in, bool *out, const char *on, const char *off)
Definition: command.c:1282
static enum command_mode get_command_mode(Jim_Interp *interp, const char *cmd_name)
Definition: command.c:879
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:966
static void tcl_output(void *privData, const char *file, unsigned int line, const char *function, const char *string)
Definition: command.c:610
static struct command * command_new(struct command_context *cmd_ctx, const char *full_name, const struct command_registration *cr)
Definition: command.c:123
static COMMAND_HELPER(command_help_show, struct help_entry *c, bool show_help, const char *cmd_match)
Definition: command.c:713
static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Definition: command.c:825
void command_done(struct command_context *cmd_ctx)
Frees the resources associated with a command context.
Definition: command.c:572
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:680
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:371
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:1209
static const struct command_registration command_subcommand_handlers[]
Definition: command.c:1066
COMMAND_HANDLER(handle_find)
Definition: command.c:581
struct command_context * copy_command_context(struct command_context *context)
Creates a copy of an existing command context.
Definition: command.c:563
void command_exit(struct command_context *context)
Shutdown a command context.
Definition: command.c:1190
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:802
#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:420
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:1274
static int help_del_command(struct command_context *cmd_ctx, const char *cmd_name)
Definition: command.c:948
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:1155
int command_context_mode(struct command_context *cmd_ctx, enum command_mode mode)
Definition: command.c:1200
int command_run_linef(struct command_context *context, const char *format,...)
Definition: command.c:541
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:556
static const struct command_registration command_builtin_handlers[]
Definition: command.c:1081
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:1264
int command_run_line(struct command_context *context, char *line)
Definition: command.c:485
#define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max)
Definition: command.c:1220
#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:400
#define ERROR_COMMAND_CLOSE_CONNECTION
Definition: command.h:399
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define CMD_JIMTCL_ARGV
Use this macro to access the jimtcl arguments for the command being handled, rather than accessing th...
Definition: command.h:161
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:211
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:251
#define ERROR_COMMAND_ARGUMENT_INVALID
Definition: command.h:402
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:272
command_mode
OpenOCD command mode is COMMAND_CONFIG at start, then switches to COMMAND_EXEC during the execution o...
Definition: command.h:39
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_UNKNOWN
Definition: command.h:43
@ COMMAND_EXEC
Definition: command.h:40
char * find_file(const char *file)
Definition: configuration.c:61
static struct esp_usb_jtag * priv
Definition: esp_usb_jtag.c:219
void jtag_poll_unmask(bool saved)
Restore saved mask for polling.
Definition: jtag/core.c:183
bool jtag_poll_mask(void)
Mask (disable) polling and return the current mask status that should be feed to jtag_poll_unmask() t...
Definition: jtag/core.c:176
The JTAG interface can be implemented with a software or hardware fifo.
static void list_add(struct list_head *new, struct list_head *head)
Definition: list.h: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:483
void keep_alive(void)
Definition: log.c:429
char * alloc_printf(const char *format,...)
Definition: log.c:378
#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:234
command_handler_t handler
Definition: command.h:235
enum command_mode mode
Definition: command.h:236
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:247
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:239
const char * help
Definition: command.h:237
void * jim_handler_data
Definition: command.h:200
command_handler_t handler
Definition: command.h:199
struct target * jim_override_target
Definition: command.h:202
enum command_mode mode
Definition: command.h:204
char * name
Definition: command.h:198
Definition: command.c:661
char * cmd_name
Definition: command.c:663
char * usage
Definition: command.c:665
struct list_head lh
Definition: command.c:662
char * help
Definition: command.c:664
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:1894
int target_call_timer_callbacks(void)
Definition: target.c:1888
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