switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / Console / OverloadedCommand.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
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
10 //
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.
14 //
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.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
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.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief OverloadedCommand public header */
30
31 #ifndef HH_SENF_Scheduler_Console_OverloadedCommand_
32 #define HH_SENF_Scheduler_Console_OverloadedCommand_ 1
33
34 // Custom includes
35 #include "Node.hh"
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>
40
41 //#include "OverloadedCommand.mpp"
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43
44 namespace senf {
45 namespace console {
46
47     class OverloadedCommandNode;
48
49     /** \brief Documentation for a single argument
50
51         This struct is used by CommandOverload::argumentDoc()
52      */
53     struct 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
59     };
60
61     /** \brief Base class for command overload of OverloadedCommandNode
62
63         This class is the base class of the commands which may be added to an
64         OverloadedCommandNode.
65       */
66     class CommandOverload
67         : public senf::intrusive_refcount
68     {
69     public:
70         //-////////////////////////////////////////////////////////////////////////
71         // Types
72
73         typedef boost::intrusive_ptr<CommandOverload> ptr;
74         typedef boost::intrusive_ptr<CommandOverload const> cptr;
75
76         //-////////////////////////////////////////////////////////////////////////
77
78         virtual ~CommandOverload();
79
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()() */
85
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.
90                                              Same as execute() */
91
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 */
100
101         std::string doc() const;        ///< Get overload documentation
102
103         OverloadedCommandNode & node() const; ///< Access owning node
104                                         /**< \pre The command \e must have been added to an
105                                              OverloadedCommandNode. */
106
107         unsigned overloadIndex() const; ///< Get index of overload in it's OverloadedCommandNode
108
109     protected:
110         CommandOverload();
111
112 #ifndef DOXYGEN
113     private:
114 #endif
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. */
119
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. */
125
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. */
130
131         virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
132             const = 0;
133                                         ///< Execute the overload
134                                         /**< This member must be implemented in the derived class
135                                              o execute the overload. */
136
137     private:
138         OverloadedCommandNode * node_;
139
140         friend class OverloadedCommandNode;
141     };
142
143     /** \brief Command node which allows multiple registered callbacks
144
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.
148
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.
151         \code
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));
157         \endcode
158
159         However, this facility is normally used not directly but indirectly (and automatically) when
160         adding argument parsing callbacks.
161
162         \warning For this to work, the commands <b>must</b> do all syntax checking before doing any
163             operation
164
165         \ingroup console_commands
166       */
167     class OverloadedCommandNode
168         : public CommandNode
169     {
170         typedef std::vector<CommandOverload::ptr> Overloads;
171
172     public:
173         //-////////////////////////////////////////////////////////////////////////
174         // Types
175
176         typedef boost::shared_ptr<OverloadedCommandNode> ptr;
177         typedef boost::shared_ptr<OverloadedCommandNode const> cptr;
178         typedef boost::weak_ptr<OverloadedCommandNode> weak_ptr;
179
180         typedef OverloadedCommandNode node_type;
181         typedef OverloadedCommandNode & return_type;
182
183         typedef boost::iterator_range<Overloads::const_iterator> OverloadsRange;
184
185         //-////////////////////////////////////////////////////////////////////////
186         ///\name Structors and default members
187         //\{
188
189         static ptr create();
190
191         //\}
192         //-////////////////////////////////////////////////////////////////////////
193
194         template <class Command>
195         Command & add(boost::intrusive_ptr<Command> overload); ///< Add an additional overload
196
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
201
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. */
206
207         OverloadsRange overloads() const; ///< Get all overloads
208
209         ptr thisptr();
210         cptr thisptr() const;
211
212         static OverloadedCommandNode & insertOverload(DirectoryNode & dir, std::string const & name,
213                                                       CommandOverload::ptr overload);
214
215     private:
216         OverloadedCommandNode();
217
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)
221             const;
222
223         Overloads overloads_;
224         std::string doc_;
225         std::string shortdoc_;
226     };
227
228     /** \brief Basic command overload
229
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>)
233       */
234     class SimpleCommandOverload
235         : public CommandOverload
236     {
237     public:
238         //-////////////////////////////////////////////////////////////////////////
239         // Types
240
241         typedef boost::intrusive_ptr<SimpleCommandOverload> ptr;
242         typedef boost::function<void (std::ostream &, ParseCommandInfo const &)> Function;
243
244         //-////////////////////////////////////////////////////////////////////////
245         ///\name Structors and default members
246         //\{
247
248         static SimpleCommandOverload::ptr create(Function fn);
249                                         ///< Create new SimpleCommandOverload
250                                         /**< \param[in] fn callback to call */
251
252         //\}
253         //-////////////////////////////////////////////////////////////////////////
254
255         SimpleCommandOverload & doc(std::string const & doc);
256                                         ///< Assign overload specific documentation
257
258     private:
259         explicit SimpleCommandOverload(Function fn);
260
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)
265             const;
266
267         Function fn_;
268         std::string doc_;
269     };
270
271     class SimpleOverloadAttributor
272         : public detail::NodeFactory
273     {
274     public:
275         typedef OverloadedCommandNode node_type;
276         typedef OverloadedCommandNode & result_type;
277
278         explicit SimpleOverloadAttributor(SimpleCommandOverload::Function fn);
279
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;
283
284         OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const;
285
286     private:
287         SimpleCommandOverload::ptr overload_;
288         mutable boost::optional<std::string> doc_;
289         mutable boost::optional<std::string> shortdoc_;
290     };
291
292 }}
293
294 //-/////////////////////////////////////////////////////////////////////////////////////////////////
295 #include "OverloadedCommand.cci"
296 //#include "OverloadedCommand.ct"
297 #include "OverloadedCommand.cti"
298 #endif
299
300 \f
301 // Local Variables:
302 // mode: c++
303 // fill-column: 100
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"
309 // End: