rti2code.cpp
Go to the documentation of this file.
1/** rti2code.cpp Utility to generate registry initialisation code from rti files */
2
3/* FAU Discrete Event Systems Library (libfaudes)
4
5Copyright (C) 2009 Ruediger Berndt
6Copyright (C) 2010, 2023, 2025 Thomas Moor
7
8This library is free software; you can redistribute it and/or
9modify it under the terms of the GNU Lesser General Public
10License as published by the Free Software Foundation; either
11version 2.1 of the License, or (at your option) any later version.
12
13This library is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16Lesser General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public
19License along with this library; if not, write to the Free Software
20Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
21
22
23#include <string>
24#include <iostream>
25#include <fstream>
26#include "corefaudes.h"
27
28
29using namespace faudes;
30
31// ******************************************************************
32// error exit
33// ******************************************************************
34
35void usage(const std::string& rMessage="") {
36 // UI hints
37 if(rMessage!="") {
38 std::cerr << rMessage << std::endl;
39 std::cout << "" << std::endl;
40 }
41 std::cerr << "rti2code: " << VersionString() << std::endl;
42 std::cerr << std::endl;
43 std::cerr << "utility to generates c code from an rti-file to " << std::endl;
44 std::cerr << "1) register faudes-types and -functions with the run-time interface," << std::endl;
45 std::cerr << "2) extract c declarations for bindings interface code." << std::endl;
46 std::cerr << std::endl;
47 std::cerr << "usage:" << std::endl;
48 std::cerr << " rti2code [-swig|-loader] <rti input file> <output basename>" << std::endl;
49 std::cerr << " rti2code -merge <rti input files> <output rti-file>" << std::endl;
50 std::cerr << std::endl;
51 std::cerr << "[note: the -loader flag will produce .h/.cpp files to instantiate prototypes" << std::endl;
52 std::cerr << "[note: the -swig flag will produce a .i file for swig include" << std::endl;
53 std::cerr << "[note: the -flat flag circumvents an issue with SWIG pre 4.1.0]" << std::endl;
54 exit(1);
55}
56
57
58// ******************************************************************
59// main programm
60// ******************************************************************
61
62int main(int argc, char *argv[]) {
63
64 // config
65 bool loader=false;
66 bool swig=false;
67 bool flat=false;
68 bool merge=false;
69
70 // primitive command line parser
71 int pos=1;
72 for(; pos<argc; pos++) {
73 std::string option(argv[pos]);
74 // option: help
75 if((option=="-?") || (option=="--help")) {
76 usage();
77 continue;
78 }
79 // option: loader
80 if(option=="-loader") {
81 loader=true;
82 continue;
83 }
84 // option: swig
85 if(option=="-swig") {
86 swig=true;
87 continue;
88 }
89 // option: flat
90 if(option=="-flat") {
91 flat=true;
92 continue;
93 }
94 // option: merge
95 if(option=="-merge") {
96 merge=true;
97 continue;
98 }
99 // option: unknown
100 if(option.c_str()[0]=='-') {
101 usage("unknown option "+ option);
102 continue;
103 }
104 // break for args
105 break;
106 }
107
108 // mode test
109 if(merge && (loader || swig)) {
110 usage("mismatching options: either merge or code generation");
111 }
112 if(!merge && !(loader || swig)) {
113 usage("mismatching options: either merge or code generation");
114 }
115 if(flat && !swig) {
116 usage("mismatching options: flat is only applicable to swig");
117 }
118 if(merge && (argc-pos <2)) {
119 usage("mismatching agruments: to few files to merge");
120 }
121 if(!merge && (argc-pos !=2)) {
122 usage("mismatching agruments: need one source and one destination for code generation");
123 }
124
125 // Merge mode -- get this done first
126 if(merge) {
127 // Load from files
128 for(; pos< argc-1; pos++) {
129 TypeRegistry::G()->MergeDocumentation(std::string(argv[pos]));
130 FunctionRegistry::G()->MergeDocumentation(std::string(argv[pos]));
131 }
132 // Dump
133 if(std::string(argv[argc-1]) != "-") {
134 SaveRegistry(std::string(argv[argc-1]));
135 } else {
136 SaveRegistry();
137 }
138 return 0;
139 }
140
141 // code-gen modes loader/swig
142 LoadRegistry(argv[pos++]);
143
144 // Code output streams
145 std::ofstream rtiheader;
146 std::ofstream rticode;
147 std::ofstream swigheader;
148 if(loader) {
149 rtiheader.open((std::string(argv[pos])+".h").c_str(), std::ios::out);
150 rticode.open((std::string(argv[pos])+".cpp").c_str(), std::ios::out);
151 }
152 if(swig){
153 swigheader.open((std::string(argv[pos])+".i").c_str(), std::ios::out);
154 }
155
156 // Introduce myself
157 if(loader) {
158 rtiheader << "/* rti2code: autogenerated libFAUDES rti registration: ";
159 rtiheader << VersionString() << " " << PluginsString() << " */" << std::endl << std::endl;
160 rticode << "/* rti2code: autogenerated libFAUDES rti registration: ";
161 rticode << VersionString() << " " << PluginsString() << " */" << std::endl << std::endl;
162 }
163 if(swig) {
164 swigheader << "/* rti2code: autogenerated libFAUDES swig bindings declarations: ";
165 swigheader << VersionString() << " " << PluginsString() << " */" << std::endl << std::endl;
166 }
167
168 // C++ static objects: auto load types
169 if(loader) {
170 rticode << "namespace faudes {" << std::endl;
171 rticode << "/* Auto-register faudes types */" << std::endl;
172 }
173
174 // Traverse type registry to figure faudes types
175 if(loader) {
177 int tcnt;
178 for(tit=TypeRegistry::G()->Begin(), tcnt=1; tit!=TypeRegistry::G()->End();tit++,tcnt++) {
179 // Get c/f type
180 std::string ctype=tit->second->CType();
181 std::string ftype=tit->second->Name();
182 // Bail out if no C type specified
183 if(ctype=="") continue;
184 // Remove name space faudes
185 size_t pos=ctype.find("faudes::");
186 if(pos!=std::string::npos)
187 ctype=ctype.substr(std::string("faudes::").length());
188 // Bail out no auto-registration specified
189 if(!tit->second->AutoRegistered()) continue;
190 // report
191 std::cout << "rti2code: generating auto-registration code for \"" << ftype << "\"" << std::endl;
192 // Produce c code
193 std::string rtiname = std::string("gRti") + ToStringInteger(tcnt) + "Register" + ftype;
194 rticode << "AutoRegisterType<" << ctype << "> " << rtiname << "(\"" << ftype <<"\");";
195 rticode << std::endl;
196 // Extra data set: element tag
197 if(tit->second->ElementTag()!="") {
198 rtiname = std::string("gRti") + ToStringInteger(tcnt) + "ElementTag" + ftype;
199 rticode << "AutoRegisterElementTag<" << ctype << "> " << rtiname << "(\"" << ftype <<
200 "\", \"" << tit->second->ElementTag() << "\");";
201 rticode << std::endl;
202 }
203 // Extra data set: element tag
204 if(tit->second->ElementType()!="") {
205 rtiname = std::string("gRti") + ToStringInteger(tcnt) + "ElementType" + ftype;
206 rticode << "AutoRegisterElementType<" << ctype << "> " << rtiname << "(\"" << ftype <<
207 "\", \"" << tit->second->ElementType() << "\");";
208 rticode << std::endl;
209 }
210 }
211 }
212
213 // C++ static objects: auto load types end
214 if(loader) {
215 rticode << "} // namespace" << std::endl;
216 }
217
218 // C++ function declaration: load types
219 if(loader) {
220 rtiheader << "namespace faudes {" << std::endl;
221 rtiheader << "void LoadRegisteredTypes(void);" << std::endl;
222 rtiheader << "} // namespace" << std::endl;
223 }
224
225 // C++ function definition: load types
226 if(loader) {
227 rticode << "namespace faudes {" << std::endl;
228 rticode << "/* Register faudes types */" << std::endl;
229 rticode << "void LoadRegisteredTypes(void) {" << std::endl;
230 }
231
232 // Traverse type registry to figure faudes types
233 if(loader) {
235 for(tit=TypeRegistry::G()->Begin(); tit!=TypeRegistry::G()->End();tit++) {
236 // Get C type
237 std::string ctype=tit->second->CType();
238 // Bail out if no c type specified
239 if(ctype=="") continue;
240 // Remove name space faudes
241 size_t pos=ctype.find("faudes::");
242 if(pos!=std::string::npos)
243 ctype=ctype.substr(std::string("faudes::").length());
244 // Report
245 std::cout << "rti2code: generating registration code for \"" << tit->second->Name() << "\"" << std::endl;
246 // Produce c code
247 rticode << " TypeRegistry::G()->Insert<" << ctype << ">(\"" << tit->second->Name() <<"\");";
248 rticode << std::endl;
249 }
250 }
251
252 // C++ function definition: load types end
253 if(loader) {
254 rticode << "}" << std::endl;
255 rticode << "} // namespace" << std::endl;
256 }
257
258
259 // C++ function declaration: load functions
260 if(loader) {
261 rtiheader << "namespace faudes {" << std::endl;
262 rtiheader << "void LoadRegisteredFunctions(void);" << std::endl;
263 rtiheader << "} // namespace" << std::endl;
264 }
265
266 // C++ function definition: load functions
267 if(loader) {
268 rticode << "namespace faudes {" << std::endl;
269 rticode << "/* Register faudes functions */" << std::endl;
270 rticode << "void LoadRegisteredFunctions(void) {" << std::endl;
271 }
272
273 // C++ class definition: Function derivates
274 if(loader) {
275 rtiheader << "namespace faudes {" << std::endl;
276 }
277
278 // Traverse function registry: define rti functions
279 int fcnt=0;
281 for(fit=FunctionRegistry::G()->Begin(); fit!=FunctionRegistry::G()->End();fit++, fcnt++) {
282 // Current function definition
283 const FunctionDefinition* fdef = fit->second;
284 // Get C type and faudes function name
285 std::string ctype=fdef->CType();
286 std::string fname = fdef->Name();
287 // Bail out if no c type specified
288 if(ctype=="") continue;
289 // Remove name space faudes
290 size_t pos=ctype.find("faudes::");
291 if(pos!=std::string::npos)
292 ctype=ctype.substr(std::string("faudes::").length());
293 // Bail out if no signature
294 if(fdef->VariantsSize()==0) {
295 std::cout << "rti2cocde: function registration: " << fname << ": no signatures" << std::endl;
296 continue;
297 }
298 // Interpret signatures: set up type array
299 std::vector< std::vector<std::string> > cparams;
300 std::vector< std::vector<Parameter::ParamAttr> > cattrib;
301 std::vector< std::vector<bool> > cretval;
302 cparams.resize(fdef->VariantsSize());
303 cattrib.resize(fdef->VariantsSize());
304 cretval.resize(fdef->VariantsSize());
305 // Loop all signatures
306 for(int i=0; i<fdef->VariantsSize(); i++) {
307 const Signature& sigi=fdef->Variant(i);
308 int retcount=0;
309 for(int j=0; j<sigi.Size(); j++) {
310 // Retrieve faudes type and attrib
311 std::string ftype=sigi.At(j).Type();
312 Parameter::ParamAttr fattr=sigi.At(j).Attribute();
313 bool fcret=sigi.At(j).CReturn();
314 // Count ret values
315 if(fcret) retcount++;
316 // Bail out on unknown faudestype
317 if(!TypeRegistry::G()->Exists(ftype)) break;
318 // Get corresponding ctype
319 std::string ctype=TypeRegistry::G()->Definition(ftype).CType();
320 // Bail out on unknown ctype
321 if(ctype=="") break;
322 // bail out on non-out ret value
323 if(fcret && !(fattr==Parameter::Out)) break;
324 // Bail out on undef attribute
325 if(fattr==Parameter::UnDef) break;
326 // Bail out on more than one ret values
327 if(retcount>1) break;
328 // Remove name space faudes
329 size_t pos=ctype.find("faudes::");
330 if(pos!=std::string::npos)
331 ctype=ctype.substr(std::string("faudes::").length());
332 // Param ok
333 cparams.at(i).push_back(ctype);
334 cattrib.at(i).push_back(fattr);
335 cretval.at(i).push_back(fcret);
336 }
337 // Test for signature error
338 if((int) cparams.at(i).size()!=sigi.Size()) {
339 std::cout << "rti2code: function registration: " << fname << ": cannot interpret signature "
340 << sigi.Name() << std::endl;
341 cparams.resize(i);
342 break;
343 }
344 }
345 // Report
346 std::cout << "rti2code: generating rti wrapper for \"" << fdef->Name() << "\"" <<
347 " #" << cparams.size() << " variants" << std::endl;
348 std::string rtiname = std::string("Rti") + ToStringInteger(fcnt) + ctype;
349 // Produce c code: register all functions function
350 if(loader) {
351 rticode << " FunctionRegistry::G()->Insert<" << rtiname << ">(\"" << fname <<"\");" << std::endl;
352 }
353 // Produce c code: class declaration intro
354 if(loader) {
355 rtiheader << "/* Function class for C++ function " << ctype << "*/" << std::endl;
356 rtiheader << "class " << rtiname << " : public Function { " << std::endl;
357 rtiheader << "public:" << std::endl;
358 rtiheader << " using Function::operator=;" << std::endl;
359 rtiheader << rtiname << "(const FunctionDefinition* fdef) : Function(fdef) {};" << std::endl;
360 rtiheader << "virtual Function* New(void) const { return new " << rtiname << "(pFuncDef); };" << std::endl;
361 rtiheader << "protected:" << std::endl;
362 }
363 // Produce c code: function class: have typed param
364 if(loader) {
365 for(unsigned int i=0; i<cparams.size(); i++)
366 for(unsigned int j=0; j<cparams.at(i).size(); j++)
367 rtiheader << cparams.at(i).at(j) << "* " << "mP_" << i << "_" << j << ";" << std::endl;
368 }
369 // Produce c code: function class: do type check
370 if(loader) {
371 rtiheader << "virtual bool DoTypeCheck(int n) {" << std::endl;
372 rtiheader << " bool res=false;" << std::endl;
373 rtiheader << " switch(mVariantIndex) { "<< std::endl;
374 for(unsigned int i=0; i<cparams.size(); i++) {
375 rtiheader << " case " << i << ": { // variant " << fdef->Variant(i).Name() << std::endl;
376 rtiheader << " switch(n) { "<< std::endl;
377 for(unsigned int j=0; j<cparams.at(i).size(); j++) {
378 rtiheader << " case " << j << ": ";
379 rtiheader << " res=DoTypeCast<" << cparams.at(i).at(j) << ">(" << j << ", mP_" << i <<"_" << j << "); ";
380 rtiheader << "break; "<< std::endl;
381 }
382 rtiheader << " default: break; " << std::endl;
383 rtiheader << " } "<< std::endl;
384 rtiheader << " break; "<< std::endl;
385 rtiheader << " } "<< std::endl;
386 }
387 rtiheader << " default: break; " << std::endl;
388 rtiheader << " } "<< std::endl;
389 rtiheader << " return res;" << std::endl;
390 rtiheader << "};" << std::endl;
391 }
392 // Produce c code: function class: do execute
393 if(loader) {
394 rtiheader << "virtual void DoExecute(void) {" << std::endl;
395 }
396 // Produce c code: do execute: switch variant
397 if(loader) {
398 rtiheader << " switch(mVariantIndex) { "<< std::endl;
399 for(unsigned int i=0; i<cparams.size(); i++) {
400 rtiheader << " case " << i << ": { // variant " << fdef->Variant(i).Name() << std::endl;
401 rtiheader << " ";
402 // Figure return value (if any)
403 for(unsigned int j=0; j<cparams.at(i).size(); j++) {
404 if(!cretval.at(i).at(j)) continue;
405 // Special case: integer
406 if(cparams.at(i).at(j) == "Integer") {
407 rtiheader << "*(mP_" << i << "_" << j << "->CReference()) = ";
408 } else
409 // Special case: boolean
410 if(cparams.at(i).at(j) == "Boolean") {
411 rtiheader << "*(mP_" << i << "_" << j << "->CReference()) = ";
412 } else
413 // Special case: integer
414 if(cparams.at(i).at(j) == "String") {
415 rtiheader << "*(mP_" << i << "_" << j << "->CReference()) = ";
416 } else
417 // Std case
418 rtiheader << "*mP_" << i << "_" << j << " = ";
419 }
420 // Function name
421 rtiheader << ctype <<"(";
422 // Parameters
423 int parpos=0;
424 for(unsigned int j=0; j<cparams.at(i).size(); j++) {
425 if(cretval.at(i).at(j)) continue;
426 if((parpos++)!=0) rtiheader << " ,";
427 // Special case: integer
428 if(cparams.at(i).at(j) == "Integer") {
429 rtiheader << "*(mP_" << i << "_" << j << "->CReference())";
430 } else
431 // Special case: boolean
432 if(cparams.at(i).at(j) == "Boolean") {
433 rtiheader << "*(mP_" << i << "_" << j << "->CReference())";
434 } else
435 // Special case: integer
436 if(cparams.at(i).at(j) == "String") {
437 rtiheader << "*(mP_" << i << "_" << j << "->CReference())";
438 } else
439 // Std case
440 rtiheader << "*mP_" << i << "_" << j;
441 }
442 rtiheader << "); break; };" << std::endl;
443 }
444 // Produce c code: switch variant; done
445 rtiheader << " default: break; " << std::endl;
446 rtiheader << " }; "<< std::endl;
447 // Produce c code: do execute: done
448 rtiheader << "}; "<< std::endl;
449 // Produce c code: function class: done
450 rtiheader << "};" << std::endl;
451 }
452
453 // Produce swig code: function definition(s)
454 if(swig) {
455 swigheader << "/* faudes-function \"" << fname << "\" */" << std::endl;
456 }
457 // Figure my plugin to insert a conditional
458 if(swig) {
459 if(!flat) {
460 std::string plugin=fdef->PlugIn();
461 swigheader << "#if " << "( SwigModule == \"Swig" << plugin << "\")";
462 //luaheader << " || ( SwigModule == \"SwigLibFaudes\")"; // requires SWIG 4.1
463 swigheader << std::endl;
464 }
465 }
466 // Use C-type function name
467 if(swig) {
468 if(ctype!=fname)
469 swigheader << "%rename(" << fname << ") " << ctype << ";" << std::endl;
470 }
471
472 // Prepare swig code: preprocessed array
473 if(swig) {
474 std::vector< std::string > lfdefs;
475 std::vector< std::string > lrtypes;
476 std::vector< std::string > lhelp;
477 // Prepare swig code: generate per signature
478 for(unsigned int i=0; i<cparams.size(); i++) {
479 // Create ctype function declaration: return value
480 std::string lrtype="void";
481 for(unsigned int j=0; j<cparams.at(i).size(); j++) {
482 if(!cretval.at(i).at(j)) continue;
483 // Special case: integer
484 if(cparams.at(i).at(j) == "Integer") {
485 lrtype="long int";
486 } else
487 // Special case: boolean
488 if(cparams.at(i).at(j) == "Boolean") {
489 lrtype="bool";
490 } else
491 // Special case: string
492 if(cparams.at(i).at(j) == "String") {
493 lrtype="std::string";
494 } else
495 // Std case ctype as refernce
496 lrtype = cparams.at(i).at(j);
497 // No more than one return value
498 break;
499 }
500 lrtypes.push_back(lrtype);
501 // Create ctype function declaration: function body
502 std::string lfdef = ctype + "(";
503 // Create ctype function declaration: parameters
504 int parpos=0;
505 for(unsigned int j=0; j<cparams.at(i).size(); j++) {
506 if(cretval.at(i).at(j)) continue;
507 if((parpos++)!=0) lfdef += ", ";
508 // Have const for +In+
509 if(cattrib.at(i).at(j)==Parameter::In)
510 lfdef += "const ";
511 // Special case: integer
512 if(cparams.at(i).at(j) == "Integer") {
513 lfdef += "long int&";
514 } else
515 // Special case: boolean
516 if(cparams.at(i).at(j) == "Boolean") {
517 lfdef += "bool&";
518 } else
519 // Special case: string
520 if(cparams.at(i).at(j) == "String") {
521 lfdef += "std::string&";
522 } else
523 // Std case ctype as refernce
524 lfdef += cparams.at(i).at(j) + "&";
525 // Mark elementary outputs
526 if(cparams.at(i).at(j) == "Boolean" || cparams.at(i).at(j) == "String"
527 || cparams.at(i).at(j) == "Integer")
528 if(cattrib.at(i).at(j)==Parameter::Out)
529 lfdef += " OUTPUT";
530 }
531 // End of function declaration
532 lfdef += ")";
533 lfdefs.push_back(lfdef);
534 // Add help entry: build nice signature
535 std::string luasig = " " + fname + "(";
536 bool leftcomma = false;
537 bool rightcomma = false;
538 for(unsigned int j=0; j<cparams.at(i).size(); j++) {
539 // Special case: elementary output
540 if(cparams.at(i).at(j) == "Boolean" || cparams.at(i).at(j) == "String"
541 || cparams.at(i).at(j) == "Integer")
542 if(cattrib.at(i).at(j)==Parameter::Out) {
543 if(leftcomma) luasig = "," + luasig;
544 // if(leftcomma) luasig = ", " + luasig; // need tab in help system?
545 luasig=cparams.at(i).at(j) + luasig;
546 leftcomma=true;
547 continue;
548 }
549 // Std case
550 if(rightcomma) luasig += ", ";
551 const Signature& sigi=fdef->Variant(i);
552 luasig += sigi.At(j).Str();
553 rightcomma=true;
554 }
555 luasig+=")";
556 // Add help entry: add with topic
557 if(fdef->TextDoc()!=""){
558 std::string topic= fdef->PlugIn();
559 std::string key1=fdef->KeywordAt(1);
560 if(topic=="CoreFaudes") {
561 topic=fdef->KeywordAt(1);
562 key1=fdef->KeywordAt(2);
563 }
564 if(topic.length()>0) topic.at(0)=toupper(topic.at(0));
565 if(key1.length()>0) key1.at(0)=toupper(key1.at(0));
566 lhelp.push_back("SwigHelpEntry(\"" + topic + "\", \"" + key1 + "\", \"" +
567 luasig + "\")");
568 } else {
569 lhelp.push_back("");
570 }
571 }
572 // Filter pseudo doublets (only differ in lrtype)
573 for(unsigned int i=1; i<lfdefs.size();i++) {
574 unsigned int j;
575 for(j=0; j<i; j++)
576 if(lfdefs.at(i)==lfdefs.at(j)) break;
577 if(j==i) continue;
578 // Invalidate entry?
579 if(lrtypes.at(j)=="void")
580 {lfdefs[j]=""; continue;}
581 if(lrtypes.at(i)=="void")
582 {lfdefs[i]=""; continue;}
583 } // Done: prepare per signature
584
585 // Generate swig definitions: write
586 int lcount=0;
587 for(unsigned int i=0; i<lfdefs.size(); i++) {
588 if(lfdefs.at(i)=="") continue;
589 swigheader << lrtypes.at(i) << " " << lfdefs.at(i) << ";" << std::endl;
590 lcount++;
591 if(lhelp.at(i)=="") continue;
592 swigheader << lhelp.at(i) << ";" << std::endl;
593 }
594 std::cout << "rti2code: generating swig interface for function \"" << fdef->Name() << "\"" <<
595 " #" << lcount << " variants" << std::endl;
596
597 // End all signatures, incl conditional
598 if(!flat) {
599 swigheader << "#endif " << std::endl;
600 }
601 swigheader << std::endl;
602 } // endif swig
603
604
605 } // loop all functions
606
607 // C++ class definition: function class: all such done
608 if(loader) {
609 rtiheader << "} // namespace" << std::endl;
610 }
611
612 // C++ class definition: register function prototypes: done
613 if(loader) {
614 rticode << "}" << std::endl;
615 rticode << "} // namespace" << std::endl;
616 }
617
618 return(0);
619}
int main()
const std::string & Name(void) const
std::string KeywordAt(int pos) const
const std::string & PlugIn(void) const
const std::string & TextDoc(void) const
const std::string & CType(void) const
const Signature & Variant(const std::string &rName) const
Iterator End(void) const
static FunctionRegistry * G()
std::map< std::string, FunctionDefinition * >::const_iterator Iterator
void MergeDocumentation(TokenReader &rTr)
Iterator Begin(void) const
std::string Str(void) const
bool CReturn(void) const
const std::string & Type(void) const
const ParamAttr & Attribute(void) const
int Size(void) const
const std::string & Name(void) const
const Parameter & At(int n) const
void MergeDocumentation(TokenReader &rTr)
const TypeDefinition & Definition(const std::string &rTypeName) const
static TypeRegistry * G()
std::map< std::string, TypeDefinition * >::const_iterator Iterator
bool Exists(const std::string &rName) const
Iterator End(void) const
void SaveRegistry(const std::string &rPath)
void LoadRegistry(const std::string &rPath)
std::string VersionString()
std::string PluginsString()
std::string ToStringInteger(Int number)
Definition cfl_utils.cpp:43
void usage(const std::string &rMessage="")
Definition rti2code.cpp:35

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen