Fix documentation build under maverick (doxygen 1.7.1)
[senf.git] / senf / Utils / Console / OverloadedCommand.cc
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 non-inline non-template implementation */
25
26 #include "OverloadedCommand.hh"
27 //#include "OverloadedCommand.ih"
28
29 // Custom includes
30
31 //#include "OverloadedCommand.mpp"
32 #define prefix_
33 //-/////////////////////////////////////////////////////////////////////////////////////////////////
34
35 //-/////////////////////////////////////////////////////////////////////////////////////////////////
36 // senf::console::OverloadedCommandNode
37
38 prefix_ senf::console::OverloadedCommandNode &
39 senf::console::OverloadedCommandNode::insertOverload(DirectoryNode & dir,
40                                                      std::string const & name,
41                                                      CommandOverload::ptr overload)
42 {
43     OverloadedCommandNode & node (
44         dir.hasChild(name)
45         ? dynamic_cast<OverloadedCommandNode &>(dir(name))
46         : dir.add(name, OverloadedCommandNode::create()));
47     node.add(overload);
48     return node;
49 }
50
51 //-/////////////////////////////////////////////////////////////////////////////////////////////////
52 // So soll die doku aussehen:
53 //
54 // Usage:
55 //      1- foo arg1:int arg2:double
56 //      2- foo arg3:string
57 //      3- foo
58 //
59 // With:
60 //      arg1 -   arg1-doc
61 //      arg2 -   arg2-doc
62 //          default: 1.23
63 //      arg3 -   arg3-doc
64 //
65 // Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj
66 // sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd
67 // Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj
68 // sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd
69 // Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj
70 // sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd
71 //
72 // Variant 1:
73 // Variant 1 doc la;ksjf lkj sdlkfj lkjekj sdflkj ekljsdlkfj wlej
74 // slkj dkj sldkfj lwekljsdf skldjf lskjdf l jsd
75 //
76 // Variant 2:
77 // Variant 2 doc lskdfj lwkej lksjdflksjf
78 //
79 // Variatn 3:
80 // Variant 3 doc slkjflw ekj lskdfj lskdjf laksdj flksj elkj aldskjf lwkejlksdj
81 // ldkfaj wlekj slkdfj lskdjf lwkejlkasdjf
82
83 prefix_ void senf::console::OverloadedCommandNode::v_help(std::ostream & os)
84     const
85 {
86     typedef std::vector<ArgumentDoc> ArgumentDocs;
87     ArgumentDocs argumentDocs;
88     bool haveDocumentedArg (false);
89
90     os << "Usage:\n";
91     {
92         Overloads::const_iterator i (overloads_.begin());
93         Overloads::const_iterator const i_end (overloads_.end());
94         unsigned index (1);
95         for (; i != i_end; ++i, ++index) {
96             os << "    ";
97             if (overloads_.size() > 1) os << index << "- ";
98             os << name();
99             for (unsigned j (0); j < (*i)->numArguments(); ++j) {
100                 ArgumentDoc arg;
101                 (*i)->argumentDoc(j, arg);
102
103                 os << ' ';
104                 if (! arg.defaultValue.empty())
105                     os << '[';
106                 if (! arg.name.empty()) os << arg.name;
107                 if (! arg.type.empty()) os << ':' << arg.type;
108                 if (arg.name.empty() && arg.type.empty()) os << "...";
109                 if (! arg.defaultValue.empty())
110                     os << ']';
111
112                 if (! arg.name.empty() || ! arg.defaultValue.empty()) {
113                     ArgumentDocs::iterator k (argumentDocs.begin());
114                     ArgumentDocs::iterator const k_end (argumentDocs.end());
115                     for (; k != k_end; ++k)
116                         if (k->name == arg.name && k->defaultValue == arg.defaultValue) {
117                             if (! arg.doc.empty() && k->doc.empty()) {
118                                 k->doc == arg.doc;
119                                 haveDocumentedArg = true;
120                             }
121                             break;
122                         }
123                     if (k == k_end) {
124                         argumentDocs.push_back(arg);
125                         if (! arg.doc.empty())
126                             haveDocumentedArg = true;
127                     }
128                 }
129             }
130             os << '\n';
131         }
132     }
133
134     if (haveDocumentedArg) {
135         os << "\n" "With:\n";
136         ArgumentDocs::const_iterator i (argumentDocs.begin());
137         ArgumentDocs::const_iterator const i_end (argumentDocs.end());
138         for (; i != i_end; ++i) {
139             if (! i->doc.empty() || ! i->defaultValue.empty()) {
140                 os << "    "
141                    << i->name
142                    << std::string(i->name.length()<8 ? 8-i->name.length() : 0, ' ')
143                    << "  "
144                    << i->doc
145                    << '\n';
146                 if (! i->defaultValue.empty())
147                     os << "        default: " << i->defaultValue << '\n';
148             }
149         }
150     }
151
152     if (! doc_.empty())
153         os << "\n" << doc_ << "\n";
154
155     {
156         Overloads::const_iterator i (overloads_.begin());
157         Overloads::const_iterator const i_end (overloads_.end());
158         unsigned index (1);
159         for (; i != i_end; ++i, ++index) {
160             std::string overloadDoc ((*i)->doc());
161             if (! overloadDoc.empty()) {
162                 os << "\n";
163                 if (overloads_.size() > 1)
164                     os << "Variant " << index << ":\n";
165                 os << overloadDoc << "\n";
166             }
167         }
168     }
169 }
170
171 prefix_ std::string senf::console::OverloadedCommandNode::v_shorthelp()
172     const
173 {
174     if (!shortdoc_.empty())
175         return shortdoc_;
176     if (!doc_.empty())
177         return doc_.substr(0,doc_.find('\n'));
178     Overloads::const_iterator i (overloads_.begin());
179     Overloads::const_iterator const i_end (overloads_.end());
180     for (; i != i_end; ++i) {
181         std::string overloadDoc ((*i)->doc());
182         if (! overloadDoc.empty())
183             return overloadDoc.substr(0,overloadDoc.find('\n'));
184     }
185     return "";
186 }
187
188 prefix_ void senf::console::OverloadedCommandNode::v_execute(boost::any & rv,
189                                                              std::ostream & os,
190                                                              ParseCommandInfo const & command)
191     const
192 {
193     Overloads::const_iterator i (overloads_.begin());
194     Overloads::const_iterator const i_end (overloads_.end());
195     SyntaxErrorException err;
196     for (; i != i_end; ++i) {
197         try {
198             (**i)(rv, os, command);
199             return;
200         }
201         catch (SyntaxErrorException & ex) {
202             err = ex;
203         };
204     }
205     throw err;
206 }
207
208 //-/////////////////////////////////////////////////////////////////////////////////////////////////
209 // senf::console::SimpleCommandOverload
210
211 prefix_ unsigned senf::console::SimpleCommandOverload::v_numArguments()
212     const
213 {
214     return 1;
215 }
216
217 prefix_ void senf::console::SimpleCommandOverload::v_argumentDoc(unsigned index, ArgumentDoc & doc)
218     const
219 {}
220
221 prefix_ std::string senf::console::SimpleCommandOverload::v_doc()
222     const
223 {
224     return doc_;
225 }
226
227 prefix_ void senf::console::SimpleCommandOverload::v_execute(boost::any & rv,
228                                                              std::ostream & os,
229                                                              ParseCommandInfo const & command)
230     const
231 {
232     fn_(os, command);
233 }
234
235 //-/////////////////////////////////////////////////////////////////////////////////////////////////
236 #undef prefix_
237 //#include "OverloadedCommand.mpp"
238
239 \f
240 // Local Variables:
241 // mode: c++
242 // fill-column: 100
243 // comment-column: 40
244 // c-file-style: "senf"
245 // indent-tabs-mode: nil
246 // ispell-local-dictionary: "american"
247 // compile-command: "scons -u test"
248 // End: