Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ParsedCommand.ih

Go to the documentation of this file.
00001 // $Id: ParsedCommand.ih 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2008
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #ifndef IH_SENF_Scheduler_Console_ParsedCommand_
00027 #define IH_SENF_Scheduler_Console_ParsedCommand_ 1
00028 
00029 // Custom includes
00030 #include <boost/function.hpp>
00031 #include <boost/intrusive_ptr.hpp>
00032 #include "Parse.hh"
00033 
00034 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00035 
00036 namespace senf {
00037 namespace console {
00038 
00039     template < class FunctionTraits,
00040                class ReturnType=typename FunctionTraits::result_type,
00041                unsigned arity=FunctionTraits::arity >
00042     class ParsedCommandOverload;
00043 
00044     template < class Overload,
00045                unsigned index=0,
00046                bool flag=(index < unsigned(Overload::traits::arity)) >
00047     class ParsedArgumentAttributor;
00048 
00049 namespace detail {
00050 
00057     struct ArgumentInfoBase
00058         : public intrusive_refcount
00059     {
00060         typedef boost::intrusive_ptr<ArgumentInfoBase> ptr;
00061 
00062         std::string type;
00063         std::string name;
00064         std::string defaultDoc;
00065         bool hasDefault;
00066         std::string doc;
00067         bool singleToken;
00068 
00069         explicit ArgumentInfoBase(std::string const & type, bool singleToken=false);
00070         virtual ~ArgumentInfoBase();
00071 
00072         virtual std::string defaultValueStr() const = 0;
00073     };
00074 
00081     template <class ParameterType>
00082     struct ArgumentInfo
00083         : public ArgumentInfoBase
00084     {
00085         typedef boost::intrusive_ptr<ArgumentInfo> ptr;
00086         typedef boost::function<void (ParseCommandInfo::TokensRange const &,
00087                                       ParameterType &)> Parser;
00088 
00089         static ptr create();
00090         ArgumentInfo();
00091 
00092         ParameterType defaultValue;
00093         Parser parser;
00094 
00095         virtual std::string defaultValueStr() const;
00096     };
00097 
00098 #ifndef DOXYGEN
00099 
00100     // FirstArgType returns void, if the function has no arguments, otherwise it returns arg1_type
00101 
00102     template <class Traits, bool flag=(Traits::arity>0)>
00103     struct FirstArgType
00104     {
00105         typedef void type;
00106     };
00107 
00108     template <class Traits>
00109     struct FirstArgType<Traits,true>
00110     {
00111         typedef typename Traits::arg1_type type;
00112     };
00113 
00114     template <class FnunctionP, class Function, bool isFN=boost::is_function<Function>::value>
00115     struct ParsedCommandTraits_i
00116     {
00117         static const bool is_callable = false;
00118         static const bool is_member = false;
00119         static const bool is_simple = false;
00120     };
00121 
00122     template <class FunctionP, class Function>
00123     struct ParsedCommandTraits_i<FunctionP, Function, true>
00124     {
00125         typedef FunctionP base_type;
00126         typedef typename senf::remove_any_pointer<base_type>::type function_type;
00127         typedef boost::function_traits<function_type> base_traits;
00128         typedef typename FirstArgType<base_traits>::type first_arg_type;
00129 
00130         static const bool has_ostream_arg = boost::is_same<first_arg_type, std::ostream &>::value;
00131 
00132         typedef typename boost::mpl::if_c<
00133             has_ostream_arg,
00134             typename function_traits_remove_arg<base_traits>::type,
00135             base_traits>
00136         ::type traits;
00137 
00138         typedef typename senf::remove_cvref<typename base_traits::result_type>::type result_type;
00139 
00140         static const bool is_callable = true;
00141         static const bool is_member = boost::is_member_pointer<base_type>::value;
00142         static const bool is_simple = false;
00143 
00144         typedef typename senf::member_class<base_type>::type class_type;
00145 
00146         typedef ParsedCommandOverload<traits> Overload;
00147         typedef ParsedArgumentAttributor<Overload> Attributor;
00148     };
00149 
00150     // Disable auto-parsing for ParseCommandInfo arg -> register manually parsed command
00151     template <class FunctionP>
00152     struct ParsedCommandTraits_i<FunctionP, void (std::ostream &, ParseCommandInfo const &), true>
00153     {
00154         static const bool is_simple = true;
00155     };
00156 
00157     template <class FunctionP>
00158     struct ParsedCommandTraits
00159         : public ParsedCommandTraits_i< FunctionP,
00160                                         typename senf::remove_any_pointer<FunctionP>::type >
00161     {};
00162 
00163     struct ParsedCommandAddNodeAccess;
00164 
00165     // What is THIS about ??
00166 
00167     // Ok, here's the dope: parsed commands may optionally have an std::ostream & first argument. If
00168     // this argument is given, then the function will be called with the console output stream as
00169     // it's first argument.
00170     //
00171     // This is implemented in the following way: ParsedCommandOverload (the class responsible for
00172     // calling the callback) will ALWAYS pass the stream as first argument. If the user callback
00173     // expects os as it's first argument, 'ignoreOneArg' will be false and the user supplied
00174     // function will be directly passed to ParsedCommandOverload.
00175     //
00176     // If however, it does NOT take an std::ostream first argument, 'ignoreOneArg' will be true and
00177     // the create member will use boost::bind to DROP the first argument.
00178 
00179     template <class Traits,
00180               bool ignoreOneArg=! Traits::has_ostream_arg,
00181               unsigned arity=Traits::traits::arity>
00182     struct CreateParsedCommandOverload
00183     {};
00184 
00185     template <class Traits, unsigned arity>
00186     struct CreateParsedCommandOverload<Traits, false, arity>
00187     {
00188         typedef typename Traits::traits traits;
00189 
00190         template <class Function>
00191         static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn)
00192             { return senf::console::ParsedCommandOverload<traits>::create(fn); };
00193     };
00194 
00195 #   define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY,                     \
00196                                             SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp), \
00197                                             4))
00198 #   include BOOST_PP_ITERATE()
00199 
00200 #endif
00201 
00202 }}}
00203 
00204 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00205 #endif
00206 
00207 
00208 // Local Variables:
00209 // mode: c++
00210 // fill-column: 100
00211 // comment-column: 40
00212 // c-file-style: "senf"
00213 // indent-tabs-mode: nil
00214 // ispell-local-dictionary: "american"
00215 // compile-command: "scons -u test"
00216 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research