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