c143bc35aea1912c69c3c47af5230744df771f58
[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     #include <senf/Console.hh>
55
56     // Define callback function.
57     void mycommand(std::ostream & os, int foo, int bar)
58     {
59         // ...
60         os << "!! Important message ...\n";
61     }
62
63     namespace kw = senf::console::kw;
64
65     int main(int, char**)
66     {
67         // Provide global documentation
68         senf::console::root()
69             .doc("This is someServer server");
70
71         // Add a command
72         senf::console::root()
73             .add("mycommand", &mycommand)
74             .doc("If <bar> is given, flurgle the <foo>, otherwise burgle it")
75             .arg("foo")
76             .arg(kw::name = "bar", kw::default_value = 0);
77
78         // Start the interactive console server
79         senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u))
80             .name("someServer");
81     }
82     \endcode
83
84     after this registration, the console can be accessed easily via telnet:
85     
86     <pre>
87     $ telnet localhost 23232
88     Trying 127.0.0.1...
89     Connected to localhost.
90     Escape character is '^]'
91     xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Registered new client 0xxxxxxx
92     someServer:/# ls
93     mycommand
94     someServer:/# mycommand
95     !! Important message  ...
96     someServer:/# exit
97     xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Disposing client 0xxxxxxx
98     Connection closed by foreign host.
99     $
100     </pre>
101
102     \see \ref console_testserver for a complete example application
103
104     \section intro_init Initialization
105
106     To make the console accessible, it must be initialized when the program is started:
107     \code
108     #include <senf/Console.hh>
109
110     int main(int argc, char * argv [])
111     {
112         // Configure console nodes, add commands ...
113
114         // Start console server
115         senf::console::start(senf::INet4SocketAddress(12345u))
116            .name("myserver");
117
118         // You need to enter the scheduler main-loop for the server to work
119         senf::Scheduler::instance().process();
120        
121         // Alternatively enter the main-loop via the PPI
122         // senf::ppi::run();
123     }
124     \endcode
125
126     This will start the server on IPv4 port 12345. The servers name (as displayed in the interactive
127     console prompt) is set to 'myserver'.
128
129     After launching the application, the server can be accessed at the given port:
130     \htmlonly
131     <pre>
132     bash$ telnet localhost 12345
133     Trying 127.0.0.1...
134     Connected to localhost.
135     Escape character is '^]'.
136
137     myserver:/$ exit
138     Connection closed by foreign host.
139     bash$
140     </pre>
141     \endhtmlonly
142
143     \section intro_nodes The node tree
144
145     The basic idea is, that the console/config library manages a directory structure of parameters
146     and auxiliary commands. Parameters are just commands which set a parameter value so everything
147     is either a directory entry (senf::console::DirectoryNode) or a command
148     (senf::console::CommandNode).
149     
150     \see \ref node_tree
151
152
153     \section intro_commands Registering console/config commands
154
155     The console/config language does not define, how arguments are passed to the commands, it just
156     tokenizes the input and passes the tokens to the commands which then handle the
157     conversion.
158
159     Since parsing the tokens into something usable is quite tedious and error prone, the library
160     implements automatic argument parsing where the argument tokens are automatically parsed
161     depending on argument types. This enables you to register a command taking an integer argument
162     which will be called with an already parsed integer value (or throw a
163     senf::console::SyntaxErrorException if the conversion fails). This will be the most often used
164     command.
165
166     \see \ref console_commands
167     
168
169     \section intro_language The console/config language
170
171     To call the commands and set parameters, a very simple language is defined. The language is
172     almost declarative (e.g. it does not have any control-flow statements) but is processed
173     imperatively from top to bottom. This is very simple and flexible.
174
175     Commands are referenced by their path in the node tree. To simplify working with deeply nested
176     directory structures, the current directory may be changed persistently or temporarily for some
177     commands.
178     \code
179     /server/port 1234;
180     
181     /logger/targets/console {
182         accept senf::log::Debug IMPORTANT;
183         accept server::ServerLog CRITICAL;
184     }
185     \endcode
186
187     \see \ref console_parser
188
189
190     \section console_misc Further features
191
192     \subsection console_serverclient Server and Client objects
193
194     The senf::console::Server and senf::console::Client objects offer further API calls. To access
195     the server instance you need to store away the senf::console::Server reference returned when
196     starting the server so you can later refer to it:
197     \code
198     int main(int, char**)
199     {
200         senf::console::Server & server ( senf::console::start( ... ) );
201     
202         // Do something ...
203
204         server.stop()
205     }
206     \endcode
207
208     The client instance can be accessed via the \c std::ostream arg of any command callback
209     \code
210     void someCallback(std::ostream & os, ... )
211     {
212         senf::console::Client & client (senf::console::Client::get(os));
213     
214         // Use the client's log target
215         client.route<senf::log::Debug, senf::Log::IMPORTANT>();
216     }
217     \endcode
218
219     \see 
220         senf::console::Server for the Server API \n
221         <a href="classsenf_1_1console_1_1Client-members.html">senf::console::Client / List of all
222         members</a> for the Client API
223
224
225     \subsection console_shell Features of the interactive console shell
226
227     The interactive shell will use the GNU readline library for the first connected
228     instance. Further users will not have access to this functionality since GNU readline is
229     completely non-reentrant.
230
231     The shell supports auto-cd and auto-completion: If you enter the name of a directory at the
232     prompt, the console will change to that directory. With auto-completion, any unique beginning of
233     a path component will be completed automatically and transparently to th corresponding full
234     name.
235  */
236
237 /** \defgroup console_commands Supported command types
238
239     The Console/config library supports quite a number of different command types. All these types
240     of command are registered, by passing them to DirectoryNode::add()
241
242     \autotoc
243
244     \section console_cmdadd Adding commands and setting attributes
245
246     Basically, all commands are added using senf::console::DirectoryNode::add(). What exactly
247     happens depends on the type of object added.
248     \code
249     dir.add("name", callback)
250     \endcode
251     will add a command 'name' which will execute 'callback' when called, where 'callback' can be a
252     lot of things as documented in the following chapters.
253
254     The add call always returns (something which can be used as) a reference to the command node
255     added:
256     \code
257     senf::console::CommandNode & node ( dir.add( ... ) );
258     \endcode
259
260     Depending on the object added, you can also bind to a more specific node type
261     (e.g. senf::console::SimpleCommand) if you know the type of node returned.
262
263     Depending on the type of object added, there are additional attributes which can be set. These
264     attributes are always set by calling them on the return value <b>before saving that value as a
265     node reference</b>. It is \e not guaranteed, you can call these members on the node
266     reference.
267     \code
268     dir.add("name", callback)
269         .doc("The documentation");
270     \endcode
271     sets the \e doc attribute (if that is available, otherwise this will fail to compile). The
272     attribute members return value is again (something which can be used as) a reference to the
273     command node
274     \code
275     senf::console::CommandNode & node (
276         dir.add("name", callback)
277             .doc("The documentation") );
278     \endcode
279
280
281     \section console_manualparse Manually parsing command arguments
282
283     This is the most primitive type of command. It will be called with an output stream and with a
284     senf::console::ParseCommandInfo reference which holds information about the command parsed.
285
286     From this information the command callback gets a list of arguments or tokens which then can be
287     interpreted in an arbitrary way.
288     \code
289     void fun1(std::ostream & os, senf::console::ParseCommandInfo const & command)
290     {
291         // Here we declare variables for the arguments
292         std::string value;
293
294         {
295             // We parse the arguments using the CheckedArgumentIteratorWrapper. This wrapper
296             // will throw a SyntaxErrorException if we access a nonexistent argument or if we
297             // do not parse all arguments.
298             senf::console::CheckedArgumentIteratorWrapper args (command.arguments());
299
300             senf::console::ParseCommandInfo::TokensRange argTokens ( *(args++) );
301             if (arg1Tokens.size() != 1)
302                 raise senf::console::SyntaxErrorException("argument syntax error");
303             value = arg1Tokens[0];
304         }
305
306         os << value << std::endl;
307     }
308     \endcode
309     
310     Registering this callback is done by simply adding it. To provide online help, pass it to
311     'doc()':
312     \code
313     senf::console::root()
314         .add("test1", &fun1)
315         .doc("Usage:\n"
316              "    test1 arg\n"
317              "\n"
318              "Echo 'arg' to the console");
319     \endcode
320
321     The callback may now be called interactively on the console by it's registered name:
322     \htmlonly
323     <pre>
324     server:/$ test1
325     invalid number of arguments
326     server:/$ test1 stefan@j32.de
327     stefan@j32.de
328     server:/$ test1 (echo me)
329     argument syntax error
330     server:/$ help test1
331     Usage:
332         test1 arg
333
334     Echo 'arg' to the console
335     server:/$
336     </pre>
337     \endhtmlonly
338
339     As you can see above, the arguments and tokens are returned as <a
340     href="http://www.boost.org/doc/libs/1_33_1/libs/range/doc/utility_class.html#iter_range">
341     boost::iterator_range</a> instances. These behave much like containers: They have \c begin() and
342     \c end() and some other useful members.
343     
344     The parser will have divided the argument tokens into arguments already. This simplifies further
345     parsing. If however you want to access the list of argument tokens as a single list, you can do
346     so using senf::console::ParseCommandInfo::tokens().
347     
348     Parsing arguments is quite simple but can get very tedious. To simplify this task, the parsing
349     can be delegated to the Console/config library. See the next section.
350
351     This type of command has only a single attribute, \e doc to set the commands documentation.
352
353
354     \section console_autoparse Automatic argument parsing
355     
356     To greatly simplify parsing complex commands, we turn to automatic argument parsing. 
357
358     \subsection console_autoadd Adding
359
360     Automatically parsed commands are registered by just adding a callback which has the correct
361     arguments and return-value defined:
362     \code
363     std::string fun2(std::string const & arg)
364     {
365         return arg;
366     }
367     \endcode
368
369     This extremely simple callback may be registered by adding it to a senf::console::DirectoryNode.
370     \code
371     senf::console::root()
372         .add("test2", &fun2);
373     \endcode
374     The functionality is now identical to \c test1:
375     \htmlonly
376     <pre>
377     server:/$ test2
378     invalid number of arguments
379     server:/$ test2 stefan@j32.de
380     stefan@j32.de
381     server:/$ test2 (echo me)
382     argument syntax error
383     server:/$ help test2
384     Usage:
385         test2 arg11:string
386     server:/$
387     </pre>
388     \endhtmlonly
389
390
391     \subsection command_ostream Accessing the console stream
392
393     Commands may have an optional first argument of type <tt>std::ostream &</tt>. This argument is
394     not considered part of the real interface. When the command is executed, the callback will be
395     passed the current consoles output stream object in this argument. With this, the callback can
396     output arbitrary messages to the network console.
397     \code
398     void fun3(std::ostream & os, unsigned n, std::string text)
399     {
400         while (n-- > 0) os << text << std::endl;
401     }
402
403     senf::console::root()
404         .add("test3", &fun3);
405     \endcode
406
407     This simple command can now be used thus:
408     \htmlonly
409     <pre>
410     server:/$ test3
411     invalid number of arguments
412     server:/$ test3 stefan@j32.de
413     invalid number of arguments
414     server:/$ test3 2 ok
415     ok
416     ok
417     server:/$ help test3
418     Usage:
419         test3 arg11:int arg12:string
420     server:/$
421     </pre>
422     \endhtmlonly
423
424     \subsection command_overload Overloading
425
426     Automatically parsed commands can be overloaded: You can register multiple commands under the
427     same name. Each overload is tried in turn until no SyntaxErrorException is raised.
428     \code
429     senf::console::root()
430         .add("test4", &fun3);
431     senf::console::root()
432         .add("test4", &fun2);
433     \endcode
434     And now, we can call \c test4 with one or two args:
435     <pre>
436     server:/$ test4
437     invalid number of arguments
438     server:/$ test4 stefan@j32.de
439     stefan@j32.de
440     server:/$ test4 2 ok
441     ok
442     ok
443     server:/$ help test4
444     Usage:
445         1- test4 arg11:int arg12:string
446         2- test4 arg21:string
447     server:/$
448     </pre>
449
450     One note: When taking the address of an overloaded function (member or non-member), the C++
451     language forces you to cast that address to one of the possible types so the compiler knows,
452     which overload is requested. So to add a function which is overloaded in C++, each overload
453     needs to be added explicitly, casting to the correct type:
454     \code
455     void over(int);
456     void over(int,int);
457
458     senf::console::root()
459         .add("over", static_cast<void (*)(int)>(&over));
460     senf::console::root()
461         .add("over", static_cast<void (*)(int,int)>(&over));
462     \endcode
463
464
465     \subsection console_attributes Attributes
466
467     As have seen so far, some documentation is automatically provided. We can add more info, by
468     setting additional attributes. 
469     \code
470     senf::console::root()
471         .add("test5", &fun3)
472         .doc("Echo text to the console")
473         .overloadDoc("Repeat {arg12} for {arg11} lines");
474     senf::console::root()
475         .add("test4", &fun2)
476         .overloadDoc("Echo the {arg21} argument")
477     \endcode
478
479     This additional info is used to provide more documentation:
480     \htmlonly
481     <pre>
482     server:/$ help test5
483     Usage:
484         1- test5 arg11:int arg12:string
485         2- test5 arg21:string
486
487     Echo text to the console
488
489     Variant 1:
490     Repeat {arg12} for {arg11} lines
491     
492     Variant 2:
493     Echo the {arg21} argument
494     senf:/$
495     </pre>
496     \endhtmlonly
497
498
499     \subsection console_argattributes Argument attributes
500
501     Additional attributes can be set for each parameter. They are all passed to the
502     senf::console::ParsedArgumentAttributor::arg() attribute.
503
504     \code
505     namespace kw = senf::console::kw;
506
507     senf::console::root()
508         .add("test6", &fun3)
509         .doc("Echo text to the console")
510         .overloadDoc("Repeat {text} for {n} lines");
511         .arg( kw::name = "n", kw::description="Number of repetitions" )
512         .arg( kw::name = "text", kw::description="Text to output" );
513     senf::console::root()
514         .add("test6", &fun2)
515         .overloadDoc("Echo the {text} argument")
516         .arg( kw::name = "text" );
517     \endcode
518
519     (Sadly, there is no way to automatically find out the \e name of an argument, just it's type.)
520     Every callback argument corresponds with a call of the \c arg() attribute. Argument attributes
521     are set using keywords from the \ref senf::console::kw namespace. You will probably either use
522     this namespace via a namespace alias (as above) or via a <tt>using namespace
523     senf::console::kw</tt> declaration (but beware of name collisions).
524
525     You don't need to specify any information for an argument: To skip an argument, just call \c
526     arg() without attributes for this argument.
527
528     After adding this information, the online help is much more readable
529       \htmlonly
530     <pre>
531     server:/$ help test6
532     Usage:
533         1- test6 n:int text:string
534         2- test6 text:string
535
536     With:
537         n         Number of repetitions
538         text      Text to output
539
540     Echo text to the console
541
542     Variant 1:
543     Repeat {text} for {n} lines
544     
545     Variant 2:
546     Echo the {text} argument
547     senf:/$
548     </pre>
549     \endhtmlonly
550
551     Since most of the time, we only need to set the name and possibly a description for arguments,
552     there is a shortcut: name and description can be specified as positional arguments in this
553     order. So the following will give the exactly same result as above:
554     \code
555     namespace kw = senf::console::kw;
556
557     senf::console::root()
558         .add("test6", &fun3)
559         .doc("Echo text to the console")
560         .overloadDoc("Repeat <text> for <n> lines");
561         .arg("n",    "Number of repetitions")
562         .arg("text", "Text to output");
563     senf::console::root()
564         .add("test6", &fun2)
565         .overloadDoc("Echo the <text> argument")
566         .arg("text");
567     \endcode
568     
569     Keyword arguments should always be used if additional attributes are set. You can however mix
570     positional and keyword arguments.
571
572     
573     \subsection console_defaults Default values
574     
575     Another information which can not be automatically gathered from the type system is default
576     values. These have to be declared explicitly:
577     \code
578     namespace kw = senf::console::kw;
579
580     senf::console::root()
581         .add("test7", &fun3)
582         .doc("Echo {text} to the console, repeating {text} for {n} lines")
583         .arg("n",    "Number of repetitions", kw::default_value=1)
584         .arg("text", "Text to output");
585     \endcode
586
587     Default values can be used together with overloading. Default (optional) value support is quite
588     flexible, it is not mandatory, for default values to be specified only for the trailing
589     arguments. For the exact definition, how parsed argument values are assigned to overload
590     arguments in the presence of default values, see \ref senf::console::kw::default_value.
591     
592     \htmlonly
593     <pre>
594     server:/$ test7 echo
595     echo
596     server:/$ test7 4 ok
597     ok
598     ok
599     ok
600     ok
601     server:/$ help test7
602     Usage:
603         test4 [n:unsigned] text:string
604     
605     With:
606         n         Number of repetitions
607             default: 1
608         text      Text to output
609
610     Echo {text} to the console, repeating {text} for {n} lines
611     server:/$
612     </pre>
613     \endhtmlonly
614
615
616     \subsection console_boostfn Non-function-pointer commands
617
618     It is possible to add other callable objects besides function (and member-function)
619     pointers. However, since it is not possible to automatically deduce the argument and return
620     types in this case, the callables have to be wrapped in a \c boost::function object:
621
622     \code
623     senf::console::root()
624         .add("test8", 
625              boost::function<void (std::ostream &, std::string const &)>(
626                  boost::bind(&fun3, _1, 4u, _2)));
627     \endcode
628
629     This works with any callable object where argument types cannot be deduced automatically:
630     Boost.Bind expressions, Boost.Lambda expressions, functors and so on.
631     
632     \htmlonly
633     <pre>
634     server:/$ test8 ok
635     ok
636     ok
637     ok
638     ok
639     server:/$ help test8
640     Usage:
641         test8 arg11:string
642     server:/$
643     </pre>
644     \endhtmlonly
645
646
647     \subsection console_attr_summary Attribute summary
648
649     Here a summary of the most common attributes
650
651     <table class="senf fixedwidth">
652
653     <tr><td style="width:14em">\link senf::console::ParsedArgumentAttributorBase::doc() .doc\endlink
654     ( \e doc )</td><td>Set documentation for all overloads</td></tr>
655     
656     <tr><td>\link senf::console::ParsedArgumentAttributorBase::overloadDoc()
657     .overloadDoc\endlink ( \e doc )</td><td>Set documentation for a specific overload</td></tr>
658
659     <tr><td>\link senf::console::ParsedArgumentAttributor::arg() .arg\endlink ( \e argument \e
660     attributes )</td><td>Set argument attributes (see below)</td></tr>
661
662     </table>
663
664     The most important argument attributes (all defined in the senf::console::kw namespace) are:
665     
666     <table class="senf fixed width">
667
668     <tr><td style="width:14em">\link senf::console::kw::name kw::name\endlink</td><td>Parameter
669     name</td></tr>
670
671     <tr><td>\link senf::console::kw::description kw::description\endlink</td><td>One-line
672     description of the argument</td></tr>
673
674     <tr><td>\link senf::console::kw::default_value kw::default_value\endlink</td><td>Arguments
675     default value</td></tr>
676
677     </table>
678
679     \see <a
680         href="classsenf_1_1console_1_1ParsedArgumentAttributor-members.html">senf::console::ParsedArgumentAttributor
681         / List of all members</a> for the complete attribute interface \n
682         \ref senf::console::kw for a list of all argument attribute keywords
683
684         
685     \section console_memberfn Member functions
686     
687     Non-static member functions are supported like non-member functions (static member functions are
688     identical to non-members). They must however be added through a senf::console::ScopedDirectory
689     instance to bind them to their instance.
690     \code
691     class Test1
692     {
693     public:
694         senf::console::ScopedDirectory<Test1> dir;
695
696         Test1(std::string label) : dir(this), label_ (label) 
697             { dir.add("test", &Test::test1);
698               dir.add("test", &Test::test2); }
699     
700         std::string test1(std::string const & text)
701             { return label_ + ": " + text; }
702
703         void test2(std::ostream & os, unsigned n, std::string const & text) 
704             { while (n-- > 0) os << label << ": " << text << std::endl; }
705
706     private:
707         std::string label_;
708     };
709
710     // ...
711
712     Test1 test1ob ("test");
713     senf::console::root().add("test1ob", test1ob.dir);
714     \endcode
715
716     Binding via senf::console::ScopedDirectory ensures, that the commands are automatically removed
717     from the tree when the object is destroyed.
718
719
720     \section console_variables Variables
721     
722     \subsection console_varadd Adding
723
724     The console/config library supports the direct registration of variables as commands. A
725     variable command consists of two overloads, one to query the current value and one to change the
726     value. 
727     \code
728     class Test2
729     {
730     public:
731         senf::console::ScopedDirectory<Test2> dir;
732
733         Test2() : dir(this), var_(0)
734             { dir.add("var", var_); }
735
736     private:
737         int var_;
738     };
739
740     Test2 test2ob;
741     senf::console::root().add("test2ob", test2ob.dir);
742     \endcode
743     This shows the most common scenario: A member variable is added to a ScopedDirectory of the same
744     class. This ensures, that the variable command node is removed from the tree when the instance
745     (and thereby the variable) are destroyed. The variable can now be used like any other command:
746     \htmlonly
747     <pre>
748     server:/$ test2ob/var
749     0
750     server:/$ test2ob/var 10
751     server:/$ test2ob/var
752     10
753     server:/$ help test2ob
754     Usage:
755         1- var new_value:int
756         2- var
757     server:/$
758     </pre>
759     \endhtmlonly
760
761
762     \subsection console_varro Read-only variables
763     
764     The library also supports read-only variables. To make a variable read-only, just wrap it in \c
765     boost::cref() (where \c cref stands for \c const reference)
766     \code
767     int var (0);
768
769     senf::console::root().add("var1", boost::cref(var));
770     \endcode
771     A read-only variable only has a single overload:
772     \htmlonly
773     <pre>
774     server:/$ var1
775     0
776     server:/$ help var1
777     Usage:
778         var1
779     server:/$ 
780     </pre>
781     \endhtmlonly
782
783
784     \subsection console_varattr Attributes
785
786     The most important Variable command attributes are
787
788     <table class="senf fixedwidth">
789
790     <tr><td style="width:14em">\link senf::console::VariableAttributor::doc() .doc\endlink
791     ( \e doc )</td><td>Set variable documentation</td></tr>
792     
793     <tr><td>\link senf::console::VariableAttributor::onChange() .onChange\endlink
794     ( \e handler )</td><td>Set change handler</td></tr>
795     
796     </table>
797
798     \see senf::console::VariableAttributor for the complete attribute interface
799
800     \subsection console_varchange Change notification
801
802     A \e handler can be set to be called, whenever the variable is changed. It will be called with a
803     reference to the old value. The handler is called, after the value has been changed
804
805     \code
806     int var (0);
807
808     // Since this is int, it would make sense to declare the argument pass-by-value (int old)
809     // but for more complex args, use a const & here
810     void varChanged(int const & old)
811     {
812         // ...
813     }
814
815     senf::console::root().add("var2",var)
816         .onChange(&varChanged);
817     \endcode
818     
819     After this setup, \c varChanged will be called, whenever the value has changed.
820
821
822     \section console_args Registering special argument types
823
824     By default, argument types which can be read and written using \c iostreams are automatically
825     supported. Other types need to be registered explicitly
826
827
828     \subsection console_args_enum Registering enum types
829
830     Enum types are a special case, since it is not possible, to find a string representation for the
831     enumerator values automatically. Therefore, enum types need to be registered manually.
832     \code
833     enum MyEnum { Sit, Run, Jump };
834     SENF_CONSOLE_REGISTER_ENUM( MyEnum, (Sit)(Run)(Jump) );
835
836     MyEnum fun4(MyEnum v) { return v }
837
838     senf::console::root()
839         .add("test9", &fun4);
840     \endcode
841
842     After an enum type is registered, it can be used like any other type for arguments or
843     return-values:
844
845     \htmlonly
846     <pre>
847     server:/$ test9 Sit
848     Sit
849     server:/$ test9 Crawl
850     argument syntax error: invalid enum value
851     server:/$ help test9
852     Usage:
853         test9 arg11:MyEnum
854     server:/$
855     </pre>
856     \endhtmlonly
857
858     \ref SENF_CONSOLE_REGISTER_ENUM() can only be used, to register enums at namespace scope. To
859     register enums defined within some class, use \ref SENF_CONSOLE_REGISTER_ENUM_MEMBER()
860
861     \code
862     class Test3
863     {
864     public:
865         enum Color { Red, Green, Blue };
866     
867         senf::console::ScopedDirectory<MyClass> dir;
868
869         Test3();
870
871         Color mem3(Color c) { return c }
872     };
873     SENF_CONSOLE_REGISTER_ENUM_MEMBER( Test3, Color, (Red)(Green)(Blue) );
874
875     Test3::Test3() : dir(this)
876         { dir.add("test", &MyClass::mem3); }
877     
878     Test3 test3ob;
879     senf::console::root().add("test3ob", test3ob.dir);
880     \endcode
881
882     Using this command/type is identical
883     \htmlonly
884     <pre>
885     server:/$ test3ob/test Red
886     Red
887     server:/$ test3ob/test White
888     argument syntax error: invalid enum value
889     server:/$ help test3ob/test
890     Usage:
891         test arg11:Color
892     </pre>
893     \endhtmlonly
894
895
896     \subsection console_args_custom Customizing argument and return value parsing/formatting
897
898     To support or customize parsing/formatting of other types, they need to be registered. In it's
899     simplest case, this works, by just providing an appropriate overload for
900     senf_console_parse_argument() and senf_console_format_value():
901     \code
902     struct Coordinate
903     {
904         Coordinate() : x(0), y(0) {}
905         Coordinate(int x_, int y_) : x(x_), y(y_) {}
906
907         int x, y;
908     }
909
910     void senf_console_parse_argument(senf::console::ParseCommandInfo::TokensRange const & tokens,
911                                      Coordinate & out)
912     {
913         senf::console::CheckedArgumentIteratorWrapper arg (tokens);
914         senf::console::parse( *(arg++), out.x );
915         senf::console::parse( *(arg++), out.y );
916     }
917
918     void senf_console_format_value(Coordinate const & value, std::ostream & os)
919     {
920         os << '(' << value.x << ' ' << value.y << ')';
921     }
922     \endcode 
923
924     The parser will accept an argument with two tokens which are each forwarded to the integer
925     parser. The senf::console::CheckedArgumentIteratorWrapper ensures two things: That all input
926     tokens are parsed and no extra trailing tokens are left unparsed and it checks, that all
927     referenced tokens really exist.
928
929     The formatter writes out the value as a parenthesized pair.
930
931     \code
932     Coordinate fun5(Coordinate const & p) { return Coordinate(2*p.x, 2*p.y) }
933     
934     namespace kw = senf::console::kw;
935
936     senf::console::root()
937         .add("test10", &fun5)
938         .arg("x","coordinate to double",
939              kw::default_value = Coordinate())
940     \endcode
941     We can now call \c test10 with a coordinate argument:
942     \htmlonly
943     <pre>
944     server:/$ test10 (2 7)
945     (4 14)
946     server:/$ help test10
947     Usage:
948         test10 [x:Coordinate]
949
950     With:
951         x         Coordinate to double
952             default: (0 0)
953     server:/$
954     </pre>
955     \endhtmlonly
956     
957     If you want to customize the formatting of default values differently from the formating of
958     return-values or if you want to change the displayed name of a type, you will need to specialize
959     the senf::console::ArgumentTraits class instead of implementing
960     senf_console_parse_argument(). See senf::console::ArgumentTraits and
961     senf::console::ReturnValueTraits for more.
962  */
963
964 \f
965 // Local Variables:
966 // mode: c++
967 // fill-column: 100
968 // comment-column: 40
969 // c-file-style: "senf"
970 // indent-tabs-mode: nil
971 // ispell-local-dictionary: "american"
972 // compile-command: "scons -u test"
973 // mode: auto-fill
974 // End:
975