b63300e90e2b0ff70c7fbb4aa35ea9685646b00c
[senf.git] / Console / Mainpage.dox
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \mainpage The Configuration and Runtime Control Framework
24
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.
29
30     \section console_intro Introduction
31
32     There are two components to the Config/console framework:
33
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
36         interactive console.
37
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.
41
42     To get started using the config/console library, see
43     \li \ref node_tree
44     \li \ref console_parser
45     \li \ref console_commands
46
47     \section console_example Example
48
49     The following example shows a \e very short summary on how to integrate the config/console
50     library. See above links for more:
51
52     \code
53     // Define callback function.
54     void mycommand(std::ostream & os, senf::console::ParseCommandInfo const & command)
55     {
56         // ...
57         os << "!! Important message ...\n";
58     }
59
60     int main(int, char**)
61     {
62         // Provide global documentation
63         senf::console::root()
64             .doc("This is someServer server");
65
66         // Add a command
67         senf::console::root()
68             .add("mycommand", &mycommand)
69             .doc("mycommand <foo> [<bar>]\n\n"
70                  "If <bar> is given, flurgle the <foo>, otherwise burgle it");
71
72         // Start the interactive console server
73         senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u))
74             .name("someServer");
75     }
76     \endcode
77
78     after this registration, the console can be accessed easily via telnet:
79     
80     <pre>
81     $ telnet localhost 23232
82     Trying 127.0.0.1...
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
86     someServer:/# ls
87     mycommand
88     someServer:/# mycommand
89     !! Important message  ...
90     someServer:/# exit
91     xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Disposing client 0xxxxxxx
92     Connection closed by foreign host.
93     $
94     </pre>
95  */
96
97 /** \defgroup console_commands Supported command types
98
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()
101
102     \autotoc
103
104     \section console_manualparse Manually parsing command arguments
105
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.
108
109     From this information the command callback gets a list of arguments or tokens which then can be
110     interpreted in an arbitrary way.
111     \code
112     void test1(std::ostream & os, senf::console::ParseCommandInfo const & command)
113     {
114         // We take exactly one argument
115         if (command.arguments().size() != 1) 
116             raise senf::console::SyntaxErrorException("invalid number of arguments");
117
118         senf::console::ParseCommandInfo::TokenRange & argTokens (
119             command.arguments()[0]);
120
121         // The argument must have exactly one token
122         if (argTokens.size() != 1)
123             raise senf::console::SyntaxErrorException("argument syntax error");
124
125         // Retrieve the token value
126         std::string arg (argTokens[0].value());
127
128         // In this example, we just write the argument to the output stream
129         os << arg << std::endl;
130     }
131     \endcode
132     
133     Registering this callback is done by simply adding it. To provide online help, pass it to
134     'doc()':
135     \code
136     senf::console::root()
137         .add("test1", &test1)
138         .doc("Usage:\n"
139              "    test1 arg\n"
140              "\n"
141              "Echo 'arg' to the console");
142     \endcode
143
144     The callback may now be called interactively on the console by it's registered name:
145     \htmlonly
146     <pre>
147     server:/$ test1
148     invalid number of arguments
149     server:/$ test1 stefan@j32.de
150     stefan@j32.de
151     server:/$ test1 (echo me)
152     argument syntax error
153     server:/$ help test1
154     Usage:
155         test1 arg
156
157     Echo 'arg' to the console
158     server:/$
159     </pre>
160     \endhtmlonly
161
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.
166     
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().
170     
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.
173
174
175     \section console_autoparse Automatic argument parsing
176     
177     To greatly simplify parsing complex commands, we turn to automatic argument parsing. This
178     feature allows to register (almost) arbitrary callbacks.
179
180     \code
181     std::string test2(std::string const & arg)
182     {
183         return arg;
184     }
185     \endcode
186
187     This extremely simple callback may be registered by adding it to a
188     senf::console::DirectoryNode.
189     \code
190     senf::console::root()
191         .add("test2", &test2);
192     \endcode
193     The functionality is now identical to \c test1:
194     \htmlonly
195     <pre>
196     server:/$ test2
197     invalid number of arguments
198     server:/$ test2 stefan@j32.de
199     stefan@j32.de
200     server:/$ test2 (echo me)
201     argument syntax error
202     server:/$ help test2
203     Usage:
204         test2 arg11:string
205     server:/$
206     </pre>
207     \endhtmlonly
208
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:
211     \code
212     namespace kw = senf::console::kw;
213
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" );
219     \endcode
220
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)
226
227     You don't need
228     to specify any information for an argument: To skip an argument, just call \c arg() without
229     attributes for this argument.
230
231     After adding this information, the online help is much more intelligible
232     \htmlonly
233     <pre>
234     server:/$ help test2
235     Usage:
236         test2 arg:string
237
238     With:
239         arg       Message to output
240
241     Echo 'arg' to the console
242     server:/$
243     </pre>
244     \endhtmlonly
245
246     \subsection command_ostream Accessing the console stream
247
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.
252
253     \subsection command_overload Command overloading
254
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
257     raised.
258
259     \code
260     void test3(std::ostream & os, unsigned n, std::string text)
261     {
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;
267     }
268
269     using namespace senf::console::kw;
270     
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" );
281     \endcode
282
283     We can now call \c test2 with one or two arguments:
284
285     \htmlonly
286     <pre>
287     server:/$ test3 "The sky is blue"
288     The sky is blue
289     server:/$ test3 4 ok
290     ok
291     ok
292     ok
293     ok
294     server:/$ help test3
295     Usage:
296         1- test3 n:unsigned text:string
297         2- test3 text:string
298     
299     With:
300         n         Numer of repetitions
301         text      Messsage to output
302
303     Echo text to the console
304
305     Variant 1:
306     Repeat 'text' for 'n' lines
307     
308     Variant 2:
309     Echo the 'text' argument
310     senf:/$    And 
311
312     </pre>
313     \endhtmlonly
314
315     \subsection console_defaults Default values
316     
317     Another information which can not be automatically gathered from the type system is default
318     values. These have to be explicitly declared:
319     \code
320     using namespace senf::console::kw;
321
322     senf::console::root()
323         .add("test4", &test2b)
324         .arg()
325         .arg( default_value = "ok" );
326     \endcode
327     (Default values must not necessarily be declared in the callback function too.) Of course,
328     default values can be used together with overloading. 
329
330     There must be no argument without default value after an argument with a default value
331     declared. This fill fail at compile time. 
332
333     \subsection console_auto_summary Attribute summary
334
335     Here a summary of all the attributes available for automatically parsed command nodes:
336     
337     <table class="senf fixedwidth">
338     
339     <tr><td style="width:12em">\c doc ( \e text )</td><td>Documentation for all overloads</td></tr>
340
341     <tr><td>\c overloadDoc ( \e text )</td><td>Documentation for a specific overliad</td></tr>
342
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
345     Attributes are:
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>
349
350     </table>
351     
352     \section console_memberfn Registering member functions
353     
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.
356     \code
357     class Test 
358     {
359     public:
360         ScopedDirectory<Test> dir;
361
362         Test(std::string label) : dir(this), label_ (label) {
363             dir.add("test4", &Test::test2);
364             dir.add("test4", &Test::test3);
365         }
366
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; }
370
371     private:
372         std::string label_;
373     };
374
375     // ...
376
377     Test testOb ("test");
378     senf::console::root().add("testobj", testOb.dir);
379     \endcode
380
381     Binding via senf::console::ScopedDirectory ensures, that the commands are automatically removed
382     from the tree when an object is destroyed.
383  */
384
385 \f
386 // Local Variables:
387 // mode: c++
388 // fill-column: 100
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"
394 // mode: auto-fill
395 // End:
396