4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 /** \mainpage The Configuration and Runtime Control Framework
25 The Console library implements a runtime interactive (network) console which allows to
26 configure, control and manipulate a running application in any way. Additionally this library
27 provides support for configuration files and command line parsing which can be used with or
28 without the network console.
30 \section console_intro Introduction
32 There are two components to the Config/console framework:
34 \li Building the node tree by registering objects and callbacks
35 \li Utilizing the config/console framework by writing configuration files or using the
38 Basic data structure of the console and config framework is the config/console node tree. This
39 tree. This tree works like a file-system. Commands are added to this tree and can then be called
40 from configuration files or from the interactive console.
42 To get started using the config/console library, see
44 \li \ref console_parser
45 \li \ref console_commands
47 \section console_example Example
49 The following example shows a \e very short summary on how to integrate the config/console
50 library. See above links for more:
53 // Define callback function.
54 void mycommand(std::ostream & os, senf::console::ParseCommandInfo const & command)
57 os << "!! Important message ...\n";
62 // Provide global documentation
64 .doc("This is someServer server");
68 .add("mycommand", &mycommand)
69 .doc("mycommand <foo> [<bar>]\n\n"
70 "If <bar> is given, flurgle the <foo>, otherwise burgle it");
72 // Start the interactive console server
73 senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u))
78 after this registration, the console can be accessed easily via telnet:
81 $ telnet localhost 23232
83 Connected to localhost.
84 Escape character is '^]'
85 xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Registered new client 0xxxxxxx
88 someServer:/# mycommand
89 !! Important message ...
91 xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Disposing client 0xxxxxxx
92 Connection closed by foreign host.
97 /** \defgroup console_commands Supported command types
99 The Console/config library supports quite a number of different command types. All these types
100 of command are registered, by passing them to DirectoryNode::add()
104 \section console_manualparse Manually parsing command arguments
106 This is the most primitive type of command. It will be called with an output stream and with a
107 senf::console::ParseCommandInfo reference which holds information about the command parsed.
109 From this information the command callback gets a list of arguments or tokens which then can be
110 interpreted in an arbitrary way.
112 void test1(std::ostream & os, senf::console::ParseCommandInfo const & command)
114 // We take exactly one argument
115 if (command.arguments().size() != 1)
116 raise senf::console::SyntaxErrorException("invalid number of arguments");
118 senf::console::ParseCommandInfo::TokenRange & argTokens (
119 command.arguments()[0]);
121 // The argument must have exactly one token
122 if (argTokens.size() != 1)
123 raise senf::console::SyntaxErrorException("argument syntax error");
125 // Retrieve the token value
126 std::string arg (argTokens[0].value());
128 // In this example, we just write the argument to the output stream
129 os << arg << std::endl;
133 Registering this callback is done by simply adding it. To provide online help, pass it to
136 senf::console::root()
137 .add("test1", &test1)
141 "Echo 'arg' to the console");
144 The callback may now be called interactively on the console by it's registered name:
148 invalid number of arguments
149 server:/$ test1 stefan@j32.de
151 server:/$ test1 (echo me)
152 argument syntax error
157 Echo 'arg' to the console
162 As you can see above, the arguments and tokens are returned as <a
163 href="http://www.boost.org/doc/libs/1_33_1/libs/range/doc/utility_class.html#iter_range">
164 boost::iterator_range</a> instances. These behave much like containers: They have \c begin() and
165 \c end() and some other useful members.
167 The parser will have divided the argument tokens into arguments already. This simplifies further
168 parsing. If however you want to access the list of argument tokens as a single list, you can do
169 so using senf::console::ParseCommandInfo::tokens().
171 Parsing arguments is quite simple but can get very tedious. To simplify this task, the parsing
172 can be delegated to the Console/config library. See the next section.
175 \section console_autoparse Automatic argument parsing
177 To greatly simplify parsing complex commands, we turn to automatic argument parsing. This
178 feature allows to register (almost) arbitrary callbacks.
181 std::string test2(std::string const & arg)
187 This extremely simple callback may be registered by adding it to a
188 senf::console::DirectoryNode.
190 senf::console::root()
191 .add("test2", &test2);
193 The functionality is now identical to \c test1:
197 invalid number of arguments
198 server:/$ test2 stefan@j32.de
200 server:/$ test2 (echo me)
201 argument syntax error
209 As we can see, some documentation is automatically provided. To add more info, we need to add
210 some additional attributes when registering the command:
212 namespace kw = senf::console::kw;
214 senf::console::root()
215 .add("test2", &test2)
216 .doc("Echo 'arg' to the console")
217 .arg( kw::name = "arg",
218 kw::description = "Message to output" );
221 (Sadly, there is no way to automatically find out the \e name of an argument, just it's type.)
222 Every callback argument corresponds with a call of the \c arg() attribute. Argument attributes
223 are set using keywords from the \ref senf::console::kw namespace. You will probably wither use
224 this namespace via a namespace alias (as above) or via a <tt>using namespace
225 senf::console::kw</tt> declaration (as in all the following examples)
228 to specify any information for an argument: To skip an argument, just call \c arg() without
229 attributes for this argument.
231 After adding this information, the online help is much more intelligible
239 arg Message to output
241 Echo 'arg' to the console
246 \subsection command_ostream Accessing the console stream
248 Commands may have an optional first argument of type <tt>std::ostream &</tt>. This argument is
249 not considered part of the real interface. When the command is executed, the callback will be
250 passed the current console's output stream object in this argument. With this, the callback can
251 output arbitrary messages to the network console. See the next section for an example.
253 \subsection command_overload Command overloading
255 Automatically parsed commands can be overloaded: You can register multiple commands under the
256 same name. If this happens, each command is tried in turn until no SyntaxErrorException is
260 void test3(std::ostream & os, unsigned n, std::string text)
262 // It's perfectly valid to check additional constraints here and throw a
263 // SyntaxErrorException. In this case, the next overload will be tried. However, you must
264 // ensure, That no action takes place before this check !
265 if ( n==0 ) throw senf::console::SyntaxErrorException("invalid value for parameter 'n'");
266 while (n-- > 0) os << text << std::endl;
269 using namespace senf::console::kw;
271 senf::console::root()
272 .add("test3", &test3)
273 .doc("Echo text to the console")
274 .overloadDoc("Repeat 'text' for 'n' lines")
275 .arg( name = "n", description = "Number of repetitions" )
276 .arg( name = "text", description = "Message to output" );
277 senf::console::root()
278 .add("test3", &test2)
279 .overloadDoc("Echo the 'text' argument")
280 .arg( name = "text", description = "Message to output" );
283 We can now call \c test2 with one or two arguments:
287 server:/$ test3 "The sky is blue"
296 1- test3 n:unsigned text:string
300 n Numer of repetitions
301 text Messsage to output
303 Echo text to the console
306 Repeat 'text' for 'n' lines
309 Echo the 'text' argument
315 \subsection console_defaults Default values
317 Another information which can not be automatically gathered from the type system is default
318 values. These have to be explicitly declared:
320 using namespace senf::console::kw;
322 senf::console::root()
323 .add("test4", &test2b)
325 .arg( default_value = "ok" );
327 (Default values must not necessarily be declared in the callback function too.) Of course,
328 default values can be used together with overloading.
330 There must be no argument without default value after an argument with a default value
331 declared. This fill fail at compile time.
333 \subsection console_auto_summary Attribute summary
335 Here a summary of all the attributes available for automatically parsed command nodes:
337 <table class="senf fixedwidth">
339 <tr><td style="width:12em">\c doc ( \e text )</td><td>Documentation for all overloads</td></tr>
341 <tr><td>\c overloadDoc ( \e text )</td><td>Documentation for a specific overliad</td></tr>
343 <tr><td>\c arg ( \e attributes )</td><td>Set parameter attributes. All attributes are
344 optional. The attribute keywords are defined in the \ref senf::console::kw namespace. Valid
346 \li \e name: Parameter name
347 \li \e description: One-line description of the argument
348 \li \e default_value: Arguments default value</td></tr>
352 \section console_memberfn Registering member functions
354 Member functions are supported like non-member functions. They must however be added through a
355 senf::console::ScopedDirectory<> instance to bind them to their instance.
360 ScopedDirectory<Test> dir;
362 Test(std::string label) : dir(this), label_ (label) {
363 dir.add("test4", &Test::test2);
364 dir.add("test4", &Test::test3);
367 std::string test2(std::string const & text) { return label_ + ": " + text; }
368 void test3(std::ostream & os, unsigned n, std::string const & text) {
369 while (n-- > 0) os << label << ": " << text << std::endl; }
377 Test testOb ("test");
378 senf::console::root().add("testobj", testOb.dir);
381 Binding via senf::console::ScopedDirectory ensures, that the commands are automatically removed
382 from the tree when an object is destroyed.
389 // comment-column: 40
390 // c-file-style: "senf"
391 // indent-tabs-mode: nil
392 // ispell-local-dictionary: "american"
393 // compile-command: "scons -u test"