X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FUtils%2FConsole%2FParsedCommand.hh;h=4df9d4185a94d38b5bba397a392a29b35ab5322f;hb=57daeae6f2e924ce3f16f9677c3474f531cba9e5;hp=ce9cad50f518e9c65f963256128cbb08afe4ff1a;hpb=f13780e9e4da7df981d6f6542fbdc714beb34765;p=senf.git diff --git a/senf/Utils/Console/ParsedCommand.hh b/senf/Utils/Console/ParsedCommand.hh index ce9cad5..4df9d41 100644 --- a/senf/Utils/Console/ParsedCommand.hh +++ b/senf/Utils/Console/ParsedCommand.hh @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2008 +// Copyright (C) 2008 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include #include @@ -44,7 +44,7 @@ #include "ParsedCommand.ih" #include "ParsedCommand.mpp" -///////////////////////////////hh.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { namespace console { @@ -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::Command(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 @@ -113,7 +116,7 @@ namespace console { should do so to make the unwieldy casts unnecessary. \section overload_parse Custom parameter parsers - + By default, parameters are parsed using \c boost::lexical_cast and therefore using \c iostreams. This means, that any type which can be read from a stream can automatically be used as argument type. @@ -174,10 +177,6 @@ namespace console { { public: typedef boost::intrusive_ptr ptr; - -#ifdef DOXYGEN - static ptr create(Function fn); -#endif }; #ifndef DOXYGEN @@ -194,7 +193,7 @@ namespace console { Attributes for parsed commands are not set directly on the node. They are set via a special attributor temporary returned when adding a parsed command to the tree. - + This class is the base class for those attributors. It provides members which do not depend in any way on the exact type of command added. @@ -207,8 +206,6 @@ namespace console { typedef OverloadedCommandNode node_type; typedef OverloadedCommandNode & result_type; - OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const; - protected: ParsedCommandAttributorBase(ParsedCommandOverloadBase::ptr overload, unsigned index); ParsedCommandAttributorBase(ParsedCommandAttributorBase const & other, unsigned index); @@ -217,21 +214,25 @@ namespace console { void argDoc(std::string const & doc); void typeName(std::string const & doc); void defaultDoc(std::string const & doc); - + ParsedCommandOverloadBase & overload() const; void overloadDoc(std::string const & doc); void nodeDoc(std::string const & doc); void shortDoc(std::string const & doc); - + private: + OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const; + ParsedCommandOverloadBase::ptr overload_; unsigned index_; boost::optional doc_; boost::optional shortdoc_; + + friend class senf::console::DirectoryNode; }; - /** \brief Non argument dependent ParsedCommandBase attributes - + /** \brief Non argument dependent ParsedCommandBase attributes + Attributes for parsed commands are not set directly on the node. They are set via a special attributor temporary returned when adding a parsed command to the tree. @@ -257,24 +258,26 @@ namespace console { /** \brief Keyword argument tags The tags defined in this namespace are used as keyword arguments via the Boost.Parameter + href="http://www.boost.org/doc/libs/release/libs/parameter/doc/html/index.html">Boost.Parameter library. 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,19 +291,19 @@ 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
         Usage:
             command [name:type_name]
-        
+
         With:
             name      description
                 default: default_doc
@@ -308,6 +311,8 @@ namespace console {
         \endhtmlonly
 
         \see \ref senf::console::ParsedArgumentAttributor::arg()
+
+        \ingroup console_commands
      */
     namespace kw {
         BOOST_PARAMETER_KEYWORD(type, name) ///< Argument name
@@ -376,7 +381,7 @@ namespace console {
                                              token list returned by the console/config parser into
                                              the appropriate value. If not set explicitly, this
                                              conversion is supplied by the ArgumentTraits
-                                             class. 
+                                             class.
 
                                              Setting the \a parser attribute allows to use a custom
                                              parser. The parser is an arbitrary callable object with
@@ -395,7 +400,7 @@ namespace console {
 
         Attributes for parsed commands are not set directly on the node. They are set via a special
         attributor temporary returned when adding a parsed command to the tree.
-        
+
         This class adds all those members, which do not depend on any specific argument but which
         need to return the correct attributor type.
 
@@ -409,7 +414,7 @@ namespace console {
         Self doc(std::string const & doc); ///< Set documentation for all overloads
         Self shortdoc(std::string const & doc); ///< Set short documentation for all overloads
         Self overloadDoc(std::string const & doc); ///< Set overload specific documentation
-        Self formatter(typename Overload::Formatter formatter); 
+        Self formatter(typename Overload::Formatter formatter);
                                         ///< Set return value formatter
                                         /**< This member is only available, if the \a ReturnType of
                                              the installed callback is not \c void.
@@ -448,12 +453,12 @@ namespace console {
     };
 
 #endif
-    
+
     /** \brief Argument dependent ParsedCommandBase attributes
 
         Attributes for parsed commands are not set directly on the node. They are set via a special
         attributor temporary returned when adding a parsed command to the tree.
-        
+
         This class adds all those members, which depend on a specific argument. Each call to \c arg
         will advance to the next argument.
 
@@ -461,7 +466,7 @@ namespace console {
      */
     template 
     class ParsedArgumentAttributor
-        : public ParsedArgumentAttributorBase< Overload, 
+        : public ParsedArgumentAttributorBase< Overload,
                                                 ParsedArgumentAttributor >
     {
         typedef boost::parameter::parameters<
@@ -473,7 +478,7 @@ namespace console {
             kw::type::parser> arg_params;
 
     public:
-        typedef typename senf::function_traits_arg_type< 
+        typedef typename senf::function_traits_arg_type<
             typename Overload::traits, int(index) >::type arg_type;
         typedef typename senf::remove_cvref< arg_type >::type value_type;
         typedef ParsedArgumentAttributor next_type;
@@ -482,17 +487,17 @@ namespace console {
                                         /**< This member changes the attributes for the current
                                              argument. The attributes are passed to arg() as keyword
                                              arguments using the Boost.Parameter
-                                             library. 
+                                             href="http://www.boost.org/doc/libs/release/libs/parameter/doc/html/index.html">Boost.Parameter
+                                             library.
                                              \code
                                              ...
-                                                 .arg( kw::name          = "name", 
+                                                 .arg( kw::name          = "name",
                                                        kw::default_value = 1 )
                                              ...
                                              \endcode
                                              The valid keywords are defined in the senf::console::kw
                                              namespace.
-                                             
+
                                              Each call to arg() will increment the argument index
                                              and advance to the next argument. This member is only
                                              present, if there is an argument at the current
@@ -518,22 +523,22 @@ namespace console {
         void argInfo(Kw const &, ArgumentPack const &, boost::mpl::false_);
 
         template 
-        void argInfo(boost::parameter::keyword const &, 
+        void argInfo(boost::parameter::keyword const &,
                      ArgumentPack const & args, boost::mpl::true_);
         template 
-        void argInfo(boost::parameter::keyword const &, 
+        void argInfo(boost::parameter::keyword const &,
                      ArgumentPack const & args, boost::mpl::true_);
         template 
-        void argInfo(boost::parameter::keyword const &, 
+        void argInfo(boost::parameter::keyword const &,
                      ArgumentPack const & args, boost::mpl::true_);
         template 
-        void argInfo(boost::parameter::keyword const &, 
+        void argInfo(boost::parameter::keyword const &,
                      ArgumentPack const & args, boost::mpl::true_);
         template 
-        void argInfo(boost::parameter::keyword const &, 
+        void argInfo(boost::parameter::keyword const &,
                      ArgumentPack const & args, boost::mpl::true_);
         template 
-        void argInfo(boost::parameter::keyword const &, 
+        void argInfo(boost::parameter::keyword const &,
                      ArgumentPack const & args, boost::mpl::true_);
 
         next_type next() const;
@@ -551,7 +556,7 @@ namespace console {
 
     template 
     class ParsedArgumentAttributor
-        : public ParsedArgumentAttributorBase< Overload, 
+        : public ParsedArgumentAttributorBase< Overload,
                                                 ParsedArgumentAttributor >
     {
     public:
@@ -572,6 +577,89 @@ namespace console {
 
 namespace factory {
 
+#ifdef DOXYGEN
+
+    /** \brief OverloadedCommandNode factory
+
+        This factory will create new OverloadedCommandNode instances or add new overloads
+        to an existing OverloadedCommandNode. The factory supports automatic argument parsing.
+
+        Commands are added to the tree using
+        \code
+        namespace fty = senf::console::factory;
+        node.add("name", fty::Command(function));
+        \endcode
+
+        The Command factory supports the following features:
+        \li Automatic argument parsing
+        \li Automatic binding of member functions. Pass the owning instance as second argument to
+            the factory
+        \li Conversion to a compatible signature. Pass the signature as template argument to the
+            factory
+
+        If the signature of the command added matches
+        \code
+        void (std::ostream &, senf::console::ParsedCommandInfo const &)
+        \endcode
+        The command is added using manual argument parsing, otherwise it is added using automatic
+        argument parsing.
+
+        See the List of all
+        members for additional attributes.
+
+        \note This class is for exposition only, the real interface consists of several overloaded
+            factory functions.
+
+        \see \ref console_manualparse \n
+            \ref console_autoparse
+     */
+    class Command : public ParsedArgumentAttributor
+    {
+    public:
+        typedef OverloadedCommandNode node_type;
+        typedef unspecified result_type;
+
+        Command(unspecified fn);        ///< Create a node calling \a fn
+        template 
+        Command(unspecified fn);        ///< Create a node calling \a fn with signature \a Signature
+                                        /**< The given \a Signature must be compatible with \a fn
+                                             for each argument and the return value. */
+
+        Command(member_function_pointer fn, Owner const * owner);
+                                        ///< Create a node calling member function \a fn on \a owner
+        template 
+        Command(member_function_pointer fn, Owner const * owner);
+                                        ///< Create a node calling member function \a fn on \a owner
+                                        ///  with the given \a Signature
+                                        /**< The given \a Signature must be compatible with \a fn
+                                             for each argument and the return value. */
+
+    };
+
+#else
+
+    template 
+    SimpleOverloadAttributor
+    Command(boost::function fn,
+            typename boost::enable_if_c::is_simple>::type * = 0);
+
+    template 
+    SimpleOverloadAttributor
+    Command(Function fn,
+            typename boost::enable_if_c::is_simple>::type * = 0);
+
+    template 
+    SimpleOverloadAttributor
+    Command(Member memfn, Owner * owner,
+            typename boost::enable_if >::type * = 0,
+            typename boost::enable_if_c::is_simple>::type * = 0);
+
+    template 
+    SimpleOverloadAttributor
+    Command(Member memfn, Owner const * owner,
+            typename boost::enable_if >::type * = 0,
+            typename boost::enable_if_c::is_simple>::type * = 0);
+
     template 
     typename senf::console::detail::ParsedCommandTraits::Attributor
     Command(boost::function fn);
@@ -579,7 +667,8 @@ namespace factory {
     template 
     typename senf::console::detail::ParsedCommandTraits::Attributor
     Command(Function fn,
-            typename boost::enable_if_c::is_callable>::type * = 0);
+            typename boost::enable_if_c::is_callable>::type * = 0,
+            typename boost::disable_if >::type * = 0);
 
     template 
     typename senf::console::detail::ParsedCommandTraits::Attributor
@@ -588,28 +677,34 @@ namespace factory {
     template 
     typename senf::console::detail::ParsedCommandTraits::Attributor
     Command(Function fn,
-            typename boost::enable_if_c::is_callable>::type * = 0);
+            typename boost::enable_if_c::is_callable>::type * = 0,
+            typename boost::disable_if >::type * = 0);
 
     template 
     typename senf::console::detail::ParsedCommandTraits::Attributor
-    BoundCommand(Owner * owner, Member memfn);
+    Command(Member memfn, Owner * owner,
+            typename boost::enable_if >::type * = 0);
 
     template 
     typename senf::console::detail::ParsedCommandTraits::Attributor
-    BoundCommand(Owner const * owner, Member memfn);
+    Command(Member memfn, Owner const * owner,
+            typename boost::enable_if >::type * = 0);
 
     template 
     typename senf::console::detail::ParsedCommandTraits::Attributor
-    BoundCommand(Owner * owner, Member memfn);
+    Command(Member memfn, Owner * owner,
+            typename boost::enable_if >::type * = 0);
 
     template 
     typename senf::console::detail::ParsedCommandTraits::Attributor
-    BoundCommand(Owner const * owner, Member memfn);
+    Command(Member memfn, Owner const * owner,
+            typename boost::enable_if >::type * = 0);
 
+#endif
 
 }}}
 
-///////////////////////////////hh.e////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 #include "ParsedCommand.cci"
 #include "ParsedCommand.ct"
 #include "ParsedCommand.cti"