4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief OverloadedCommand public header */
26 #ifndef HH_SENF_Scheduler_Console_OverloadedCommand_
27 #define HH_SENF_Scheduler_Console_OverloadedCommand_ 1
31 #include <boost/intrusive_ptr.hpp>
32 #include <boost/range/iterator_range.hpp>
33 #include <senf/Utils/intrusive_refcount.hh>
34 #include <boost/optional.hpp>
36 //#include "OverloadedCommand.mpp"
37 ///////////////////////////////hh.p////////////////////////////////////////
42 class OverloadedCommandNode;
44 /** \brief Documentation for a single argument
46 This struct is used by CommandOverload::argumentDoc()
49 std::string name; ///< Argument name
50 std::string type; ///< Argument type (string representation)
51 std::string defaultValue; ///< Default value (string representation) or empty string
52 std::string doc; ///< Documentation for this argument
53 bool singleToken; ///< \c true, if argument is parsed from single token
56 /** \brief Base class for command overload of OverloadedCommandNode
58 This class is the base class of the commands which may be added to an
59 OverloadedCommandNode.
62 : public senf::intrusive_refcount
65 ///////////////////////////////////////////////////////////////////////////
68 typedef boost::intrusive_ptr<CommandOverload> ptr;
69 typedef boost::intrusive_ptr<CommandOverload const> cptr;
71 ///////////////////////////////////////////////////////////////////////////
73 virtual ~CommandOverload();
75 void execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command);
76 ///< Call the overload
77 /**< If the \a arguments are not acceptable for this
78 overload, a SyntaxErrorException must be thrown.
79 Same as operator()() */
81 void operator()(boost::any & rv, std::ostream & os, ParseCommandInfo const & command);
82 ///< Call the overload
83 /**< If the \a arguments are not acceptable for this
84 overload, a SyntaxErrorException must be thrown.
87 unsigned numArguments() const; ///< Number of arguments this overload takes
88 void argumentDoc(unsigned index, ArgumentDoc & doc) const;
89 ///< Get information on argument \a index
90 /**< The information is returned in \e doc. \e doc must be
91 empty before this call.
92 \pre \a index < numArguments()
93 \param[in] index Argument index
94 \param[out] doc Argument documentation */
96 std::string doc() const; ///< Get overload documentation
98 OverloadedCommandNode & node() const; ///< Access owning node
99 /**< \pre The command \e must have been added to an
100 OverloadedCommandNode. */
102 unsigned overloadIndex() const; ///< Get index of overload in it's OverloadedCommandNode
110 virtual unsigned v_numArguments() const = 0;
111 ///< Return the number of arguments
112 /**< This member must be implemented in the derived class to
113 return the number of arguments, the command expects. */
115 virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const = 0;
116 ///< Return argument documentation
117 /**< The member must be implemented int the derived class to
118 return all documentation information for the \a
119 index'th parameter in \a doc. */
121 virtual std::string v_doc() const = 0;
122 ///< Return overload documentation
123 /**< This member must be implemented in the derived class to
124 return the overloads documentation string. */
126 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
128 ///< Execute the overload
129 /**< This member must be implemented in the derived class
130 o execute the overload. */
133 OverloadedCommandNode * node_;
135 friend class OverloadedCommandNode;
138 /** \brief Command node which allows multiple registered callbacks
140 OverloadedCommandNode is like SimpleCommandNode but allows to register multiple commands to
141 a single node. This works by calling each command in the list consecutively until no
142 'SyntaxErrorException' exception is thrown.
144 This works by first adding an OverloadedCommandNode to the directory in question and then
145 adding commands to that node. Commands are derived from CommandOverload.
147 senf::console::DirectoryNode & dir (...);
148 senf::console::OverloadedCommandNode & cmd (
149 dir.add("cmd", senf::console::OverloadedCommandNode::create()) );
150 cmd.add(senf::console::SimpleCommandOverload::create(&callback));
151 cmd.add(senf::console::SimpleCommandOverload::create(&anotherCallback));
154 However, this facility is normally used not directly but indirectly (and automatically) when
155 adding argument parsing callbacks.
157 \warning For this to work, the commands <b>must</b> do all syntax checking before doing any
160 \ingroup console_commands
162 class OverloadedCommandNode
165 typedef std::vector<CommandOverload::ptr> Overloads;
168 ///////////////////////////////////////////////////////////////////////////
171 typedef boost::shared_ptr<OverloadedCommandNode> ptr;
172 typedef boost::shared_ptr<OverloadedCommandNode const> cptr;
173 typedef boost::weak_ptr<OverloadedCommandNode> weak_ptr;
175 typedef OverloadedCommandNode node_type;
176 typedef OverloadedCommandNode & return_type;
178 typedef boost::iterator_range<Overloads::const_iterator> OverloadsRange;
180 ///////////////////////////////////////////////////////////////////////////
181 ///\name Structors and default members
187 ///////////////////////////////////////////////////////////////////////////
189 template <class Command>
190 Command & add(boost::intrusive_ptr<Command> overload); ///< Add an additional overload
192 OverloadedCommandNode & doc(std::string const & doc);
193 ///< Assign global help for all overloads
194 OverloadedCommandNode & shortdoc(std::string const & doc);
195 ///< Assign short documentation for all overloads
197 unsigned overloadIndex(CommandOverload const & overload);
198 ///< Return the overload index for \a overload
199 /**< overloadIndex returns the index of \a overload in the
200 internal list of overloads. */
202 OverloadsRange overloads() const; ///< Get all overloads
205 cptr thisptr() const;
207 static OverloadedCommandNode & insertOverload(DirectoryNode & dir, std::string const & name,
208 CommandOverload::ptr overload);
211 OverloadedCommandNode();
213 virtual void v_help(std::ostream & output) const;
214 virtual std::string v_shorthelp() const;
215 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
218 Overloads overloads_;
220 std::string shortdoc_;
223 /** \brief Basic command overload
225 This is an implementation of CommandOverload which allows to call an arbitrary callback with
226 the correct signature
227 (<tt>void (std::ostream &, senf::console::ParseCommandInfo const &)</tt>)
229 class SimpleCommandOverload
230 : public CommandOverload
233 ///////////////////////////////////////////////////////////////////////////
236 typedef boost::intrusive_ptr<SimpleCommandOverload> ptr;
237 typedef boost::function<void (std::ostream &, ParseCommandInfo const &)> Function;
239 ///////////////////////////////////////////////////////////////////////////
240 ///\name Structors and default members
243 static SimpleCommandOverload::ptr create(Function fn);
244 ///< Create new SimpleCommandOverload
245 /**< \param[in] fn callback to call */
248 ///////////////////////////////////////////////////////////////////////////
250 SimpleCommandOverload & doc(std::string const & doc);
251 ///< Assign overload specific documentation
254 explicit SimpleCommandOverload(Function fn);
256 virtual unsigned v_numArguments() const;
257 virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const;
258 virtual std::string v_doc() const;
259 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
266 class SimpleOverloadAttributor
267 : public detail::NodeFactory
270 typedef OverloadedCommandNode node_type;
271 typedef OverloadedCommandNode & result_type;
273 explicit SimpleOverloadAttributor(SimpleCommandOverload::Function fn);
275 SimpleOverloadAttributor const & doc(std::string const & doc) const;
276 SimpleOverloadAttributor const & shortdoc(std::string const & doc) const;
277 SimpleOverloadAttributor const & overloadDoc(std::string const & doc) const;
279 OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const;
282 SimpleCommandOverload::ptr overload_;
283 mutable boost::optional<std::string> doc_;
284 mutable boost::optional<std::string> shortdoc_;
289 ///////////////////////////////hh.e////////////////////////////////////////
290 #include "OverloadedCommand.cci"
291 //#include "OverloadedCommand.ct"
292 #include "OverloadedCommand.cti"
299 // comment-column: 40
300 // c-file-style: "senf"
301 // indent-tabs-mode: nil
302 // ispell-local-dictionary: "american"
303 // compile-command: "scons -u test"