diff --git a/Examples/test-suite/lua/li_carrays_runme.lua b/Examples/test-suite/lua/li_carrays_runme.lua index 285d7b32a..d007fae36 100644 --- a/Examples/test-suite/lua/li_carrays_runme.lua +++ b/Examples/test-suite/lua/li_carrays_runme.lua @@ -1,8 +1,6 @@ require("import") -- the import fn import("li_carrays") -- import code - --- moving to global -for k,v in pairs(li_carrays) do _G[k]=v end +lc = li_carrays -- catch "undefined" global variables local env = _ENV -- Lua 5.2 @@ -10,22 +8,22 @@ if not env then env = getfenv () end -- Lua 5.1 setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end}) -- Testing for %array_functions(int,intArray) -ary = new_intArray(2) -intArray_setitem(ary, 0, 0) -intArray_setitem(ary, 1, 1) -assert(intArray_getitem(ary, 0)==0) -assert(intArray_getitem(ary, 1)==1) -delete_intArray(ary) +ary = lc.new_intArray(2) +lc.intArray_setitem(ary, 0, 0) +lc.intArray_setitem(ary, 1, 1) +assert(lc.intArray_getitem(ary, 0)==0) +assert(lc.intArray_getitem(ary, 1)==1) +lc.delete_intArray(ary) -- Testing for %array_class(double, doubleArray) -d = doubleArray(10) +d = lc.doubleArray(10) d[0] = 7 d[5] = d[0] + 3 assert(d[5] + d[0] == 17) --print(d[5] + d[0]) ptr = d:cast() -- to ptr -d2 = doubleArray_frompointer(ptr) -- and back to array +d2 = lc.doubleArray_frompointer(ptr) -- and back to array assert(d2[5] + d2[0] == 17) --print(d2[5] + d2[0]) diff --git a/Examples/test-suite/lua/member_pointer_runme.lua b/Examples/test-suite/lua/member_pointer_runme.lua index 8dddab295..1240d92a0 100644 --- a/Examples/test-suite/lua/member_pointer_runme.lua +++ b/Examples/test-suite/lua/member_pointer_runme.lua @@ -1,43 +1,46 @@ --Example using pointers to member functions - require("import") -- the import fn import("member_pointer") -- import code +mp = member_pointer -for k,v in pairs(member_pointer) do _G[k]=v end +-- catching undefined variables +local env = _ENV -- Lua 5.2 +if not env then env = getfenv () end -- Lua 5.1 +setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end}) function check(what, expected, actual) assert(expected == actual,"Failed: "..what.." Expected: "..expected.." Actual: "..actual) end -- Get the pointers -area_pt = areapt() -perim_pt = perimeterpt() +area_pt = mp.areapt() +perim_pt = mp.perimeterpt() -- Create some objects -s = Square(10) +s = mp.Square(10) -- Do some calculations -check ("Square area ", 100.0, do_op(s,area_pt)) -check ("Square perim", 40.0, do_op(s,perim_pt)) +check ("Square area ", 100.0, mp.do_op(s,area_pt)) +check ("Square perim", 40.0, mp.do_op(s,perim_pt)) -- Try the variables -- these have to still be part of the 'member_pointer' table -memberPtr = member_pointer.areavar -memberPtr = member_pointer.perimetervar +memberPtr = mp.areavar +memberPtr = mp.perimetervar -check ("Square area ", 100.0, do_op(s,member_pointer.areavar)) -check ("Square perim", 40.0, do_op(s,member_pointer.perimetervar)) +check ("Square area ", 100.0, mp.do_op(s,mp.areavar)) +check ("Square perim", 40.0, mp.do_op(s,mp.perimetervar)) -- Modify one of the variables -member_pointer.areavar = perim_pt +mp.areavar = perim_pt -check ("Square perimeter", 40.0, do_op(s,member_pointer.areavar)) +check ("Square perimeter", 40.0, mp.do_op(s,mp.areavar)) -- Try the constants -memberPtr = AREAPT -memberPtr = PERIMPT -memberPtr = NULLPT +memberPtr = mp.AREAPT +memberPtr = mp.PERIMPT +memberPtr = mp.NULLPT -check ("Square area ", 100.0, do_op(s,AREAPT)) -check ("Square perim", 40.0, do_op(s,PERIMPT)) +check ("Square area ", 100.0, mp.do_op(s,mp.AREAPT)) +check ("Square perim", 40.0, mp.do_op(s,mp.PERIMPT)) diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg index 764ec5fe4..4ed260774 100644 --- a/Lib/lua/luarun.swg +++ b/Lib/lua/luarun.swg @@ -138,19 +138,19 @@ typedef struct { } swig_lua_attribute; -struct swig_lua_class; +struct _swig_lua_class; // Can be used to create namespaces. Currently used to // wrap class static methods/variables/constants -struct swig_lua_namespace { +typedef struct _swig_lua_namespace { const char *name; swig_lua_method *ns_methods; swig_lua_attribute *ns_attributes; swig_lua_const_info *ns_constants; - swig_lua_class **ns_classes; - swig_lua_namespace **ns_namespaces; -}; + struct _swig_lua_class **ns_classes; + struct _swig_lua_namespace **ns_namespaces; +} swig_lua_namespace; -struct swig_lua_class { +typedef struct _swig_lua_class { const char *name; // Name that this class has in Lua const char *fqname; // Fully qualified name - Scope + class name swig_type_info **type; @@ -159,9 +159,9 @@ struct swig_lua_class { swig_lua_method *methods; swig_lua_attribute *attributes; swig_lua_namespace *cls_static; - struct swig_lua_class **bases; + struct _swig_lua_class **bases; const char **base_names; -}; +} swig_lua_class; /* this is the struct for wrapping all pointers in SwigLua */ @@ -351,6 +351,10 @@ SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State* L, swig_lua_namespace* assert(lua_istable(L,-1)); SWIG_Lua_InstallConstants(L, ns->ns_constants); + /* add methods to the namespace/module table */ + for(i=0;ns->ns_methods[i].name;i++){ + SWIG_Lua_add_function(L,ns->ns_methods[i].name,ns->ns_methods[i].func); + } lua_getmetatable(L,-1); /* add fns */ @@ -358,6 +362,8 @@ SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State* L, swig_lua_namespace* SWIG_Lua_add_variable(L,ns->ns_attributes[i].name,ns->ns_attributes[i].getmethod,ns->ns_attributes[i].setmethod); } +#if 0 + // TODO: REMOVE. .fn table is unused /* add methods to the metatable */ SWIG_Lua_get_table(L,".fn"); /* find the .fn table */ assert(lua_istable(L,-1)); /* just in case */ @@ -365,6 +371,7 @@ SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State* L, swig_lua_namespace* SWIG_Lua_add_function(L,ns->ns_methods[i].name,ns->ns_methods[i].func); } lua_pop(L,1); +#endif /* clear stack - remove metatble */ lua_pop(L,1); @@ -393,7 +400,7 @@ SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State* L, swig_lua_namespace* when function is called) Function always returns newly registered table on top of the stack */ -SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns, bool reg) +SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns, int reg) { int begin = lua_gettop(L); assert(lua_istable(L,-1)); /* just in case. This is supposed to be module table or parent namespace table */ @@ -428,7 +435,7 @@ SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns, swig_lua_namespace** sub_namespace = ns->ns_namespaces; if( sub_namespace != 0) { while(*sub_namespace != 0) { - SWIG_Lua_namespace_register(L, *sub_namespace, true); + SWIG_Lua_namespace_register(L, *sub_namespace, 1); lua_pop(L,1); // removing sub-namespace table sub_namespace++; } @@ -867,7 +874,7 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State* L, swig_lua_class* cls assert(lua_istable(L,-1)); /* just in case */ assert(strcmp(clss->name, clss->cls_static->name) == 0); /* in class those 2 must be equal */ - SWIG_Lua_namespace_register(L,clss->cls_static, true); + SWIG_Lua_namespace_register(L,clss->cls_static, 1); assert(lua_istable(L,-1)); /* just in case */ diff --git a/Lib/lua/luaruntime.swg b/Lib/lua/luaruntime.swg index 0011c9d52..5e4ba9fd9 100644 --- a/Lib/lua/luaruntime.swg +++ b/Lib/lua/luaruntime.swg @@ -49,9 +49,9 @@ SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */ SWIG_Lua_init_base_class(L,(swig_lua_class*)(swig_types[i]->clientdata)); } } - bool globalRegister = false; + int globalRegister = 0; #ifdef SWIG_LUA_MODULE_GLOBAL - globalRegister = true; + globalRegister = 1; #endif SWIG_Lua_namespace_register(L,&swig___Global, globalRegister); #endif diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx index 0c5821326..824590b3a 100644 --- a/Source/Modules/lua.cxx +++ b/Source/Modules/lua.cxx @@ -91,14 +91,16 @@ class DohPtrGuard { // Guard is empty, ptr - any: assigns new value for guard // Guard is holding pointer, ptr == 0 - releases value that guard holds // Any other combination - assert - void operator=( DOH* ptr ) { + DOH* operator=( DOH* ptr ) { attach(ptr); + return ptr; } DOH* ptr() { return p_ptr; } const DOH* ptr() const { return p_ptr; } operator DOH* () { return p_ptr; } operator DOH* () const { return p_ptr; } + operator bool() const { return ptr != 0; } private: DOH* p_ptr; // pointer to actual object @@ -129,11 +131,11 @@ class DohPtrGuard { // Overloading DohDelete for DohPtrGuard. You might not call DohDelete on DohPtrGuard instances, // as it is supposed to manage underlying pointer by itself -void DohDelete(const DohPtrGuard& guard) { +void DohDelete(const DohPtrGuard& /*guard*/) { Printf( stderr, "ERROR: Attempt to delete guarded pointer without deleting it's guardian\n" ); assert(false); } -void DohDelete(DohPtrGuard& guard) { +void DohDelete(DohPtrGuard& /*guard*/) { Printf( stderr, "ERROR: Attempt to delete guarded pointer without deleting it's guardian\n" ); assert(false); } @@ -152,12 +154,23 @@ Lua Options (available with -lua)\n\ -eluac - LTR compatible wrappers in \"crass compress\" mode for elua\n\ -nomoduleglobal - Do not register the module name as a global variable \n\ but return the module table from calls to require.\n\ + -api-lvl-from NUM\n\ + - Force support for old-style bindings. All old-style bindings\n\ + from NUM to current new-style bindings will be supported. For example,\n\ + if current lua bindings API version is 10 and NUM==7 then SWIG will\n\ + generate bindings compatible with lua bindings versions 7,8,9 and,\n\ + of course current version of bindings, 10.\n\ + API levels:\n\ + 2 - SWIG 2.*\n\ + 3 - SWIG 3.*\n\ + Default NUM is 2.\n\ \n"; static int nomoduleglobal = 0; static int elua_ltr = 0; static int eluac_ltr = 0; -static int v2_compatibility = 1; +static int v2_compatibility = 0; +static const int default_api_level = 2; /* NEW LANGUAGE NOTE:*********************************************** To add a new language, you need to derive your class from @@ -260,6 +273,7 @@ public: virtual void main(int argc, char *argv[]) { + int api_level = default_api_level; // Default api level /* Set location of SWIG library */ SWIG_library_directory("lua"); @@ -277,10 +291,30 @@ public: } else if(strcmp(argv[i], "-eluac") == 0) { eluac_ltr = 1; Swig_mark_arg(i); + } else if(strcmp(argv[i], "-api-lvl-from") == 0) { + if(argv[i+1]) { + api_level = atoi(argv[i+1]); + if(api_level == 0) + Swig_arg_error(); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } } } } + // Set API-compatibility options + if(api_level <= 2) // Must be compatible with SWIG 2.* + v2_compatibility = 1; + // template for further API breaks + //if(api_level <= 3) + // v3_compatibility = 1; + //if(api_level <= 4) + // v4_compatibility = 1; + + /* NEW LANGUAGE NOTE:*********************************************** This is the boilerplate code, setting a few #defines and which lib directory to use @@ -400,7 +434,7 @@ public: if (elua_ltr || eluac_ltr) { /* Final close up of wrappers */ - closeNamespaces(f_wrappers); // TODO: Remove last parameter + closeNamespaces(f_wrappers); SwigType_emit_type_table(f_runtime, f_wrappers); } else { //Printv(f_wrappers, s_cmd_tab, s_var_tab, s_const_tab, NIL); @@ -491,6 +525,16 @@ public: Setattr(n, "varget:wrap:name", wrapname); } + // Helper for functionWrapper - determines whether we should + // register method in the appropriate class/namespace/module + // table or not. + // (not => it is variable wrapper or something similar) + bool functionWrapperRegisterNow() const { + if (current[VARIABLE]) + return false; + return (current[NO_CPP] || current[STATIC_FUNC]); + } + virtual int functionWrapper(Node *n) { REPORT("functionWrapper",n); @@ -503,14 +547,13 @@ public: Parm *p; String *tm; int i; - //Printf(stdout,"functionWrapper %s %s %d\n",name,iname,current); + //Printf(stdout,"functionWrapper %s %s %d\n",name,iname,current); // TODO: COMMENT BACK String *overname = 0; if (Getattr(n, "sym:overloaded")) { overname = Getattr(n, "sym:overname"); } else { if (!luaAddSymbol(target_name, n)) { - Printf(stderr,"addSymbol(%s) failed\n",target_name); return SWIG_ERROR; } } @@ -790,13 +833,14 @@ public: different language mappings seem to use different ideas NEW LANGUAGE NOTE:END ************************************************/ /* Now register the function with the interpreter. */ + int result = SWIG_OK; if (!Getattr(n, "sym:overloaded")) { - if (current[NO_CPP] || current[STATIC_FUNC]) { // emit normal fns & static fns - registerMethod(getNSpace(), n); + if (functionWrapperRegisterNow()) { // emit normal fns & static fns + registerMethod(luaCurrentSymbolNSpace(), n); } } else { if (!Getattr(n, "sym:nextSibling")) { - dispatchFunction(n); + result = dispatchFunction(n); } } @@ -808,7 +852,7 @@ public: // Delete(description); DelWrapper(f); - return SWIG_OK; + return result; } /* ------------------------------------------------------------ @@ -823,7 +867,7 @@ public: nost of the real work in again typemaps: look for %typecheck(SWIG_TYPECHECK_*) in the .swg file NEW LANGUAGE NOTE:END ************************************************/ - void dispatchFunction(Node *n) { + int dispatchFunction(Node *n) { //REPORT("dispatchFunction", n); /* Last node in overloaded chain */ @@ -841,6 +885,10 @@ public: //Printf(stdout,"Swig_overload_dispatch %s %s '%s' %d\n",symname,wname,dispatch,maxargs); + if (!luaAddSymbol(target_name, n)) { + return SWIG_ERROR; + } + Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL); Wrapper_add_local(f, "argc", "int argc"); Printf(tmp, "int argv[%d]={1", maxargs + 1); @@ -870,8 +918,12 @@ public: Printf(f->code, "lua_error(L);return 0;\n"); Printv(f->code, "}\n", NIL); Wrapper_print(f, f_wrappers); - if (current[NO_CPP] || current[STATIC_FUNC]) { // emit normal fns & static fns - registerMethod(getNSpace(), n); + + // Remember C name of the wrapping function + rememberWrapName(n, wname); + + if (functionWrapperRegisterNow()) { // emit normal fns & static fns + registerMethod(luaCurrentSymbolNSpace(), n); } if (current[CONSTRUCTOR]) { if( constructor_name != 0 ) @@ -879,12 +931,11 @@ public: constructor_name = Copy(wname); } - // Remember C name of the wrapping function - rememberWrapName(n, wname); - DelWrapper(f); Delete(dispatch); Delete(tmp); + + return SWIG_OK; } @@ -906,8 +957,8 @@ public: current[VARIABLE] = true; // let SWIG generate the wrappers int result = Language::variableWrapper(n); + registerVariable( luaCurrentSymbolNSpace(), n, "varget:wrap:name", "varset:wrap:name" ); current[VARIABLE] = false; - registerVariable( getNSpace(), n, "varget:wrap:name", "varset:wrap:name" ); return result; } @@ -926,10 +977,26 @@ public: String *rawval = Getattr(n, "rawval"); String *value = rawval ? rawval : Getattr(n, "value"); String *tm; + PtrGuard target_name_v2; + PtrGuard tm_v2; + PtrGuard iname_v2; + PtrGuard n_v2; if (!luaAddSymbol(target_name, n)) return SWIG_ERROR; + bool make_v2_compatible = v2_compatibility && getCurrentClass() != 0; + //Printf( stdout, "V2 compatible: %d\n", int(make_v2_compatible) ); // TODO: REMOVE + if( make_v2_compatible ) { + target_name_v2 = Swig_name_member(0, class_symname, target_name); + iname_v2 = Swig_name_member(0, class_symname, iname); + n_v2 = Copy(n); + //Printf( stdout, "target name v2: %s, symname v2 %s\n", target_name_v2.ptr(), iname_v2.ptr());// TODO:REMOVE + if (!luaAddSymbol(iname_v2, n, class_parent_nspace)) { + return SWIG_ERROR; + } + } + Swig_save("lua_constantMember", n, "sym:name", NIL); Setattr(n, "sym:name", target_name); /* Special hook for member pointer */ @@ -940,16 +1007,17 @@ public: } if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) { + //Printf(stdout, "tm v1: %s\n", tm); // TODO:REMOVE Replaceall(tm, "$source", value); - Replaceall(tm, "$target", name); + Replaceall(tm, "$target", target_name); Replaceall(tm, "$value", value); Replaceall(tm, "$nsname", nsname); - Hash *nspaceHash = getNamespaceHash( getNSpace() ); + Hash *nspaceHash = getNamespaceHash( luaCurrentSymbolNSpace() ); String *s_const_tab = Getattr(nspaceHash, "constants"); Printf(s_const_tab, " %s,\n", tm); } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { Replaceall(tm, "$source", value); - Replaceall(tm, "$target", name); + Replaceall(tm, "$target", target_name); Replaceall(tm, "$value", value); Replaceall(tm, "$nsname", nsname); Printf(f_init, "%s\n", tm); @@ -959,34 +1027,35 @@ public: Swig_restore(n); return SWIG_NOWRAP; } - /* TODO: Review - if( v2_compatibility && getCurrentClass() ) { - if (!luaAddSymbol(iname, n, class_parent_nspace)) - return SWIG_ERROR; - Setattr(n, "sym:name", iname); - if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) { - Replaceall(tm, "$source", value); - Replaceall(tm, "$target", name); - Replaceall(tm, "$value", value); - Replaceall(tm, "$nsname", nsname); + if( make_v2_compatible ) { + Setattr(n_v2, "sym:name", target_name_v2); + tm_v2 = Swig_typemap_lookup("consttab", n_v2, name, 0); + if (tm_v2) { + //Printf(stdout, "tm v2: %s\n", tm_v2.ptr()); // TODO:REMOVE + Replaceall(tm_v2, "$source", value); + Replaceall(tm_v2, "$target", target_name_v2); + Replaceall(tm_v2, "$value", value); + Replaceall(tm_v2, "$nsname", nsname); Hash *nspaceHash = getNamespaceHash( class_parent_nspace ); String *s_const_tab = Getattr(nspaceHash, "constants"); - Printf(s_const_tab, " %s,\n", tm); - } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { - Replaceall(tm, "$source", value); - Replaceall(tm, "$target", name); - Replaceall(tm, "$value", value); - Replaceall(tm, "$nsname", nsname); - Printf(f_init, "%s\n", tm); + Printf(s_const_tab, " %s,\n", tm_v2.ptr()); } else { - Delete(nsname); - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); - Swig_restore(n); - return SWIG_NOWRAP; + tm_v2 = Swig_typemap_lookup("constcode", n_v2, name, 0); + if( !tm_v2) { + // This can't be. + assert(false); + Swig_restore(n); + return SWIG_ERROR; + } + Replaceall(tm_v2, "$source", value); + Replaceall(tm_v2, "$target", target_name_v2); + Replaceall(tm_v2, "$value", value); + Replaceall(tm_v2, "$nsname", nsname); + Printf(f_init, "%s\n", tm_v2.ptr()); } } - */ + Swig_restore(n); Delete(nsname); return SWIG_OK; @@ -1019,9 +1088,11 @@ public: // So this is the exact copy of function from Language with // correct handling of namespaces String *oldNSpace = getNSpace(); + /* TODO: REVIEW/REMOVE_and_replace_with_Language::enumDeclaration if( getCurrentClass() == 0 ) { setNSpace(Getattr(n, "sym:nspace")); - } + }*/ + setNSpace(Getattr(n, "sym:nspace")); if (!ImportMode) { current[STATIC_CONST] = true; @@ -1054,12 +1125,11 @@ public: Setattr(n, "value", tmpValue); Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */ - constantWrapper(n); + int result = constantWrapper(n); Delete(tmpValue); Swig_restore(n); - // TODO: Backward compatibility: add ClassName_ConstantName member - return SWIG_OK; + return result; } /* ------------------------------------------------------------ @@ -1173,11 +1243,11 @@ public: // Replacing namespace with namespace + class in order to static // member be put inside class static area class_parent_nspace = getNSpace(); - setNSpace(class_static_nspace); + //setNSpace(class_static_nspace); TODO: REMOVE // Generate normal wrappers Language::classHandler(n); // Restore correct nspace - setNSpace(nspace); + //setNSpace(nspace); // TODO: REMOVE if remove above class_parent_nspace = 0; SwigType_add_pointer(t); @@ -1418,6 +1488,22 @@ public: return SWIG_OK; } + /* ---------------------------------------------------------------------- + * globalfunctionHandler() + * It can be called: + * 1. Usual C/C++ global function. + * 2. During class parsing for functions declared/defined as friend + * 3. During class parsing from staticmemberfunctionHandler + * ---------------------------------------------------------------------- */ + int globalfunctionHandler(Node *n) { + bool oldVal = current[NO_CPP]; + if(!current[STATIC_FUNC]) // If static funct, don't switch to NO_CPP + current[NO_CPP] = true; + int result = Language::globalfunctionHandler(n); + current[NO_CPP] = oldVal; + return result; + } + /* ----------------------------------------------------------------------- * staticmemberfunctionHandler() * @@ -1427,7 +1513,6 @@ public: virtual int staticmemberfunctionHandler(Node *n) { REPORT("staticmemberfunctionHandler", n); current[STATIC_FUNC] = true; - //String *symname = Getattr(n, "sym:name"); int result = Language::staticmemberfunctionHandler(n); current[STATIC_FUNC] = false;; @@ -1444,18 +1529,6 @@ public: Swig_restore(n); } - if (Getattr(n, "sym:nextSibling")) - return SWIG_OK; - - //Swig_require("luaclassobj_staticmemberfunctionHandler", n, "luaclassobj:wrap:name", NIL); - //String *name = Getattr(n, "name"); - //String *rname, *realname; - //realname = symname ? symname : name; - //rname = Getattr(n, "luaclassobj:wrap:name"); - // TODO: Add backward compatibility here: add "ClassName_FuncName" to global table - //Printv(s_cls_methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL); - //Swig_restore(n); - return SWIG_OK; } @@ -1495,13 +1568,10 @@ public: if( !GetFlag(n,"wrappedasconstant") ) { Setattr(n, "lua:name", v2_name); registerVariable( class_parent_nspace, n, "varget:wrap:name", "varset:wrap:name"); - } else { - Setattr(n, "lua:name", v2_name); - String* oldNSpace = getNSpace(); - setNSpace(class_parent_nspace); - constantWrapper(n); - setNSpace(oldNSpace); } + // If static member variable was wrapped as constant, then + // constant wrapper has already performed all actions + // necessary for v2_compatibility Delete(v2_name); Swig_restore(n); } @@ -1805,6 +1875,12 @@ public: // Recursively close all non-closed namespaces. Prints data to dataOutput, void closeNamespaces(File *dataOutput) { + // Special handling for empty module. + if( Getattr(namespaces_hash, "") == 0 ) { + // Module is empty. Create hash for global scope in order to have swig__Global + // variable in resulting file + getNamespaceHash(0); + } Iterator ki = First(namespaces_hash); List* to_close = NewList(); while (ki.key) { @@ -1904,14 +1980,19 @@ public: } } - - // Our implementation of addSymbol. Determines scope correctly, then calls Language::addSymbol - int luaAddSymbol(const String *s, const Node *n) { + // This function determines actual namespace/scope where any symbol at the + // current moment should be placed. It looks at the 'current' array + // and depending on where are we - static class member/function, + // instance class member/function or just global functions decides + // where symbol should be put. + // The namespace/scope doesn't depend from symbol, only from 'current' + String* luaCurrentSymbolNSpace() { String* scope = 0; // If ouside class, than NSpace is used. - if( !getCurrentClass()) + // If inside class, but current[NO_CPP], then this is friend function. It belongs to NSpace + if( !getCurrentClass() || current[NO_CPP]) { scope = getNSpace(); - else { + } else { // If inside class, then either class static namespace or class fully qualified name is used assert(!current[NO_CPP]); if(current[STATIC_FUNC] || current[STATIC_VAR] || current[STATIC_CONST] ) { @@ -1924,13 +2005,26 @@ public: } assert(scope != 0); } - //Printf(stdout, "addSymbol: %s scope: %s\n", s, scope); - return Language::addSymbol(s,n,scope); + return scope; + } + + // Our implementation of addSymbol. Determines scope correctly, then calls Language::addSymbol + int luaAddSymbol(const String *s, const Node *n) { + String *scope = luaCurrentSymbolNSpace(); + //Printf(stdout, "luaAddSymbol: %s scope: %s\n", s, scope); + int result = Language::addSymbol(s,n,scope); + if( !result ) + Printf(stderr,"addSymbol(%s to scope %s) failed\n",s, scope); + return result; } // Overload. Enforces given scope. Actually, it simply forwards call to Language::addSymbol int luaAddSymbol(const String*s, const Node*n, const_String_or_char_ptr scope) { - return Language::addSymbol(s,n,scope); + //Printf(stdout, "luaAddSymbol: %s scope: %s\n", s, scope); + int result = Language::addSymbol(s,n,scope); + if( !result ) + Printf(stderr,"addSymbol(%s to scope %s) failed\n",s, scope); + return result; } // Function creates fully qualified name of given symbol. Current NSpace and current class