Utils/Console: Add short help to 'ls' output
[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(boost::any & rv, 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()(boost::any & rv, 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(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
124             const = 0;
125                                         ///< Execute the overload
126                                         /**< This member must be implemented in the derived class
127                                              o execute the overload. */
128
129     private:
130         OverloadedCommandNode * node_;
131
132         friend class OverloadedCommandNode;
133     };
134
135     /** \brief Command node which allows multiple registered callbacks
136
137         OverloadedCommandNode is like SimpleCommandNode but allows to register multiple commands to
138         a single node. This works by calling each command in the list consecutively until no
139         'SyntaxErrorException' exception is thrown.
140
141         This works by first adding an OverloadedCommandNode to the directory in question and then
142         adding commands to that node. Commands are derived from CommandOverload. 
143         \code
144         senf::console::DirectoryNode & dir (...);
145         senf::console::OverloadedCommandNode & cmd (
146             dir.add("cmd", senf::console::OverloadedCommandNode::create()) );
147         cmd.add(senf::console::SimpleCommandOverload::create(&callback));
148         cmd.add(senf::console::SimpleCommandOverload::create(&anotherCallback));
149         \endcode
150
151         However, this facility is normally used not directly but indirectly (and automatically) when
152         adding argument parsing callbacks.
153
154         \warning For this to work, the commands <b>must</b> do all syntax checking before doing any
155             operation
156
157         \ingroup console_commands
158       */
159     class OverloadedCommandNode
160         : public CommandNode
161     {
162     public:
163         ///////////////////////////////////////////////////////////////////////////
164         // Types
165
166         typedef boost::shared_ptr<OverloadedCommandNode> ptr;
167         typedef boost::shared_ptr<OverloadedCommandNode const> cptr;
168         typedef boost::weak_ptr<OverloadedCommandNode> weak_ptr;
169
170         typedef OverloadedCommandNode node_type;
171         typedef OverloadedCommandNode & return_type;
172
173         ///////////////////////////////////////////////////////////////////////////
174         ///\name Structors and default members
175         ///@{
176
177         static ptr create();
178
179         ///@}
180         ///////////////////////////////////////////////////////////////////////////
181         
182         template <class Command>
183         Command & add(boost::intrusive_ptr<Command> overload); ///< Add an additional overload
184
185         OverloadedCommandNode & doc(std::string const & doc);
186                                         ///< Assign global help for all overloads
187         OverloadedCommandNode & shortdoc(std::string const & doc);
188                                         ///< Assign short documentation for all overloads
189
190         unsigned overloadIndex(CommandOverload const & overload);
191                                         ///< Return the overload index for \a overload
192                                         /**< overloadIndex returns the index of \a overload in the
193                                              internal list of overloads. */
194
195         ptr thisptr();
196         cptr thisptr() const;
197
198     private:
199         OverloadedCommandNode();
200
201         virtual void v_help(std::ostream & output) const;
202         virtual std::string v_shorthelp() const;
203         virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
204             const;
205
206         typedef std::vector<CommandOverload::ptr> Overloads;
207
208         Overloads overloads_;
209         std::string doc_;
210         std::string shortdoc_;
211     };
212
213     /** \brief Basic command overload
214
215         This is an implementation of CommandOverload which allows to call an arbitrary callback with
216         the correct signature 
217         (<tt>void (std::ostream &, senf::console::ParseCommandInfo const &)</tt>)
218       */
219     class SimpleCommandOverload
220         : public CommandOverload
221     {
222     public:
223         ///////////////////////////////////////////////////////////////////////////
224         // Types
225
226         typedef boost::intrusive_ptr<SimpleCommandOverload> ptr;
227         typedef boost::function<void (std::ostream &, ParseCommandInfo const &)> Function;
228
229         ///////////////////////////////////////////////////////////////////////////
230         ///\name Structors and default members
231         ///@{
232
233         static SimpleCommandOverload::ptr create(Function fn);
234                                         ///< Create new SimpleCommandOverload
235                                         /**< \param[in] fn callback to call */
236
237         ///@}
238         ///////////////////////////////////////////////////////////////////////////
239
240         SimpleCommandOverload & doc(std::string const & doc);
241                                         ///< Assign overload specific documentation
242
243     private:
244         explicit SimpleCommandOverload(Function fn);
245
246         virtual unsigned v_numArguments() const;
247         virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const;
248         virtual std::string v_doc() const;
249         virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
250             const;
251
252         Function fn_;
253         std::string doc_;
254     };
255
256 }}
257
258 ///////////////////////////////hh.e////////////////////////////////////////
259 #include "OverloadedCommand.cci"
260 //#include "OverloadedCommand.ct"
261 #include "OverloadedCommand.cti"
262 #endif
263
264 \f
265 // Local Variables:
266 // mode: c++
267 // fill-column: 100
268 // comment-column: 40
269 // c-file-style: "senf"
270 // indent-tabs-mode: nil
271 // ispell-local-dictionary: "american"
272 // compile-command: "scons -u test"
273 // End: