update command handler documentation

Adds sections on command registration and chaining, giving an overview
to developers that want to use these features.
This commit is contained in:
Zachary T Welch 2009-11-24 18:47:35 -08:00
parent 9d4c89f37f
commit ed90b6659f
2 changed files with 83 additions and 18 deletions

View File

@ -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,

View File

@ -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 = "[<name>]",
},
{
.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 <code>openocd -f hello.cfg</code>
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 [<name>]
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 <code>ocd_</code>-prefixed routine,
providing a measure of high-level error handling.
*/