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