diff --git a/Common/Bindings.cpp b/Common/Bindings.cpp new file mode 100644 index 0000000000000000000000000000000000000000..049026c19acb59d0f967157a7750fa3d545d796d --- /dev/null +++ b/Common/Bindings.cpp @@ -0,0 +1,13 @@ +#include <stdarg.h> +#include "Bindings.h" +#include <stdio.h> +void methodBinding::setArgNames(const char *arg1, ...) { + va_list ap; + va_start(ap,arg1); + const char * name=arg1; + while(name!=NULL){ + _argNames.push_back(name); + name = va_arg(ap,const char *); + } + va_end(ap); +} diff --git a/Common/Bindings.h b/Common/Bindings.h index 0b254c188180ee00381285c693b1f4fb0b03d464..fb3c408fb3715d5361d700b8873565ef85aa204a 100644 --- a/Common/Bindings.h +++ b/Common/Bindings.h @@ -1,18 +1,23 @@ #ifndef _BINDINGS_H_ #define _BINDINGS_H_ #include <string> -#include <list> +#include <vector> #include <typeinfo> -#include "GmshConfig.h" class methodBinding{ std::string _description; + std::vector<std::string> _argNames; public: - void setArgNames(std::string arg1, ...){} + inline const std::vector<std::string> &getArgNames()const{ + return _argNames; + } + void setArgNames(const char * arg1, ...); void setDescription(std::string description){_description=description;} inline const std::string getDescription() const {return _description;} }; + + #if defined(HAVE_LUA) #include "LuaBindings.h" #else //no bindings diff --git a/Common/BindingsTypeName.h b/Common/BindingsTypeName.h new file mode 100644 index 0000000000000000000000000000000000000000..0dab638b6a5c273deddf40ba3528d2e08d63fb12 --- /dev/null +++ b/Common/BindingsTypeName.h @@ -0,0 +1,158 @@ +#ifndef BINDINGS_TYPE_NAME_H +#define BINDINGS_TYPE_NAME_H +#include <vector> +#include <string> +/*** store a unique static class name for each binded class ***/ +template <typename type> +class className{ + static std::string _name; + public: + static void set(std::string name){ + if(_name!=""){ + throw; + } + _name=name; + } + static const std::string &get(){ + if(_name==""){ + throw; + } + return _name; + } +}; +template<typename type> +std::string className<type>::_name; + +template <> +class className<std::string>{ + public: + static const std::string get(){ + return "string"; + } +}; +template <> +class className<int>{ + public: + static const std::string get(){ + return "int"; + } +}; +template <> +class className<double>{ + public: + static const std::string get(){ + return "double"; + } +}; +template <> +class className<void>{ + public: + static const std::string get(){ + return "void"; + } +}; +template <typename t> +class className<t*>{ + public: + static const std::string get(){ + return className<t>::get(); + } +}; +template <typename t> +class className<const t &>{ + public: + static const std::string get(){ + return className<t>::get(); + } +}; + +template <typename cb> +class argTypeNames; +template <typename tr, typename tObj, typename t0, typename t1, typename t2, typename t3> +class argTypeNames<tr (tObj::*)(t0,t1,t2,t3)>{ + public: + static void get(std::vector<std::string> &names){ + names.clear(); + names.push_back(className<tr>::get()); + names.push_back(className<t0>::get()); + names.push_back(className<t1>::get()); + names.push_back(className<t2>::get()); + names.push_back(className<t3>::get()); + } +}; +template <typename tr, typename tObj, typename t0, typename t1, typename t2> +class argTypeNames<tr (tObj::*)(t0,t1,t2)>{ + public: + static void get(std::vector<std::string> &names){ + names.clear(); + names.push_back(className<tr>::get()); + names.push_back(className<t0>::get()); + names.push_back(className<t1>::get()); + names.push_back(className<t2>::get()); + } +}; +template <typename tr, typename tObj, typename t0, typename t1> +class argTypeNames<tr (tObj::*)(t0,t1)>{ + public: + static void get(std::vector<std::string> &names){ + names.clear(); + names.push_back(className<tr>::get()); + names.push_back(className<t0>::get()); + names.push_back(className<t1>::get()); + } +}; +template <typename tr, typename tObj, typename t0> +class argTypeNames<tr (tObj::*)(t0)>{ + public: + static void get(std::vector<std::string> &names){ + names.clear(); + names.push_back(className<tr>::get()); + names.push_back(className<t0>::get()); + } +}; +template <typename tr, typename tObj> +class argTypeNames<tr (tObj::*)()>{ + public: + static void get(std::vector<std::string> &names){ + names.clear(); + names.push_back(className<tr>::get()); + } +}; +template <typename cb> +class argTypeNames; +template <typename tr, typename tObj, typename t0, typename t1, typename t2, typename t3> +class argTypeNames<tr (tObj::*)(t0,t1,t2,t3)const>{ + public: + static void get(std::vector<std::string> &names){ + argTypeNames<tr (tObj::*)(t0,t1,t2,t3)>::get(names); + } +}; +template <typename tr, typename tObj, typename t0, typename t1, typename t2> +class argTypeNames<tr (tObj::*)(t0,t1,t2)const>{ + public: + static void get(std::vector<std::string> &names){ + argTypeNames<tr (tObj::*)(t0,t1,t2)>::get(names); + } +}; +template <typename tr, typename tObj, typename t0, typename t1> +class argTypeNames<tr (tObj::*)(t0,t1)const>{ + public: + static void get(std::vector<std::string> &names){ + argTypeNames<tr (tObj::*)(t0,t1)>::get(names); + } +}; +template <typename tr, typename tObj, typename t0> +class argTypeNames<tr (tObj::*)(t0)const>{ + public: + static void get(std::vector<std::string> &names){ + argTypeNames<tr (tObj::*)(t0)>::get(names); + } +}; +template <typename tr, typename tObj> +class argTypeNames<tr (tObj::*)()const>{ + public: + static void get(std::vector<std::string> &names){ + argTypeNames<tr (tObj::*)()>::get(names); + } +}; +#endif diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index f1eda826c322436a5e382556133f570599b2480b..b0c8624f9e3ff5739939ce4cdb4079e6086f942f 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -23,6 +23,7 @@ set(SRC TreeUtils.cpp avl.cpp MallocUtils.cpp ConnectionManager.cpp + Bindings.cpp ) file(GLOB HDR RELATIVE ${CMAKE_SOURCE_DIR}/Common *.h) diff --git a/Common/LuaBindings.cpp b/Common/LuaBindings.cpp index 1b98e8ca00ff3b305e4f1e9310e2287ed02dcf2c..7a8dee96bdf5971cbc069f543eb884d0637ad1bf 100644 --- a/Common/LuaBindings.cpp +++ b/Common/LuaBindings.cpp @@ -41,13 +41,30 @@ const char *colorBlue = "\033[1;34m"; const char *colorDefault = "\033[0m"; const char *colorBold = "\033[1m"; +static void print_method(std::string name, luaMethodBinding *mb, bool isConstructor=false) { + std::vector<std::string> argTypeNames; + mb->getArgTypeNames(argTypeNames); + std::cout<<" "; + if(!isConstructor) + std::cout<<colorBold<<argTypeNames[0]; + std::cout<<colorBlue<<" "<<name<<colorDefault<<colorBold<<" ("; + for(int i=1;i< argTypeNames.size(); i++){ + if(i!=1) + std::cout<<", "; + std::cout<<colorBold<<argTypeNames[i]<<colorDefault; + if(mb->getArgNames().size()>i-1) + std::cout<<" "<<mb->getArgNames()[i-1]; + } + std::cout<<colorBold<<")\n"<<colorDefault; + const std::string description=mb->getDescription(); + std::cout<<(description.empty()?"no help available":description) <<"\n"; + +} static void list_methods(classBinding *cb){ if(cb->methods.size()) - std::cout<<colorBold<<"Methods from "<<cb->getClassName()<<colorDefault<<"\n"; + std::cout<<colorGreen<<"Methods from "<<cb->getClassName()<<colorDefault<<"\n"; for(std::map<std::string,luaMethodBinding *>::iterator it = cb->methods.begin(); it!=cb->methods.end(); it++){ - std::cout<<colorBlue<<" "<<it->first<<colorDefault<<" : "; - const std::string description=it->second->getDescription(); - std::cout<<(description.empty()?"no help available":description) <<"\n"; + print_method(it->first,it->second); } if(cb->getParent()) list_methods(cb->getParent()); @@ -76,12 +93,17 @@ static int lua_help (lua_State *L){ const std::string description=cb->getDescription(); std::cout<<(description.empty()?"no help available":description) <<"\n"; std::cout<<"\n"; + if(cb->getConstructor()){ + std::cout<<colorGreen<<"Constructor"<<colorDefault<<"\n"; + print_method(className,cb->getConstructor(),true); + std::cout<<"\n"; + } list_methods(cb); std::cout<<"\n"; if(cb->children.size()){ - std::cout<<colorBold<<"Children of "<<cb->getClassName()<<colorDefault<<"\n"; + std::cout<<colorGreen<<"Children of "<<cb->getClassName()<<colorDefault<<"\n"; for(std::set<classBinding *>::iterator it = cb->children.begin(); it!=cb->children.end(); it++){ - std::cout<<" "<<colorGreen<<(*it)->getClassName()<<colorDefault<<" : "; + std::cout<<" "<<colorBlue<<(*it)->getClassName()<<colorDefault<<" : "; const std::string description=(*it)->getDescription(); std::cout<<(description.empty()?"no help available":description) <<"\n"; } @@ -167,15 +189,15 @@ binding::binding(){ // Register Lua bindings GModel::registerBindings(this); + fullMatrix<double>::registerBindings(this); + function::registerBindings(this); + dgConservationLaw::registerBindings(this); dgSystemOfEquations::registerBindings(this); dgBoundaryCondition::registerBindings(this); - dgConservationLaw::registerBindings(this); dgConservationLawShallowWater2dRegisterBindings(this); dgConservationLawWaveEquationRegisterBindings(this); dgConservationLawAdvectionRegisterBindings(this); dgPerfectGasLaw2dRegisterBindings(this); - fullMatrix<double>::registerBindings(this); - function::registerBindings(this); functionLua::registerBindings(this); function::registerDefaultFunctions(); MVertex::registerBindings(this); diff --git a/Common/LuaBindings.h b/Common/LuaBindings.h index 6e28eb222e8ecc66840a1195003f9e25da492bc4..f0e4c36e31d30bd3592766ca023f3bdb5ee3bda4 100644 --- a/Common/LuaBindings.h +++ b/Common/LuaBindings.h @@ -1,17 +1,20 @@ #ifndef _LUA_BINDINGS_H_ #define _LUA_BINDINGS_H_ +#include <map> +#include <vector> +#include <set> +#include "GmshConfig.h" +#include "GmshMessage.h" #include "Bindings.h" #ifdef HAVE_LUA -//#include "BindingsDocTemplates.h" +#include "BindingsTypeName.h" extern "C" { #include "lua.h" #include "lauxlib.h" } -#include <vector> -#include <set> class classBinding; class binding { @@ -27,26 +30,6 @@ class binding { classBinding *addClass(std::string className); }; -/*** store a unique static class name for each binded class ***/ -template <typename type> -class className{ - static std::string _name; - public: - static void set(std::string name){ - if(_name!="") - throw; - _name=name; - } - static const std::string &get(){ - if(_name=="") - throw; - return _name; - } -}; -template<typename type> -std::string className<type>::_name; - - /*** lua Stack : templates to get/push value from/on the lua stack ***/ @@ -55,7 +38,7 @@ template<class type> class luaStack { public: static type get(lua_State *L, int ia){ - printf("error cannot get generic class in lua, only pointers are implemented\n"); + Msg::Error("error cannot get generic class in lua, only pointers are implemented\n"); } static void push(lua_State *L, type obj){ Msg::Error("cannot push generic class in lua, only pointers are implemented\n"); @@ -309,6 +292,8 @@ static int luaCall(lua_State *L,void (tObj::*_f)() const) { return 0; }; + + //non const, no return template <typename tObj, typename t0, typename t1, typename t2, typename t3> static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2,t3)) { @@ -337,6 +322,9 @@ static int luaCall(lua_State *L,void (tObj::*_f)()) { }; +/*** arg names ***/ + + /*** actual bindings classes ***/ class luaMethodBinding :public methodBinding{ public: @@ -348,6 +336,7 @@ class luaMethodBinding :public methodBinding{ luaMethodBinding(){ _luaname=""; } + virtual void getArgTypeNames(std::vector<std::string> &names){}; }; template <typename cb> @@ -360,8 +349,8 @@ class methodBindingT:public luaMethodBinding { int call (lua_State *L) { return luaCall(L,_f); } - void getArgNames(std::string &returnTypeName, std::vector<std::string> &argTypeName) { - getArgNames(_f,returnTypeName,argTypeName); + void getArgTypeNames(std::vector<std::string> &names) { + argTypeNames<cb>::get(names); } }; @@ -373,6 +362,9 @@ class constructorBindingT:public luaMethodBinding { (luaStack<tObj*>::push(L,new tObj(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2),luaStack<t2>::get(L,3), luaStack<t3>::get(L,4)))); return 1; } + void getArgTypeNames(std::vector<std::string> &names) { + argTypeNames<void (tObj::*)(t0,t1,t2,t3)>::get(names); + } }; template <typename tObj> @@ -383,6 +375,9 @@ class constructorBindingT<tObj,void,void,void,void>:public luaMethodBinding { (luaStack<tObj*>::push(L,new tObj())); return 1; } + void getArgTypeNames(std::vector<std::string> &names) { + argTypeNames<void (tObj::*)()>::get(names); + } }; template <typename tObj, typename t0> class constructorBindingT<tObj,t0,void,void,void>:public luaMethodBinding { @@ -392,6 +387,9 @@ class constructorBindingT<tObj,t0,void,void,void>:public luaMethodBinding { (luaStack<tObj*>::push(L,new tObj(luaStack<t0>::get(L,1)))); return 1; } + void getArgTypeNames(std::vector<std::string> &names) { + argTypeNames<void (tObj::*)(t0)>::get(names); + } }; template <typename tObj, typename t0, typename t1> class constructorBindingT<tObj,t0,t1,void,void>:public luaMethodBinding { @@ -401,6 +399,9 @@ class constructorBindingT<tObj,t0,t1,void,void>:public luaMethodBinding { (luaStack<tObj*>::push(L,new tObj(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2)))); return 1; } + void getArgTypeNames(std::vector<std::string> &names) { + argTypeNames<void (tObj::*)(t0,t1)>::get(names); + } }; template <typename tObj, typename t0, typename t1, typename t2> class constructorBindingT<tObj,t0,t1,t2,void>:public luaMethodBinding { @@ -410,11 +411,15 @@ class constructorBindingT<tObj,t0,t1,t2,void>:public luaMethodBinding { (luaStack<tObj*>::push(L,new tObj(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2),luaStack<t2>::get(L,3)))); return 1; } + void getArgTypeNames(std::vector<std::string> &names) { + argTypeNames<void (tObj::*)(t0,t1,t2)>::get(names); + } }; class classBinding { std::string _className; binding *_b; + luaMethodBinding *_constructor; static int callMethod(lua_State *L) { return static_cast<luaMethodBinding*>(lua_touserdata(L, lua_upvalueindex(1)))->call(L); } @@ -444,17 +449,22 @@ class classBinding { lua_pushcclosure(L, callMethod, 1); lua_setfield(L, mt,"__call"); lua_pop(L,2); + _constructor=constructor; } //for the doc std::string _description; classBinding *_parent; public: std::set<classBinding *> children; + inline luaMethodBinding *getConstructor(){ + return _constructor; + } // get userdata from Lua stack and return pointer to T object classBinding(binding *b, std::string name){ _b=b; lua_State *L = _b->L; _className=name; + _constructor=NULL; // there are 3 tables involved : // methods : the table of the C++ functions we bind (exept constructor) diff --git a/Numeric/fullMatrix.cpp b/Numeric/fullMatrix.cpp index 8a75bc796d2c329a96fff7175aaca66491ba03ad..865a4b41e8faed26065ade38b9265f05378683dd 100644 --- a/Numeric/fullMatrix.cpp +++ b/Numeric/fullMatrix.cpp @@ -293,10 +293,17 @@ template<> void fullMatrix<double>::registerBindings(binding *b) { classBinding *cb = b->addClass<fullMatrix<double> >("fullMatrix"); - cb->addMethod("size1", &fullMatrix<double>::size1); - cb->addMethod("size2", &fullMatrix<double>::size2); - cb->addMethod("get", &fullMatrix<double>::get); - cb->addMethod("set", &fullMatrix<double>::set); - cb->addMethod("gemm", &fullMatrix<double>::gemm); - cb->setConstructor<fullMatrix<double>,int,int>(); + methodBinding *cm; + cm = cb->addMethod("size1", &fullMatrix<double>::size1); + cm->setDescription("return the number of rows in the matrix"); + cm = cb->addMethod("size2", &fullMatrix<double>::size2); + cm->setDescription("return the number of columns in the matrix"); + cm = cb->addMethod("get", &fullMatrix<double>::get); + cm->setArgNames("i","j",NULL); + cm->setDescription("return the (i,j) entry of the matrix"); + cm = cb->addMethod("set", &fullMatrix<double>::set); + cm->setArgNames("i","j","v",NULL); + cm->setDescription("set the (i,j) entry of the matrix to v"); + cm = cb->addMethod("gemm", &fullMatrix<double>::gemm); + cm = cb->setConstructor<fullMatrix<double>,int,int>(); }