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