4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief OverloadedCommand public header */
31 #ifndef HH_SENF_Scheduler_Console_OverloadedCommand_
32 #define HH_SENF_Scheduler_Console_OverloadedCommand_ 1
36 #include <boost/intrusive_ptr.hpp>
37 #include <boost/range/iterator_range.hpp>
38 #include <senf/Utils/intrusive_refcount.hh>
39 #include <boost/optional.hpp>
41 //#include "OverloadedCommand.mpp"
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
47 class OverloadedCommandNode;
49 /** \brief Documentation for a single argument
51 This struct is used by CommandOverload::argumentDoc()
54 std::string name; ///< Argument name
55 std::string type; ///< Argument type (string representation)
56 std::string defaultValue; ///< Default value (string representation) or empty string
57 std::string doc; ///< Documentation for this argument
58 bool singleToken; ///< \c true, if argument is parsed from single token
61 /** \brief Base class for command overload of OverloadedCommandNode
63 This class is the base class of the commands which may be added to an
64 OverloadedCommandNode.
67 : public senf::intrusive_refcount
70 //-////////////////////////////////////////////////////////////////////////
73 typedef boost::intrusive_ptr<CommandOverload> ptr;
74 typedef boost::intrusive_ptr<CommandOverload const> cptr;
76 //-////////////////////////////////////////////////////////////////////////
78 virtual ~CommandOverload();
80 void execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command);
81 ///< Call the overload
82 /**< If the \a arguments are not acceptable for this
83 overload, a SyntaxErrorException must be thrown.
84 Same as operator()() */
86 void operator()(boost::any & rv, std::ostream & os, ParseCommandInfo const & command);
87 ///< Call the overload
88 /**< If the \a arguments are not acceptable for this
89 overload, a SyntaxErrorException must be thrown.
92 unsigned numArguments() const; ///< Number of arguments this overload takes
93 void argumentDoc(unsigned index, ArgumentDoc & doc) const;
94 ///< Get information on argument \a index
95 /**< The information is returned in \e doc. \e doc must be
96 empty before this call.
97 \pre \a index < numArguments()
98 \param[in] index Argument index
99 \param[out] doc Argument documentation */
101 std::string doc() const; ///< Get overload documentation
103 OverloadedCommandNode & node() const; ///< Access owning node
104 /**< \pre The command \e must have been added to an
105 OverloadedCommandNode. */
107 unsigned overloadIndex() const; ///< Get index of overload in it's OverloadedCommandNode
115 virtual unsigned v_numArguments() const = 0;
116 ///< Return the number of arguments
117 /**< This member must be implemented in the derived class to
118 return the number of arguments, the command expects. */
120 virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const = 0;
121 ///< Return argument documentation
122 /**< The member must be implemented int the derived class to
123 return all documentation information for the \a
124 index'th parameter in \a doc. */
126 virtual std::string v_doc() const = 0;
127 ///< Return overload documentation
128 /**< This member must be implemented in the derived class to
129 return the overloads documentation string. */
131 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
133 ///< Execute the overload
134 /**< This member must be implemented in the derived class
135 o execute the overload. */
138 OverloadedCommandNode * node_;
140 friend class OverloadedCommandNode;
143 /** \brief Command node which allows multiple registered callbacks
145 OverloadedCommandNode is like SimpleCommandNode but allows to register multiple commands to
146 a single node. This works by calling each command in the list consecutively until no
147 'SyntaxErrorException' exception is thrown.
149 This works by first adding an OverloadedCommandNode to the directory in question and then
150 adding commands to that node. Commands are derived from CommandOverload.
152 senf::console::DirectoryNode & dir (...);
153 senf::console::OverloadedCommandNode & cmd (
154 dir.add("cmd", senf::console::OverloadedCommandNode::create()) );
155 cmd.add(senf::console::SimpleCommandOverload::create(&callback));
156 cmd.add(senf::console::SimpleCommandOverload::create(&anotherCallback));
159 However, this facility is normally used not directly but indirectly (and automatically) when
160 adding argument parsing callbacks.
162 \warning For this to work, the commands <b>must</b> do all syntax checking before doing any
165 \ingroup console_commands
167 class OverloadedCommandNode
170 typedef std::vector<CommandOverload::ptr> Overloads;
173 //-////////////////////////////////////////////////////////////////////////
176 typedef boost::shared_ptr<OverloadedCommandNode> ptr;
177 typedef boost::shared_ptr<OverloadedCommandNode const> cptr;
178 typedef boost::weak_ptr<OverloadedCommandNode> weak_ptr;
180 typedef OverloadedCommandNode node_type;
181 typedef OverloadedCommandNode & return_type;
183 typedef boost::iterator_range<Overloads::const_iterator> OverloadsRange;
185 //-////////////////////////////////////////////////////////////////////////
186 ///\name Structors and default members
192 //-////////////////////////////////////////////////////////////////////////
194 template <class Command>
195 Command & add(boost::intrusive_ptr<Command> overload); ///< Add an additional overload
197 OverloadedCommandNode & doc(std::string const & doc);
198 ///< Assign global help for all overloads
199 OverloadedCommandNode & shortdoc(std::string const & doc);
200 ///< Assign short documentation for all overloads
202 unsigned overloadIndex(CommandOverload const & overload);
203 ///< Return the overload index for \a overload
204 /**< overloadIndex returns the index of \a overload in the
205 internal list of overloads. */
207 OverloadsRange overloads() const; ///< Get all overloads
210 cptr thisptr() const;
212 static OverloadedCommandNode & insertOverload(DirectoryNode & dir, std::string const & name,
213 CommandOverload::ptr overload);
216 OverloadedCommandNode();
218 virtual void v_help(std::ostream & output) const;
219 virtual std::string v_shorthelp() const;
220 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
223 Overloads overloads_;
225 std::string shortdoc_;
228 /** \brief Basic command overload
230 This is an implementation of CommandOverload which allows to call an arbitrary callback with
231 the correct signature
232 (<tt>void (std::ostream &, senf::console::ParseCommandInfo const &)</tt>)
234 class SimpleCommandOverload
235 : public CommandOverload
238 //-////////////////////////////////////////////////////////////////////////
241 typedef boost::intrusive_ptr<SimpleCommandOverload> ptr;
242 typedef boost::function<void (std::ostream &, ParseCommandInfo const &)> Function;
244 //-////////////////////////////////////////////////////////////////////////
245 ///\name Structors and default members
248 static SimpleCommandOverload::ptr create(Function fn);
249 ///< Create new SimpleCommandOverload
250 /**< \param[in] fn callback to call */
253 //-////////////////////////////////////////////////////////////////////////
255 SimpleCommandOverload & doc(std::string const & doc);
256 ///< Assign overload specific documentation
259 explicit SimpleCommandOverload(Function fn);
261 virtual unsigned v_numArguments() const;
262 virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const;
263 virtual std::string v_doc() const;
264 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
271 class SimpleOverloadAttributor
272 : public detail::NodeFactory
275 typedef OverloadedCommandNode node_type;
276 typedef OverloadedCommandNode & result_type;
278 explicit SimpleOverloadAttributor(SimpleCommandOverload::Function fn);
280 SimpleOverloadAttributor const & doc(std::string const & doc) const;
281 SimpleOverloadAttributor const & shortdoc(std::string const & doc) const;
282 SimpleOverloadAttributor const & overloadDoc(std::string const & doc) const;
284 OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const;
287 SimpleCommandOverload::ptr overload_;
288 mutable boost::optional<std::string> doc_;
289 mutable boost::optional<std::string> shortdoc_;
294 //-/////////////////////////////////////////////////////////////////////////////////////////////////
295 #include "OverloadedCommand.cci"
296 //#include "OverloadedCommand.ct"
297 #include "OverloadedCommand.cti"
304 // comment-column: 40
305 // c-file-style: "senf"
306 // indent-tabs-mode: nil
307 // ispell-local-dictionary: "american"
308 // compile-command: "scons -u test"