Console: Add 'Variable' command 'onChange' implementation
[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 Library
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     \autotoc
31
32     \section console_intro Introduction
33
34     There are three parts to the Config/console library:
35
36     \li The console/config library is based on a \link node_tree tree of console/config
37         nodes. \endlink
38     \li Besides directories, the node contains command nodes. Commands are based on \link
39         console_commands variables or callbacks.\endlink
40     \li The console/config library is utilized by writing configuration files or interactive
41         commands in \link console_parser the console/config language.\endlink
42
43     The node tree works like a directory structure. Commands are entered into this directory
44     structure and can be called passing arbitrary arguments. Configuration parameters are just
45     commands which set their respective parameter, however the library allows commands to do much
46     more than just that.
47
48     \section console_example Example
49
50     The following example shows a \e very short summary on how to integrate the config/console
51     library. See above links for more:
52
53     \code
54     // Define callback function.
55     void mycommand(std::ostream & os, int foo, int bar)
56     {
57         // ...
58         os << "!! Important message ...\n";
59     }
60
61     namespace kw = senf::console::kw;
62
63     int main(int, char**)
64     {
65         // Provide global documentation
66         senf::console::root()
67             .doc("This is someServer server");
68
69         // Add a command
70         senf::console::root()
71             .add("mycommand", &mycommand)
72             .doc("If <bar> is given, flurgle the <foo>, otherwise burgle it")
73             .arg("foo")
74             .arg(kw::name = "bar", kw::default_value = 0);
75
76         // Start the interactive console server
77         senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u))
78             .name("someServer");
79     }
80     \endcode
81
82     after this registration, the console can be accessed easily via telnet:
83     
84     <pre>
85     $ telnet localhost 23232
86     Trying 127.0.0.1...
87     Connected to localhost.
88     Escape character is '^]'
89     xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Registered new client 0xxxxxxx
90     someServer:/# ls
91     mycommand
92     someServer:/# mycommand
93     !! Important message  ...
94     someServer:/# exit
95     xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Disposing client 0xxxxxxx
96     Connection closed by foreign host.
97     $
98     </pre>
99
100
101     \section intro_nodes The node tree
102
103     The basic idea is, that the console/config library manages a directory structure of parameters
104     and auxiliary commands. Parameters are just commands which set a parameter value so everything
105     is either a directory entry (senf::console::DirectoryNode) or a command
106     (senf::console::CommandNode).
107     
108     \see \ref node_tree
109
110
111     \section intro_commands Console/config commands
112
113     The console/config language does not define, how arguments are passed to the commands, it just
114     tokenizes the input and passes the tokens to the commands which then handle the
115     conversion.
116
117     Since parsing the tokens into something usable is quite tedious and error prone, the library
118     implements automatic argument parsing where the argument tokens are automatically parsed
119     depending on argument types. This enables you to register a command taking an integer argument
120     which will be called with an already parsed integer value (or throw a
121     senf::console::SyntaxErrorException if the conversion fails). This will be the most often used
122     command.
123
124     \see \ref console_commands
125     
126
127     \section intro_language The console/config language
128
129     To call the commands and set parameters, a very simple language is defined. The language is
130     almost declarative (e.g. it does not have any control-flow statements) but is processed
131     imperatively from top to bottom. This is very simple and flexible.
132
133     Commands are referenced by their path in the node tree. To simplify working with deeply nested
134     directory structures, the current directory may be changed persistently or temporarily for some
135     commands.
136     \code
137     /server/port 1234;
138     
139     /logger/targets/console {
140         accept senf::log::Debug IMPORTANT;
141         accept server::ServerLog CRITICAL;
142     }
143     \endcode
144
145     \see \ref console_parser
146  */
147
148 /** \defgroup console_commands Supported command types
149
150     The Console/config library supports quite a number of different command types. All these types
151     of command are registered, by passing them to DirectoryNode::add()
152
153     \autotoc
154
155     \section console_cmdadd Adding commands and setting attributes
156
157     Basically, all commands are added using senf::console::DirectoryNode::add(). What exactly
158     happens depends on the type of object added.
159     \code
160     dir.add("name", callback)
161     \endcode
162     will add a command 'name' which will execute 'callback' when called, where 'callback' can be a
163     lot of things as documented in the following chapters.
164
165     The add call always returns (something which can be used as) a reference to the command node
166     added:
167     \code
168     senf::console::CommandNode & node ( dir.add( ... ) );
169     \endcode
170
171     Depending on the object added, you can also bind to a more specific node type
172     (e.g. senf::console::SimpleCommand) if you know the type of node returned.
173
174     Depending on the type of object added, there are additional attributes which can be set. These
175     attributes are always set by calling them on the return value <b>before saving that value as a
176     node reference</b>. It is \e not guaranteed, you can call these members on the node
177     reference.
178     \code
179     dir.add("name", callback)
180         .doc("The documentation");
181     \endcode
182     sets the \e doc attribute (if that is available, otherwise this will fail to compile). The
183     attribute members return value is again (something which can be used as) a reference to the
184     command node
185     \code
186     senf::console::CommandNode & node (
187         dir.add("name", callback)
188             .doc("The documentation") );
189     \endcode
190
191
192     \section console_manualparse Manually parsing command arguments
193
194     This is the most primitive type of command. It will be called with an output stream and with a
195     senf::console::ParseCommandInfo reference which holds information about the command parsed.
196
197     From this information the command callback gets a list of arguments or tokens which then can be
198     interpreted in an arbitrary way.
199     \code
200     void fun1(std::ostream & os, senf::console::ParseCommandInfo const & command)
201     {
202         // We take exactly one argument
203         if (command.arguments().size() != 1) 
204             raise senf::console::SyntaxErrorException("invalid number of arguments");
205
206         senf::console::ParseCommandInfo::TokenRange & argTokens (
207             command.arguments()[0]);
208
209         // The argument must have exactly one token
210         if (argTokens.size() != 1)
211             raise senf::console::SyntaxErrorException("argument syntax error");
212
213         // Retrieve the token value
214         std::string arg (argTokens[0].value());
215
216         // In this example, we just write the argument to the output stream
217         os << arg << std::endl;
218     }
219     \endcode
220     
221     Registering this callback is done by simply adding it. To provide online help, pass it to
222     'doc()':
223     \code
224     senf::console::root()
225         .add("test1", &fun1)
226         .doc("Usage:\n"
227              "    test1 arg\n"
228              "\n"
229              "Echo 'arg' to the console");
230     \endcode
231
232     The callback may now be called interactively on the console by it's registered name:
233     \htmlonly
234     <pre>
235     server:/$ test1
236     invalid number of arguments
237     server:/$ test1 stefan@j32.de
238     stefan@j32.de
239     server:/$ test1 (echo me)
240     argument syntax error
241     server:/$ help test1
242     Usage:
243         test1 arg
244
245     Echo 'arg' to the console
246     server:/$
247     </pre>
248     \endhtmlonly
249
250     As you can see above, the arguments and tokens are returned as <a
251     href="http://www.boost.org/doc/libs/1_33_1/libs/range/doc/utility_class.html#iter_range">
252     boost::iterator_range</a> instances. These behave much like containers: They have \c begin() and
253     \c end() and some other useful members.
254     
255     The parser will have divided the argument tokens into arguments already. This simplifies further
256     parsing. If however you want to access the list of argument tokens as a single list, you can do
257     so using senf::console::ParseCommandInfo::tokens().
258     
259     Parsing arguments is quite simple but can get very tedious. To simplify this task, the parsing
260     can be delegated to the Console/config library. See the next section.
261
262     This type of command has only a single attribute, \e doc to set the commands documentation.
263
264
265     \section console_autoparse Automatic argument parsing
266     
267     To greatly simplify parsing complex commands, we turn to automatic argument parsing. 
268
269     \subsection console_autoadd Adding
270
271     Automatically parsed commands are registered by just adding a callback which has the correct
272     arguments and return-value defined:
273     \code
274     std::string fun2(std::string const & arg)
275     {
276         return arg;
277     }
278     \endcode
279
280     This extremely simple callback may be registered by adding it to a senf::console::DirectoryNode.
281     \code
282     senf::console::root()
283         .add("test2", &fun2);
284     \endcode
285     The functionality is now identical to \c test1:
286     \htmlonly
287     <pre>
288     server:/$ test2
289     invalid number of arguments
290     server:/$ test2 stefan@j32.de
291     stefan@j32.de
292     server:/$ test2 (echo me)
293     argument syntax error
294     server:/$ help test2
295     Usage:
296         test2 arg11:string
297     server:/$
298     </pre>
299     \endhtmlonly
300
301
302     \subsection command_ostream Accessing the console stream
303
304     Commands may have an optional first argument of type <tt>std::ostream &</tt>. This argument is
305     not considered part of the real interface. When the command is executed, the callback will be
306     passed the current console's output stream object in this argument. With this, the callback can
307     output arbitrary messages to the network console.
308     \code
309     void fun3(std::ostream & os, unsigned n, std::string text)
310     {
311         while (n-- > 0) os << text << std::endl;
312     }
313
314     senf::console::root()
315         .add("test3", &fun3);
316     \endcode
317
318     This simple command can now be used thus:
319     \htmlonly
320     <pre>
321     server:/$ test3
322     invalid number of arguments
323     server:/$ test3 stefan@j32.de
324     invalid number of arguments
325     server:/$ test3 2 ok
326     ok
327     ok
328     server:/$ help test3
329     Usage:
330         test3 arg11:int arg12:string
331     server:/$
332     </pre>
333     \endhtmlonly
334
335     \subsection command_overload Overloading
336
337     Automatically parsed commands can be overloaded: You can register multiple commands under the
338     same name. Each overload is tried in turn until no SyntaxErrorException is raised.
339     \code
340     senf::console::root()
341         .add("test4", &fun3);
342     senf::console::root()
343         .add("test4", &fun2);
344     \endcode
345     And now, we can call \c test4 with one or two args:
346     <pre>
347     server:/$ test4
348     invalid number of arguments
349     server:/$ test4 stefan@j32.de
350     stefan@j32.de
351     server:/$ test4 2 ok
352     ok
353     ok
354     server:/$ help test4
355     Usage:
356         1- test4 arg11:int arg12:string
357         2- test4 arg21:string
358     server:/$
359     </pre>
360
361     One note: When taking the address of an overloaded function (member or non-member), the C++
362     language forces you to cast that address to one of the possible types so the compiler knows,
363     which overload is requested. So to add a function which is overloaded in C++, each overload
364     needs to be added explicitly, casting to the correct type:
365     \code
366     void over(int);
367     void over(int,int);
368
369     senf::console::root()
370         .add("over", static_cast<void (*)(int)>(&over));
371     senf::console::root()
372         .add("over", static_cast<void (*)(int,int)>(&over));
373     \endcode
374
375
376     \subsection console_attributes Attributes
377
378     As have seen so far, some documentation is automatically provided. We can add more info, by
379     setting additional attributes. 
380     \code
381     senf::console::root()
382         .add("test5", &fun3)
383         .doc("Echo text to the console")
384         .overloadDoc("Repeat {arg12} for {arg11} lines");
385     senf::console::root()
386         .add("test4", &fun2)
387         .overloadDoc("Echo the {arg21} argument")
388     \endcode
389
390     This additional info is used to provide more documentation:
391     \htmlonly
392     <pre>
393     server:/$ help test5
394     Usage:
395         1- test5 arg11:int arg12:string
396         2- test5 arg21:string
397
398     Echo text to the console
399
400     Variant 1:
401     Repeat {arg12} for {arg11} lines
402     
403     Variant 2:
404     Echo the {arg21} argument
405     senf:/$
406     </pre>
407     \endhtmlonly
408
409
410     \subsection console_argattributes Argument attributes
411
412     Additional attributes can be set for each parameter. They are all passed to the
413     senf::console::ParsedArgumentAttributor::arg() attribute.
414
415     \code
416     namespace kw = senf::console::kw;
417
418     senf::console::root()
419         .add("test6", &fun3)
420         .doc("Echo text to the console")
421         .overloadDoc("Repeat {text} for {n} lines");
422         .arg( kw::name = "n", kw::description="Number of repetitions" )
423         .arg( kw::name = "text", kw::description="Text to output" );
424     senf::console::root()
425         .add("test6", &fun2)
426         .overloadDoc("Echo the {text} argument")
427         .arg( kw::name = "text" );
428     \endcode
429
430     (Sadly, there is no way to automatically find out the \e name of an argument, just it's type.)
431     Every callback argument corresponds with a call of the \c arg() attribute. Argument attributes
432     are set using keywords from the \ref senf::console::kw namespace. You will probably either use
433     this namespace via a namespace alias (as above) or via a <tt>using namespace
434     senf::console::kw</tt> declaration (but beware of name collisions).
435
436     You don't need to specify any information for an argument: To skip an argument, just call \c
437     arg() without attributes for this argument.
438
439     After adding this information, the online help is much more readable
440       \htmlonly
441     <pre>
442     server:/$ help test6
443     Usage:
444         1- test6 n:int text:string
445         2- test6 text:string
446
447     With:
448         n         Number of repetitions
449         text      Text to output
450
451     Echo text to the console
452
453     Variant 1:
454     Repeat {text} for {n} lines
455     
456     Variant 2:
457     Echo the {text} argument
458     senf:/$
459     </pre>
460     \endhtmlonly
461
462     Since most of the time, we only need to set the name and possibly a description for arguments,
463     there is a shortcut: name and description can be specified as positional arguments in this
464     order. So the following will give the exactly same result as above:
465     \code
466     namespace kw = senf::console::kw;
467
468     senf::console::root()
469         .add("test6", &fun3)
470         .doc("Echo text to the console")
471         .overloadDoc("Repeat <text> for <n> lines");
472         .arg("n",    "Number of repetitions")
473         .arg("text", "Text to output");
474     senf::console::root()
475         .add("test6", &fun2)
476         .overloadDoc("Echo the <text> argument")
477         .arg("text");
478     \endcode
479     
480     Keyword arguments should always be used if additional attributes are set. You can however mix
481     positional and keyword arguments.
482
483     
484     \subsection console_defaults Default values
485     
486     Another information which can not be automatically gathered from the type system is default
487     values. These have to be declared explicitly:
488     \code
489     namespace kw = senf::console::kw;
490
491     senf::console::root()
492         .add("test7", &fun3)
493         .doc("Echo {text} to the console, repeating {text} for {n} lines")
494         .arg("n",    "Number of repetitions", kw::default_value=1)
495         .arg("text", "Text to output");
496     \endcode
497
498     Default values can be used together with overloading. Default (optional) value support is quite
499     flexible, it is not mandatory, for default values to be specified only for the trailing
500     arguments. For the exact definition, how parsed argument values are assigned to overload
501     arguments in the presence of default values, see \ref senf::console::kw::default_value.
502     
503     \htmlonly
504     <pre>
505     server:/$ test7 echo
506     echo
507     server:/$ test7 4 ok
508     ok
509     ok
510     ok
511     ok
512     server:/$ help test7
513     Usage:
514         test4 [n:unsigned] text:string
515     
516     With:
517         n         Number of repetitions
518             default: 1
519         text      Text to output
520
521     Echo {text} to the console, repeating {text} for {n} lines
522     server:/$
523     </pre>
524     \endhtmlonly
525
526
527     \subsection console_boostfn Non-function-pointer commands
528
529     It is possible to add other callable objects besides function (and member-function)
530     pointers. However, since it is not possible to automatically deduce the argument and return
531     types in this case, the callables have to be wrapped in a \c boost::function object:
532
533     \code
534     senf::console::root()
535         .add("test8", 
536              boost::function<void (std::ostream &, std::string const &)>(
537                  boost::bind(&fun3, _1, 4u, _2)));
538     \endcode
539
540     This works with any callable object where argument types cannot be deduced automatically:
541     Boost.Bind expressions, Boost.Lambda expressions, functors and so on.
542     
543     \htmlonly
544     <pre>
545     server:/$ test8 ok
546     ok
547     ok
548     ok
549     ok
550     server:/$ help test8
551     Usage:
552         test8 arg11:string
553     server:/$
554     </pre>
555     \endhtmlonly
556
557
558     \subsection console_attr_summary Attribute summary
559
560     Here a summary of the most common attributes
561
562     <table class="senf fixedwidth">
563
564     <tr><td style="width:14em">\link senf::console::ParsedArgumentAttributorBase::doc() .doc\endlink
565     ( \e doc )</td><td>Set documentation for all overloads</td></tr>
566     
567     <tr><td>\link senf::console::ParsedArgumentAttributorBase::overloadDoc()
568     .overloadDoc\endlink ( \e doc )</td><td>Set documentation for a specific overload</td></tr>
569
570     <tr><td>\link senf::console::ParsedArgumentAttributor::arg() .arg\endlink ( \e argument \e
571     attributes )</td><td>Set argument attributes (see below)</td></tr>
572
573     </table>
574
575     The most important argument attributes (all defined in the senf::console::kw namespace) are:
576     
577     <table class="senf fixed width">
578
579     <tr><td style="width:14em">\link senf::console::kw::name kw::name\endlink</td><td>Parameter
580     name</td></tr>
581
582     <tr><td>\link senf::console::kw::description kw::description\endlink</td><td>One-line
583     description of the argument</td></tr>
584
585     <tr><td>\link senf::console::kw::default_value kw::default_value\endlink</td><td>Arguments
586     default value</td></tr>
587
588     </table>
589
590     \see <a
591         href="classsenf_1_1console_1_1ParsedArgumentAttributor-members.html">senf::console::ParsedArgumentAttributor
592         / List of all members</a> for the complete attribute interface \n
593         \ref senf::console::kw for a list of all argument attribute keywords
594
595         
596     \section console_memberfn Member functions
597     
598     Member functions are supported like non-member functions. They must however be added through a
599     senf::console::ScopedDirectory instance to bind them to their instance.
600     \code
601     class Test1
602     {
603     public:
604         senf::console::ScopedDirectory<Test1> dir;
605
606         Test1(std::string label) : dir(this), label_ (label) 
607             { dir.add("test", &Test::test1);
608               dir.add("test", &Test::test2); }
609     
610         std::string test1(std::string const & text)
611             { return label_ + ": " + text; }
612
613         void test2(std::ostream & os, unsigned n, std::string const & text) 
614             { while (n-- > 0) os << label << ": " << text << std::endl; }
615
616     private:
617         std::string label_;
618     };
619
620     // ...
621
622     Test1 test1ob ("test");
623     senf::console::root().add("test1ob", test1ob.dir);
624     \endcode
625
626     Binding via senf::console::ScopedDirectory ensures, that the commands are automatically removed
627     from the tree when the object is destroyed.
628
629
630     \section console_variables Variables
631     
632     \subsection console_varadd Adding
633
634     The console/config library supports the direct registration of variables as commands. A
635     variable command consists of two overloads, one to query the current value and one to change the
636     value. 
637     \code
638     class Test2
639     {
640     public:
641         senf::console::ScopedDirectory<Test2> dir;
642
643         Test2() : dir(this), var_(0)
644             { dir.add("var", var_); }
645
646     private:
647         int var_;
648     };
649
650     Test2 test2ob;
651     senf::console::root().add("test2ob", test2ob.dir);
652     \endcode
653     This shows the most common scenario: A member variable is added to a ScopedDirectory of the same
654     class. This ensures, that the variable command node is removed from the tree when the instance
655     (and thereby the variable) are destroyed. The variable can now be used like any other command:
656     \htmlonly
657     <pre>
658     server:/$ test2ob/var
659     0
660     server:/$ test2ob/var 10
661     server:/$ test2ob/var
662     10
663     server:/$ help test2ob
664     Usage:
665         1- var new_value:int
666         2- var
667     server:/$
668     </pre>
669     \endhtmlonly
670
671
672     \subsection console_varro Read-only variables
673     
674     The library also supports read-only variables. To make a variable read-only, just wrap it in \c
675     boost::cref() (where \c cref stands for \c const reference)
676     \code
677     int var (0);
678
679     senf::console::root().add("var1", boost::cref(var));
680     \endcode
681     A read-only variable only has a single overload:
682     \htmlonly
683     <pre>
684     server:/$ var1
685     0
686     server:/$ help var1
687     Usage:
688         var1
689     server:/$ 
690     </pre>
691     \endhtmlonly
692
693
694     \subsection console_varattr Attributes
695
696     The most important Variable command attributes are
697
698     <table class="senf fixedwidth">
699
700     <tr><td style="width:14em">\link senf::console::VariableAttributor::doc() .doc\endlink
701     ( \e doc )</td><td>Set variable documentation</td></tr>
702     
703     <tr><td>\link senf::console::VariableAttributor::onChange() .onchange\endlink
704     ( \e handler )</td><td>Set change handler</td></tr>
705     
706     </table>
707
708     \see senf::console::VariableAttributor for the complete attribute interface
709
710     \subsection console_varchange Change notification
711
712     A \e handler can be set to be called, whenever the variable is changed. It will be called with a
713     reference to the old value. The handler is called, after the value has been changed
714
715     \code
716     int var (0);
717
718     // Since this is int, it would make sense to declare the argument pass-by-value (int old)
719     // but for more complex args, use a const & here
720     void varChanged(int const & old)
721     {
722         // ...
723     }
724
725     senf::console::root().add("var2",var)
726         .onChange(&varChanged);
727     \endcode
728     
729     After this setup, \c varChanged will be called, whenever the value has changed.
730
731
732     \see senf::console::VariableAttributor for the complete attribute interface
733  */
734
735 \f
736 // Local Variables:
737 // mode: c++
738 // fill-column: 100
739 // comment-column: 40
740 // c-file-style: "senf"
741 // indent-tabs-mode: nil
742 // ispell-local-dictionary: "american"
743 // compile-command: "scons -u test"
744 // mode: auto-fill
745 // End:
746