change all bool parsers to accept any value
[openocd.git] / src / helper / command.h
index 169852ef6d0425ed56d1a68cd024a88c3985d357..a2e979708e66a3e890bd28b673abd9f18337f38f 100644 (file)
@@ -60,7 +60,7 @@ typedef int (*command_output_handler_t)(struct command_context *context,
 struct command_context
 {
        enum command_mode mode;
-       struct command_s *commands;
+       struct command *commands;
        int current_target;
        /* Execute a command.
         *
@@ -80,6 +80,17 @@ struct command_context
        void *output_handler_priv;
 };
 
+/**
+ * When run_command is called, a new instance will be created on the
+ * stack, filled with the proper values, and passed by reference to the
+ * required COMMAND_HANDLER routine.
+ */
+struct command_invocation {
+       struct command_context *ctx;
+       const char *name;
+       unsigned argc;
+       const char **argv;
+};
 
 /**
  * Command handlers may be defined with more parameters than the base
@@ -87,8 +98,7 @@ struct command_context
  * defining all such derivative types using this macro.
  */
 #define __COMMAND_HANDLER(name, extra...) \
-               int name(struct command_context *cmd_ctx, \
-                               const char *args[], unsigned argc, ##extra)
+               int name(struct command_invocation *cmd, ##extra)
 
 /**
  * Use this to macro to call a command helper (or a nested handler).
@@ -104,7 +114,7 @@ struct command_context
  * variables in intervening scope(s) by accident.
  */
 #define CALL_COMMAND_HANDLER(name, extra...) \
-               name(cmd_ctx, args, argc, ##extra)
+               name(cmd, ##extra)
 
 /**
  * Always use this macro to define new command handler functions.
@@ -121,25 +131,40 @@ struct command_context
  */
 #define COMMAND_HELPER(name, extra...) __COMMAND_HANDLER(name, extra)
 
+/**
+ * Use this macro to access the context of the command being handled,
+ * rather than accessing the variable directly.  It may be moved.
+ */
+#define CMD_CTX cmd->ctx
+/**
+ * Use this macro to access the number of arguments for the command being
+ * handled, rather than accessing the variable directly.  It may be moved.
+ */
+#define CMD_ARGC cmd->argc
+/**
+ * Use this macro to access the arguments for the command being handled,
+ * rather than accessing the variable directly.  It may be moved.
+ */
+#define CMD_ARGV cmd->argv
 /**
  * Use this macro to access the name of the command being handled,
  * rather than accessing the variable directly.  It may be moved.
  */
-#define CMD_NAME args[-1]
+#define CMD_NAME cmd->name
 
 
 /// The type signature for commands' handler functions.
 typedef __COMMAND_HANDLER((*command_handler_t));
 
-typedef struct command_s
+struct command
 {
        char *name;
-       struct command_s *parent;
-       struct command_s *children;
+       struct command *parent;
+       struct command *children;
        command_handler_t handler;
        enum command_mode mode;
-       struct command_s *next;
-} command_t;
+       struct command *next;
+};
 
 /**
  * @param c The command to be named.
@@ -149,10 +174,10 @@ typedef struct command_s
  * are separated by single spaces.  The caller must free() the string
  * when done with it.
  */
-char *command_name(struct command_s *c, char delim);
+char *command_name(struct command *c, char delim);
 
-command_t* register_command(struct command_context *context,
-               command_t *parent, char *name, command_handler_t handler,
+struct command* register_command(struct command_context *context,
+               struct command *parent, char *name, command_handler_t handler,
                enum command_mode mode, char *help);
 
 int unregister_command(struct command_context *context, char *name);
@@ -165,7 +190,10 @@ struct command_context* copy_command_context(struct command_context* context);
 
 int command_context_mode(struct command_context *context, enum command_mode mode);
 
-struct command_context* command_init(void);
+/**
+ * Creates a new command context using the startup TCL provided.
+ */
+struct command_context* command_init(const char *startup_tcl);
 int command_done(struct command_context *context);
 
 void command_print(struct command_context *context, const char *format, ...)
@@ -190,7 +218,8 @@ extern int fast_and_dangerous;
 
 extern Jim_Interp *interp;
 
-void register_jim(struct command_context *context, const char *name, int (*cmd)(Jim_Interp *interp, int argc, Jim_Obj *const *argv), const char *help);
+void register_jim(struct command_context *context, const char *name,
+               Jim_CmdProc cmd, const char *help);
 
 long jim_global_long(const char *variable);
 
@@ -228,12 +257,42 @@ DECLARE_PARSE_WRAPPER(_s8, int8_t);
        do { \
                int retval = parse_##type(in, &(out)); \
                if (ERROR_OK != retval) { \
-                       command_print(cmd_ctx, stringify(out) \
+                       command_print(CMD_CTX, stringify(out) \
+                               " option value ('%s') is not valid", in); \
+                       return retval; \
+               } \
+       } 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
+ * strings for true and false options (e.g. "on" and "off" or
+ * "enable" and "disable").
+ */
+#define COMMAND_PARSE_BOOL(in, out, on, off) \
+       do { \
+               bool value; \
+               int retval = command_parse_bool_arg(in, &value); \
+               if (ERROR_OK != retval) { \
+                       command_print(CMD_CTX, stringify(out) \
                                " option value ('%s') is not valid", in); \
+                       command_print(CMD_CTX, "  choices are '%s' or '%s'", \
+                               on, off); \
                        return retval; \
                } \
+               out = value; \
        } while (0)
 
+int command_parse_bool_arg(const char *in, bool *out);
+COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label);
+
+/// parses an on/off command argument
+#define COMMAND_PARSE_ON_OFF(in, out) \
+               COMMAND_PARSE_BOOL(in, out, "on", "off")
+/// parses an enable/disable command argument
+#define COMMAND_PARSE_ENABLE(in, out) \
+               COMMAND_PARSE_BOOL(in, out, "enable", "disable")
+
 void script_debug(Jim_Interp *interp, const char *cmd,
                unsigned argc, Jim_Obj *const *argv);
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)