X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fcommand.h;h=886bde86b6289c6505ae4d44da6e59711243fdb7;hp=1f2dc5b591f3a97d533f96cb649df066d07dd487;hb=HEAD;hpb=fa23b1a71e4f1974791e90055c301f9bf124e835 diff --git a/src/helper/command.h b/src/helper/command.h index 1f2dc5b591..dc45070420 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -1,22 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * ***************************************************************************/ #ifndef OPENOCD_HELPER_COMMAND_H @@ -24,8 +13,8 @@ #include #include -#include +#include #include #include @@ -38,6 +27,15 @@ #define PRINTF_ATTRIBUTE_FORMAT printf #endif +/** + * OpenOCD command mode is COMMAND_CONFIG at start, then switches to COMMAND_EXEC + * during the execution of command 'init'. + * The field 'mode' in struct command_registration specifies in which command mode + * the command can be executed: + * - during COMMAND_CONFIG only, + * - during COMMAND_EXEC only, + * - in both modes (COMMAND_ANY). + */ enum command_mode { COMMAND_EXEC, COMMAND_CONFIG, @@ -81,9 +79,21 @@ struct command_invocation { const char *name; unsigned argc; const char **argv; + Jim_Obj * const *jimtcl_argv; Jim_Obj *output; }; +/** + * Return true if the command @c cmd is registered by OpenOCD. + */ +bool jimcmd_is_oocd_command(Jim_Cmd *cmd); + +/** + * Return the pointer to the command's private data specified during the + * registration of command @a cmd . + */ +void *jimcmd_privdata(Jim_Cmd *cmd); + /** * Command handlers may be defined with more parameters than the base * set provided by command.c. This macro uses C99 magic to allow @@ -144,6 +154,11 @@ struct command_invocation { * rather than accessing the variable directly. It may be moved. */ #define CMD_ARGV (cmd->argv) +/** + * Use this macro to access the jimtcl arguments for the command being + * handled, rather than accessing the variable directly. It may be moved. + */ +#define CMD_JIMTCL_ARGV (cmd->jimtcl_argv) /** * Use this macro to access the name of the command being handled, * rather than accessing the variable directly. It may be moved. @@ -361,10 +376,21 @@ struct command_context *copy_command_context(struct command_context *cmd_ctx); */ void command_done(struct command_context *context); +/* + * command_print() and command_print_sameline() are used to produce the TCL + * output of OpenOCD commands. command_print() automatically adds a '\n' at + * the end or the format string. Use command_print_sameline() to avoid the + * trailing '\n', e.g. to concatenate the command output in the same line. + * The very last '\n' of the command is stripped away (see run_command()). + * For commands that strictly require a '\n' as last output character, add + * it explicitly with either an empty command_print() or with a '\n' in the + * last command_print() and add a comment to document it. + */ void command_print(struct command_invocation *cmd, const char *format, ...) __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); void command_print_sameline(struct command_invocation *cmd, const char *format, ...) __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); + int command_run_line(struct command_context *context, char *line); int command_run_linef(struct command_context *context, const char *format, ...) __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); @@ -416,7 +442,7 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t); #define COMMAND_PARSE_NUMBER(type, in, out) \ do { \ int retval_macro_tmp = parse_ ## type(in, &(out)); \ - if (ERROR_OK != retval_macro_tmp) { \ + if (retval_macro_tmp != ERROR_OK) { \ command_print(CMD, stringify(out) \ " option value ('%s') is not valid", in); \ return retval_macro_tmp; \ @@ -426,6 +452,48 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t); #define COMMAND_PARSE_ADDRESS(in, out) \ COMMAND_PARSE_NUMBER(target_addr, in, out) +/** + * @brief parses the command argument at position @a argn into @a out + * as a @a type, or prints a command error referring to @a name_str + * and passes the error code to the caller. @a argn will be incremented + * if no error occurred. Otherwise the calling function will return + * the error code produced by the parsing function. + * + * This function may cause the calling function to return immediately, + * so it should be used carefully to avoid leaking resources. In most + * situations, parsing should be completed in full before proceeding + * to allocate resources, and this strategy will most prevents leaks. + */ +#define COMMAND_PARSE_ADDITIONAL_NUMBER(type, argn, out, name_str) \ + do { \ + if (argn+1 >= CMD_ARGC || CMD_ARGV[argn+1][0] == '-') { \ + command_print(CMD, "no " name_str " given"); \ + return ERROR_FAIL; \ + } \ + ++argn; \ + COMMAND_PARSE_NUMBER(type, CMD_ARGV[argn], out); \ + } while (0) + +/** + * @brief parses the command argument at position @a argn into @a out + * as a @a type if the argument @a argn does not start with '-'. + * and passes the error code to the caller. @a argn will be incremented + * if no error occurred. Otherwise the calling function will return + * the error code produced by the parsing function. + * + * This function may cause the calling function to return immediately, + * so it should be used carefully to avoid leaking resources. In most + * situations, parsing should be completed in full before proceeding + * to allocate resources, and this strategy will most prevents leaks. + */ +#define COMMAND_PARSE_OPTIONAL_NUMBER(type, argn, out) \ + do { \ + if (argn+1 < CMD_ARGC && CMD_ARGV[argn+1][0] != '-') { \ + ++argn; \ + COMMAND_PARSE_NUMBER(type, CMD_ARGV[argn], out); \ + } \ + } while (0) + /** * Parse the string @c as a binary parameter, storing the boolean value * in @c out. The strings @c on and @c off are used to match different @@ -436,7 +504,7 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t); do { \ bool value; \ int retval_macro_tmp = command_parse_bool_arg(in, &value); \ - if (ERROR_OK != retval_macro_tmp) { \ + if (retval_macro_tmp != ERROR_OK) { \ command_print(CMD, stringify(out) \ " option value ('%s') is not valid", in); \ command_print(CMD, " choices are '%s' or '%s'", \ @@ -456,6 +524,4 @@ COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label); #define COMMAND_PARSE_ENABLE(in, out) \ COMMAND_PARSE_BOOL(in, out, "enable", "disable") -void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv); - #endif /* OPENOCD_HELPER_COMMAND_H */