Add 'unflatten' to doxygen/dot processing
[senf.git] / Utils / Console / Mainpage.dox
index 16e7376..4d43cfc 100644 (file)
     The first possibility to control this is to change the root node. This is done by 
     \li passing that root node to the helper class or to the parse helper as an additional argument
         (see the respective documentation).
-    \li passing it to the senf:;console::ConfigBundle constructor when parsing multiple sources.
+    \li passing it to the senf::console::ConfigBundle constructor when parsing multiple sources.
     
     for example:
 
     \subsection console_noninteractive Non-interactive network console
 
     After a new connection is established, the console server waits a short time for data to arrive.
-    arrive. Only if nothing happens in the first 500ms, an interactive session is initialized.
+    Only if nothing happens in the first 500ms, an interactive session is initialized.
 
     By sending data immediately after opening the connection, the console is switched into
     non-interactive mode. In this mode, no prompt is displayed. In this mode, commands are \e not
 
     Commands are executed as soon as the terminating character (';', '{' or '}') is received or when
     the sending end of the connection is closed.    
+
+    \section console_udp Non-interactive UDP console
+
+    The UDP console allows to script the console tree via UDP packets. Every UDP packet must be a
+    complete command (or sequence of commands). The combined reply of all these commands will be
+    returned in a single UDP packet. This reply can be disabled or directed to a different address. 
+
+    To start a UDP server, just create an instance of the senf::console::UDPServer class
+    \code
+    senf::console::UDPServer server (senf::INet4SocketAddress("127.0.0.1:23232"));
+    \endcode
+    (Remember to enter the scheduler main-loop for processing)
+
+    Commands may then be sent to this UDP console e.g. using netcat
+    <pre>
+    $ echo "cd sys; ls" | nc6 -u --half-close localhost 23232 2>/dev/null
+    </pre>
+
+    \see senf::console::UDPServer
  */
 
 /** \defgroup console_commands Supported command types
             // do not parse all arguments.
             senf::console::CheckedArgumentIteratorWrapper args (command.arguments());
 
-            senf::console::ParseCommandInfo::TokensRange argTokens ( *(args++) );
+            // Extract the first argument. This is again a token range.
+            senf::console::ParseCommandInfo::TokensRange arg1Tokens ( *(args++) );
             if (arg1Tokens.size() != 1)
                 raise senf::console::SyntaxErrorException("argument syntax error");
-            value = arg1Tokens[0];
+            value = arg1Tokens[0].value();
         }
 
         os << value << std::endl;
     One note: When taking the address of an overloaded function (member or non-member), the C++
     language forces you to cast that address to one of the possible types so the compiler knows,
     which overload is requested. So to add a function which is overloaded in C++, each overload
-    needs to be added explicitly, casting to the correct type:
+    needs to be added explicitly, casting to the correct type. There are some macros in
+    Utils/membind.hh to simplify this:
+
     \code
     void over(int);
     void over(int,int);
 
     senf::console::root()
-        .add("over", static_cast<void (*)(int)>(&over));
+        .add("over", SENF_FNP(void, over, (int)));
     senf::console::root()
-        .add("over", static_cast<void (*)(int,int)>(&over));
+        .add("over", SENF_FNP(void, over, (int,int));
         
     class SomeModule {
       senf::console::ScopedDirectory<SomeModule> dir;
       void overlodedMethod(unsigned int)   {....};
         
       void addConsoleCommands() {
-        dir.node().add("overlodedMethod", senf::membind(
-            static_cast<unsigned int (SomeModule::*)() const>(&SomeModule::overlodedMethod), this));
-        dir.node().add("overlodedMethod", senf::membind(
-            static_cast<void (SomeModule::*)(unsigned int)>(&SomeModule::overlodedMethod), this));
+        dir.node().add("overlodedMethod", 
+                       SENF_MEMBINDFNP(unsigned int, SomeModule, overlodedMethod, () const));
+        dir.node().add("overlodedMethod", 
+                       SENF_MEMBINDFNP(unsigned int, SomeModule, overlodedMethod, (unsigned int));
       }
     }
     \endcode
     public:
         enum Color { Red, Green, Blue };
     
-        senf::console::ScopedDirectory<MyClass> dir;
+        senf::console::ScopedDirectory<Test3> dir;
 
         Test3();
 
     SENF_CONSOLE_REGISTER_ENUM_MEMBER( Test3, Color, (Red)(Green)(Blue) );
 
     Test3::Test3() : dir(this)
-        { dir.add("test", &MyClass::mem3); }
+        { dir.add("test", &Test3::mem3); }
     
     Test3 test3ob;
     senf::console::root().add("test3ob", test3ob.dir);