35 void Usage(
const std::string& rMessage=
"") {
38 std::cerr << rMessage << std::endl;
39 std::cout <<
"" << 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 [-flat] <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 -flat option circumvents an issue with SWIG pre 4.1.0]" << std::endl;
60 int main(
int argc,
char *argv[]) {
66 if(std::string(argv[1])==
"-merge") {
70 for(
int i=2; i< argc-1; i++) {
75 if(std::string(argv[argc-1]) !=
"-") {
85 if(std::string(argv[1])==
"-flat") flat=
true;
86 if(flat && argc != 4)
Usage();
87 if(!flat && argc != 3)
Usage();
93 std::ofstream rtiheader;
94 rtiheader.open((std::string(argv[argc-1])+
".h").c_str(), std::ios::out);
95 std::ofstream rticode;
96 rticode.open((std::string(argv[argc-1])+
".cpp").c_str(), std::ios::out);
97 std::ofstream luaheader;
98 luaheader.open((std::string(argv[argc-1])+
".i").c_str(), std::ios::out);
101 rtiheader <<
"/* rti2code: autogenerated libFAUDES rti registration: ";
103 rticode <<
"/* rti2code: autogenerated libFAUDES rti registration: ";
105 luaheader <<
"/* rti2code: autogenerated libFAUDES swig bindings declarations: ";
109 rticode <<
"namespace faudes {" << std::endl;
110 rticode <<
"/* Auto-register faudes types */" << std::endl;
117 std::string ctype=tit->second->CType();
118 std::string ftype=tit->second->Name();
120 if(ctype==
"")
continue;
122 size_t pos=ctype.find(
"faudes::");
123 if(pos!=std::string::npos)
124 ctype=ctype.substr(std::string(
"faudes::").length());
126 if(!tit->second->AutoRegistered())
continue;
128 std::cout <<
"Generating auto-registration code for \"" << ftype <<
"\"" << std::endl;
130 std::string rtiname = std::string(
"gRti") +
ToStringInteger(tcnt) +
"Register" + ftype;
131 rticode <<
"AutoRegisterType<" << ctype <<
"> " << rtiname <<
"(\"" << ftype <<
"\");";
132 rticode << std::endl;
134 if(tit->second->XElementTag()!=
"") {
135 rtiname = std::string(
"gRti") +
ToStringInteger(tcnt) +
"XElementTag" + ftype;
136 rticode <<
"AutoRegisterXElementTag<" << ctype <<
"> " << rtiname <<
"(\"" << ftype <<
137 "\", \"" << tit->second->XElementTag() <<
"\");";
138 rticode << std::endl;
143 rticode <<
"} // namespace" << std::endl;
146 rtiheader <<
"namespace faudes {" << std::endl;
147 rtiheader <<
"void LoadRegisteredTypes(void);" << std::endl;
148 rtiheader <<
"} // namespace" << std::endl;
151 rticode <<
"namespace faudes {" << std::endl;
152 rticode <<
"/* Register faudes types */" << std::endl;
153 rticode <<
"void LoadRegisteredTypes(void) {" << std::endl;
158 std::string ctype=tit->second->CType();
160 if(ctype==
"")
continue;
162 size_t pos=ctype.find(
"faudes::");
163 if(pos!=std::string::npos)
164 ctype=ctype.substr(std::string(
"faudes::").length());
166 std::cout <<
"Generating registration code for \"" << tit->second->Name() <<
"\"" << std::endl;
168 rticode <<
" TypeRegistry::G()->Insert<" << ctype <<
">(\"" << tit->second->Name() <<
"\");";
169 rticode << std::endl;
173 rticode <<
"}" << std::endl;
174 rticode <<
"} // namespace" << std::endl;
178 rtiheader <<
"namespace faudes {" << std::endl;
179 rtiheader <<
"void LoadRegisteredFunctions(void);" << std::endl;
180 rtiheader <<
"} // namespace" << std::endl;
183 rticode <<
"namespace faudes {" << std::endl;
184 rticode <<
"/* Register faudes functions */" << std::endl;
185 rticode <<
"void LoadRegisteredFunctions(void) {" << std::endl;
188 rtiheader <<
"namespace faudes {" << std::endl;
197 std::string ctype=fdef->
CType();
198 std::string fname = fdef->
Name();
200 if(ctype==
"")
continue;
202 size_t pos=ctype.find(
"faudes::");
203 if(pos!=std::string::npos)
204 ctype=ctype.substr(std::string(
"faudes::").length());
207 std::cout <<
"Function registration: " << fname <<
": no signatures" << std::endl;
211 std::vector< std::vector<std::string> > cparams;
212 std::vector< std::vector<Parameter::ParamAttr> > cattrib;
213 std::vector< std::vector<bool> > cretval;
221 for(
int j=0; j<sigi.
Size(); j++) {
223 std::string ftype=sigi.
At(j).
Type();
227 if(fcret) retcount++;
239 if(retcount>1)
break;
241 size_t pos=ctype.find(
"faudes::");
242 if(pos!=std::string::npos)
243 ctype=ctype.substr(std::string(
"faudes::").length());
245 cparams.at(i).push_back(ctype);
246 cattrib.at(i).push_back(fattr);
247 cretval.at(i).push_back(fcret);
250 if((
int) cparams.at(i).size()!=sigi.
Size()) {
251 std::cout <<
"Function registration: " << fname <<
": cannot interpret signature "
252 << sigi.
Name() << std::endl;
258 std::cout <<
"Generating rti wrapper for \"" << fdef->
Name() <<
"\"" <<
259 " #" << cparams.size() <<
" variants" << std::endl;
261 std::string rtiname = std::string(
"Rti") +
ToStringInteger(fcnt) + ctype;
262 rticode <<
" FunctionRegistry::G()->Insert<" << rtiname <<
">(\"" << fname <<
"\");" << std::endl;
264 rtiheader <<
"/* Function class for C++ function " << ctype <<
"*/" << std::endl;
265 rtiheader <<
"class " << rtiname <<
" : public Function { " << std::endl;
266 rtiheader <<
"public:" << std::endl;
267 rtiheader << rtiname <<
"(const FunctionDefinition* fdef) : Function(fdef) {};" << std::endl;
268 rtiheader <<
"virtual Function* New(void) const { return new " << rtiname <<
"(pFuncDef); };" << std::endl;
269 rtiheader <<
"protected:" << std::endl;
271 for(
unsigned int i=0; i<cparams.size(); i++)
272 for(
unsigned int j=0; j<cparams.at(i).size(); j++)
273 rtiheader << cparams.at(i).at(j) <<
"* " <<
"mP_" << i <<
"_" << j <<
";" << std::endl;
275 rtiheader <<
"virtual bool DoTypeCheck(int n) {" << std::endl;
276 rtiheader <<
" bool res=false;" << std::endl;
277 rtiheader <<
" switch(mVariantIndex) { "<< std::endl;
278 for(
unsigned int i=0; i<cparams.size(); i++) {
279 rtiheader <<
" case " << i <<
": { // variant " << fdef->
Variant(i).
Name() << std::endl;
280 rtiheader <<
" switch(n) { "<< std::endl;
281 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
282 rtiheader <<
" case " << j <<
": ";
283 rtiheader <<
" res=DoTypeCast<" << cparams.at(i).at(j) <<
">(" << j <<
", mP_" << i <<
"_" << j <<
"); ";
284 rtiheader <<
"break; "<< std::endl;
286 rtiheader <<
" default: break; " << std::endl;
287 rtiheader <<
" } "<< std::endl;
288 rtiheader <<
" break; "<< std::endl;
289 rtiheader <<
" } "<< std::endl;
291 rtiheader <<
" default: break; " << std::endl;
292 rtiheader <<
" } "<< std::endl;
293 rtiheader <<
" return res;" << std::endl;
294 rtiheader <<
"};" << std::endl;
296 rtiheader <<
"virtual void DoExecute(void) {" << std::endl;
298 rtiheader <<
" switch(mVariantIndex) { "<< std::endl;
299 for(
unsigned int i=0; i<cparams.size(); i++) {
300 rtiheader <<
" case " << i <<
": { // variant " << fdef->
Variant(i).
Name() << std::endl;
303 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
304 if(!cretval.at(i).at(j))
continue;
306 if(cparams.at(i).at(j) ==
"Integer") {
307 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
310 if(cparams.at(i).at(j) ==
"Boolean") {
311 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
314 if(cparams.at(i).at(j) ==
"String") {
315 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
318 rtiheader <<
"*mP_" << i <<
"_" << j <<
" = ";
321 rtiheader << ctype <<
"(";
324 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
325 if(cretval.at(i).at(j))
continue;
326 if((parpos++)!=0) rtiheader <<
" ,";
328 if(cparams.at(i).at(j) ==
"Integer") {
329 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
332 if(cparams.at(i).at(j) ==
"Boolean") {
333 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
336 if(cparams.at(i).at(j) ==
"String") {
337 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
340 rtiheader <<
"*mP_" << i <<
"_" << j;
342 rtiheader <<
"); break; };" << std::endl;
345 rtiheader <<
" default: break; " << std::endl;
346 rtiheader <<
" }; "<< std::endl;
348 rtiheader <<
"}; "<< std::endl;
350 rtiheader <<
"};" << std::endl;
353 luaheader <<
"/* faudes-function \"" << fname <<
"\" */" << std::endl;
356 std::string plugin=fdef->
PlugIn();
357 luaheader <<
"#if " <<
"( SwigModule == \"Swig" << plugin <<
"\")";
359 luaheader << std::endl;
363 luaheader <<
"%rename(" << fname <<
") " << ctype <<
";" << std::endl;
366 std::vector< std::string > lfdefs;
367 std::vector< std::string > lrtypes;
368 std::vector< std::string > lhelp;
370 for(
unsigned int i=0; i<cparams.size(); i++) {
372 std::string lrtype=
"void";
373 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
374 if(!cretval.at(i).at(j))
continue;
376 if(cparams.at(i).at(j) ==
"Integer") {
380 if(cparams.at(i).at(j) ==
"Boolean") {
384 if(cparams.at(i).at(j) ==
"String") {
385 lrtype=
"std::string";
388 lrtype + cparams.at(i).at(j);
392 lrtypes.push_back(lrtype);
394 std::string lfdef = ctype +
"(";
397 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
398 if(cretval.at(i).at(j))
continue;
399 if((parpos++)!=0) lfdef +=
", ";
404 if(cparams.at(i).at(j) ==
"Integer") {
405 lfdef +=
"long int&";
408 if(cparams.at(i).at(j) ==
"Boolean") {
412 if(cparams.at(i).at(j) ==
"String") {
413 lfdef +=
"std::string&";
416 lfdef += cparams.at(i).at(j) +
"&";
418 if(cparams.at(i).at(j) ==
"Boolean" || cparams.at(i).at(j) ==
"String"
419 || cparams.at(i).at(j) ==
"Integer")
425 lfdefs.push_back(lfdef);
427 std::string luasig =
" " + fname +
"(";
428 bool leftcomma =
false;
429 bool rightcomma =
false;
430 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
432 if(cparams.at(i).at(j) ==
"Boolean" || cparams.at(i).at(j) ==
"String"
433 || cparams.at(i).at(j) ==
"Integer")
435 if(leftcomma) luasig =
"," + luasig;
437 luasig=cparams.at(i).at(j) + luasig;
442 if(rightcomma) luasig +=
", ";
444 luasig += sigi.
At(j).
Str();
450 std::string topic= fdef->
PlugIn();
452 if(topic==
"CoreFaudes") {
456 if(topic.length()>0) topic.at(0)=toupper(topic.at(0));
457 if(key1.length()>0) key1.at(0)=toupper(key1.at(0));
458 lhelp.push_back(
"SwigHelpEntry(\"" + topic +
"\", \"" + key1 +
"\", \"" +
465 for(
unsigned int i=1; i<lfdefs.size();i++) {
468 if(lfdefs.at(i)==lfdefs.at(j))
break;
471 if(lrtypes.at(j)==
"void")
472 {lfdefs[j]=
"";
continue;}
473 if(lrtypes.at(i)==
"void")
474 {lfdefs[i]=
"";
continue;}
479 for(
unsigned int i=0; i<lfdefs.size(); i++) {
480 if(lfdefs.at(i)==
"")
continue;
481 luaheader << lrtypes.at(i) <<
" " << lfdefs.at(i) <<
";" << std::endl;
483 if(lhelp.at(i)==
"")
continue;
484 luaheader << lhelp.at(i) <<
";" << std::endl;
486 std::cout <<
"Generating swig interface for function \"" << fdef->
Name() <<
"\"" <<
487 " #" << lcount <<
" variants" << std::endl;
491 luaheader <<
"#endif " << std::endl;
493 luaheader << std::endl;
499 rtiheader <<
"} // namespace" << std::endl;
502 rticode <<
"}" << std::endl;
503 rticode <<
"} // namespace" << std::endl;
const std::string & Name(void) const
Get name of the entety to document (aka faudes-type or faudes-function).
std::string KeywordAt(int pos) const
const std::string & PlugIn(void) const
Get name of plugin.
const std::string & TextDoc(void) const
const std::string & CType(void) const
Get corresponding C++ type.
A FunctionDefinition defines the interface to a faudes-function.
const Signature & Variant(const std::string &rName) const
Return reference to Signature by name.
int VariantsSize(void) const
Return number of supported Signature instances.
Iterator End(void) const
STL interator to the internal function-name map.
static FunctionRegistry * G()
Method to access the single global instance of the registry.
std::map< std::string, FunctionDefinition * >::const_iterator Iterator
Convenience typedef to access registry entries.
void MergeDocumentation(TokenReader &rTr)
Scan token input for function documentation.
Iterator Begin(void) const
STL interator to the internal function-name map.
std::string Str(void) const
Convenience method to produce a textual representation of a parameter.
bool CReturn(void) const
Get C-Return flag.
ParamAttr
A function parameter has has one out of four so called io-attrributes;.
const std::string & Type(void) const
Get type.
const ParamAttr & Attribute(void) const
Get Attribute.
int Size(void) const
Return number of parameters.
const std::string & Name(void) const
Return signature name.
const Parameter & At(int n) const
Get parameter type by position.
void MergeDocumentation(TokenReader &rTr)
Scan token input for type documentation.
const TypeDefinition & Definition(const std::string &rTypeName) const
Look up the type definition by faudes-type name.
static TypeRegistry * G()
Method to access the single global instance of the registry.
bool Exists(const std::string &rName) const
Test existence of a faudes-type by its name.
Iterator End(void) const
STL interator to the internal type-name map.
std::map< std::string, TypeDefinition * >::const_iterator Iterator
Convenience typedef to access registry entries.
Includes all libFAUDES headers, no plugins.
void SaveRegistry(const std::string &rPath)
Dump all registered types and functions.
void LoadRegistry(const std::string &rPath)
Load all registered types and functions.
libFAUDES resides within the namespace faudes.
std::string VersionString()
Return FAUDES_VERSION as std::string.
std::string PluginsString()
Return FAUDES_PLUGINS as std::string.
std::string ToStringInteger(Int number)
integer to string
int main(int argc, char *argv[])
void Usage(const std::string &rMessage="")