| |
libFAUDES
Sections
Index
|
rti2code.cppGo to the documentation of this file.00001 /** rti2code.cpp Utility to generate registry initialisation code from rti files */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2009 Ruediger Berndt 00006 Copyright (C) 2009 Thomas Moor 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2.1 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library; if not, write to the Free Software 00020 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00021 00022 00023 #include <string> 00024 #include <iostream> 00025 #include <fstream> 00026 #include "corefaudes.h" 00027 00028 00029 using namespace faudes; 00030 00031 int main(int argc, char *argv[]) { 00032 00033 // simple command line 00034 if(argc != 3) { 00035 std::cerr << "rti2code: " << FDVersionString() << std::endl; 00036 std::cerr << std::endl; 00037 std::cerr << "utility to generates c code from an rti-file to " << std::endl; 00038 std::cerr << "1) register faudes-types and -functions with the run-time interface," << std::endl; 00039 std::cerr << "2) extract c declarations for luabindings interface code." << std::endl; 00040 std::cerr << std::endl; 00041 std::cerr << "usage: rti2code <rti input file> <output basename>" << std::endl; 00042 exit(1); 00043 } 00044 00045 // load registry 00046 LoadRegistry(argv[1]); 00047 00048 // code output streams 00049 std::ofstream rtiheader; 00050 rtiheader.open((std::string(argv[argc-1])+".h").c_str(), std::ios::out); 00051 std::ofstream rticode; 00052 rticode.open((std::string(argv[argc-1])+".cpp").c_str(), std::ios::out); 00053 std::ofstream luaheader; 00054 luaheader.open((std::string(argv[argc-1])+".i").c_str(), std::ios::out); 00055 00056 // introduce myself 00057 rtiheader << "/* rti2code: autogenerated libFAUDES rti registration: "; 00058 rtiheader << FDVersionString() << " " << FDPluginsString() << " */" << std::endl << std::endl; 00059 rticode << "/* rti2code: autogenerated libFAUDES rti registration: "; 00060 rticode << FDVersionString() << " " << FDPluginsString() << " */" << std::endl << std::endl; 00061 luaheader << "/* rti2code: autogenerated libFAUDES luabindings declarations: "; 00062 luaheader << FDVersionString() << " " << FDPluginsString() << " */" << std::endl << std::endl; 00063 00064 // c function declaration: load types 00065 rtiheader << "namespace faudes {" << std::endl; 00066 rtiheader << "void LoadAutoregisteredTypes(void);" << std::endl; 00067 rtiheader << "} // namespace" << std::endl; 00068 00069 // c function definition: load types 00070 rticode << "namespace faudes {" << std::endl; 00071 rticode << "/* Register faudes types */" << std::endl; 00072 rticode << "void LoadAutoregisteredTypes(void) {" << std::endl; 00073 00074 // traverse type registry to figure faudes types 00075 TypeRegistry::Iterator tit; 00076 for(tit=TypeRegistry::G()->Begin(); tit!=TypeRegistry::G()->End();tit++) { 00077 // get c type 00078 std::string ctype=tit->second->CType(); 00079 // bail out if no c type specified 00080 if(ctype=="") continue; 00081 // remove name space faudes 00082 size_t pos=ctype.find("faudes::"); 00083 if(pos!=std::string::npos) 00084 ctype=ctype.substr(std::string("faudes::").length()); 00085 // report 00086 std::cout << "Generating code for: faudes type \"" << tit->second->Name() << "\"" << std::endl; 00087 // produce c code 00088 rticode << " TypeRegistry::G()->Insert<" << ctype << ">(\"" << tit->second->Name() <<"\");"; 00089 rticode << std::endl; 00090 } 00091 00092 // c function definition: load types end 00093 rticode << "}" << std::endl; 00094 rticode << "} // namespace" << std::endl; 00095 00096 00097 // c function declaration: load functions 00098 rtiheader << "namespace faudes {" << std::endl; 00099 rtiheader << "void LoadAutoregisteredFunctions(void);" << std::endl; 00100 rtiheader << "} // namespace" << std::endl; 00101 00102 // c function definition: load functions 00103 rticode << "namespace faudes {" << std::endl; 00104 rticode << "/* Register faudes functions */" << std::endl; 00105 rticode << "void LoadAutoregisteredFunctions(void) {" << std::endl; 00106 00107 // c class definition: Function derivates 00108 rtiheader << "namespace faudes {" << std::endl; 00109 00110 // traverse function registry: define rti functions 00111 int fcnt=0; 00112 FunctionRegistry::Iterator fit; 00113 for(fit=FunctionRegistry::G()->Begin(); fit!=FunctionRegistry::G()->End();fit++, fcnt++) { 00114 // current function definition 00115 const FunctionDefinition* fdef = fit->second; 00116 // get c type and faudes function name 00117 std::string ctype=fdef->CType(); 00118 std::string fname = fdef->Name(); 00119 // bail out if no c type specified 00120 if(ctype=="") continue; 00121 // remove name space faudes 00122 size_t pos=ctype.find("faudes::"); 00123 if(pos!=std::string::npos) 00124 ctype=ctype.substr(std::string("faudes::").length()); 00125 // bail out if no signature 00126 if(fdef->VariantsSize()==0) { 00127 std::cout << "Function registration: " << fname << ": no signatures" << std::endl; 00128 continue; 00129 } 00130 // interpret signatures: set up type array 00131 std::vector< std::vector<std::string> > cparams; 00132 std::vector< std::vector<Parameter::ParamAttr> > cattrib; 00133 cparams.resize(fdef->VariantsSize()); 00134 cattrib.resize(fdef->VariantsSize()); 00135 // loop all signatures 00136 for(int i=0; i<fdef->VariantsSize(); i++) { 00137 const Signature& sigi=fdef->Variant(i); 00138 for(int j=0; j<sigi.Size(); j++) { 00139 // retrieve faudes type and attrib 00140 std::string ftype=sigi.At(j).mTDName; 00141 Parameter::ParamAttr fattr=sigi.At(j).mAttr; 00142 // bail out on unknown faudestype 00143 if(!TypeRegistry::G()->Exists(ftype)) break; 00144 // get corresponding ctype 00145 std::string ctype=TypeRegistry::G()->Definition(ftype).CType(); 00146 // bail out on unknown ctype 00147 if(ctype=="") break; 00148 // remove name space faudes 00149 size_t pos=ctype.find("faudes::"); 00150 if(pos!=std::string::npos) 00151 ctype=ctype.substr(std::string("faudes::").length()); 00152 // param ok 00153 cparams.at(i).push_back(ctype); 00154 cattrib.at(i).push_back(fattr); 00155 } 00156 // test for signature error 00157 if((int) cparams.at(i).size()!=sigi.Size()) { 00158 std::cout << "Function registration: " << fname << ": cannot interpret signature" << std::endl; 00159 cparams.resize(i); 00160 break; 00161 } 00162 } 00163 // report 00164 std::cout << "Generating code for: faudes function \"" << fdef->Name() << "\"" << std::endl; 00165 // produce c code: register all functions function 00166 std::string rtiname = std::string("Rti") + ToStringInteger(fcnt) + ctype; 00167 rticode << " FunctionRegistry::G()->Insert<" << rtiname << ">(\"" << fname <<"\");" << std::endl; 00168 // produce c code: class declaration intro 00169 rtiheader << "/* Function class for c function " << ctype << "*/" << std::endl; 00170 rtiheader << "class " << rtiname << " : public Function { " << std::endl; 00171 rtiheader << "public:" << std::endl; 00172 rtiheader << rtiname << "(const FunctionDefinition* fdef) : Function(fdef) {};" << std::endl; 00173 rtiheader << "virtual Function* New(void) const { return new " << rtiname << "(pFuncDef); };" << std::endl; 00174 rtiheader << "protected:" << std::endl; 00175 // produce c code: function class: have typed param 00176 for(unsigned int i=0; i<cparams.size(); i++) 00177 for(unsigned int j=0; j<cparams.at(i).size(); j++) 00178 rtiheader << cparams.at(i).at(j) << "* " << "mP_" << i << "_" << j << ";" << std::endl; 00179 // produce c code: function class: do type check 00180 rtiheader << "virtual bool DoTypeCheck(int n) {" << std::endl; 00181 rtiheader << " bool res=false;" << std::endl; 00182 rtiheader << " switch(mVariantIndex) { "<< std::endl; 00183 for(unsigned int i=0; i<cparams.size(); i++) { 00184 rtiheader << " case " << i << ": { // variant " << fdef->Variant(i).Name() << std::endl; 00185 rtiheader << " switch(n) { "<< std::endl; 00186 for(unsigned int j=0; j<cparams.at(i).size(); j++) { 00187 rtiheader << " case " << j << ": "; 00188 rtiheader << " res=DoTypeCast<" << cparams.at(i).at(j) << ">(" << j << ", mP_" << i <<"_" << j << "); "; 00189 rtiheader << "break; "<< std::endl; 00190 } 00191 rtiheader << " default: break; " << std::endl; 00192 rtiheader << " } "<< std::endl; 00193 rtiheader << " break; "<< std::endl; 00194 rtiheader << " } "<< std::endl; 00195 } 00196 rtiheader << " default: break; " << std::endl; 00197 rtiheader << " } "<< std::endl; 00198 rtiheader << " return res;" << std::endl; 00199 rtiheader << "};" << std::endl; 00200 // produce c code: function class: do execute 00201 rtiheader << "virtual void DoExecute(void) {" << std::endl; 00202 // produce c code: do execute: switch variant 00203 rtiheader << " switch(mVariantIndex) { "<< std::endl; 00204 for(unsigned int i=0; i<cparams.size(); i++) { 00205 rtiheader << " case " << i << ": { // variant " << fdef->Variant(i).Name() << std::endl; 00206 rtiheader << " " << ctype <<"("; 00207 for(unsigned int j=0; j<cparams.at(i).size(); j++) { 00208 if(j!=0) rtiheader << " ,"; 00209 // special case: integer 00210 if(cparams.at(i).at(j) == "Integer") { 00211 rtiheader << "*(mP_" << i << "_" << j << "->CReference())"; 00212 } else 00213 // special case: boolean 00214 if(cparams.at(i).at(j) == "Boolean") { 00215 rtiheader << "*(mP_" << i << "_" << j << "->CReference())"; 00216 } else 00217 // special case: integer 00218 if(cparams.at(i).at(j) == "String") { 00219 rtiheader << "*(mP_" << i << "_" << j << "->CReference())"; 00220 } else 00221 // std case 00222 rtiheader << "*mP_" << i << "_" << j; 00223 } 00224 rtiheader << "); break; };" << std::endl; 00225 } 00226 // produce c code: switch variant; done 00227 rtiheader << " default: break; " << std::endl; 00228 rtiheader << " }; "<< std::endl; 00229 // produce c code: do execute: done 00230 rtiheader << "}; "<< std::endl; 00231 // produce c code: function class: done 00232 rtiheader << "};" << std::endl; 00233 00234 // produce c code: lua function definition(s) 00235 luaheader << "/* faudes-function \"" << fname << "\" */" << std::endl; 00236 // figure my plugin to insert a conditional 00237 std::string plugin=fdef->PlugIn(); 00238 luaheader << "#if " << "SwigModule == \"Swig" << plugin << "\"" << std::endl; 00239 // use ctype function name 00240 if(ctype!=fname) 00241 luaheader << "%rename(" << fname << ") " << ctype << ";" << std::endl; 00242 // generate per signature 00243 for(unsigned int i=0; i<cparams.size(); i++) { 00244 // create ctype function declaration 00245 luaheader << "void " << ctype <<"("; 00246 for(unsigned int j=0; j<cparams.at(i).size(); j++) { 00247 if(j!=0) luaheader << ", "; 00248 // have const for +In+ 00249 if(cattrib.at(i).at(j)==Parameter::In) 00250 luaheader << "const "; 00251 // special case: integer 00252 if(cparams.at(i).at(j) == "Integer") { 00253 luaheader << "long int&"; 00254 } else 00255 // special case: boolean 00256 if(cparams.at(i).at(j) == "Boolean") { 00257 luaheader << "bool&"; 00258 } else 00259 // special case: string 00260 if(cparams.at(i).at(j) == "String") { 00261 luaheader << "std::string&"; 00262 } else 00263 // std case ctype as refernce 00264 luaheader << cparams.at(i).at(j) << "&"; 00265 // mark elementary outputs 00266 if(cparams.at(i).at(j) == "Boolean" || cparams.at(i).at(j) == "String" 00267 || cparams.at(i).at(j) == "Integer") 00268 if(cattrib.at(i).at(j)==Parameter::Out) 00269 luaheader << " OUTPUT"; 00270 } 00271 // end of function declaration 00272 luaheader << ");" << std::endl; 00273 00274 // add help entry: build nice signature 00275 std::string luasig = " " + fname + "("; 00276 bool leftcomma = false; 00277 bool rightcomma = false; 00278 for(unsigned int j=0; j<cparams.at(i).size(); j++) { 00279 // special case: elementary output 00280 if(cparams.at(i).at(j) == "Boolean" || cparams.at(i).at(j) == "String" 00281 || cparams.at(i).at(j) == "Integer") 00282 if(cattrib.at(i).at(j)==Parameter::Out) { 00283 if(leftcomma) luasig = "," + luasig; 00284 // if(leftcomma) luasig = ", " + luasig; // need tab in help system? 00285 luasig=cparams.at(i).at(j) + luasig; 00286 leftcomma=true; 00287 continue; 00288 } 00289 // std case 00290 if(rightcomma) luasig += ", "; 00291 const Signature& sigi=fdef->Variant(i); 00292 luasig += sigi.At(j).Str(); 00293 rightcomma=true; 00294 } 00295 luasig+=")"; 00296 // add help entry: add with topic 00297 if(fdef->TextDoc()!=""){ 00298 std::string topic= fdef->PlugIn(); 00299 std::string key1=fdef->KeywordAt(1); 00300 if(topic=="CoreFaudes") { 00301 topic=fdef->KeywordAt(1); 00302 key1=fdef->KeywordAt(2); 00303 } 00304 if(topic.length()>0) topic.at(0)=toupper(topic.at(0)); 00305 if(key1.length()>0) key1.at(0)=toupper(key1.at(0)); 00306 luaheader << "SwigHelpEntry(\"" << topic <<"\", \"" << key1 << "\", \"" << luasig << "\");" << std::endl; 00307 } 00308 00309 } // done: per signature; 00310 00311 // and all signatures, incl conditional 00312 luaheader << "#endif " << std::endl; 00313 luaheader << std::endl; 00314 00315 00316 } // loop all functions 00317 00318 // c class definition: function class: all such done 00319 rtiheader << "} // namespace" << std::endl; 00320 00321 // c class definition: register function prototypes: done 00322 rticode << "}" << std::endl; 00323 rticode << "} // namespace" << std::endl; 00324 00325 return(0); 00326 } |
libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6