From: g0dil Date: Mon, 3 May 2010 15:33:42 +0000 (+0000) Subject: Utils/Console: New add() API documentation updates X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=b8a2a9d30d2c0aa986c6c86f9cc9288ead67ebdb Utils/Console: New add() API documentation updates git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1615 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Utils/Console/Mainpage.dox b/senf/Utils/Console/Mainpage.dox index 4177e2f..9b25f2e 100644 --- a/senf/Utils/Console/Mainpage.dox +++ b/senf/Utils/Console/Mainpage.dox @@ -65,6 +65,7 @@ } namespace kw = senf::console::kw; + namespace fty = senf::console::factory; int main(int argc, char** argv) { @@ -73,11 +74,10 @@ .doc("This is someServer server"); // Add a command - senf::console::root() - .add("mycommand", &mycommand) + senf::console::root().add("mycommand", fty::Command(&mycommand) .doc("If is given, flurgle the , otherwise burgle it") .arg("foo") - .arg(kw::name = "bar", kw::default_value = 0); + .arg(kw::name = "bar", kw::default_value = 0) ); // Parse command line parameters senf::console::parseOptions(argc,argv); @@ -363,7 +363,8 @@ parsing. \code - // Create a console/config aware object and place it into the node tree + // Create a console/config aware object and place it (that is it's directory node) into the node + // tree FooObject foo; senf::console::root().add("foo", foo.dir); @@ -573,20 +574,19 @@ /** \defgroup console_commands Supported command types The Console/config library supports quite a number of different command types. All these types - of command are registered, by passing them to DirectoryNode::add() + of command are registered by passing an appropriate factory instance to DirectoryNode::add() \autotoc \section console_cmdadd Adding commands and setting attributes - Basically, all commands are added using senf::console::DirectoryNode::add(). What exactly - happens depends on the type of object added. + Basically, all commands are added using senf::console::DirectoryNode::add(). \code - dir.add("name", callback) + namespace fty = senf::console::factory; + dir.add("name", fty::Command(callback)); \endcode - will add a command 'name' which will execute 'callback' when called, where 'callback' can be a - lot of things as documented in the following chapters. + will add the command 'name' which will execute 'callback' when called. The add call always returns (something which can be used as) a reference to the command node added: @@ -598,21 +598,14 @@ (e.g. senf::console::SimpleCommand) if you know the type of node returned. Depending on the type of object added, there are additional attributes which can be set. These - attributes are always set by calling them on the return value before saving that value as a - node reference. It is \e not guaranteed, you can call these members on the node - reference. - \code - dir.add("name", callback) - .doc("The documentation"); - \endcode - sets the \e doc attribute (if that is available, otherwise this will fail to compile). The - attribute members return value is again (something which can be used as) a reference to the - command node + attributes are always set by calling them on the factory return value. It is \e not guaranteed, + you can call these members on the node reference returned by the \c add() call. \code - senf::console::CommandNode & node ( - dir.add("name", callback) - .doc("The documentation") ); + namespace fty = senf::console::factory; + dir.add("name", fty::Command(callback) + .doc("The documentation") ); \endcode + sets the \e doc attribute (if that is available, otherwise this will fail to compile). \section console_manualparse Manually parsing command arguments @@ -648,12 +641,12 @@ Registering this callback is done by simply adding it. To provide online help, pass it to 'doc()': \code - senf::console::root() - .add("test1", &fun1) + namespace fty = senf::console::factory; + senf::console::root().add("test1", fty::Command(&fun1) .doc("Usage:\n" " test1 arg\n" "\n" - "Echo 'arg' to the console"); + "Echo 'arg' to the console") ); \endcode The callback may now be called interactively on the console by it's registered name: @@ -707,8 +700,8 @@ This extremely simple callback may be registered by adding it to a senf::console::DirectoryNode. \code - senf::console::root() - .add("test2", &fun2); + namespace fty = senf::console::factory; + senf::console::root().add("test2", fty::Command(&fun2)); \endcode The functionality is now identical to \c test1: \htmlonly @@ -734,13 +727,14 @@ passed the current consoles output stream object in this argument. With this, the callback can output arbitrary messages to the network console. \code + namespace fty = senf::console::factory; + void fun3(std::ostream & os, unsigned n, std::string text) { while (n-- > 0) os << text << std::endl; } - senf::console::root() - .add("test3", &fun3); + senf::console::root().add("test3", fty::Command(&fun3)); \endcode This simple command can now be used thus: @@ -766,10 +760,10 @@ Automatically parsed commands can be overloaded: You can register multiple commands under the same name. Each overload is tried in turn until no SyntaxErrorException is raised. \code - senf::console::root() - .add("test4", &fun3); - senf::console::root() - .add("test4", &fun2); + namespace fty = senf::console::factory; + + senf::console::root().add("test4", fty::Command(&fun3)); + senf::console::root().add("test4", fty::Command(&fun2)); \endcode And now, we can call \c test4 with one or two args:
@@ -794,13 +788,13 @@
     Utils/membind.hh to simplify this:
 
     \code
+    namespace fty = senf::console::factory;
+
     void over(int);
     void over(int,int);
 
-    senf::console::root()
-        .add("over", SENF_FNP(void, over, (int)));
-    senf::console::root()
-        .add("over", SENF_FNP(void, over, (int,int));
+    senf::console::root().add("over", fty::Command(SENF_FNP(void, over, (int))));
+    senf::console::root().add("over", fty::Command(SENF_FNP(void, over, (int,int)));
 
     class SomeModule {
       senf::console::ScopedDirectory dir;
@@ -809,10 +803,12 @@
       void overlodedMethod(unsigned int)   {....};
 
       void addConsoleCommands() {
-        dir.node().add("overlodedMethod",
-                       SENF_MEMBINDFNP(unsigned int, SomeModule, overlodedMethod, () const));
-        dir.node().add("overlodedMethod",
-                       SENF_MEMBINDFNP(unsigned int, SomeModule, overlodedMethod, (unsigned int));
+        dir.node()
+            .add("overlodedMethod", fty::Command(
+                     SENF_MEMBINDFNP(unsigned int, SomeModule, overlodedMethod, () const)));
+        dir.node()
+            .add("overlodedMethod", fty::Command(
+                     SENF_MEMBINDFNP(unsigned int, SomeModule, overlodedMethod, (unsigned int))));
       }
     }
     \endcode
@@ -823,13 +819,13 @@
     As have seen so far, some documentation is automatically provided. We can add more info, by
     setting additional attributes.
     \code
-    senf::console::root()
-        .add("test5", &fun3)
+    namespace fty = senf::console::factory;
+
+    senf::console::root().add("test5", fty::Command(&fun3)
         .doc("Echo text to the console")
-        .overloadDoc("Repeat {arg12} for {arg11} lines");
-    senf::console::root()
-        .add("test4", &fun2)
-        .overloadDoc("Echo the {arg21} argument")
+        .overloadDoc("Repeat {arg12} for {arg11} lines") );
+    senf::console::root().add("test4", fty::Command(&fun2)
+        .overloadDoc("Echo the {arg21} argument") );
     \endcode
 
     This additional info is used to provide more documentation:
@@ -859,17 +855,16 @@
 
     \code
     namespace kw = senf::console::kw;
+    namespace fty = senf::console::factory;
 
-    senf::console::root()
-        .add("test6", &fun3)
+    senf::console::root().add("test6", fty::Command(&fun3)
         .doc("Echo text to the console")
         .overloadDoc("Repeat {text} for {n} lines");
         .arg( kw::name = "n", kw::description="Number of repetitions" )
-        .arg( kw::name = "text", kw::description="Text to output" );
-    senf::console::root()
-        .add("test6", &fun2)
+        .arg( kw::name = "text", kw::description="Text to output" ) );
+    senf::console::root().add("test6", fty::Command(&fun2)
         .overloadDoc("Echo the {text} argument")
-        .arg( kw::name = "text" );
+        .arg( kw::name = "text" ) );
     \endcode
 
     (Sadly, there is no way to automatically find out the \e name of an argument, just it's type.)
@@ -909,16 +904,15 @@
     order. So the following will give the exactly same result as above:
     \code
     namespace kw = senf::console::kw;
+    namespace fty = senf::console::factory;
 
-    senf::console::root()
-        .add("test6", &fun3)
+    senf::console::root().add("test6", fty::Command(&fun3)
         .doc("Echo text to the console")
         .overloadDoc("Repeat  for  lines");
         .arg("n",    "Number of repetitions")
-        .arg("text", "Text to output");
-    senf::console::root()
-        .add("test6", &fun2)
-        .overloadDoc("Echo the  argument")
+        .arg("text", "Text to output") );
+    senf::console::root().add("test6", fty::Command(&fun2)
+        .overloadDoc("Echo the  argument") );
         .arg("text");
     \endcode
 
@@ -932,12 +926,12 @@
     values. These have to be declared explicitly:
     \code
     namespace kw = senf::console::kw;
+    namespace fty = senf::console::factory;
 
-    senf::console::root()
-        .add("test7", &fun3)
+    senf::console::root().add("test7", fty::Command(&fun3)
         .doc("Echo {text} to the console, repeating {text} for {n} lines")
         .arg("n",    "Number of repetitions", kw::default_value=1)
-        .arg("text", "Text to output");
+        .arg("text", "Text to output") );
     \endcode
 
     Default values can be used together with overloading. Default (optional) value support is quite
@@ -973,13 +967,13 @@
 
     It is possible to add other callable objects besides function (and member-function)
     pointers. However, since it is not possible to automatically deduce the argument and return
-    types in this case, the callables have to be wrapped in a \c boost::function object:
-
+    types in this case, the signature has to be specified explicitly:
     \code
+    namespace fty = senf::console::factory;
+
     senf::console::root()
-        .add("test8",
-             boost::function(
-                 boost::bind(&fun3, _1, 4u, _2)));
+        .add("test8",fty::Command(
+                         boost::bind(&fun3, _1, 4u, _2)));
     \endcode
 
     This works with any callable object where argument types cannot be deduced automatically:
@@ -1044,14 +1038,16 @@
     identical to non-members). They must however be added through a senf::console::ScopedDirectory
     instance to bind them to their instance.
     \code
+    namespace fty = senf::console::factory;
+
     class Test1
     {
     public:
         senf::console::ScopedDirectory dir;
 
         Test1(std::string label) : dir(this), label_ (label)
-            { dir.add("test", &Test::test1);
-              dir.add("test", &Test::test2); }
+            { dir.add("test", fty::Command(&Test::test1, this));
+              dir.add("test", fty::Command(&Test::test2, this)); }
 
         std::string test1(std::string const & text)
             { return label_ + ": " + text; }
@@ -1081,13 +1077,15 @@
     variable command consists of two overloads, one to query the current value and one to change the
     value.
     \code
+    namespace fty = senf::console::factory;
+
     class Test2
     {
     public:
         senf::console::ScopedDirectory dir;
 
         Test2() : dir(this), var_(0)
-            { dir.add("var", var_); }
+            { dir.add("var", fty::Variabl(var_) ); }
 
     private:
         int var_;
@@ -1120,9 +1118,11 @@
     The library also supports read-only variables. To make a variable read-only, just wrap it in \c
     boost::cref() (where \c cref stands for \c const reference)
     \code
+    namespace fty = senf::console::factory;
+
     int var (0);
 
-    senf::console::root().add("var1", boost::cref(var));
+    senf::console::root().add("var1", fty::Variable(boost::cref(var)));
     \endcode
     A read-only variable only has a single overload:
     \htmlonly
@@ -1160,6 +1160,8 @@
     reference to the old value. The handler is called, after the value has been changed
 
     \code
+    namespace fty = senf::console::factory;
+
     int var (0);
 
     // Since this is int, it would make sense to declare the argument pass-by-value (int old)
@@ -1169,8 +1171,8 @@
         // ...
     }
 
-    senf::console::root().add("var2",var)
-        .onChange(&varChanged);
+    senf::console::root().add("var2", fty::Variable(var)
+        .onChange(&varChanged) );
     \endcode
 
     After this setup, \c varChanged will be called, whenever the value has changed.
@@ -1261,13 +1263,14 @@
     Enum types are a special case, since it is not possible, to find a string representation for the
     enumerator values automatically. Therefore, enum types need to be registered manually.
     \code
+    namespace fty = senf::console::factory;
+
     enum MyEnum { Sit, Run, Jump };
     SENF_CONSOLE_REGISTER_ENUM( MyEnum, (Sit)(Run)(Jump) );
 
     MyEnum fun4(MyEnum v) { return v }
 
-    senf::console::root()
-        .add("test9", &fun4);
+    senf::console::root().add("test9", fty::Command(&fun4));
     \endcode
 
     After an enum type is registered, it can be used like any other type for arguments or
@@ -1290,6 +1293,8 @@
     register enums defined within some class, use \ref SENF_CONSOLE_REGISTER_ENUM_MEMBER()
 
     \code
+    namespace fty = senf::console::factory;
+
     class Test3
     {
     public:
@@ -1304,7 +1309,7 @@
     SENF_CONSOLE_REGISTER_ENUM_MEMBER( Test3, Color, (Red)(Green)(Blue) );
 
     Test3::Test3() : dir(this)
-        { dir.add("test", &Test3::mem3); }
+        { dir.add("test", fty::Command(&Test3::mem3, this)); }
 
     Test3 test3ob;
     senf::console::root().add("test3ob", test3ob.dir);
@@ -1327,22 +1332,25 @@
     \subsection console_args_convert Handling argument types by conversion
 
     Sometimes an argument type is best handled by just pretending it to be of some other type. The
-    basic idea is, to us \c boost::function to convert the real argument type to some different type
+    basic idea is, to provide an explicit signature with different (but compatible) types to the
+    factory:
 
     \code
+    namespace fty = senf::console::factory;
+
     int fun4(int value)
     {
         return value;
     }
 
     senf::console::root()
-        .add("test8", boost::function(&fun4));
+        .add("test8", fty::Command(&fun4));
     \endcode
 
-    Here, the type signature specified via \c boost::function is different from the real type
-    signature but is compatible. \c boost::function automatically handles the conversion
-    process. Since the console library now sees the argument and return value of type \c bool,
-    the values will be parsed and formatted as boolean values.
+    Here, the type signature passed to fty::Command is different from the real type signature but it
+    is compatible, the conversion is handled automatically. Since the console library now sees the
+    argument and return value of type \c bool, the values will be parsed and formatted as boolean
+    values.
 
 
     \subsection console_args_special Special Console types
@@ -1390,12 +1398,14 @@
     The formatter writes out the value as a parenthesized pair.
 
     \code
+    namespace fty = senf::console::factory;
+
     Coordinate fun5(Coordinate const & p) { return Coordinate(2*p.x, 2*p.y) }
 
     namespace kw = senf::console::kw;
 
     senf::console::root()
-        .add("test10", &fun5)
+        .add("test10", fty::Command(&fun5))
         .arg("x","coordinate to double",
              kw::default_value = Coordinate())
     \endcode
diff --git a/senf/Utils/Console/Node.hh b/senf/Utils/Console/Node.hh
index 5765dd6..286f516 100644
--- a/senf/Utils/Console/Node.hh
+++ b/senf/Utils/Console/Node.hh
@@ -58,7 +58,7 @@
             dir.doc("Manager for something");
 
             // Add a member function (the pointer-to-member is automatically bound to this instance)
-            dir.add("member", fty::Command(this, &SomeClass::member)
+            dir.add("member", fty::Command(&SomeClass::member, this)
                 .doc("Do the member operation"));
         }
 
@@ -132,7 +132,7 @@
     \code
     void callback(std::ostream & os, senf::console::ParseCommandInfo const & command) { ... }
     // ...
-    myDirectory.add("foo",&callback);
+    myDirectory.add("foo",fty::Command(&callback));
     \endcode
 
     Every node is identified among it's siblings by it's name. The name of the node is set when
@@ -158,10 +158,10 @@
     Depending on the node type added, additional node parameters may be set. For example, every node
     has a documentation parameter which is used by the online-help system. To assign these
     parameters, the node exposes corresponding member functions. Since
-    senf::console::DirectoryNode::add() returns the newly added node by reference, additional
-    parameters may just be added to the end of the add command:
+    senf::console::DirectoryNode::add() returns the newly added node by reference. Additional
+    parameters may be added after the factory call:
     \code
-    myDirectory.add("foo",&fooCallback).doc("The foo method");
+    myDirectory.add("foo", fty::Command(&fooCallback).doc("The foo method") );
     \endcode
     Since the parameter setters all return the node reference, additional parameters may just be
     added to the end of the command.
@@ -387,8 +387,8 @@ namespace console {
         This node type provides the internal and root nodes of the tree. It allows to add arbitrary
         children and supports directory traversal.
 
-        Nodes are normally not instantiated manually but are created by the DirectoryNode via
-        mkdir() or add(). Special add() members however allow externally allocated node objects.
+        Nodes are normally not instantiated manually but are created using factory calls. Special
+        add() members however allow externally allocated node objects.
 
         Nodes may be added to the tree only once, otherwise chaos will ensue. Since nodes are always
         managed dynamically, there is a special ScopedDirectory proxy template which provides a
diff --git a/senf/Utils/Console/ParsedCommand.hh b/senf/Utils/Console/ParsedCommand.hh
index 753bd83..6c443ba 100644
--- a/senf/Utils/Console/ParsedCommand.hh
+++ b/senf/Utils/Console/ParsedCommand.hh
@@ -64,12 +64,13 @@ namespace console {
 
         \section overload_add Adding argument parsing callbacks to the tree
 
-        Adding appropriate callbacks to the tree is very simple: just path a function pointer to
-        DirectoryNode::add() or a member function pointer to ScopedDirectory::add().
+        To add overloads to the tree, use the senf::console::factory::Command factory:
         \code
+        namespace fty = senf::console::factory;
+
         std::string taskStatus(int id);
 
-        senf::console::root().add("taskStatus", &taskStatus);
+        senf::console::root().add("taskStatus", fty::Command(&taskStatus));
         \endcode
 
         There are quite a number of additional parameters available to be set. These parameters are
@@ -77,11 +78,11 @@ namespace console {
         calls after adding the node:
 
         \code
-        senf::console::root().add("taskStatus", &taskStatus)
+        senf::console::root().add("taskStatus", fty::Command(&taskStatus)
             .doc("Query the current task status")
             .arg( name = "id",
                   description = "numeric id of task to check, -1 for the current task."
-                  default_value = -1 );
+                  default_value = -1 ) );
         \endcode
 
         You may also add an additional \c std::ostream & Argument as first argument to the
@@ -95,17 +96,19 @@ namespace console {
         std::string taskStatus(std::string const & name);
 
         senf::console::root()
-            .add("taskStatus", static_cast(&taskStatus))
+            .add("taskStatus", fty::Command(static_cast(
+                                                &taskStatus))
             .doc("Query the current task status")
             .overloadDoc("Query status by id")
             .arg( name = "id",
                   description = "numeric id of task to check, -1 for the current task."
-                  default_value = -1 );
+                  default_value = -1 ) );
         senf::console::root()
-            .add("taskStatus", static_cast(&taskStatus))
+            .add("taskStatus", fty::Commande(static_cast(
+                                                 &taskStatus))
             .overloadDoc("Query status by name")
             .arg( name = "name",
-                  description = "name of task to check" );
+                  description = "name of task to check" ) );
         \endcode
 
         We can see here, that taking the address of an overloaded function requires a cast. If you
@@ -262,19 +265,21 @@ namespace console {
 
         For the keyword tags, the standard C++ scoping rules apply
         \code
+        namespace fty=senf::console::factory;
+
         // Either qualify them with their complete namespace
-        dir.add(...)
-            .arg( senf::console::kw::name = "name" );
+        dir.add(..., fty::Command(...)
+            .arg( senf::console::kw::name = "name" ) );
 
         // Or use a namespace alias
         namespace kw = senf::console::kw;
-        dir.add(...)
-            .arg( kw::name = "name" );
+        dir.add(..., fty::Command(...)
+            .arg( kw::name = "name" ) );
 
         // Or import the keywords into the current namespace (beware of name collisions)
         using namespace senf::console::kw;
-        dir.add(...)
-            .arg( name = "name" );
+        dir.add(..., fty::Command(...)
+            .arg( name = "name" ) );
         \endcode
 
         The second alternative is preferred, the using namespace directive may be used as
@@ -288,12 +293,12 @@ namespace console {
         \code
         void command(int);
 
-        dir.add("command", &command)
+        dir.add("command", fty::Command(&command)
             .arg( kw::name          = "name",
                   kw::description   = "description",
                   kw::default_value = 1,
                   kw::type_name     = "type_name",
-                  kw::default_doc   = "default_doc" );
+                  kw::default_doc   = "default_doc" ) );
         \endcode
         Will create the following documentation:
         \htmlonly
diff --git a/senf/Utils/Console/ScopedDirectory.hh b/senf/Utils/Console/ScopedDirectory.hh
index 2b298f9..e5f1248 100644
--- a/senf/Utils/Console/ScopedDirectory.hh
+++ b/senf/Utils/Console/ScopedDirectory.hh
@@ -96,7 +96,7 @@ namespace console {
 
             MyClass() : configDir(this)
             {
-                configDIr.add(...);
+                configDir.add(...);
             }
         };
         \endcode
diff --git a/senf/Utils/Console/Utility.hh b/senf/Utils/Console/Utility.hh
index 6cf2433..e13c248 100644
--- a/senf/Utils/Console/Utility.hh
+++ b/senf/Utils/Console/Utility.hh
@@ -53,7 +53,7 @@ namespace console {
         char foo(char v) { return v; }
 
         senf::console::root().add(
-            "foo", boost::function< CharAsString (CharAsString) >(&foo));
+            "foo", fty::Command< CharAsString (CharAsString) >(&foo));
         \endcode
 
         \tparam CharT character type, one of \c char, \c signed \c char or \c unsigned \c char
@@ -146,7 +146,7 @@ namespace console {
         SENF_CONSOLE_REGISTER_ENUM(MyFlags, (Foo)(Bar)(Baz)(Boo));
 
         // Register the function with a FlagCollection argument type
-        consoleDir.add("func", boost::function)>(&func));
+        consoleDir.add("func", fty::Command)>(&func));
         \endcode
 
         To use the FlagCollection class
diff --git a/senf/Utils/Console/Variables.hh b/senf/Utils/Console/Variables.hh
index de9da46..a732b41 100644
--- a/senf/Utils/Console/Variables.hh
+++ b/senf/Utils/Console/Variables.hh
@@ -82,7 +82,7 @@ namespace factory {
             int var;
             ScopedDirectory<> dir;
 
-        dir.add("var", var);
+        dir.add("var", fty::Variable(var));
         \endcode
 
         Variables should be registered only with a ScopedDirectory declared in the same scope
@@ -97,7 +97,7 @@ namespace factory {
         boost::cref(). Such a variable cannot be changed only queried. Therefore, it does not have
         the parser() and typeName() attributes.
         \code
-            dir.add("const_var", boost::cref(var))
+            dir.add("const_var", fty::Variable(boost::cref(var)));
         \endcode
 
         \ingroup console_commands
diff --git a/tools/doxygrep b/tools/doxygrep
new file mode 100755
index 0000000..9928bfc
--- /dev/null
+++ b/tools/doxygrep
@@ -0,0 +1,27 @@
+#!/usr/bin/perl -0777n
+
+BEGIN { 
+    $re = shift;
+    if (! $re) {
+	print STDERR 
+	    "Usage: doxygrep  [...]\n".
+	    "\n".
+	    "Greps for  only within doxygen comments in [files] or stdin\n";
+	exit(1);
+    }
+}
+
+while(m{/\*\*