Move sourcecode into 'senf/' directory
[senf.git] / senf / Utils / Console / OverloadedCommand.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief OverloadedCommand public header */
25
26 #ifndef HH_SENF_Scheduler_Console_OverloadedCommand_
27 #define HH_SENF_Scheduler_Console_OverloadedCommand_ 1
28
29 // Custom includes
30 #include "Node.hh"
31 #include <boost/intrusive_ptr.hpp>
32 #include <boost/range/iterator_range.hpp>
33 #include "../../Utils/intrusive_refcount.hh"
34
35 //#include "OverloadedCommand.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
37
38 namespace senf {
39 namespace console {
40
41     class OverloadedCommandNode;
42
43     /** \brief Documentation for a single argument
44
45         This struct is used by CommandOverload::argumentDoc()
46      */
47     struct ArgumentDoc {
48         std::string name; ///< Argument name
49         std::string type; ///< Argument type (string representation)
50         std::string defaultValue; ///< Default value (string representation) or empty string
51         std::string doc; ///< Documentation for this argument
52         bool singleToken; ///< \c true, if argument is parsed from single token
53     };
54
55     /** \brief Base class for command overload of OverloadedCommandNode
56
57         This class is the base class of the commands which may be added to an
58         OverloadedCommandNode.
59       */
60     class CommandOverload
61         : public senf::intrusive_refcount
62     {
63     public:
64         ///////////////////////////////////////////////////////////////////////////
65         // Types
66
67         typedef boost::intrusive_ptr<CommandOverload> ptr;
68         typedef boost::intrusive_ptr<CommandOverload const> cptr;
69
70         ///////////////////////////////////////////////////////////////////////////
71
72         virtual ~CommandOverload();
73
74         void execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command);
75                                         ///< Call the overload
76                                         /**< If the \a arguments are not acceptable for this
77                                              overload, a SyntaxErrorException must be thrown. 
78                                              Same as operator()() */
79
80         void operator()(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 execute() */
85         
86         unsigned numArguments() const;  ///< Number of arguments this overload takes
87         void argumentDoc(unsigned index, ArgumentDoc & doc) const;
88                                         ///< Get information on argument \a index
89                                         /**< The information is returned in \e doc. \e doc must be
90                                              empty before this call.
91                                              \pre \a index < numArguments()
92                                              \param[in] index Argument index
93                                              \param[out] doc Argument documentation */
94
95         std::string doc() const;        ///< Get overload documentation
96         
97         OverloadedCommandNode & node() const; ///< Access owning node
98                                         /**< \pre The command \e must have been added to an
99                                              OverloadedCommandNode. */
100
101         unsigned overloadIndex() const; ///< Get index of overload in it's OverloadedCommandNode
102
103     protected:
104         CommandOverload();
105
106 #ifndef DOXYGEN
107     private:
108 #endif
109         virtual unsigned v_numArguments() const = 0;
110                                         ///< Return the number of arguments
111                                         /**< This member must be implemented in the derived class to
112                                              return the number of arguments, the command expects. */
113
114         virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const = 0;
115                                         ///< Return argument documentation
116                                         /**< The member must be implemented int the derived class to
117                                              return all documentation information for the \a
118                                              index'th parameter in \a doc. */
119
120         virtual std::string v_doc() const = 0;
121                                         ///< Return overload documentation
122                                         /**< This member must be implemented in the derived class to
123                                              return the overloads documentation string. */
124
125         virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
126             const = 0;
127                                         ///< Execute the overload
128                                         /**< This member must be implemented in the derived class
129                                              o execute the overload. */
130
131     private:
132         OverloadedCommandNode * node_;
133
134         friend class OverloadedCommandNode;
135     };
136
137     /** \brief Command node which allows multiple registered callbacks
138
139         OverloadedCommandNode is like SimpleCommandNode but allows to register multiple commands to
140         a single node. This works by calling each command in the list consecutively until no
141         'SyntaxErrorException' exception is thrown.
142
143         This works by first adding an OverloadedCommandNode to the directory in question and then
144         adding commands to that node. Commands are derived from CommandOverload. 
145         \code
146         senf::console::DirectoryNode & dir (...);
147         senf::console::OverloadedCommandNode & cmd (
148             dir.add("cmd", senf::console::OverloadedCommandNode::create()) );
149         cmd.add(senf::console::SimpleCommandOverload::create(&callback));
150         cmd.add(senf::console::SimpleCommandOverload::create(&anotherCallback));
151         \endcode
152
153         However, this facility is normally used not directly but indirectly (and automatically) when
154         adding argument parsing callbacks.
155
156         \warning For this to work, the commands <b>must</b> do all syntax checking before doing any
157             operation
158
159         \ingroup console_commands
160       */
161     class OverloadedCommandNode
162         : public CommandNode
163     {
164         typedef std::vector<CommandOverload::ptr> Overloads;
165
166     public:
167         ///////////////////////////////////////////////////////////////////////////
168         // Types
169
170         typedef boost::shared_ptr<OverloadedCommandNode> ptr;
171         typedef boost::shared_ptr<OverloadedCommandNode const> cptr;
172         typedef boost::weak_ptr<OverloadedCommandNode> weak_ptr;
173
174         typedef OverloadedCommandNode node_type;
175         typedef OverloadedCommandNode & return_type;
176
177         typedef boost::iterator_range<Overloads::const_iterator> OverloadsRange;
178
179         ///////////////////////////////////////////////////////////////////////////
180         ///\name Structors and default members
181         ///@{
182
183         static ptr create();
184
185         ///@}
186         ///////////////////////////////////////////////////////////////////////////
187         
188         template <class Command>
189         Command & add(boost::intrusive_ptr<Command> overload); ///< Add an additional overload
190
191         OverloadedCommandNode & doc(std::string const & doc);
192                                         ///< Assign global help for all overloads
193         OverloadedCommandNode & shortdoc(std::string const & doc);
194                                         ///< Assign short documentation for all overloads
195
196         unsigned overloadIndex(CommandOverload const & overload);
197                                         ///< Return the overload index for \a overload
198                                         /**< overloadIndex returns the index of \a overload in the
199                                              internal list of overloads. */
200
201         OverloadsRange overloads() const; ///< Get all overloads
202
203         ptr thisptr();
204         cptr thisptr() const;
205
206     private:
207         OverloadedCommandNode();
208
209         virtual void v_help(std::ostream & output) const;
210         virtual std::string v_shorthelp() const;
211         virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
212             const;
213
214         Overloads overloads_;
215         std::string doc_;
216         std::string shortdoc_;
217     };
218
219     /** \brief Basic command overload
220
221         This is an implementation of CommandOverload which allows to call an arbitrary callback with
222         the correct signature 
223         (<tt>void (std::ostream &, senf::console::ParseCommandInfo const &)</tt>)
224       */
225     class SimpleCommandOverload
226         : public CommandOverload
227     {
228     public:
229         ///////////////////////////////////////////////////////////////////////////
230         // Types
231
232         typedef boost::intrusive_ptr<SimpleCommandOverload> ptr;
233         typedef boost::function<void (std::ostream &, ParseCommandInfo const &)> Function;
234
235         ///////////////////////////////////////////////////////////////////////////
236         ///\name Structors and default members
237         ///@{
238
239         static SimpleCommandOverload::ptr create(Function fn);
240                                         ///< Create new SimpleCommandOverload
241                                         /**< \param[in] fn callback to call */
242
243         ///@}
244         ///////////////////////////////////////////////////////////////////////////
245
246         SimpleCommandOverload & doc(std::string const & doc);
247                                         ///< Assign overload specific documentation
248
249     private:
250         explicit SimpleCommandOverload(Function fn);
251
252         virtual unsigned v_numArguments() const;
253         virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const;
254         virtual std::string v_doc() const;
255         virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
256             const;
257
258         Function fn_;
259         std::string doc_;
260     };
261
262 }}
263
264 ///////////////////////////////hh.e////////////////////////////////////////
265 #include "OverloadedCommand.cci"
266 //#include "OverloadedCommand.ct"
267 #include "OverloadedCommand.cti"
268 #endif
269
270 \f
271 // Local Variables:
272 // mode: c++
273 // fill-column: 100
274 // comment-column: 40
275 // c-file-style: "senf"
276 // indent-tabs-mode: nil
277 // ispell-local-dictionary: "american"
278 // compile-command: "scons -u test"
279 // End: