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