Utils/Console: Add short help to 'ls' output
[senf.git] / Utils / Console / ParsedCommand.cti
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 ParsedCommand inline template implementation */
25
26 #include "ParsedCommand.ih"
27
28 // Custom includes
29 #include "../../Utils/membind.hh"
30 #include <boost/format.hpp>
31 #include "../../Utils/parameter.hh"
32
33 #define prefix_ inline
34 ///////////////////////////////cti.p///////////////////////////////////////
35
36 ///////////////////////////////////////////////////////////////////////////
37 // senf::console::detail::ArgumentInfo<ParameterType>
38
39 template <class ParameterType>
40 prefix_ typename senf::console::detail::ArgumentInfo<ParameterType>::ptr
41 senf::console::detail::ArgumentInfo<ParameterType>::create()
42 {
43     return ptr(new ArgumentInfo());
44 }
45
46 template <class ParameterType>
47 prefix_ senf::console::detail::ArgumentInfo<ParameterType>::ArgumentInfo()
48     : ArgumentInfoBase ( ArgumentTraits<ParameterType>::description() ),
49       defaultValue ()
50 {}
51
52 template <class ParameterType>
53 prefix_ std::string senf::console::detail::ArgumentInfo<ParameterType>::defaultValueStr()
54     const
55 {
56     return hasDefault ? ArgumentTraits<ParameterType>::str(defaultValue) : "";
57 }
58
59 ///////////////////////////////////////////////////////////////////////////
60 // senf::console::ParsedCommandOverloadBase
61
62 template <class Type>
63 prefix_ void senf::console::ParsedCommandOverloadBase::addParameter()
64 {
65     parameters_.push_back(detail::ArgumentInfo<Type>::create());
66 }
67
68 ///////////////////////////////////////////////////////////////////////////
69 // senf::console::ParsedCommandOverload<FunctionTraits,n>
70
71 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY,                       \
72                                          SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp),   \
73                                          2))
74 #include BOOST_PP_ITERATE()
75
76 ///////////////////////////////////////////////////////////////////////////
77 // senf::console::ParsedCommandAttributor<Overload>
78
79 template <class Overload>
80 prefix_ Overload & senf::console::ParsedCommandAttributor<Overload>::overload()
81     const
82 {
83     return static_cast<Overload &>(ParsedCommandAttributorBase::overload());
84 }
85
86 template <class Overload>
87 prefix_
88 senf::console::ParsedCommandAttributor<Overload>::ParsedCommandAttributor(Overload & overload,
89                                                                           unsigned index)
90     : ParsedCommandAttributorBase (overload, index)
91 {}
92
93 ///////////////////////////////////////////////////////////////////////////
94 // senf::console::ParsedArgumentAttributorBase<Overload,Self>
95
96 template <class Overload, class Self, class ReturnType>
97 prefix_ Self
98 senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::doc(std::string const & doc)
99     const
100 {
101     this->ParsedCommandAttributorBase::nodeDoc(doc);
102     return static_cast<Self const &>(*this);
103 }
104
105 template <class Overload, class Self, class ReturnType>
106 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
107 shortdoc(std::string const & doc)
108     const
109 {
110     this->ParsedCommandAttributorBase::shortDoc(doc);
111     return static_cast<Self const &>(*this);
112 }
113
114 template <class Overload, class Self, class ReturnType>
115 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
116 overloadDoc(std::string const & doc)
117     const
118 {
119     this->ParsedCommandAttributorBase::overloadDoc(doc);
120     return static_cast<Self const &>(*this);
121 }
122
123 template <class Overload, class Self, class ReturnType>
124 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
125 formatter(typename Overload::Formatter f)
126     const
127 {
128     this->overload().formatter(f);
129     return static_cast<Self const &>(*this);
130 }
131
132 template <class Overload, class Self, class ReturnType>
133 prefix_
134 senf::console::ParsedArgumentAttributorBase<Overload,Self,ReturnType>::
135 ParsedArgumentAttributorBase(Overload & overload, unsigned index)
136     : ParsedCommandAttributor<Overload> (overload, index)
137 {}
138
139 template <class Overload, class Self>
140 prefix_ Self
141 senf::console::ParsedArgumentAttributorBase<Overload,Self,void>::doc(std::string const & doc)
142     const
143 {
144     this->ParsedCommandAttributorBase::nodeDoc(doc);
145     return static_cast<Self const &>(*this);
146 }
147
148 template <class Overload, class Self>
149 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload, Self, void>::
150 shortdoc(std::string const & doc)
151     const
152 {
153     this->ParsedCommandAttributorBase::shortDoc(doc);
154     return static_cast<Self const &>(*this);
155 }
156
157 template <class Overload, class Self>
158 prefix_ Self senf::console::ParsedArgumentAttributorBase<Overload,Self,void>::
159 overloadDoc(std::string const & doc)
160     const
161 {
162     this->ParsedCommandAttributorBase::overloadDoc(doc);
163     return static_cast<Self const &>(*this);
164 }
165
166 template <class Overload, class Self>
167 prefix_
168 senf::console::ParsedArgumentAttributorBase<Overload,Self,void>::
169 ParsedArgumentAttributorBase(Overload & overload, unsigned index)
170     : ParsedCommandAttributor<Overload> (overload, index)
171 {}
172
173 ///////////////////////////////////////////////////////////////////////////
174 // senf::console::ParsedArgumentAttributor<Overload,index,flag>
175
176 template <class Overload, unsigned index, bool flag>
177 prefix_ typename senf::console::ParsedArgumentAttributor<Overload,index,flag>::next_type
178 senf::console::ParsedArgumentAttributor<Overload,index,flag>::arg()
179     const
180 {
181     return next();
182 }
183
184 template <class Overload, unsigned index, bool flag>
185 template <class ArgumentPack>
186 prefix_ typename senf::console::ParsedArgumentAttributor<Overload,index,flag>::next_type
187 senf::console::ParsedArgumentAttributor<Overload,index,flag>::
188 argInfo(ArgumentPack const & args)
189     const
190 {
191 #   define ProcessArg(tag) \
192         argInfo( kw:: tag, args, senf::has_parameter< ArgumentPack, kw::type:: tag >() )
193
194     ProcessArg(name);
195     ProcessArg(description);
196     ProcessArg(default_value);
197     ProcessArg(type_name);
198     ProcessArg(default_doc);
199     ProcessArg(parser);
200
201     return next();
202
203 #   undef ProcessArg
204 }
205
206 template <class Overload, unsigned index, bool flag>
207 template <class Kw, class ArgumentPack>
208 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
209 argInfo(Kw const &, ArgumentPack const &, boost::mpl::false_)
210     const
211 {}
212
213 template <class Overload, unsigned index, bool flag>
214 template <class ArgumentPack>
215 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
216 argInfo(boost::parameter::keyword<kw::type::name> const &, ArgumentPack const & args,
217         boost::mpl::true_)
218     const
219 {
220     this->argName(args[kw::name]);
221 }
222
223 template <class Overload, unsigned index, bool flag>
224 template <class ArgumentPack>
225 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
226 argInfo(boost::parameter::keyword<kw::type::description> const &, ArgumentPack const & args,
227         boost::mpl::true_)
228     const
229 {
230     this->argDoc(args[kw::description]);
231 }
232
233 template <class Overload, unsigned index, bool flag>
234 template <class ArgumentPack>
235 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
236 argInfo(boost::parameter::keyword<kw::type::default_value> const &, ArgumentPack const & args,
237         boost::mpl::true_)
238     const
239 {
240     this->defaultValue(args[kw::default_value]);
241 }
242
243 template <class Overload, unsigned index, bool flag>
244 template <class ArgumentPack>
245 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
246 argInfo(boost::parameter::keyword<kw::type::type_name> const &, ArgumentPack const & args,
247         boost::mpl::true_)
248     const
249 {
250     this->typeName(args[kw::type_name]);
251 }
252
253 template <class Overload, unsigned index, bool flag>
254 template <class ArgumentPack>
255 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
256 argInfo(boost::parameter::keyword<kw::type::default_doc> const &, ArgumentPack const & args,
257         boost::mpl::true_)
258     const
259 {
260     BOOST_STATIC_ASSERT(( senf::has_parameter<ArgumentPack, kw::type::default_value>::value ));
261     this->defaultDoc(args[kw::default_doc]);
262 }
263
264 template <class Overload, unsigned index, bool flag>
265 template <class ArgumentPack>
266 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
267 argInfo(boost::parameter::keyword<kw::type::parser> const &, ArgumentPack const & args,
268         boost::mpl::true_)
269     const
270 {
271     this->parser(args[kw::parser]);
272 }
273
274 template <class Overload, unsigned index, bool flag>
275 prefix_
276 senf::console::ParsedArgumentAttributor<Overload,index,flag>::
277 ParsedArgumentAttributor(Overload & overload)
278     : ParsedArgumentAttributorBase<Overload, ParsedArgumentAttributor> (overload, index)
279 {}
280
281 template <class Overload, unsigned index, bool flag>
282 prefix_ typename senf::console::ParsedArgumentAttributor<Overload,index,flag>::next_type
283 senf::console::ParsedArgumentAttributor<Overload,index,flag>::next()
284     const
285 {
286     return ParsedArgumentAttributor<Overload, index+1>(this->overload());
287 }
288
289 template <class Overload, unsigned index, bool flag>
290 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::
291 defaultValue(value_type const & value)
292     const
293 {
294     this->overload().arg<index>().defaultValue = value;
295     this->overload().arg(index).hasDefault = true;
296 }
297
298 template <class Overload, unsigned index, bool flag>
299 template <class Fn>
300 prefix_ void senf::console::ParsedArgumentAttributor<Overload,index,flag>::parser(Fn fn)
301     const
302 {
303     this->overload().arg<index>().parser = fn;
304 }
305
306 ///////////////////////////////////////////////////////////////////////////
307 // senf::console::ParsedArgumentAttributor<Overload, index, false>
308
309 template <class Overload, unsigned index>
310 prefix_
311 senf::console::ParsedArgumentAttributor<Overload, index, false>::
312 ParsedArgumentAttributor(Overload & overload)
313     : ParsedArgumentAttributorBase< 
314           Overload, ParsedArgumentAttributor<Overload, index, false> > (overload, index)
315 {}
316
317 ///////////////////////////////////////////////////////////////////////////
318 // namespace members
319
320 namespace senf {
321 namespace console {
322 namespace detail {
323
324 #ifndef DOXYGEN
325
326     struct ParsedCommandAddNodeAccess
327     {
328         template <class Attributor, class Node>
329         static Attributor attributor(Node & node)
330             { return Attributor(node); }
331     };
332
333     // What is THIS about ??
334
335     // Ok, here's the dope: parsed commands may optionally have an std::ostream & first argument. If
336     // this argument is given, then the function will be called with the console output stream as
337     // it's first argument.
338     //
339     // This is implemented in the following way: ParsedCommandOverload (the class responsible for
340     // calling the callback) will ALWAYS pass the stream as first argument. If the user callback
341     // expects os as it's first argument, 'ignoreOneArg' will be false and the user supplied
342     // function will be directly passed to ParsedCommandOverload.
343     //
344     // If however, it does NOT take an std::ostream first argument, 'ignoreOneArg' will be true and
345     // the create member will use boost::bind to DROP the first argument.
346     
347     template <class Traits, 
348               bool ignoreOneArg=! Traits::has_ostream_arg, 
349               unsigned arity=Traits::traits::arity>
350     struct CreateParsedCommandOverload
351     {};
352
353     template <class Traits, unsigned arity>
354     struct CreateParsedCommandOverload<Traits, false, arity>
355     {
356         typedef typename Traits::traits traits;
357         
358         template <class Function>
359         static typename senf::console::ParsedCommandOverload<traits>::ptr create(Function fn) 
360             { return senf::console::ParsedCommandOverload<traits>::create(fn); };
361     };
362
363 #   define BOOST_PP_ITERATION_PARAMS_1 (4, (0, SENF_CONSOLE_MAX_COMMAND_ARITY,                     \
364                                             SENF_ABSOLUTE_INCLUDE_PATH(Utils/Console/ParsedCommand.mpp), \
365                                             4))
366 #   include BOOST_PP_ITERATE()
367
368     template <class Signature, class Fn>
369     typename senf::console::detail::ParsedCommandTraits<Signature>::Attributor
370     addOverloadedCommandNode(senf::console::DirectoryNode & node,  std::string const & name, Fn fn)
371     {
372         senf::console::OverloadedCommandNode & cmdNode (
373             node.hasChild(name) 
374             ? dynamic_cast<senf::console::OverloadedCommandNode &>(node(name))
375             : node.add(name, senf::console::OverloadedCommandNode::create()) );
376
377         typedef senf::console::detail::ParsedCommandTraits<Signature> CmdTraits;
378         typedef senf::console::ParsedCommandOverload<typename CmdTraits::traits> Overload;
379         typedef senf::console::ParsedArgumentAttributor<Overload> Attributor;
380
381         return senf::console::detail::ParsedCommandAddNodeAccess::attributor<Attributor>(
382             cmdNode.add( CreateParsedCommandOverload<CmdTraits>::create(fn) ) );
383     }
384
385 #endif
386
387 }}}
388
389 #ifndef DOXYGEN
390
391 template <class Function>
392 typename senf::console::detail::ParsedCommandTraits<Function>::Attributor
393 senf::console::senf_console_add_node(DirectoryNode & node, std::string const & name,
394                                      Function fn, int,
395                                      typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_callable>::type *)
396 {
397     return senf::console::detail::addOverloadedCommandNode<Function>(node, name, fn);
398 }
399
400 template <class Signature>
401 typename senf::console::detail::ParsedCommandTraits<Signature>::Attributor
402 senf::console::senf_console_add_node(DirectoryNode & node, std::string const & name,
403                                      boost::function<Signature> fn, int)
404 {
405     return senf::console::detail::addOverloadedCommandNode<Signature>(node, name, fn);
406 }
407
408 template <class Owner, class Function>
409 typename senf::console::detail::ParsedCommandTraits<Function>::Attributor
410 senf::console::senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name,
411                                      Function fn, int,
412                                      typename boost::enable_if_c<detail::ParsedCommandTraits<Function>::is_member>::type *)
413 {
414     return senf::console::detail::addOverloadedCommandNode<Function>(
415         node, name, senf::membind(fn,&owner));
416 }
417
418 #endif
419
420 ///////////////////////////////cti.e///////////////////////////////////////
421 #undef prefix_
422
423 \f
424 // Local Variables:
425 // mode: c++
426 // fill-column: 100
427 // comment-column: 40
428 // c-file-style: "senf"
429 // indent-tabs-mode: nil
430 // ispell-local-dictionary: "american"
431 // compile-command: "scons -u test"
432 // End: