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