X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FMainpage.dox;h=b63300e90e2b0ff70c7fbb4aa35ea9685646b00c;hb=8025a3e571ed9de108f7203907baa4cabc801ea9;hp=9c0ea9a8c2a1041c67dfc74197f18dd62bdb748e;hpb=be33ff96c5b89738694da272d8610564cce48bfb;p=senf.git diff --git a/Console/Mainpage.dox b/Console/Mainpage.dox index 9c0ea9a..b63300e 100644 --- a/Console/Mainpage.dox +++ b/Console/Mainpage.dox @@ -42,6 +42,7 @@ To get started using the config/console library, see \li \ref node_tree \li \ref console_parser + \li \ref console_commands \section console_example Example @@ -93,6 +94,294 @@ */ +/** \defgroup console_commands Supported command types + + The Console/config library supports quite a number of different command types. All these types + of command are registered, by passing them to DirectoryNode::add() + + \autotoc + + \section console_manualparse Manually parsing command arguments + + This is the most primitive type of command. It will be called with an output stream and with a + senf::console::ParseCommandInfo reference which holds information about the command parsed. + + From this information the command callback gets a list of arguments or tokens which then can be + interpreted in an arbitrary way. + \code + void test1(std::ostream & os, senf::console::ParseCommandInfo const & command) + { + // We take exactly one argument + if (command.arguments().size() != 1) + raise senf::console::SyntaxErrorException("invalid number of arguments"); + + senf::console::ParseCommandInfo::TokenRange & argTokens ( + command.arguments()[0]); + + // The argument must have exactly one token + if (argTokens.size() != 1) + raise senf::console::SyntaxErrorException("argument syntax error"); + + // Retrieve the token value + std::string arg (argTokens[0].value()); + + // In this example, we just write the argument to the output stream + os << arg << std::endl; + } + \endcode + + Registering this callback is done by simply adding it. To provide online help, pass it to + 'doc()': + \code + senf::console::root() + .add("test1", &test1) + .doc("Usage:\n" + " test1 arg\n" + "\n" + "Echo 'arg' to the console"); + \endcode + + The callback may now be called interactively on the console by it's registered name: + \htmlonly +
+ server:/$ test1 + invalid number of arguments + server:/$ test1 stefan@j32.de + stefan@j32.de + server:/$ test1 (echo me) + argument syntax error + server:/$ help test1 + Usage: + test1 arg + + Echo 'arg' to the console + server:/$ ++ \endhtmlonly + + As you can see above, the arguments and tokens are returned as + boost::iterator_range instances. These behave much like containers: They have \c begin() and + \c end() and some other useful members. + + The parser will have divided the argument tokens into arguments already. This simplifies further + parsing. If however you want to access the list of argument tokens as a single list, you can do + so using senf::console::ParseCommandInfo::tokens(). + + Parsing arguments is quite simple but can get very tedious. To simplify this task, the parsing + can be delegated to the Console/config library. See the next section. + + + \section console_autoparse Automatic argument parsing + + To greatly simplify parsing complex commands, we turn to automatic argument parsing. This + feature allows to register (almost) arbitrary callbacks. + + \code + std::string test2(std::string const & arg) + { + return arg; + } + \endcode + + This extremely simple callback may be registered by adding it to a + senf::console::DirectoryNode. + \code + senf::console::root() + .add("test2", &test2); + \endcode + The functionality is now identical to \c test1: + \htmlonly +
+ server:/$ test2 + invalid number of arguments + server:/$ test2 stefan@j32.de + stefan@j32.de + server:/$ test2 (echo me) + argument syntax error + server:/$ help test2 + Usage: + test2 arg11:string + server:/$ ++ \endhtmlonly + + As we can see, some documentation is automatically provided. To add more info, we need to add + some additional attributes when registering the command: + \code + namespace kw = senf::console::kw; + + senf::console::root() + .add("test2", &test2) + .doc("Echo 'arg' to the console") + .arg( kw::name = "arg", + kw::description = "Message to output" ); + \endcode + + (Sadly, there is no way to automatically find out the \e name of an argument, just it's type.) + Every callback argument corresponds with a call of the \c arg() attribute. Argument attributes + are set using keywords from the \ref senf::console::kw namespace. You will probably wither use + this namespace via a namespace alias (as above) or via a using namespace + senf::console::kw declaration (as in all the following examples) + + You don't need + to specify any information for an argument: To skip an argument, just call \c arg() without + attributes for this argument. + + After adding this information, the online help is much more intelligible + \htmlonly +
+ server:/$ help test2 + Usage: + test2 arg:string + + With: + arg Message to output + + Echo 'arg' to the console + server:/$ ++ \endhtmlonly + + \subsection command_ostream Accessing the console stream + + Commands may have an optional first argument of type std::ostream &. This argument is + not considered part of the real interface. When the command is executed, the callback will be + passed the current console's output stream object in this argument. With this, the callback can + output arbitrary messages to the network console. See the next section for an example. + + \subsection command_overload Command overloading + + Automatically parsed commands can be overloaded: You can register multiple commands under the + same name. If this happens, each command is tried in turn until no SyntaxErrorException is + raised. + + \code + void test3(std::ostream & os, unsigned n, std::string text) + { + // It's perfectly valid to check additional constraints here and throw a + // SyntaxErrorException. In this case, the next overload will be tried. However, you must + // ensure, That no action takes place before this check ! + if ( n==0 ) throw senf::console::SyntaxErrorException("invalid value for parameter 'n'"); + while (n-- > 0) os << text << std::endl; + } + + using namespace senf::console::kw; + + senf::console::root() + .add("test3", &test3) + .doc("Echo text to the console") + .overloadDoc("Repeat 'text' for 'n' lines") + .arg( name = "n", description = "Number of repetitions" ) + .arg( name = "text", description = "Message to output" ); + senf::console::root() + .add("test3", &test2) + .overloadDoc("Echo the 'text' argument") + .arg( name = "text", description = "Message to output" ); + \endcode + + We can now call \c test2 with one or two arguments: + + \htmlonly +
+ server:/$ test3 "The sky is blue" + The sky is blue + server:/$ test3 4 ok + ok + ok + ok + ok + server:/$ help test3 + Usage: + 1- test3 n:unsigned text:string + 2- test3 text:string + + With: + n Numer of repetitions + text Messsage to output + + Echo text to the console + + Variant 1: + Repeat 'text' for 'n' lines + + Variant 2: + Echo the 'text' argument + senf:/$ And + ++ \endhtmlonly + + \subsection console_defaults Default values + + Another information which can not be automatically gathered from the type system is default + values. These have to be explicitly declared: + \code + using namespace senf::console::kw; + + senf::console::root() + .add("test4", &test2b) + .arg() + .arg( default_value = "ok" ); + \endcode + (Default values must not necessarily be declared in the callback function too.) Of course, + default values can be used together with overloading. + + There must be no argument without default value after an argument with a default value + declared. This fill fail at compile time. + + \subsection console_auto_summary Attribute summary + + Here a summary of all the attributes available for automatically parsed command nodes: + +
\c doc ( \e text ) | Documentation for all overloads |
\c overloadDoc ( \e text ) | Documentation for a specific overliad |
\c arg ( \e attributes ) | Set parameter attributes. All attributes are + optional. The attribute keywords are defined in the \ref senf::console::kw namespace. Valid + Attributes are: + \li \e name: Parameter name + \li \e description: One-line description of the argument + \li \e default_value: Arguments default value |