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