Fixing enums

This commit is contained in:
Artem Serebriyskiy 2014-03-03 09:54:13 +04:00
commit 1898099620
3 changed files with 55 additions and 45 deletions

View file

@ -510,14 +510,16 @@ Enums are exported into a class table. For example, given some enums:
enum Days { SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };
struct Test {
enum { TEST1 = 10, TEST2 = 20 };
#ifdef __cplusplus // There are no static members in C language
static const int ICONST = 12;
#endif
};
</pre></div>
<p>
This is 'effectively' converted into the following Lua code:
There is a slight difference in behaviour in C mode and C++ model. In C++ mode this is 'effectively' converted into the following Lua code:
</p>
<div class="targetlang"><pre>
&gt; print(example.const.SUNDAY)
&gt; print(example.SUNDAY)
0
&gt; print(example.Test.TEST1)
10
@ -525,6 +527,15 @@ This is 'effectively' converted into the following Lua code:
12
</pre></div>
<p>In C mode enums from structs are exported into global namespace (due to C Standard). See below:</p>
<div class="targetlang"><pre>
&gt; print(example.SUNDAY)
0
&gt; -- See the difference here
&gt; print(example.TEST1)
10
</pre></div>
<p>
<b>Compatibility Note:</b> Versions of SWIG prior to SWIG-3.0.0 did not generate the class table members above.
The following code was the only way to access these constants/enums:
@ -540,17 +551,17 @@ The old-style bindings are still generated in addition to the new ones.
If the <tt>-no-old-metatable-bindings</tt> option is used, then these old-style bindings are not generated.
</p>
<p>
However, in C mode, names of enums are not prefixed with names of structure. This is the due to the C Standard.
However, in C mode, prefixed names of enums are not exported. There is no sense in having both Test_TEST1 and TEST1 in global namespace.
</p>
<div class="targetlang"><pre>
&gt; print(example.TEST1)
10
&gt; print(example.ICONST)
12
&gt; print(example.Test_TEST1)
nil
</pre></div>
<p>
It is worth mentioning, that <tt>example.Test.TEST1</tt> and <tt>example.Test_TEST1</tt> are different entities and changing one does not change the other.
Given the fact, that these are constantes and they are not supposed to be changed, it is up to you to avoid such issues.
Given the fact that these are constantes and they are not supposed to be changed, it is up to you to avoid such issues.
</p>
<H3><a name="Lua_nn12"></a>26.3.5 Pointers</H3>

View file

@ -19,8 +19,8 @@ assert(enums.globalinstance3==30)
assert(enums.AnonEnum1==0)
assert(enums.AnonEnum2==100)
-- In C enums from struct are exported without prefixing with struct name
-- In C++ they are prefixed.
-- In C enums from struct are exported into global namespace (without prefixing with struct name)
-- In C++ they are prefixed (as compatibility thing).
-- We are emulating xor :)
assert(enums.BAR1 ~= enums.Foo_BAR1) -- It is either C style, or C++ style, but not both
assert((enums.BAR1 ~= nil ) or (enums.Foo_BAR1 ~= nil))

View file

@ -1110,47 +1110,43 @@ public:
bool make_v2_compatible = v2_compatibility && getCurrentClass() != 0;
if (make_v2_compatible) {
// Special handling for enums in C mode - they are not prefixed with structure name
if(!CPlusPlus && current[ENUM_CONST]) {
lua_name_v2 = lua_name;
DohIncref(lua_name_v2);
iname_v2 = iname;
DohIncref(iname_v2);
} else {
// Don't do anything for enums in C mode - they are already
// wrapped correctly
if (CPlusPlus || !current[ENUM_CONST]) {
lua_name_v2 = Swig_name_member(0, proxy_class_name, lua_name);
iname_v2 = Swig_name_member(0, proxy_class_name, iname);
}
n_v2 = Copy(n);
//Printf( stdout, "target name v2: %s, symname v2 %s\n", lua_name_v2.ptr(), iname_v2.ptr());// TODO:REMOVE
if (!luaAddSymbol(iname_v2, n, getNSpace())) {
Swig_restore(n);
return SWIG_ERROR;
}
n_v2 = Copy(n);
//Printf( stdout, "target name v2: %s, symname v2 %s\n", lua_name_v2.ptr(), iname_v2.ptr());// TODO:REMOVE
if (!luaAddSymbol(iname_v2, n, getNSpace())) {
Swig_restore(n);
return SWIG_ERROR;
}
Setattr(n_v2, "sym:name", lua_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", lua_name_v2);
Replaceall(tm_v2, "$value", value);
Replaceall(tm_v2, "$nsname", nsname);
registerConstant(getNSpace(), tm_v2);
} else {
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", lua_name_v2);
Replaceall(tm_v2, "$value", value);
Replaceall(tm_v2, "$nsname", nsname);
Printf(f_init, "%s\n", tm_v2);
Setattr(n_v2, "sym:name", lua_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", lua_name_v2);
Replaceall(tm_v2, "$value", value);
Replaceall(tm_v2, "$nsname", nsname);
registerConstant(getNSpace(), tm_v2);
} else {
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", lua_name_v2);
Replaceall(tm_v2, "$value", value);
Replaceall(tm_v2, "$nsname", nsname);
Printf(f_init, "%s\n", tm_v2);
}
Delete(n_v2);
}
Delete(n_v2);
}
Swig_restore(n);
@ -2174,6 +2170,9 @@ public:
// If inside class, but current[NO_CPP], then this is friend function. It belongs to NSpace
if (!getCurrentClass() || current[NO_CPP]) {
scope = getNSpace();
} else if (current[ENUM_CONST] && !CPlusPlus ) {
// Enums in C mode go to NSpace
scope = getNSpace();
} else {
// If inside class, then either class static namespace or class fully qualified name is used
assert(!current[NO_CPP]);