Line data Source code
1 : /*
2 : * Copyright (c) 2010-2013: G-CSC, Goethe University Frankfurt
3 : * Author: Martin Rupp
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : /**
34 : * \file class_helper.cpp
35 : *
36 : * \author Martin Rupp
37 : *
38 : * \date 20.10.2010
39 : *
40 : * ClassHierarchy implementation, GetClassHierarchy
41 : *
42 : * Goethe-Center for Scientific Computing 2009-2010.
43 : */
44 :
45 : #include <string>
46 : #include <vector>
47 : #include <algorithm>
48 :
49 : #include "class_helper.h"
50 : #include "registry.h"
51 : #include "common/util/string_util.h"
52 :
53 : using namespace std;
54 :
55 : namespace ug
56 : {
57 : namespace bridge
58 : {
59 : extern Registry& GetUGRegistry();
60 :
61 :
62 0 : void ClassHierarchy::insert_class(const IExportedClass &c)
63 : {
64 :
65 : // get name and visualization options of function
66 : std::vector<std::string> vGroups;
67 0 : TokenizeString(c.group(), vGroups, '/');
68 :
69 : ClassHierarchy *base = this;
70 :
71 0 : for(vector<std::string>::const_iterator it = vGroups.begin(); it != vGroups.end(); ++it)
72 : {
73 0 : const std::string thename = TrimString(*it);
74 0 : if(thename.length() <= 0) continue;
75 : bool bFound = false;
76 0 : for(size_t j=0; j<base->subclasses.size(); j++)
77 : {
78 0 : if(base->subclasses.at(j).name.compare(thename) == 0)
79 : {
80 : base = &base->subclasses.at(j);
81 : bFound = true;
82 : break;
83 : }
84 : }
85 :
86 0 : if(!bFound)
87 : {
88 : ClassHierarchy newclass;
89 : newclass.name = thename;
90 0 : newclass.bGroup = true;
91 0 : base->subclasses.push_back(newclass);
92 : base = &base->subclasses.back();
93 : }
94 : }
95 :
96 0 : const vector<const char *> *pNames = c.class_names();
97 :
98 0 : if(pNames == NULL) return;
99 :
100 0 : for(vector<const char*>::const_reverse_iterator rit = pNames->rbegin(); rit != pNames->rend(); ++rit)
101 : {
102 0 : const char *thename = (*rit);
103 : bool bFound = false;
104 0 : for(size_t j=0; j<base->subclasses.size(); j++)
105 : {
106 0 : if(base->subclasses.at(j).name.compare(thename) == 0)
107 : {
108 : base = &base->subclasses.at(j);
109 : bFound = true;
110 : break;
111 : }
112 : }
113 :
114 0 : if(!bFound)
115 : {
116 : ClassHierarchy newclass;
117 : newclass.name = thename;
118 0 : newclass.bGroup = false;
119 0 : base->subclasses.push_back(newclass);
120 : base = &base->subclasses.back();
121 : }
122 : }
123 0 : }
124 :
125 0 : void ClassHierarchy::sort()
126 : {
127 0 : std::sort(subclasses.begin(), subclasses.end());
128 0 : for(size_t i=0; i<subclasses.size(); i++)
129 0 : subclasses[i].sort();
130 0 : }
131 :
132 0 : ClassHierarchy *ClassHierarchy::find_class(const char *classname)
133 : {
134 0 : if(name.compare(classname) == 0)
135 : return this;
136 0 : for(size_t i=0; i < subclasses.size(); i++)
137 : {
138 0 : ClassHierarchy *c = subclasses[i].find_class(classname);
139 0 : if(c) return c;
140 : }
141 : return NULL;
142 : }
143 :
144 0 : void GetClassHierarchy(ClassHierarchy &hierarchy, const Registry ®)
145 : {
146 : hierarchy.subclasses.clear();
147 0 : hierarchy.name = "UGBase";
148 0 : for(size_t i=0; i<reg.num_classes(); ++i)
149 0 : hierarchy.insert_class(reg.get_class(i));
150 0 : hierarchy.sort();
151 0 : }
152 :
153 :
154 :
155 :
156 :
157 0 : void PrintClassSubHierarchy(ClassHierarchy &c, int level)
158 : {
159 0 : for(int j=0; j<level; j++) UG_LOG(" ");
160 : UG_LOG(c.name << endl);
161 0 : if(c.subclasses.size())
162 : {
163 0 : for(size_t i=0; i<c.subclasses.size(); i++)
164 0 : PrintClassSubHierarchy(c.subclasses[i], level+1);
165 : }
166 0 : }
167 :
168 0 : string ClassHierarchyString(const Registry ®, const char *classname)
169 : {
170 0 : std::stringstream ss;
171 0 : const IExportedClass *c = reg.get_class(classname);
172 0 : if(c == NULL)
173 : {
174 0 : ss << "Class name " << classname << " not found\n";
175 : return ss.str();
176 : }
177 :
178 0 : ss << "\nClass Hierarchy of " << classname << "\n";
179 :
180 : int level = 0;
181 0 : const std::vector<const char*> *names = c->class_names();
182 0 : if(names != NULL && !names->empty())
183 : {
184 0 : for(int i = names->size()-1; i>0; i--)
185 : {
186 0 : for(int j=0; j<level; j++) ss << " ";
187 0 : ss << names->at(i) << endl;
188 0 : level++;
189 : }
190 : }
191 :
192 : ClassHierarchy hierarchy;
193 0 : GetClassHierarchy(hierarchy, reg);
194 0 : ClassHierarchy *ch = hierarchy.find_class(classname);
195 0 : if(ch)
196 0 : PrintClassSubHierarchy(*ch, level);
197 : else
198 : {
199 0 : for(int j=0; j<level; j++) ss << " ";
200 0 : ss << classname;
201 : }
202 :
203 : return ss.str();
204 0 : }
205 :
206 :
207 :
208 : /**
209 : *
210 : * \brief Gets a description of the i-th parameter of a ParameterStack
211 : * todo: perhaps this function would be better somewhere else like in parameter_stack.cpp
212 : */
213 0 : string ParameterToString(const ParameterInfo &par, int i)
214 : {
215 0 : string res = string("");
216 0 : if(par.is_vector(i)) res.append("std::vector<");
217 0 : switch(par.type(i))
218 : {
219 0 : default:
220 : case Variant::VT_INVALID:
221 0 : res.append("unknown");
222 : break;
223 0 : case Variant::VT_BOOL:
224 0 : res.append("bool");
225 : break;
226 0 : case Variant::VT_INT:
227 0 : res.append("integer");
228 : break;
229 0 : case Variant::VT_FLOAT:
230 0 : res.append("number");
231 : break;
232 0 : case Variant::VT_DOUBLE:
233 0 : res.append("number");
234 : break;
235 0 : case Variant::VT_CSTRING:
236 0 : res.append("string");
237 : break;
238 0 : case Variant::VT_STDSTRING:
239 0 : res.append("string");
240 : break;
241 : case Variant::VT_POINTER:
242 0 : res.append(par.class_name(i)).append("*");
243 : break;
244 0 : case Variant::VT_CONST_POINTER:
245 0 : res.append("const ").append(par.class_name(i)).append("*");
246 : break;
247 0 : case Variant::VT_SMART_POINTER:
248 0 : res.append("SmartPtr<").append(par.class_name(i)).append(">");
249 : break;
250 0 : case Variant::VT_CONST_SMART_POINTER:
251 0 : res.append("ConstSmartPtr<").append(par.class_name(i)).append(">");
252 : break;
253 : }
254 0 : if(par.is_vector(i)) res.append(">");
255 0 : return res;
256 : }
257 :
258 : template<typename T>
259 0 : string PrintParametersIn(const T &thefunc, const char*highlightclassname)
260 : {
261 0 : std::stringstream ss;
262 0 : ss << "(";
263 0 : for(size_t i=0; i < (size_t)thefunc.params_in().size(); ++i)
264 : {
265 0 : if(i>0) ss << ", ";
266 : bool b=false;
267 0 : if(highlightclassname != NULL && thefunc.params_in().class_name(i) != NULL &&
268 0 : strcmp(thefunc.params_in().class_name(i), highlightclassname)==0)
269 : b = true;
270 0 : if(b) ss << "[";
271 0 : ss << ParameterToString(thefunc.params_in(), i);
272 0 : if(i < thefunc.num_parameter())
273 0 : if(!thefunc.parameter_name(i).empty())
274 : ss << " " << thefunc.parameter_name(i);
275 0 : if(b) ss << "]";
276 : }
277 0 : ss << ")";
278 0 : return ss.str();
279 0 : }
280 :
281 : //bool PrintParametersIn(const ExportedFunctionBase &thefunc, const char*highlightclassname = NULL);
282 : //bool PrintParametersIn(const ExportedConstructor &thefunc, const char*highlightclassname = NULL);
283 :
284 0 : string PrintParametersOut(const ExportedFunctionBase &thefunc)
285 : {
286 0 : std::stringstream ss;
287 0 : if(thefunc.params_out().size() == 1)
288 : {
289 0 : ss << ParameterToString(thefunc.params_out(), 0);
290 : //file << " " << thefunc.return_name();
291 0 : ss << " ";
292 : }
293 0 : else if(thefunc.params_out().size() > 1)
294 : {
295 0 : ss << "(";
296 0 : for(int i=0; i < thefunc.params_out().size(); ++i)
297 : {
298 0 : if(i>0) ss << ", ";
299 0 : ss << ParameterToString(thefunc.params_out(), i);
300 :
301 : }
302 0 : ss << ") ";
303 : }
304 0 : return ss.str();
305 0 : }
306 :
307 : /**
308 : *
309 : * Prints parameters of the function thefunc.
310 : * If highlightclassname != NULL, it highlights parameters which implement the highlightclassname class.
311 : */
312 0 : string FunctionInfo(const ExportedFunctionBase &thefunc, bool isConst, const char *classname, const char *highlightclassname, bool bPrintHelp)
313 : {
314 0 : std::stringstream ss;
315 0 : ss << PrintParametersOut(thefunc);
316 0 : if(classname)
317 0 : ss << classname << ":";
318 :
319 : ss << thefunc.name();
320 :
321 0 : ss << PrintParametersIn<ExportedFunctionBase>(thefunc, highlightclassname);
322 :
323 0 : if(isConst) ss << " const";
324 0 : if(bPrintHelp)
325 : {
326 0 : if(thefunc.tooltip().length() != 0)
327 : ss << "\n tooltip: " << thefunc.tooltip();
328 0 : if(thefunc.help().length() != 0)
329 : ss << "\n help: " << thefunc.help();
330 : }
331 0 : return ss.str();
332 0 : }
333 :
334 : /**
335 : *
336 : * Prints parameters of the constructor constr.
337 : * If highlightclassname != NULL, it highlights parameters which implement the highlightclassname class.
338 : */
339 0 : string ConstructorInfo(const ExportedConstructor &constr,
340 : const char *classname, const char *highlightclassname)
341 : {
342 0 : UG_LOG(classname << ":" << classname);
343 0 : return PrintParametersIn<ExportedConstructor>(constr, highlightclassname);
344 : }
345 :
346 :
347 0 : const ExportedFunction *FindFunction(const Registry ®, const char *functionname)
348 : {
349 0 : for(size_t i=0; i<reg.num_functions(); i++)
350 : {
351 0 : if(strcmp(functionname, reg.get_function(i).name().c_str()) == 0)
352 0 : return ®.get_function(i);
353 : }
354 : return NULL;
355 : }
356 :
357 : /**
358 : *
359 : * searches for a function named functionname in the registry and prints it
360 : */
361 0 : string FunctionInfo(const Registry ®, const char *functionname)
362 : {
363 0 : const ExportedFunction *f = FindFunction(reg, functionname);
364 0 : if(f)
365 : {
366 0 : return FunctionInfo(*f, false, NULL, NULL, true);
367 : }
368 : else
369 0 : return "";
370 : }
371 :
372 : /**
373 : *
374 : * \brief Prints the (const) method of one class
375 : */
376 0 : string ClassInfo(const IExportedClass &c)
377 : {
378 0 : std::stringstream ss;
379 0 : ss << "class " << c.name() << "\n";
380 0 : if(c.is_instantiable())
381 0 : ss << " has constructor\n";
382 : else
383 0 : ss << " has no constructor\n";
384 0 : ss << " " << c.num_methods() << " method(s):" << endl;
385 :
386 0 : for(size_t k=0; k<c.num_methods(); ++k)
387 : {
388 0 : ss << " - ";
389 0 : ss << FunctionInfo(c.get_method(k), false, NULL, NULL, true);
390 : ss << endl;
391 : }
392 0 : ss << " " << c.num_const_methods() << " const method(s):" << endl;
393 0 : for(size_t k=0; k<c.num_const_methods(); ++k)
394 : {
395 0 : ss << " - ";
396 0 : ss << FunctionInfo(c.get_const_method(k), true);
397 : ss << endl;
398 : }
399 0 : return ss.str();
400 0 : }
401 :
402 :
403 : /**
404 : *
405 : * Searches the classname in the Registry and prints info of the class
406 : */
407 0 : string ClassInfo(const Registry ®, const char *classname)
408 : {
409 : // search registry for that class
410 0 : const IExportedClass *c = reg.get_class(classname);
411 0 : if(c)
412 : {
413 0 : return ClassInfo(*c);
414 : }
415 : else
416 0 : return "";
417 : }
418 :
419 :
420 : /**
421 : *
422 : * \return true, if the class classname is in a parameter in the ParameterStack par
423 : */
424 0 : bool IsClassInParameters(const ParameterInfo &par, const char *classname)
425 : {
426 : int i;
427 0 : for(i=0; i<par.size(); ++i)
428 : {
429 0 : if(par.type(i) != Variant::VT_POINTER && par.type(i) != Variant::VT_CONST_POINTER)
430 0 : continue;
431 0 : if(par.class_name_node(i) != NULL && strcmp(par.class_name(i), classname)==0)
432 : break;
433 : }
434 :
435 0 : if(i==par.size()) return false;
436 0 : else return true;
437 : }
438 :
439 :
440 : /**
441 : *
442 : * \param reg Registry
443 : * \param classname the class (and only this class) to print usage in functions/member functions of.
444 : * \param OutParameters
445 : */
446 0 : string ClassUsageExact(const Registry ®, const char *classname, bool OutParameters)
447 : {
448 0 : std::stringstream ss;
449 : // check functions
450 0 : for(size_t i=0; i<reg.num_functions(); i++)
451 : {
452 0 : const ExportedFunctionBase &thefunc = reg.get_function(i);
453 0 : if((!OutParameters && IsClassInParameters(thefunc.params_in(), classname)) ||
454 0 : (OutParameters && IsClassInParameters(thefunc.params_out(), classname)))
455 : {
456 0 : ss << " " << FunctionInfo(thefunc, false, classname) << endl;
457 : }
458 : }
459 :
460 : // check classes
461 0 : for(size_t i=0; i<reg.num_classes(); i++)
462 : {
463 0 : const IExportedClass &c = reg.get_class(i);
464 0 : for(size_t i=0; i<c.num_methods(); i++)
465 : {
466 0 : const ExportedFunctionBase &thefunc = c.get_method(i);
467 0 : if((!OutParameters && IsClassInParameters(thefunc.params_in(), classname)) ||
468 0 : (OutParameters && IsClassInParameters(thefunc.params_out(), classname)))
469 : {
470 0 : ss << " " << FunctionInfo(thefunc, false, c.name().c_str(), classname) << endl;
471 : }
472 : }
473 :
474 0 : for(size_t i=0; i<c.num_const_methods(); i++)
475 : {
476 0 : const ExportedFunctionBase &thefunc = c.get_const_method(i);
477 0 : if((!OutParameters && IsClassInParameters(thefunc.params_in(), classname)) ||
478 0 : (OutParameters && IsClassInParameters(thefunc.params_out(), classname)))
479 : {
480 0 : ss << " " << FunctionInfo(thefunc, false, c.name().c_str(), classname) << endl;
481 : }
482 : }
483 : }
484 0 : return ss.str();
485 0 : }
486 :
487 :
488 : } // namespace bridge
489 : } // namespace ug
490 :
|