47a08dcef7f68630e056ce2592c94c24129b96c0
[senf.git] / 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 << "    " << index << "- " << name();
84             for (unsigned j (0); j < (*i)->numArguments(); ++j) {
85                 ArgumentDoc arg;
86                 (*i)->argumentDoc(j, arg);
87
88                 os << ' ';
89                 if (! arg.defaultValue.empty())
90                     os << '[';
91                 if (! arg.name.empty()) os << arg.name;
92                 if (! arg.type.empty()) os << ':' << arg.type;
93                 if (arg.name.empty() && arg.type.empty()) os << "...";
94                 if (! arg.defaultValue.empty())
95                     os << ']';
96
97                 if (! arg.name.empty()) {
98                     ArgumentDocs::iterator k (argumentDocs.begin());
99                     ArgumentDocs::iterator const k_end (argumentDocs.end());
100                     for (; k != k_end; ++k)
101                         if (k->name == arg.name && k->defaultValue == arg.defaultValue) {
102                             if (! arg.doc.empty() && k->doc.empty()) {
103                                 k->doc == arg.doc;
104                                 haveDocumentedArg = true;
105                             }
106                             break;
107                         }
108                     if (k == k_end) {
109                         argumentDocs.push_back(arg);
110                         if (! arg.doc.empty())
111                             haveDocumentedArg = true;
112                     }
113                 }
114             }
115             os << '\n';
116         }
117     }
118
119     if (haveDocumentedArg) {
120         os << "\n" "With:\n";
121         ArgumentDocs::const_iterator i (argumentDocs.begin());
122         ArgumentDocs::const_iterator const i_end (argumentDocs.end());
123         for (; i != i_end; ++i) {
124             if (! i->doc.empty()) {
125                 os << "    " 
126                    << i->name 
127                    << std::string(i->name.length()<8 ? 8-i->name.length() : 0, ' ')
128                    << "  "
129                    << i->doc
130                    << '\n';
131                 if (! i->defaultValue.empty())
132                     os << "        default: " << i->defaultValue << '\n';
133             }
134         }
135     }
136     
137     if (! doc_.empty())
138         os << "\n" << doc_ << "\n";
139     
140     {
141         Overloads::const_iterator i (overloads_.begin());
142         Overloads::const_iterator const i_end (overloads_.end());
143         unsigned index (1);
144         for (; i != i_end; ++i, ++index) {
145             std::string overloadDoc ((*i)->doc());
146             if (! overloadDoc.empty())
147                 os << "\n" << "Variant " << index << ":\n"
148                    << overloadDoc << "\n";
149         }
150     }
151 }
152
153 prefix_ void senf::console::OverloadedCommandNode::v_execute(std::ostream & output,
154                                                              ParseCommandInfo const & command)
155     const
156 {
157     Overloads::const_iterator i (overloads_.begin());
158     Overloads::const_iterator const i_end (overloads_.end());
159     SyntaxErrorException err;
160     for (; i != i_end; ++i) {
161         try {
162             (**i)(output, command);
163             return;
164         }
165         catch (SyntaxErrorException & ex) {
166             err = ex;
167         };
168     }
169     throw err;
170 }
171
172 ///////////////////////////////////////////////////////////////////////////
173 // senf::console::SimpleCommandOverload
174
175 prefix_ unsigned senf::console::SimpleCommandOverload::v_numArguments()
176     const
177 {
178     return 1;
179 }
180
181 prefix_ void senf::console::SimpleCommandOverload::v_argumentDoc(unsigned index, ArgumentDoc & doc)
182     const
183 {}
184
185 prefix_ std::string senf::console::SimpleCommandOverload::v_doc()
186     const
187 {
188     return doc_;
189 }
190
191 prefix_ void senf::console::SimpleCommandOverload::v_execute(std::ostream & os,
192                                                              ParseCommandInfo const & command)
193     const
194 {
195     fn_(os, command);
196 }
197
198 ///////////////////////////////cc.e////////////////////////////////////////
199 #undef prefix_
200 //#include "OverloadedCommand.mpp"
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: