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