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