Console: Refactor argument parsing into iterator
[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         ParseCommandInfo::ArgumentsRange args (command.arguments());
292         ParseCommandInfo::ArgumentsRange::iterator arg (args.begin());
293
294         // Check that we are not missing our argument
295         if (arg == args.end())
296             raise senf::console::SyntaxErrorException("invalid number of arguments");
297
298         senf::console::ParseCommandInfo::TokensRange & arg1Tokens ( *(arg++) );
299
300         // Check that we don't have additional arguments
301         if (arg != args.end())
302             raise senf::console::SyntaxErrorException("invalid number of arguments");
303
304         // The argument must have exactly one token
305         if (arg1Tokens.size() != 1)
306             raise senf::console::SyntaxErrorException("argument syntax error");
307
308         // Retrieve the token value
309         std::string arg (argTokens[0].value());
310
311         // In this example, we just write the argument to the output stream
312         os << arg << std::endl;
313     }
314     \endcode
315     
316     Registering this callback is done by simply adding it. To provide online help, pass it to
317     'doc()':
318     \code
319     senf::console::root()
320         .add("test1", &fun1)
321         .doc("Usage:\n"
322              "    test1 arg\n"
323              "\n"
324              "Echo 'arg' to the console");
325     \endcode
326
327     The callback may now be called interactively on the console by it's registered name:
328     \htmlonly
329     <pre>
330     server:/$ test1
331     invalid number of arguments
332     server:/$ test1 stefan@j32.de
333     stefan@j32.de
334     server:/$ test1 (echo me)
335     argument syntax error
336     server:/$ help test1
337     Usage:
338         test1 arg
339
340     Echo 'arg' to the console
341     server:/$
342     </pre>
343     \endhtmlonly
344
345     As you can see above, the arguments and tokens are returned as <a
346     href="http://www.boost.org/doc/libs/1_33_1/libs/range/doc/utility_class.html#iter_range">
347     boost::iterator_range</a> instances. These behave much like containers: They have \c begin() and
348     \c end() and some other useful members.
349     
350     The parser will have divided the argument tokens into arguments already. This simplifies further
351     parsing. If however you want to access the list of argument tokens as a single list, you can do
352     so using senf::console::ParseCommandInfo::tokens().
353     
354     Parsing arguments is quite simple but can get very tedious. To simplify this task, the parsing
355     can be delegated to the Console/config library. See the next section.
356
357     This type of command has only a single attribute, \e doc to set the commands documentation.
358
359
360     \section console_autoparse Automatic argument parsing
361     
362     To greatly simplify parsing complex commands, we turn to automatic argument parsing. 
363
364     \subsection console_autoadd Adding
365
366     Automatically parsed commands are registered by just adding a callback which has the correct
367     arguments and return-value defined:
368     \code
369     std::string fun2(std::string const & arg)
370     {
371         return arg;
372     }
373     \endcode
374
375     This extremely simple callback may be registered by adding it to a senf::console::DirectoryNode.
376     \code
377     senf::console::root()
378         .add("test2", &fun2);
379     \endcode
380     The functionality is now identical to \c test1:
381     \htmlonly
382     <pre>
383     server:/$ test2
384     invalid number of arguments
385     server:/$ test2 stefan@j32.de
386     stefan@j32.de
387     server:/$ test2 (echo me)
388     argument syntax error
389     server:/$ help test2
390     Usage:
391         test2 arg11:string
392     server:/$
393     </pre>
394     \endhtmlonly
395
396
397     \subsection command_ostream Accessing the console stream
398
399     Commands may have an optional first argument of type <tt>std::ostream &</tt>. This argument is
400     not considered part of the real interface. When the command is executed, the callback will be
401     passed the current consoles output stream object in this argument. With this, the callback can
402     output arbitrary messages to the network console.
403     \code
404     void fun3(std::ostream & os, unsigned n, std::string text)
405     {
406         while (n-- > 0) os << text << std::endl;
407     }
408
409     senf::console::root()
410         .add("test3", &fun3);
411     \endcode
412
413     This simple command can now be used thus:
414     \htmlonly
415     <pre>
416     server:/$ test3
417     invalid number of arguments
418     server:/$ test3 stefan@j32.de
419     invalid number of arguments
420     server:/$ test3 2 ok
421     ok
422     ok
423     server:/$ help test3
424     Usage:
425         test3 arg11:int arg12:string
426     server:/$
427     </pre>
428     \endhtmlonly
429
430     \subsection command_overload Overloading
431
432     Automatically parsed commands can be overloaded: You can register multiple commands under the
433     same name. Each overload is tried in turn until no SyntaxErrorException is raised.
434     \code
435     senf::console::root()
436         .add("test4", &fun3);
437     senf::console::root()
438         .add("test4", &fun2);
439     \endcode
440     And now, we can call \c test4 with one or two args:
441     <pre>
442     server:/$ test4
443     invalid number of arguments
444     server:/$ test4 stefan@j32.de
445     stefan@j32.de
446     server:/$ test4 2 ok
447     ok
448     ok
449     server:/$ help test4
450     Usage:
451         1- test4 arg11:int arg12:string
452         2- test4 arg21:string
453     server:/$
454     </pre>
455
456     One note: When taking the address of an overloaded function (member or non-member), the C++
457     language forces you to cast that address to one of the possible types so the compiler knows,
458     which overload is requested. So to add a function which is overloaded in C++, each overload
459     needs to be added explicitly, casting to the correct type:
460     \code
461     void over(int);
462     void over(int,int);
463
464     senf::console::root()
465         .add("over", static_cast<void (*)(int)>(&over));
466     senf::console::root()
467         .add("over", static_cast<void (*)(int,int)>(&over));
468     \endcode
469
470
471     \subsection console_attributes Attributes
472
473     As have seen so far, some documentation is automatically provided. We can add more info, by
474     setting additional attributes. 
475     \code
476     senf::console::root()
477         .add("test5", &fun3)
478         .doc("Echo text to the console")
479         .overloadDoc("Repeat {arg12} for {arg11} lines");
480     senf::console::root()
481         .add("test4", &fun2)
482         .overloadDoc("Echo the {arg21} argument")
483     \endcode
484
485     This additional info is used to provide more documentation:
486     \htmlonly
487     <pre>
488     server:/$ help test5
489     Usage:
490         1- test5 arg11:int arg12:string
491         2- test5 arg21:string
492
493     Echo text to the console
494
495     Variant 1:
496     Repeat {arg12} for {arg11} lines
497     
498     Variant 2:
499     Echo the {arg21} argument
500     senf:/$
501     </pre>
502     \endhtmlonly
503
504
505     \subsection console_argattributes Argument attributes
506
507     Additional attributes can be set for each parameter. They are all passed to the
508     senf::console::ParsedArgumentAttributor::arg() attribute.
509
510     \code
511     namespace kw = senf::console::kw;
512
513     senf::console::root()
514         .add("test6", &fun3)
515         .doc("Echo text to the console")
516         .overloadDoc("Repeat {text} for {n} lines");
517         .arg( kw::name = "n", kw::description="Number of repetitions" )
518         .arg( kw::name = "text", kw::description="Text to output" );
519     senf::console::root()
520         .add("test6", &fun2)
521         .overloadDoc("Echo the {text} argument")
522         .arg( kw::name = "text" );
523     \endcode
524
525     (Sadly, there is no way to automatically find out the \e name of an argument, just it's type.)
526     Every callback argument corresponds with a call of the \c arg() attribute. Argument attributes
527     are set using keywords from the \ref senf::console::kw namespace. You will probably either use
528     this namespace via a namespace alias (as above) or via a <tt>using namespace
529     senf::console::kw</tt> declaration (but beware of name collisions).
530
531     You don't need to specify any information for an argument: To skip an argument, just call \c
532     arg() without attributes for this argument.
533
534     After adding this information, the online help is much more readable
535       \htmlonly
536     <pre>
537     server:/$ help test6
538     Usage:
539         1- test6 n:int text:string
540         2- test6 text:string
541
542     With:
543         n         Number of repetitions
544         text      Text to output
545
546     Echo text to the console
547
548     Variant 1:
549     Repeat {text} for {n} lines
550     
551     Variant 2:
552     Echo the {text} argument
553     senf:/$
554     </pre>
555     \endhtmlonly
556
557     Since most of the time, we only need to set the name and possibly a description for arguments,
558     there is a shortcut: name and description can be specified as positional arguments in this
559     order. So the following will give the exactly same result as above:
560     \code
561     namespace kw = senf::console::kw;
562
563     senf::console::root()
564         .add("test6", &fun3)
565         .doc("Echo text to the console")
566         .overloadDoc("Repeat <text> for <n> lines");
567         .arg("n",    "Number of repetitions")
568         .arg("text", "Text to output");
569     senf::console::root()
570         .add("test6", &fun2)
571         .overloadDoc("Echo the <text> argument")
572         .arg("text");
573     \endcode
574     
575     Keyword arguments should always be used if additional attributes are set. You can however mix
576     positional and keyword arguments.
577
578     
579     \subsection console_defaults Default values
580     
581     Another information which can not be automatically gathered from the type system is default
582     values. These have to be declared explicitly:
583     \code
584     namespace kw = senf::console::kw;
585
586     senf::console::root()
587         .add("test7", &fun3)
588         .doc("Echo {text} to the console, repeating {text} for {n} lines")
589         .arg("n",    "Number of repetitions", kw::default_value=1)
590         .arg("text", "Text to output");
591     \endcode
592
593     Default values can be used together with overloading. Default (optional) value support is quite
594     flexible, it is not mandatory, for default values to be specified only for the trailing
595     arguments. For the exact definition, how parsed argument values are assigned to overload
596     arguments in the presence of default values, see \ref senf::console::kw::default_value.
597     
598     \htmlonly
599     <pre>
600     server:/$ test7 echo
601     echo
602     server:/$ test7 4 ok
603     ok
604     ok
605     ok
606     ok
607     server:/$ help test7
608     Usage:
609         test4 [n:unsigned] text:string
610     
611     With:
612         n         Number of repetitions
613             default: 1
614         text      Text to output
615
616     Echo {text} to the console, repeating {text} for {n} lines
617     server:/$
618     </pre>
619     \endhtmlonly
620
621
622     \subsection console_boostfn Non-function-pointer commands
623
624     It is possible to add other callable objects besides function (and member-function)
625     pointers. However, since it is not possible to automatically deduce the argument and return
626     types in this case, the callables have to be wrapped in a \c boost::function object:
627
628     \code
629     senf::console::root()
630         .add("test8", 
631              boost::function<void (std::ostream &, std::string const &)>(
632                  boost::bind(&fun3, _1, 4u, _2)));
633     \endcode
634
635     This works with any callable object where argument types cannot be deduced automatically:
636     Boost.Bind expressions, Boost.Lambda expressions, functors and so on.
637     
638     \htmlonly
639     <pre>
640     server:/$ test8 ok
641     ok
642     ok
643     ok
644     ok
645     server:/$ help test8
646     Usage:
647         test8 arg11:string
648     server:/$
649     </pre>
650     \endhtmlonly
651
652
653     \subsection console_attr_summary Attribute summary
654
655     Here a summary of the most common attributes
656
657     <table class="senf fixedwidth">
658
659     <tr><td style="width:14em">\link senf::console::ParsedArgumentAttributorBase::doc() .doc\endlink
660     ( \e doc )</td><td>Set documentation for all overloads</td></tr>
661     
662     <tr><td>\link senf::console::ParsedArgumentAttributorBase::overloadDoc()
663     .overloadDoc\endlink ( \e doc )</td><td>Set documentation for a specific overload</td></tr>
664
665     <tr><td>\link senf::console::ParsedArgumentAttributor::arg() .arg\endlink ( \e argument \e
666     attributes )</td><td>Set argument attributes (see below)</td></tr>
667
668     </table>
669
670     The most important argument attributes (all defined in the senf::console::kw namespace) are:
671     
672     <table class="senf fixed width">
673
674     <tr><td style="width:14em">\link senf::console::kw::name kw::name\endlink</td><td>Parameter
675     name</td></tr>
676
677     <tr><td>\link senf::console::kw::description kw::description\endlink</td><td>One-line
678     description of the argument</td></tr>
679
680     <tr><td>\link senf::console::kw::default_value kw::default_value\endlink</td><td>Arguments
681     default value</td></tr>
682
683     </table>
684
685     \see <a
686         href="classsenf_1_1console_1_1ParsedArgumentAttributor-members.html">senf::console::ParsedArgumentAttributor
687         / List of all members</a> for the complete attribute interface \n
688         \ref senf::console::kw for a list of all argument attribute keywords
689
690         
691     \section console_memberfn Member functions
692     
693     Non-static member functions are supported like non-member functions (static member functions are
694     identical to non-members). They must however be added through a senf::console::ScopedDirectory
695     instance to bind them to their instance.
696     \code
697     class Test1
698     {
699     public:
700         senf::console::ScopedDirectory<Test1> dir;
701
702         Test1(std::string label) : dir(this), label_ (label) 
703             { dir.add("test", &Test::test1);
704               dir.add("test", &Test::test2); }
705     
706         std::string test1(std::string const & text)
707             { return label_ + ": " + text; }
708
709         void test2(std::ostream & os, unsigned n, std::string const & text) 
710             { while (n-- > 0) os << label << ": " << text << std::endl; }
711
712     private:
713         std::string label_;
714     };
715
716     // ...
717
718     Test1 test1ob ("test");
719     senf::console::root().add("test1ob", test1ob.dir);
720     \endcode
721
722     Binding via senf::console::ScopedDirectory ensures, that the commands are automatically removed
723     from the tree when the object is destroyed.
724
725
726     \section console_variables Variables
727     
728     \subsection console_varadd Adding
729
730     The console/config library supports the direct registration of variables as commands. A
731     variable command consists of two overloads, one to query the current value and one to change the
732     value. 
733     \code
734     class Test2
735     {
736     public:
737         senf::console::ScopedDirectory<Test2> dir;
738
739         Test2() : dir(this), var_(0)
740             { dir.add("var", var_); }
741
742     private:
743         int var_;
744     };
745
746     Test2 test2ob;
747     senf::console::root().add("test2ob", test2ob.dir);
748     \endcode
749     This shows the most common scenario: A member variable is added to a ScopedDirectory of the same
750     class. This ensures, that the variable command node is removed from the tree when the instance
751     (and thereby the variable) are destroyed. The variable can now be used like any other command:
752     \htmlonly
753     <pre>
754     server:/$ test2ob/var
755     0
756     server:/$ test2ob/var 10
757     server:/$ test2ob/var
758     10
759     server:/$ help test2ob
760     Usage:
761         1- var new_value:int
762         2- var
763     server:/$
764     </pre>
765     \endhtmlonly
766
767
768     \subsection console_varro Read-only variables
769     
770     The library also supports read-only variables. To make a variable read-only, just wrap it in \c
771     boost::cref() (where \c cref stands for \c const reference)
772     \code
773     int var (0);
774
775     senf::console::root().add("var1", boost::cref(var));
776     \endcode
777     A read-only variable only has a single overload:
778     \htmlonly
779     <pre>
780     server:/$ var1
781     0
782     server:/$ help var1
783     Usage:
784         var1
785     server:/$ 
786     </pre>
787     \endhtmlonly
788
789
790     \subsection console_varattr Attributes
791
792     The most important Variable command attributes are
793
794     <table class="senf fixedwidth">
795
796     <tr><td style="width:14em">\link senf::console::VariableAttributor::doc() .doc\endlink
797     ( \e doc )</td><td>Set variable documentation</td></tr>
798     
799     <tr><td>\link senf::console::VariableAttributor::onChange() .onChange\endlink
800     ( \e handler )</td><td>Set change handler</td></tr>
801     
802     </table>
803
804     \see senf::console::VariableAttributor for the complete attribute interface
805
806     \subsection console_varchange Change notification
807
808     A \e handler can be set to be called, whenever the variable is changed. It will be called with a
809     reference to the old value. The handler is called, after the value has been changed
810
811     \code
812     int var (0);
813
814     // Since this is int, it would make sense to declare the argument pass-by-value (int old)
815     // but for more complex args, use a const & here
816     void varChanged(int const & old)
817     {
818         // ...
819     }
820
821     senf::console::root().add("var2",var)
822         .onChange(&varChanged);
823     \endcode
824     
825     After this setup, \c varChanged will be called, whenever the value has changed.
826
827
828     \section console_args Registering special argument types
829
830     By default, argument types which can be read and written using \c iostreams are automatically
831     supported. Other types need to be registered explicitly
832
833
834     \subsection console_args_enum Registering enum types
835
836     Enum types are a special case, since it is not possible, to find a string representation for the
837     enumerator values automatically. Therefore, enum types need to be registered manually.
838     \code
839     enum MyEnum { Sit, Run, Jump };
840     SENF_CONSOLE_REGISTER_ENUM( MyEnum, (Sit)(Run)(Jump) );
841
842     MyEnum fun4(MyEnum v) { return v }
843
844     senf::console::root()
845         .add("test9", &fun4);
846     \endcode
847
848     After an enum type is registered, it can be used like any other type for arguments or
849     return-values:
850
851     \htmlonly
852     <pre>
853     server:/$ test9 Sit
854     Sit
855     server:/$ test9 Crawl
856     argument syntax error: invalid enum value
857     server:/$ help test9
858     Usage:
859         test9 arg11:MyEnum
860     server:/$
861     </pre>
862     \endhtmlonly
863
864     \ref SENF_CONSOLE_REGISTER_ENUM() can only be used, to register enums at namespace scope. To
865     register enums defined within some class, use \ref SENF_CONSOLE_REGISTER_ENUM_MEMBER()
866
867     \code
868     class Test3
869     {
870     public:
871         enum Color { Red, Green, Blue };
872     
873         senf::console::ScopedDirectory<MyClass> dir;
874
875         Test3();
876
877         Color mem3(Color c) { return c }
878     };
879     SENF_CONSOLE_REGISTER_ENUM_MEMBER( Test3, Color, (Red)(Green)(Blue) );
880
881     Test3::Test3() : dir(this)
882         { dir.add("test", &MyClass::mem3); }
883     
884     Test3 test3ob;
885     senf::console::root().add("test3ob", test3ob.dir);
886     \endcode
887
888     Using this command/type is identical
889     \htmlonly
890     <pre>
891     server:/$ test3ob/test Red
892     Red
893     server:/$ test3ob/test White
894     argument syntax error: invalid enum value
895     server:/$ help test3ob/test
896     Usage:
897         test arg11:Color
898     </pre>
899     \endhtmlonly
900
901
902     \subsection console_args_custom Customizing argument and return value parsing/formatting
903
904     To support or customize parsing/formatting of other types, they need to be registered. In it's
905     simplest case, this works, by just providing an appropriate overload for
906     senf_console_parse_argument() and senf_console_format_value():
907     \code
908     struct Coordinate
909     {
910         Coordinate() : x(0), y(0) {}
911         Coordinate(int x_, int y_) : x(x_), y(y_) {}
912
913         int x, y;
914     }
915
916     void senf_console_parse_argument(senf::console::ParseCommandInfo::TokensRange const & tokens,
917                                      Coordinate & out)
918     {
919         if (tokens.size() != 2)
920             throw SyntaxErrorException("parameter syntax error");
921         senf::console::ArgumentTraits<int>::parse(
922             senf::console::ParseCommandInfo::TokensRange( tokens.begin(), tokens.begin()+1 ),
923             out.x )
924         senf::console::ArgumentTraits<int>::parse(
925             senf::console::ParseCommandInfo::TokensRange( tokens.begin()+1, tokens.end() ),
926             out.y )
927     }
928
929     void senf_console_format_value(Coordinate const & value, std::ostream & os)
930     {
931         os << '(' << value.x << ' ' << value.y << ')';
932     }
933     \endcode
934     The parser will accept an argument with two tokens which are each forwarded to the integer
935     parser. The formatter writes out the value as a parenthesized pair.
936
937     \code
938     Coordinate fun5(Coordinate const & p) { return Coordinate(2*p.x, 2*p.y) }
939     
940     namespace kw = senf::console::kw;
941
942     senf::console::root()
943         .add("test10", &fun5)
944         .arg("x","coordinate to double",
945              kw::default_value = Coordinate())
946     \endcode
947     We can now call \c test10 with a coordinate argument:
948     \htmlonly
949     <pre>
950     server:/$ test10 (2 7)
951     (4 14)
952     server:/$ help test10
953     Usage:
954         test10 [x:Coordinate]
955
956     With:
957         x         Coordinate to double
958             default: (0 0)
959     server:/$
960     </pre>
961     \endhtmlonly
962     
963     If you want to customize the formatting of default values differently from the formating of
964     return-values or if you want to change the displayed name of a type, you will need to specialize
965     the senf::console::ArgumentTraits class instead of implementing
966     senf_console_parse_argument(). See senf::console::ArgumentTraits and
967     senf::console::ReturnValueTraits for more.
968  */
969
970 \f
971 // Local Variables:
972 // mode: c++
973 // fill-column: 100
974 // comment-column: 40
975 // c-file-style: "senf"
976 // indent-tabs-mode: nil
977 // ispell-local-dictionary: "american"
978 // compile-command: "scons -u test"
979 // mode: auto-fill
980 // End:
981