From ed90b6659f6d6b98b59d65f7a889e0221bdffa87 Mon Sep 17 00:00:00 2001 From: Zachary T Welch Date: Tue, 24 Nov 2009 18:47:35 -0800 Subject: [PATCH] update command handler documentation Adds sections on command registration and chaining, giving an overview to developers that want to use these features. --- doc/manual/helper.txt | 36 +++++++++++++++++++ doc/manual/primer/commands.txt | 65 ++++++++++++++++++++++++---------- 2 files changed, 83 insertions(+), 18 deletions(-) diff --git a/doc/manual/helper.txt b/doc/manual/helper.txt index e7454b698..aa52355f5 100644 --- a/doc/manual/helper.txt +++ b/doc/manual/helper.txt @@ -80,6 +80,42 @@ command handlers and helpers: - @c CMD_ARGC - the number of command arguments - @c CMD_ARGV - array of command argument strings +@section helpercmdregister Command Registration + +In order to use a command handler, it must be registered with the +command subsystem. All commands are registered with command_registration +structures, specifying the name of the command, its handler, its allowed +mode(s) of execution, and strings that provide usage and help text. +A single handler may be registered using multiple names, but any name +may have only one handler associated with it. + +The @c register_commands() and @c register_commands() functions provide +registration, while the @c unregister_command() and +@c unregister_all_commands() functions will remove existing commands. +These may be called at any time, allowing the command set to change in +response to system actions. + +@subsection helpercmdjim Jim Command Registration + +The command_registration structure provides support for registering +native Jim command handlers (@c jim_handler) too. For these handlers, +the module can provide help and usage support; however, this mechanism +allows Jim handlers to be called as sub-commands of other commands. +These commands may be registered with a private data value (@c +jim_handler_data) that will be available when called, as with low-level +Jim command registration. + +A command may have a normal @c handler or a @c jim_handler, but not both. + +@subsection helpercmdregisterchains Command Chaining + +When using register_commands(), the array of commands may reference +other arrays. When the @c chain field is filled in a +command_registration record, the commands on in the chained list will +added in one of two places. If the record defines a new command, then +the chained commands are added under it; otherwise, the commands are +added in the same context as the other commands in the array. + @section helpercmdprimer Command Development Primer This @ref primercommand provides details about the @c hello module, diff --git a/doc/manual/primer/commands.txt b/doc/manual/primer/commands.txt index b15f66975..c9db7ccb0 100644 --- a/doc/manual/primer/commands.txt +++ b/doc/manual/primer/commands.txt @@ -63,42 +63,71 @@ Before this new function can be used, it must be registered somehow. For a new module, registering should be done in a new function for the purpose, which must be called from @c openocd.c: @code + +static const struct command_registration hello_command_handlers[] = { + { + .name = "hello", + .mode = COMMAND_ANY, + .handler = &handle_hello_command, + .help = "print a warm greetings", + .usage = "[]", + }, + { + .chain = foo_command_handlers, + } + COMMAND_REGISTRATION_DONE +}; + int hello_register_commands(struct command_context_s *cmd_ctx) { - struct command_s *cmd = register_command(cmd_ctx, NULL, "hello", - NULL, COMMAND_ANY, "print greetings"); - return cmd ? ERROR_OK : -ENOMEM; + return register_commands(cmd_ctx, NULL, handle_command_handlers); } @endcode That's it! The command should now be registered and avaiable to scripts. +@section primercmdchain Command Chaining + +This example also shows how to chain command handler registration, so +your modules can "inherit" commands provided by other (sub)modules. +Here, the hello module includes the foo commands in the same context +that the 'hello' command will be registered. + +If the @c chain field had been put in the 'hello' command, then the +@c foo module commands would be registered under it. Indeed, that +technique is used to define the 'foo bar' and 'foo baz' commands, +as well as for the example drivers that use these modules. + +The code for the 'foo' command handlers can be found in @c hello.c. + @section primercmdcode Trying These Example Commands -The commands may be enabled by editing src/openocd.c and uncommenting -the call to @c hello_register_commands and rebuilding the source tree. +These commands have been inherited by the dummy interface, faux flash, +and testee target drivers. The easiest way to test these is by using the +dummy interface. -Once OpenOCD has been built with this example code, the following script -demonstrate the abilities that the @c hello module provides: +Once OpenOCD has been built with this example code, the following command +demonstrates the abilities that the @c hello module provides: @code -hello -hello World -hello {John Doe} -hello John Doe # error: too many arguments +openocd -c 'interface dummy' \ + -c 'dummy hello' \ + -c 'dummy hello World' \ + -c 'dummy hello {John Doe}' \ + -c 'dummy hello John Doe' # error: too many arguments @endcode If saved in @c hello.cfg, then running openocd -f hello.cfg -should produce the following output before exiting: +should produce the following output before displaying the help text and +exiting: @code Greetings! Greetings, World! Greetings, John Doe! -Error: ocd_hello: too many arguments +Error: hello: too many arguments +Runtime error, file "openocd.cfg", line 14: + hello: too many arguments +dummy hello [] + prints a warm welcome @endcode -This difference between the registered and displayed command name comes from -the fact that the TCL scripts are provided with a stub that calls the munged -name. This stub wraps the internal ocd_-prefixed routine, -providing a measure of high-level error handling. - */