29 using namespace faudes;
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 luabindings interface code." << std::endl;
46 std::cerr << std::endl;
47 std::cerr <<
"usage:" << std::endl;
48 std::cerr <<
" rti2code <rti input file> <output basename>" << std::endl;
49 std::cerr <<
" rti2code -merge <rti input files> <output rti-file>" << std::endl;
58 int main(
int argc,
char *argv[]) {
64 if(std::string(argv[1])==
"-merge") {
68 for(
int i=2; i< argc-1; i++) {
73 if(std::string(argv[argc-1]) !=
"-") {
82 if(argc != 3)
Usage();
88 std::ofstream rtiheader;
89 rtiheader.open((std::string(argv[argc-1])+
".h").c_str(), std::ios::out);
90 std::ofstream rticode;
91 rticode.open((std::string(argv[argc-1])+
".cpp").c_str(), std::ios::out);
92 std::ofstream luaheader;
93 luaheader.open((std::string(argv[argc-1])+
".i").c_str(), std::ios::out);
96 rtiheader <<
"/* rti2code: autogenerated libFAUDES rti registration: ";
98 rticode <<
"/* rti2code: autogenerated libFAUDES rti registration: ";
100 luaheader <<
"/* rti2code: autogenerated libFAUDES luabindings declarations: ";
104 rticode <<
"namespace faudes {" << std::endl;
105 rticode <<
"/* Auto-register faudes types */" << std::endl;
112 std::string ctype=tit->second->CType();
113 std::string ftype=tit->second->Name();
115 if(ctype==
"")
continue;
117 size_t pos=ctype.find(
"faudes::");
118 if(pos!=std::string::npos)
119 ctype=ctype.substr(std::string(
"faudes::").length());
121 if(!tit->second->AutoRegistered())
continue;
123 std::cout <<
"Generating auto-registration code for \"" << ftype <<
"\"" << std::endl;
125 std::string rtiname = std::string(
"gRti") +
ToStringInteger(tcnt) +
"Register" + ftype;
126 rticode <<
"AutoRegisterType<" << ctype <<
"> " << rtiname <<
"(\"" << ftype <<
"\");";
127 rticode << std::endl;
129 if(tit->second->XElementTag()!=
"") {
130 rtiname = std::string(
"gRti") +
ToStringInteger(tcnt) +
"XElementTag" + ftype;
131 rticode <<
"AutoRegisterXElementTag<" << ctype <<
"> " << rtiname <<
"(\"" << ftype <<
132 "\", \"" << tit->second->XElementTag() <<
"\");";
133 rticode << std::endl;
138 rticode <<
"} // namespace" << std::endl;
141 rtiheader <<
"namespace faudes {" << std::endl;
142 rtiheader <<
"void LoadRegisteredTypes(void);" << std::endl;
143 rtiheader <<
"} // namespace" << std::endl;
146 rticode <<
"namespace faudes {" << std::endl;
147 rticode <<
"/* Register faudes types */" << std::endl;
148 rticode <<
"void LoadRegisteredTypes(void) {" << std::endl;
153 std::string ctype=tit->second->CType();
155 if(ctype==
"")
continue;
157 size_t pos=ctype.find(
"faudes::");
158 if(pos!=std::string::npos)
159 ctype=ctype.substr(std::string(
"faudes::").length());
161 std::cout <<
"Generating registration code for \"" << tit->second->Name() <<
"\"" << std::endl;
163 rticode <<
" TypeRegistry::G()->Insert<" << ctype <<
">(\"" << tit->second->Name() <<
"\");";
164 rticode << std::endl;
168 rticode <<
"}" << std::endl;
169 rticode <<
"} // namespace" << std::endl;
173 rtiheader <<
"namespace faudes {" << std::endl;
174 rtiheader <<
"void LoadRegisteredFunctions(void);" << std::endl;
175 rtiheader <<
"} // namespace" << std::endl;
178 rticode <<
"namespace faudes {" << std::endl;
179 rticode <<
"/* Register faudes functions */" << std::endl;
180 rticode <<
"void LoadRegisteredFunctions(void) {" << std::endl;
183 rtiheader <<
"namespace faudes {" << std::endl;
192 std::string ctype=fdef->
CType();
193 std::string fname = fdef->
Name();
195 if(ctype==
"")
continue;
197 size_t pos=ctype.find(
"faudes::");
198 if(pos!=std::string::npos)
199 ctype=ctype.substr(std::string(
"faudes::").length());
202 std::cout <<
"Function registration: " << fname <<
": no signatures" << std::endl;
206 std::vector< std::vector<std::string> > cparams;
207 std::vector< std::vector<Parameter::ParamAttr> > cattrib;
208 std::vector< std::vector<bool> > cretval;
216 for(
int j=0; j<sigi.
Size(); j++) {
218 std::string ftype=sigi.
At(j).
Type();
222 if(fcret) retcount++;
234 if(retcount>1)
break;
236 size_t pos=ctype.find(
"faudes::");
237 if(pos!=std::string::npos)
238 ctype=ctype.substr(std::string(
"faudes::").length());
240 cparams.at(i).push_back(ctype);
241 cattrib.at(i).push_back(fattr);
242 cretval.at(i).push_back(fcret);
245 if((
int) cparams.at(i).size()!=sigi.
Size()) {
246 std::cout <<
"Function registration: " << fname <<
": cannot interpret signature "
247 << sigi.
Name() << std::endl;
253 std::cout <<
"Generating rti wrapper for \"" << fdef->
Name() <<
"\"" <<
254 " #" << cparams.size() <<
" variants" << std::endl;
256 std::string rtiname = std::string(
"Rti") +
ToStringInteger(fcnt) + ctype;
257 rticode <<
" FunctionRegistry::G()->Insert<" << rtiname <<
">(\"" << fname <<
"\");" << std::endl;
259 rtiheader <<
"/* Function class for C++ function " << ctype <<
"*/" << std::endl;
260 rtiheader <<
"class " << rtiname <<
" : public Function { " << std::endl;
261 rtiheader <<
"public:" << std::endl;
262 rtiheader << rtiname <<
"(const FunctionDefinition* fdef) : Function(fdef) {};" << std::endl;
263 rtiheader <<
"virtual Function* New(void) const { return new " << rtiname <<
"(pFuncDef); };" << std::endl;
264 rtiheader <<
"protected:" << std::endl;
266 for(
unsigned int i=0; i<cparams.size(); i++)
267 for(
unsigned int j=0; j<cparams.at(i).size(); j++)
268 rtiheader << cparams.at(i).at(j) <<
"* " <<
"mP_" << i <<
"_" << j <<
";" << std::endl;
270 rtiheader <<
"virtual bool DoTypeCheck(int n) {" << std::endl;
271 rtiheader <<
" bool res=false;" << std::endl;
272 rtiheader <<
" switch(mVariantIndex) { "<< std::endl;
273 for(
unsigned int i=0; i<cparams.size(); i++) {
274 rtiheader <<
" case " << i <<
": { // variant " << fdef->
Variant(i).
Name() << std::endl;
275 rtiheader <<
" switch(n) { "<< std::endl;
276 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
277 rtiheader <<
" case " << j <<
": ";
278 rtiheader <<
" res=DoTypeCast<" << cparams.at(i).at(j) <<
">(" << j <<
", mP_" << i <<
"_" << j <<
"); ";
279 rtiheader <<
"break; "<< std::endl;
281 rtiheader <<
" default: break; " << std::endl;
282 rtiheader <<
" } "<< std::endl;
283 rtiheader <<
" break; "<< std::endl;
284 rtiheader <<
" } "<< std::endl;
286 rtiheader <<
" default: break; " << std::endl;
287 rtiheader <<
" } "<< std::endl;
288 rtiheader <<
" return res;" << std::endl;
289 rtiheader <<
"};" << std::endl;
291 rtiheader <<
"virtual void DoExecute(void) {" << std::endl;
293 rtiheader <<
" switch(mVariantIndex) { "<< std::endl;
294 for(
unsigned int i=0; i<cparams.size(); i++) {
295 rtiheader <<
" case " << i <<
": { // variant " << fdef->
Variant(i).
Name() << std::endl;
298 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
299 if(!cretval.at(i).at(j))
continue;
301 if(cparams.at(i).at(j) ==
"Integer") {
302 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
305 if(cparams.at(i).at(j) ==
"Boolean") {
306 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
309 if(cparams.at(i).at(j) ==
"String") {
310 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference()) = ";
313 rtiheader <<
"*mP_" << i <<
"_" << j <<
" = ";
316 rtiheader << ctype <<
"(";
319 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
320 if(cretval.at(i).at(j))
continue;
321 if((parpos++)!=0) rtiheader <<
" ,";
323 if(cparams.at(i).at(j) ==
"Integer") {
324 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
327 if(cparams.at(i).at(j) ==
"Boolean") {
328 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
331 if(cparams.at(i).at(j) ==
"String") {
332 rtiheader <<
"*(mP_" << i <<
"_" << j <<
"->CReference())";
335 rtiheader <<
"*mP_" << i <<
"_" << j;
337 rtiheader <<
"); break; };" << std::endl;
340 rtiheader <<
" default: break; " << std::endl;
341 rtiheader <<
" }; "<< std::endl;
343 rtiheader <<
"}; "<< std::endl;
345 rtiheader <<
"};" << std::endl;
348 luaheader <<
"/* faudes-function \"" << fname <<
"\" */" << std::endl;
350 std::string plugin=fdef->
PlugIn();
351 luaheader <<
"#if " <<
"SwigModule == \"Swig" << plugin <<
"\"" << std::endl;
354 luaheader <<
"%rename(" << fname <<
") " << ctype <<
";" << std::endl;
357 std::vector< std::string > lfdefs;
358 std::vector< std::string > lrtypes;
359 std::vector< std::string > lhelp;
361 for(
unsigned int i=0; i<cparams.size(); i++) {
363 std::string lrtype=
"void";
364 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
365 if(!cretval.at(i).at(j))
continue;
367 if(cparams.at(i).at(j) ==
"Integer") {
371 if(cparams.at(i).at(j) ==
"Boolean") {
375 if(cparams.at(i).at(j) ==
"String") {
376 lrtype=
"std::string";
379 lrtype + cparams.at(i).at(j);
383 lrtypes.push_back(lrtype);
385 std::string lfdef = ctype +
"(";
388 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
389 if(cretval.at(i).at(j))
continue;
390 if((parpos++)!=0) lfdef +=
", ";
395 if(cparams.at(i).at(j) ==
"Integer") {
396 lfdef +=
"long int&";
399 if(cparams.at(i).at(j) ==
"Boolean") {
403 if(cparams.at(i).at(j) ==
"String") {
404 lfdef +=
"std::string&";
407 lfdef += cparams.at(i).at(j) +
"&";
409 if(cparams.at(i).at(j) ==
"Boolean" || cparams.at(i).at(j) ==
"String"
410 || cparams.at(i).at(j) ==
"Integer")
416 lfdefs.push_back(lfdef);
418 std::string luasig =
" " + fname +
"(";
419 bool leftcomma =
false;
420 bool rightcomma =
false;
421 for(
unsigned int j=0; j<cparams.at(i).size(); j++) {
423 if(cparams.at(i).at(j) ==
"Boolean" || cparams.at(i).at(j) ==
"String"
424 || cparams.at(i).at(j) ==
"Integer")
426 if(leftcomma) luasig =
"," + luasig;
428 luasig=cparams.at(i).at(j) + luasig;
433 if(rightcomma) luasig +=
", ";
435 luasig += sigi.
At(j).
Str();
441 std::string topic= fdef->
PlugIn();
443 if(topic==
"CoreFaudes") {
447 if(topic.length()>0) topic.at(0)=toupper(topic.at(0));
448 if(key1.length()>0) key1.at(0)=toupper(key1.at(0));
449 lhelp.push_back(
"SwigHelpEntry(\"" + topic +
"\", \"" + key1 +
"\", \"" +
456 for(
unsigned int i=1; i<lfdefs.size();i++) {
459 if(lfdefs.at(i)==lfdefs.at(j))
break;
462 if(lrtypes.at(j)==
"void")
463 {lfdefs[j]=
"";
continue;}
464 if(lrtypes.at(i)==
"void")
465 {lfdefs[i]=
"";
continue;}
470 for(
unsigned int i=0; i<lfdefs.size(); i++) {
471 if(lfdefs.at(i)==
"")
continue;
472 luaheader << lrtypes.at(i) <<
" " << lfdefs.at(i) <<
";" << std::endl;
474 if(lhelp.at(i)==
"")
continue;
475 luaheader << lhelp.at(i) <<
";" << std::endl;
477 std::cout <<
"Generating swig interface for function \"" << fdef->
Name() <<
"\"" <<
478 " #" << lcount <<
" variants" << std::endl;
481 luaheader <<
"#endif " << std::endl;
482 luaheader << std::endl;
488 rtiheader <<
"} // namespace" << std::endl;
491 rticode <<
"}" << std::endl;
492 rticode <<
"} // namespace" << std::endl;