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 [-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;
62 int main(
int argc,
char *argv[]) {
72 for(; pos<argc; pos++) {
73 std::string option(argv[pos]);
75 if((option==
"-?") || (option==
"--help")) {
80 if(option==
"-loader") {
95 if(option==
"-merge") {
100 if(option.c_str()[0]==
'-') {
101 usage(
"unknown option "+ option);
109 if(merge && (loader || swig)) {
110 usage(
"mismatching options: either merge or code generation");
112 if(!merge && !(loader || swig)) {
113 usage(
"mismatching options: either merge or code generation");
116 usage(
"mismatching options: flat is only applicable to swig");
118 if(merge && (argc-pos <3)) {
119 usage(
"mismatching agruments: to few files to merge");
121 if(!merge && (argc-pos !=2)) {
122 usage(
"mismatching agruments: need one source and one destination for code generation");
128 for(; pos< argc-1; pos++) {
133 if(std::string(argv[argc-1]) !=
"-") {
145 std::ofstream rtiheader;
146 std::ofstream rticode;
147 std::ofstream swigheader;
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);
153 swigheader.open((std::string(argv[pos])+
".i").c_str(), std::ios::out);
158 rtiheader <<
"/* rti2code: autogenerated libFAUDES rti registration: ";
160 rticode <<
"/* rti2code: autogenerated libFAUDES rti registration: ";
164 swigheader <<
"/* rti2code: autogenerated libFAUDES swig bindings declarations: ";
170 rticode <<
"namespace faudes {" << std::endl;
171 rticode <<
"/* Auto-register faudes types */" << std::endl;
180 std::string ctype=tit->second->CType();
181 std::string ftype=tit->second->Name();
183 if(ctype==
"")
continue;
185 size_t pos=ctype.find(
"faudes::");
186 if(pos!=std::string::npos)
187 ctype=ctype.substr(std::string(
"faudes::").length());
189 if(!tit->second->AutoRegistered())
continue;
191 std::cout <<
"rti2code: generating auto-registration code for \"" << ftype <<
"\"" << std::endl;
193 std::string rtiname = std::string(
"gRti") +
ToStringInteger(tcnt) +
"Register" + ftype;
194 rticode <<
"AutoRegisterType<" << ctype <<
"> " << rtiname <<
"(\"" << ftype <<
"\");";
195 rticode << std::endl;
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;
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;
215 rticode <<
"} // namespace" << std::endl;
220 rtiheader <<
"namespace faudes {" << std::endl;
221 rtiheader <<
"void LoadRegisteredTypes(void);" << std::endl;
222 rtiheader <<
"} // namespace" << std::endl;
227 rticode <<
"namespace faudes {" << std::endl;
228 rticode <<
"/* Register faudes types */" << std::endl;
229 rticode <<
"void LoadRegisteredTypes(void) {" << std::endl;
238 std::string ctype=tit->second->CType();
240 if(ctype==
"")
continue;
242 size_t pos=ctype.find(
"faudes::");
243 if(pos!=std::string::npos)
244 ctype=ctype.substr(std::string(
"faudes::").length());
246 std::cout <<
"rti2code: generating registration code for \"" << tit->second->Name() <<
"\"" << std::endl;
248 rticode <<
" TypeRegistry::G()->Insert<" << ctype <<
">(\"" << tit->second->Name() <<
"\");";
249 rticode << std::endl;
255 rticode <<
"}" << std::endl;
256 rticode <<
"} // namespace" << std::endl;
262 rtiheader <<
"namespace faudes {" << std::endl;
263 rtiheader <<
"void LoadRegisteredFunctions(void);" << std::endl;
264 rtiheader <<
"} // namespace" << std::endl;
269 rticode <<
"namespace faudes {" << std::endl;
270 rticode <<
"/* Register faudes functions */" << std::endl;
271 rticode <<
"void LoadRegisteredFunctions(void) {" << std::endl;
276 rtiheader <<
"namespace faudes {" << std::endl;
286 std::string ctype=fdef->
CType();
287 std::string fname = fdef->
Name();
289 if(ctype==
"")
continue;
291 size_t pos=ctype.find(
"faudes::");
292 if(pos!=std::string::npos)
293 ctype=ctype.substr(std::string(
"faudes::").length());
296 std::cout <<
"rti2cocde: function registration: " << fname <<
": no signatures" << std::endl;
300 std::vector< std::vector<std::string> > cparams;
301 std::vector< std::vector<Parameter::ParamAttr> > cattrib;
302 std::vector< std::vector<bool> > cretval;
310 for(
int j=0; j<sigi.
Size(); j++) {
312 std::string ftype=sigi.
At(j).
Type();
316 if(fcret) retcount++;
328 if(retcount>1)
break;
330 size_t pos=ctype.find(
"faudes::");
331 if(pos!=std::string::npos)
332 ctype=ctype.substr(std::string(
"faudes::").length());
334 cparams.at(i).push_back(ctype);
335 cattrib.at(i).push_back(fattr);
336 cretval.at(i).push_back(fcret);
339 if((
int) cparams.at(i).size()!=sigi.
Size()) {
340 std::cout <<
"rti2code: function registration: " << fname <<
": cannot interpret signature "
341 << sigi.
Name() << std::endl;
347 std::cout <<
"rti2code: generating rti wrapper for \"" << fdef->
Name() <<
"\"" <<
348 " #" << cparams.size() <<
" variants" << std::endl;
349 std::string rtiname = std::string(
"Rti") +
ToStringInteger(fcnt) + ctype;
352 rticode <<
" FunctionRegistry::G()->Insert<" << rtiname <<
">(\"" << fname <<
"\");" << std::endl;
356 rtiheader <<
"/* Function class for C++ function " << ctype <<
"*/" << std::endl;
357 rtiheader <<
"class " << rtiname <<
" : public Function { " << std::endl;
358 rtiheader <<
"public:" << std::endl;
359 rtiheader <<
" using Function::operator=;" << std::endl;
360 rtiheader << rtiname <<
"(const FunctionDefinition* fdef) : Function(fdef) {};" << std::endl;
361 rtiheader <<
"virtual Function* New(void) const { return new " << rtiname <<
"(pFuncDef); };" << std::endl;
362 rtiheader <<
"protected:" << std::endl;
366 for(
unsigned int i=0; i<cparams.size(); i++)
367 for(
unsigned int j=0; j<cparams.at(i).size(); j++)
368 rtiheader << cparams.at(i).at(j) <<
"* " <<
"mP_" << i <<
"_" << j <<
";" << std::endl;
372 rtiheader <<
"virtual bool DoTypeCheck(int n) {" << std::endl;
373 rtiheader <<
" bool res=false;" << std::endl;
374 rtiheader <<
" switch(mVariantIndex) { "<< std::endl;
375 for(
unsigned int i=0; i<cparams.size(); i++) {
376 rtiheader <<
" case " << i <<
": { // variant " << fdef->
Variant(i).
Name() << std::endl;
377 rtiheader <<
" switch(n) { "<< std::endl;
378 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
379 rtiheader <<
" case " << j <<
": ";
380 rtiheader <<
" res=DoTypeCast<" << cparams.at(i).at(j) <<
">(" << j <<
", mP_" << i <<
"_" << j <<
"); ";
381 rtiheader <<
"break; "<< std::endl;
383 rtiheader <<
" default: break; " << std::endl;
384 rtiheader <<
" } "<< std::endl;
385 rtiheader <<
" break; "<< std::endl;
386 rtiheader <<
" } "<< std::endl;
388 rtiheader <<
" default: break; " << std::endl;
389 rtiheader <<
" } "<< std::endl;
390 rtiheader <<
" return res;" << std::endl;
391 rtiheader <<
"};" << std::endl;
395 rtiheader <<
"virtual void DoExecute(void) {" << std::endl;
399 rtiheader <<
" switch(mVariantIndex) { "<< std::endl;
400 for(
unsigned int i=0; i<cparams.size(); i++) {
401 rtiheader <<
" case " << i <<
": { // variant " << fdef->
Variant(i).
Name() << std::endl;
404 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
405 if(!cretval.at(i).at(j))
continue;
407 if(cparams.at(i).at(j) ==
"Integer") {
408 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
411 if(cparams.at(i).at(j) ==
"Boolean") {
412 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
415 if(cparams.at(i).at(j) ==
"String") {
416 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
419 rtiheader <<
"*mP_" << i <<
"_" << j <<
" = ";
422 rtiheader << ctype <<
"(";
425 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
426 if(cretval.at(i).at(j))
continue;
427 if((parpos++)!=0) rtiheader <<
" ,";
429 if(cparams.at(i).at(j) ==
"Integer") {
430 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
433 if(cparams.at(i).at(j) ==
"Boolean") {
434 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
437 if(cparams.at(i).at(j) ==
"String") {
438 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
441 rtiheader <<
"*mP_" << i <<
"_" << j;
443 rtiheader <<
"); break; };" << std::endl;
446 rtiheader <<
" default: break; " << std::endl;
447 rtiheader <<
" }; "<< std::endl;
449 rtiheader <<
"}; "<< std::endl;
451 rtiheader <<
"};" << std::endl;
456 swigheader <<
"/* faudes-function \"" << fname <<
"\" */" << std::endl;
461 std::string plugin=fdef->
PlugIn();
462 swigheader <<
"#if " <<
"( SwigModule == \"Swig" << plugin <<
"\")";
464 swigheader << std::endl;
470 swigheader <<
"%rename(" << fname <<
") " << ctype <<
";" << std::endl;
475 std::vector< std::string > lfdefs;
476 std::vector< std::string > lrtypes;
477 std::vector< std::string > lhelp;
479 for(
unsigned int i=0; i<cparams.size(); i++) {
481 std::string lrtype=
"void";
482 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
483 if(!cretval.at(i).at(j))
continue;
485 if(cparams.at(i).at(j) ==
"Integer") {
489 if(cparams.at(i).at(j) ==
"Boolean") {
493 if(cparams.at(i).at(j) ==
"String") {
494 lrtype=
"std::string";
497 lrtype = cparams.at(i).at(j);
501 lrtypes.push_back(lrtype);
503 std::string lfdef = ctype +
"(";
506 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
507 if(cretval.at(i).at(j))
continue;
508 if((parpos++)!=0) lfdef +=
", ";
513 if(cparams.at(i).at(j) ==
"Integer") {
514 lfdef +=
"long int&";
517 if(cparams.at(i).at(j) ==
"Boolean") {
521 if(cparams.at(i).at(j) ==
"String") {
522 lfdef +=
"std::string&";
525 lfdef += cparams.at(i).at(j) +
"&";
527 if(cparams.at(i).at(j) ==
"Boolean" || cparams.at(i).at(j) ==
"String"
528 || cparams.at(i).at(j) ==
"Integer")
534 lfdefs.push_back(lfdef);
536 std::string luasig =
" " + fname +
"(";
537 bool leftcomma =
false;
538 bool rightcomma =
false;
539 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
541 if(cparams.at(i).at(j) ==
"Boolean" || cparams.at(i).at(j) ==
"String"
542 || cparams.at(i).at(j) ==
"Integer")
544 if(leftcomma) luasig =
"," + luasig;
546 luasig=cparams.at(i).at(j) + luasig;
551 if(rightcomma) luasig +=
", ";
553 luasig += sigi.
At(j).
Str();
559 std::string topic= fdef->
PlugIn();
561 if(topic==
"CoreFaudes") {
565 if(topic.length()>0) topic.at(0)=toupper(topic.at(0));
566 if(key1.length()>0) key1.at(0)=toupper(key1.at(0));
567 lhelp.push_back(
"SwigHelpEntry(\"" + topic +
"\", \"" + key1 +
"\", \"" +
574 for(
unsigned int i=1; i<lfdefs.size();i++) {
577 if(lfdefs.at(i)==lfdefs.at(j))
break;
580 if(lrtypes.at(j)==
"void")
581 {lfdefs[j]=
"";
continue;}
582 if(lrtypes.at(i)==
"void")
583 {lfdefs[i]=
"";
continue;}
588 for(
unsigned int i=0; i<lfdefs.size(); i++) {
589 if(lfdefs.at(i)==
"")
continue;
590 swigheader << lrtypes.at(i) <<
" " << lfdefs.at(i) <<
";" << std::endl;
592 if(lhelp.at(i)==
"")
continue;
593 swigheader << lhelp.at(i) <<
";" << std::endl;
595 std::cout <<
"rti2code: generating swig interface for function \"" << fdef->
Name() <<
"\"" <<
596 " #" << lcount <<
" variants" << std::endl;
600 swigheader <<
"#endif " << std::endl;
602 swigheader << std::endl;
610 rtiheader <<
"} // namespace" << std::endl;
615 rticode <<
"}" << std::endl;
616 rticode <<
"} // namespace" << std::endl;
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
int VariantsSize(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
const std::string & Type(void) const
const ParamAttr & Attribute(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
std::map< std::string, TypeDefinition * >::const_iterator Iterator
void SaveRegistry(const std::string &rPath)
void LoadRegistry(const std::string &rPath)
std::string VersionString()
std::string PluginsString()
std::string ToStringInteger(Int number)
int main(int argc, char *argv[])
void usage(const std::string &rMessage="")