libFAUDES

Sections

Index

lbp_function.cpp

Go to the documentation of this file.
00001 /** @file lbp_function.cpp luafaudes class to run scripts as rti functions */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005 Copyright (C) 2010 Thomas Moor
00006 
00007 This library is free software; you can redistribute it and/or
00008 modify it under the terms of the GNU Lesser General Public
00009 License as published by the Free Software Foundation; either
00010 version 2.1 of the License, or (at your option) any later version.
00011 
00012 This library is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 Lesser General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public
00018 License along with this library; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00020 
00021 // my header
00022 #include "lbp_function.h"
00023 
00024 // all lua headers, incl luafaudes
00025 #include "libluafaudes.h"
00026 
00027 
00028 
00029 namespace faudes{
00030 
00031 /*
00032 ********************************************************************
00033 ********************************************************************
00034 ********************************************************************
00035 
00036 Implementation of class LuaFunctionDefinition
00037 
00038 ********************************************************************
00039 ********************************************************************
00040 ********************************************************************
00041 */
00042 
00043 // faudes type
00044 FAUDES_TYPE_IMPLEMENTATION(LuaFunctionDefinition,LuaFunctionDefinition,FunctionDefinition)
00045 
00046 // construct
00047 LuaFunctionDefinition::LuaFunctionDefinition(const std::string& name) : 
00048   FunctionDefinition(name) 
00049 {
00050   Prototype(new LuaFunction(0));
00051   FD_DLB("LuaFunctionDefinition::LuaFunctionDefinition("<<this<<"): name   " << name);
00052   FD_DLB("LuaFunctionDefinition::LuaFunctionDefinition("<<this<<"): proto   " << mpFunction);
00053   FD_DLB("LuaFunctionDefinition::LuaFunctionDefinition("<<this<<"): has def " << mpFunction->Definition());
00054 }
00055 
00056 // copy construct
00057 LuaFunctionDefinition::LuaFunctionDefinition(const LuaFunctionDefinition& rSrc) : 
00058   FunctionDefinition(rSrc.Name())
00059 {
00060   FD_DLB("LuaFunctionDefinition::LuaFunctionDefinition(copy)");
00061   DoAssign(rSrc);
00062 }
00063 
00064 // std faudes type
00065 void LuaFunctionDefinition::DoAssign(const LuaFunctionDefinition& rSrc) {
00066   FD_DLB("LuaFunctionDefinition::DoAssign()");
00067   // assign base members
00068   FunctionDefinition::DoAssign(rSrc);
00069   // assign my members
00070   mLuaCode=rSrc.mLuaCode;
00071   mLuaFile=rSrc.mLuaFile;
00072   // special member
00073   pLuaFunction=dynamic_cast<LuaFunction*>(mpFunction);
00074   // report
00075   FD_DLB("LuaFunctionDefinition::DoAssign("<<this<<"): name   " << mName);
00076   FD_DLB("LuaFunctionDefinition::DoAssign("<<this<<"): proto   " << mpFunction);
00077   FD_DLB("LuaFunctionDefinition::DoAssign("<<this<<"): has def " << mpFunction->Definition())
00078 }
00079 
00080 // std faudes type
00081 bool LuaFunctionDefinition::DoEqual(const LuaFunctionDefinition& rOther) const {
00082   // test base members
00083   if(!FunctionDefinition::DoEqual(rOther)) return false;
00084   // test my members
00085   if(mLuaCode!=rOther.mLuaCode) return false;
00086   if(mLuaFile!=rOther.mLuaFile) return false;
00087   return true;
00088 }
00089 
00090 // clear (all but prototype)
00091 void LuaFunctionDefinition::Clear(){
00092   FD_DLB("LuaFunctionDefinition::Clear(): " << Name());
00093   // call base
00094   FunctionDefinition::Clear();
00095   // clear my data
00096   mLuaCode.clear();
00097 }
00098 
00099 
00100 // set prototype object
00101 void LuaFunctionDefinition::Prototype(Function* pFunc){
00102   FunctionDefinition::Prototype(pFunc);
00103   // set typed version
00104   pLuaFunction=dynamic_cast<LuaFunction*>(pFunc);
00105 }
00106 
00107 
00108 // get lua code
00109 const std::string& LuaFunctionDefinition::LuaCode(void) const {
00110   return mLuaCode;
00111 }
00112 
00113 // set lua code
00114 void LuaFunctionDefinition::LuaCode(const std::string& rCode) {
00115   mLuaCode=rCode;
00116 }
00117 
00118 
00119 // test all variants
00120 std::string LuaFunctionDefinition::SyntaxCheck(void) {
00121   // trivial case ... ok
00122   if(VariantsSize()==0) {
00123     FD_DLB("LuaFunctionDefinition::SyntaxCheck(): no variants defined, fine");
00124     return "";
00125   }    
00126   // allocate function
00127   faudes::LuaFunction* lfnct = pLuaFunction->New();
00128   // iterate variants
00129   std::string err = "";
00130   for(int i=0; i<lfnct->VariantsSize(); i++) {
00131     // select
00132     lfnct->Variant(i);
00133     FD_DLB("LuaFunctionDefinition::SyntaxCheck(): variant " << 
00134       lfnct->Variant()->Name());
00135     // allocate args (exception on unknown type, will lead to mem leak)
00136     try {
00137       lfnct->AllocateValues();
00138       // let luafunction have a go
00139       if(err=="") try {
00140         lfnct->SyntaxCheck();
00141       } catch(faudes::Exception ex)  {
00142         err = ex.What();
00143       }
00144       // free args
00145       lfnct->FreeValues();
00146     // alloc err
00147     } catch(faudes::Exception ex)  {
00148       err = "cannot allocate parameters for variant " + lfnct->Variant()->Name();
00149     }
00150   } // iterate variants
00151   delete lfnct;
00152   // done
00153   return err;
00154 }
00155 
00156 
00157 // token io
00158 void LuaFunctionDefinition::DoRead(TokenReader& rTr,  const std::string& rLabel, const Type* pContext) {
00159   FD_DLB("LuaFunctionDefinition::DoRead()");
00160   // ignore
00161   (void) pContext;
00162   // label
00163   std::string label=rLabel;
00164   if(label=="") label="LuaFunctionDefinition";
00165   // base can handle this
00166   FunctionDefinition::DoRead(rTr,label,pContext);
00167   // report
00168   FD_DLB("LuaFunctionDefinition::DoRead(): done " << mPlugIn << "::" << mName);
00169 }
00170 
00171 
00172 // token io
00173 void LuaFunctionDefinition::DoReadCore(TokenReader& rTr) {
00174   FD_DLB("LuaFunctionDefinition::DoReadCore()");
00175   // call base
00176   FunctionDefinition::DoReadCore(rTr);  
00177   // read my members
00178   Token token;
00179   rTr.Peek(token);
00180   // case a: embedded lua code
00181   if(token.IsBegin())
00182   if(token.StringValue()=="LuaCode") {
00183     mLuaFile="";
00184     rTr.ReadBegin("LuaCode");
00185     mLuaCode=rTr.ReadString();
00186     rTr.ReadEnd("LuaCode");
00187   }
00188   // case b: lua file
00189   if(token.IsBegin())
00190   if(token.StringValue()=="LuaFile") {
00191     rTr.ReadBegin("LuaFile");
00192     std::string mLuaFile=rTr.ReadString();
00193     // todo: read that file
00194     rTr.ReadEnd("LuaFile");
00195   }
00196 }
00197 
00198 
00199 // token io
00200 void LuaFunctionDefinition::DoWrite(TokenWriter& rTw,  const std::string& rLabel, const Type* pContext) const {
00201    // label
00202   std::string label=rLabel;
00203   if(label=="") label="LuaFunctionDefinition";
00204   // base can handle
00205   Documentation::DoWrite(rTw,label,pContext); 
00206 }
00207 
00208 // token io
00209 void LuaFunctionDefinition::DoWriteCore(TokenWriter& rTw) const {
00210   FD_DLB("LuaFunctionDefinition::DoWriteCore(): file " << rTw.FileName());
00211   // call base core
00212   FunctionDefinition::DoWriteCore(rTw);  
00213   // case a: embedded code
00214   if(mLuaFile=="") {
00215     rTw.WriteBegin("LuaCode");
00216     rTw.WriteVerbatim(mLuaCode);
00217     rTw.WriteEnd("LuaCode");
00218   }
00219   // case a: embedded code
00220   if(mLuaFile!="") {
00221     rTw.WriteBegin("LuaFile");
00222     rTw.WriteString(mLuaFile);
00223     rTw.WriteEnd("LuaFile");
00224     // todo: write that file
00225   }
00226 }
00227 
00228 /*
00229 ********************************************************************
00230 ********************************************************************
00231 ********************************************************************
00232 
00233 Implementation of class LuaFunction
00234 
00235 ********************************************************************
00236 ********************************************************************
00237 ********************************************************************
00238 */
00239 
00240 // Constructor 
00241 LuaFunction::LuaFunction(const LuaFunctionDefinition* fdef) : 
00242   Function(fdef),
00243   pLuaFuncDef(fdef)
00244 {
00245   FD_DLB("LuaFunction::LuaFunction(): fdef  " << pFuncDef);
00246 }
00247 
00248 // new on heap
00249 LuaFunction* LuaFunction::New(void) const {
00250   return new LuaFunction(pLuaFuncDef);
00251 }
00252 
00253 // set function definition
00254 void LuaFunction::Definition(const FunctionDefinition* fdef) {
00255   // cast and pass to base
00256   pLuaFuncDef = dynamic_cast<const LuaFunctionDefinition*>(fdef);
00257   Function::Definition(pLuaFuncDef);
00258 }
00259 
00260 // get function definition
00261 const LuaFunctionDefinition* LuaFunction::Definition(void) const {
00262   return pLuaFuncDef;
00263 }
00264 
00265 // implement typecheck
00266 bool LuaFunction::DoTypeCheck(int n) {
00267   FD_DLB("LuaFunction::DoTypeCheck("<< n << "): for " << Variant()->At(n).Type());
00268   const Type* proto = TypeRegistry::G()->Prototype(Variant()->At(n).Type()); 
00269   if(!proto) {
00270     FD_DLB("LuaFunction::DoTypeCheck("<< n << "): unknown type");
00271     return false;
00272   }
00273   if(!proto->Cast(ParamValue(n))) {
00274     FD_DLB("LuaFunction::DoTypeCheck("<< n << "): could not cast param value");
00275     return false;
00276   }
00277   return true;
00278 }
00279 
00280 
00281 // swigs version of user data (lua runtime version 4, swig 1.3.36)
00282 typedef void *(*swig_converter_func)(void *, int *);
00283 typedef struct swig_type_info *(*swig_dycast_func)(void **);
00284 typedef struct swig_cast_info {
00285   swig_type_info         *type;     /* pointer to type that is equivalent to this type */
00286   swig_converter_func     converter;    /* function to cast the void pointers */
00287   struct swig_cast_info  *next;     /* pointer to next cast in linked list */
00288   struct swig_cast_info  *prev;     /* pointer to the previous cast */
00289 } swig_cast_info;
00290 typedef struct swig_type_info {
00291   const char             *name;     /* mangled name of this type */
00292   const char             *str;      /* human readable name of this type */
00293   swig_dycast_func        dcast;    /* dynamic cast function down a hierarchy */
00294   struct swig_cast_info  *cast;     /* linked list of types that can cast into this type */
00295   void                   *clientdata;   /* language specific type data */
00296   int                    owndata;   /* flag if the structure owns the clientdata */
00297 } swig_type_info;
00298 typedef struct {
00299   swig_type_info   *type;
00300   int               own;                        /* 1 <> owned by swig (garbadge collector wont destroy) */  
00301   void              *ptr;
00302 } swig_lua_userdata;
00303 
00304 
00305 
00306 /* Swig runtime sytem: dynamic cast of swig userdata pointers */
00307 /* We need this to cast swig's userdata to the faudes base type */
00308 /* faudes::Type. See SWIG runtime SWIG_ConvertPtr. */
00309 void* SwigCastPtr(void* ptr, swig_type_info *from, swig_type_info *ty) {
00310   void* res=ptr;
00311   if(!ptr) return res;
00312   if(!from) return res;
00313   if(!ty) return res;
00314   swig_cast_info *iter = ty->cast;
00315   while(iter) {
00316     if(iter->type == from) {
00317       if(iter == ty->cast) break;
00318       iter->prev->next = iter->next;
00319       if(iter->next)
00320         iter->next->prev = iter->prev;
00321       iter->next = ty->cast;
00322       iter->prev = 0;
00323       if(ty->cast) ty->cast->prev = iter;
00324       ty->cast = iter;
00325       break;
00326     }
00327     iter = iter->next;
00328   }
00329   if(!iter) return res;
00330   if(!iter->converter) return res;
00331   int nm;
00332   res= (*iter->converter)(ptr,&nm);
00333   return res;
00334 }
00335 
00336 // implement execute: run stages
00337 void LuaFunction::DoExecute(void) {
00338   FD_DLB("LuaFunction::DoExecute()");
00339   /*
00340   for(int i=0; i< Variant()->Size(); i++) {
00341     FD_DLB("LuaFunction::DoExecute(): value at #" << i);
00342     ParamValue(i)->Write();
00343   }
00344   */
00345   // have a state
00346   mpL = lua_open();    
00347   // run stages
00348   DoExecuteA();
00349   DoExecuteB();
00350   DoExecuteC();
00351   DoExecuteD();
00352   // clean stack
00353   lua_pop(mpL, 1); // table from stage A
00354   // done
00355   lua_close(mpL); 
00356   mpL=0;
00357   FD_DLB("LuaFunction::DoExecute(): done");
00358 }
00359 
00360 // implement execute: syntaxcheck
00361 void LuaFunction::SyntaxCheck(void) {
00362   FD_DLB("LuaFunction::SyntaxCheck()");
00363   // have a state
00364   mpL = lua_open();    
00365   // run stages
00366   DoExecuteA();
00367   DoExecuteB();
00368   DoExecuteD();
00369   // clean stack
00370   lua_pop(mpL, 1); // function from stage B
00371   lua_pop(mpL, 1); // table from stage A
00372   // done
00373   lua_close(mpL); 
00374   mpL=0;
00375 }
00376 
00377 // implement execute: get function on the stack
00378 void LuaFunction::DoExecuteA(void) {
00379   FD_DLB("LuaFunction::DoExecuteA()");
00380   // prepare lua
00381   lua_gc(mpL, LUA_GCSTOP, 0);     // stop collector during initialization 
00382   luaL_openlibs(mpL);             // open libraries 
00383   luaopen_faudes_allplugins(mpL); // luafaudes: register
00384   //luafaudes_dotready();         // luafaudes: test dot
00385   lua_gc(mpL, LUA_GCRESTART, 0);  // start garbage collector
00386   // load my script
00387   const char* script = pLuaFuncDef->LuaCode().c_str();
00388   int script_len = pLuaFuncDef->LuaCode().size();
00389   int errload=luaL_loadbuffer(mpL, script, script_len, "luafaudes");
00390   if(errload!=0) {
00391     std::string lerr= std::string(lua_tostring(mpL, -1));
00392     int c1 = lerr.find_first_of(':');
00393     if(c1<0) c1=0;
00394     int c2 = lerr.find_first_of(':',c1+1);
00395     if(c2<0) c2=1;
00396     std::string line = lerr.substr(c1+1,c2-c1-1);  
00397     if(c2>1) {
00398       lerr="error in Lua script: line " + line + ": " + lerr.substr(c2+2);
00399     }
00400     lua_close(mpL); 
00401     mpL=0;    
00402     throw Exception("LuaFunction::DoExecuteA()", lerr, 49);
00403   }
00404   // run the script
00405   int errrun=lua_pcall(mpL, 0, 0, 0); 
00406   if(errrun!=0) {
00407     std::stringstream errstr;
00408     errstr << "failed to run script: ";
00409     errstr << std::string(lua_tostring(mpL, -1));
00410     lua_close(mpL); 
00411     mpL=0;
00412     throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49);
00413   }
00414   // get the swig generated table of faudes functions
00415   lua_getglobal(mpL,"faudes");
00416   mFtable=lua_gettop(mpL);
00417   if(!lua_istable(mpL,-1)) {
00418     std::stringstream errstr;
00419     errstr << "failed to load faudes table";
00420     lua_close(mpL);
00421     mpL=0; 
00422     throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49);
00423   }
00424   // mangle my function name
00425   std::string fname = Variant()->Name();
00426   unsigned int src=0;
00427   unsigned int dst=0;
00428   while(src<fname.length()) {
00429     if(isalnum(fname.at(src))) {fname[dst++]=fname[src++]; continue;}
00430     fname[dst++]='_';
00431     for(;src<fname.length();src++) 
00432       if(isalnum(fname.at(src))) break;
00433   }
00434   fname.resize(dst);
00435   // find my function
00436   lua_getglobal(mpL,fname.c_str()); 
00437   if(!lua_isfunction(mpL,-1)) {
00438     std::stringstream errstr;
00439     errstr << "missing function \"" << fname << "\"";
00440     lua_close(mpL);
00441     mpL=0; 
00442     throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49);
00443   }
00444   // construct a plain Type usrdata
00445   lua_pushstring(mpL,"Type");
00446   lua_gettable(mpL,mFtable);
00447   if(!lua_isfunction(mpL,-1)) {
00448     std::stringstream errstr;
00449     errstr << "failed to load constructor for plain Type";
00450     lua_close(mpL);
00451     mpL=0; 
00452     throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49);
00453   }
00454   if(lua_pcall(mpL, 0, 1, 0) != 0) { 
00455     std::stringstream errstr;
00456     errstr << "failed to construct plain Type (1)";
00457     lua_close(mpL);
00458     mpL=0; 
00459     throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49);
00460   }
00461   swig_lua_userdata* susr = (swig_lua_userdata*) lua_touserdata (mpL, -1);
00462   if(!susr) {
00463     std::stringstream errstr;
00464     errstr << "failed to construct plain Type (2)";
00465     lua_close(mpL);
00466     mpL=0; 
00467     throw Exception("LuaFunction::DoExecuteA()", errstr.str(), 49);
00468   }
00469   FD_DLB("LuaFunction::DoExecuteA(): plain type is " << susr->type->name);
00470   mFType=susr->type;
00471   lua_pop(mpL, 1); 
00472 }
00473 
00474 // implement execute: prepare parameters
00475 void LuaFunction::DoExecuteB(void) {
00476   FD_DLB("LuaFunction::DoExecuteB()");
00477   // construct my parameters in lua
00478   for(int i=0; i< Variant()->Size(); i++) {
00479     const std::string& ftype= Variant()->At(i).Type();
00480     // special case: int as lua number
00481     if(ftype=="Integer") {
00482       lua_pushnumber(mpL,((Integer*)ParamValue(i))->CValue());
00483       FD_DLB("LuaFunction::DoExecuteB(): created ftype " << ftype);
00484       continue;
00485     }
00486     // special case: bool as lua bool
00487     if(ftype=="Boolean") {
00488       lua_pushboolean(mpL,((Boolean*)ParamValue(i))->CValue());
00489       FD_DLB("LuaFunction::DoExecuteB(): created ftype " << ftype);
00490       continue;
00491     }
00492     // special case: str as lua string
00493     if(ftype=="String") {
00494       lua_pushstring(mpL,((String*)ParamValue(i))->CValue().c_str());
00495       FD_DLB("LuaFunction::DoExecuteB(): created ftype " << ftype);
00496       continue;
00497     }
00498     // std case: faudes type: construct 1
00499     lua_pushstring(mpL,ftype.c_str());
00500     lua_gettable(mpL,mFtable);
00501     if(!lua_isfunction(mpL,-1)) {
00502       std::stringstream errstr;
00503       errstr << "failed to load constructor for \"" << ftype << "\"";
00504       lua_close(mpL);
00505       mpL=0; 
00506       throw Exception("LuaFunction::DoExecuteB()", errstr.str(), 49);
00507     }
00508     // std case: faudes type: construct 2
00509     if(lua_pcall(mpL, 0, 1, 0) != 0) { 
00510       std::stringstream errstr;
00511       errstr << "failed to construct for \"" << ftype << "\" (1)";
00512       lua_close(mpL);
00513       mpL=0; 
00514       throw Exception("LuaFunction::DoExecuteB()", errstr.str(), 49);
00515     }
00516     // std case: test user data pointer
00517     swig_lua_userdata* susr = (swig_lua_userdata*) lua_touserdata (mpL, -1);
00518     if(!susr) {
00519       std::stringstream errstr;
00520       errstr << "failed to construct for\"" << ftype << "\" (2)";
00521       lua_close(mpL);
00522       mpL=0; 
00523       throw Exception("LuaFunction::DoExecuteB()", errstr.str(), 49);
00524     }
00525     // inspect stack 
00526     FD_DLB("LuaFunction::DoExecuteB(): created stype " << susr->type->name << " for ftype " << ftype);
00527     FD_DLB("LuaFunction::DoExecuteB(): faudes parameter at " << ParamValue(i));
00528     FD_DLB("LuaFunction::DoExecuteB(): swig usrdata ptr  " << susr->ptr);
00529     void* fptr=SwigCastPtr(susr->ptr,susr->type,(swig_type_info*)mFType);
00530     FD_DLB("LuaFunction::DoExecuteB(): faudes::Type converted ptr " << fptr);
00531     // copy parameter value
00532     if(Variant()->At(i).Attribute()!=Parameter::Out) {
00533       FD_DLB("LuaFunction::DoExecuteB(): copy parameter value");
00534       ((Type*)fptr)->Assign(*ParamValue(i));
00535     }
00536     // note: the original idea did not work out ..
00537     // need to further investige how SWIG interacts with Lua 
00538     // if(susr->own) free(susr->ptr);
00539     //susr->own=0;
00540     //susr->ptr = ParamValue(i);
00541   }
00542 }
00543 
00544 // implement execute: execute the function
00545 void LuaFunction::DoExecuteC(void) {
00546   FD_DLB("LuaFunction::DoExecuteC()");
00547   // run my function
00548   if(lua_pcall(mpL, Variant()->Size(), Variant()->Size(), 0) != 0) { 
00549     FD_DLB("LuaFunction::DoExecuteC(): detect error");
00550     std::string lerr= std::string(lua_tostring(mpL, -1));
00551     // user request via loopback exception
00552     if(lerr.find("break on application request")!=std::string::npos) {
00553       lerr="break on application request";
00554     }
00555     // user request via explicit exception
00556     else if(lerr.find("luafaudes script:")!=std::string::npos) {
00557       unsigned int c1=lerr.find("luafaudes script:");
00558       lerr=lerr.substr(c1);
00559     }
00560     // have line number ?
00561     else if(lerr.size()>=2) {
00562       unsigned int c1 = lerr.find_first_of(':');
00563       if(c1==std::string::npos) c1=0;
00564       if(c1+1>=lerr.size()) c1=0;
00565       unsigned int c2 = lerr.find_first_of(':',c1+1);
00566       if(c2==std::string::npos) c2=c1+1;
00567       if(c2>c1+1) {
00568         std::string line = lerr.substr(c1+1,c2-c1-1);  
00569         lerr="error in Lua script: line " + line + ": " + lerr.substr(c2+2);
00570       }
00571     }
00572     // anyway: close lua
00573     lua_close(mpL); 
00574     mpL=0;
00575     throw Exception("LuaFunction::DoExecuteC()", lerr, 49);
00576   }
00577   FD_DLB("LuaFunction::DoExecuteC():done ");
00578 }
00579 
00580 // implement execute: retrieve results
00581 void LuaFunction::DoExecuteD(void) {
00582   FD_DLB("LuaFunction::DoExecuteD()");
00583   // retrieve results from stack
00584   for(int i=Variant()->Size()-1; i>=0; i--) {
00585     const std::string& ftype= Variant()->At(i).Type();
00586     // special case: int as lua number
00587     if(ftype=="Integer" && lua_isnumber(mpL,-1)) {
00588       FD_DLB("LuaFunction::DoExecuteD(): retrieve type " << ftype);
00589       ((Integer*)ParamValue(i))->CValue(lua_tonumber(mpL,-1));
00590       lua_pop(mpL, 1); 
00591       continue;
00592     }
00593     // special case: bool as lua bool
00594     if(ftype=="Boolean" && lua_isboolean(mpL,-1)) {
00595       ((Boolean*)ParamValue(i))->CValue(lua_toboolean(mpL,-1));
00596       FD_DLB("LuaFunction::DoExecuteD(): retrieved type " << ftype);
00597       lua_pop(mpL, 1); 
00598       continue;
00599     }
00600     // special case: str as lua string
00601     if(ftype=="String" && lua_isstring(mpL,-1)) {
00602       ((String*)ParamValue(i))->CValue(lua_tostring(mpL,-1));
00603       FD_DLB("LuaFunction::DoExecuteD(): retrieved type " << ftype);
00604       lua_pop(mpL, 1); 
00605       continue;
00606     }
00607     // std case: sould use references for faudes values anyway ... see ExecuteC
00608     if(lua_isuserdata(mpL,-1)) {
00609       FD_DLB("LuaFunction::DoExecuteD(): try to retrieve type " << ftype);
00610       swig_lua_userdata* susr = (swig_lua_userdata*) lua_touserdata(mpL, -1);
00611       if(susr) {
00612         FD_DLB("LuaFunction::DoExecuteD(): found swig type " << susr->type->name << " at " << susr->ptr);
00613         FD_DLB("LuaFunction::DoExecuteD(): usr data at " << susr->ptr);
00614         void* fptr=SwigCastPtr(susr->ptr,susr->type,(swig_type_info*)mFType);
00615         FD_DLB("LuaFunction::DoExecuteD(): faudes::Type converted ptr " << fptr);
00616         // copy parameter value
00617         if(Variant()->At(i).Attribute()!=Parameter::In) {
00618           FD_DLB("LuaFunction::DoExecuteD(): copy parameter value");
00619           ParamValue(i)->Assign(*((Type*)fptr));
00620         }
00621         // pop
00622         lua_pop(mpL, 1); 
00623         continue;
00624       }
00625     }
00626     // report error
00627     std::stringstream errstr;
00628     errstr << "invalid return values in \"" << Variant()->Name() << "\"";
00629     lua_close(mpL); 
00630     mpL=0;
00631     throw Exception("LuaFunction::DoExecuteD()", errstr.str(), 49);
00632   }
00633 } 
00634 
00635 
00636 } // namespace
00637 

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3