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 
5 Copyright (C) 2009 Ruediger Berndt
6 Copyright (C) 2010, 2023, 2025 Thomas Moor
7 
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12 
13 This library 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 GNU
16 Lesser General Public License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, 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 
29 using namespace faudes;
30 
31 // ******************************************************************
32 // error exit
33 // ******************************************************************
34 
35 void 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 
62 int 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 }
const std::string & Name(void) const
Definition: cfl_types.cpp:565
std::string KeywordAt(int pos) const
Definition: cfl_types.cpp:621
const std::string & PlugIn(void) const
Definition: cfl_types.cpp:566
const std::string & TextDoc(void) const
Definition: cfl_types.cpp:568
const std::string & CType(void) const
Definition: cfl_types.cpp:567
const Signature & Variant(const std::string &rName) const
Iterator End(void) const
static FunctionRegistry * G()
std::map< std::string, FunctionDefinition * >::const_iterator Iterator
Definition: cfl_registry.h:541
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()
bool Exists(const std::string &rName) const
Iterator End(void) const
std::map< std::string, TypeDefinition * >::const_iterator Iterator
Definition: cfl_registry.h:54
void SaveRegistry(const std::string &rPath)
void LoadRegistry(const std::string &rPath)
std::string VersionString()
Definition: cfl_utils.cpp:141
std::string PluginsString()
Definition: cfl_utils.cpp:146
std::string ToStringInteger(Int number)
Definition: cfl_utils.cpp:43
int main(int argc, char *argv[])
Definition: rti2code.cpp:62
void usage(const std::string &rMessage="")
Definition: rti2code.cpp:35

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