enum issues

Started by
3 comments, last by WitchLord 12 years, 11 months ago
Hi

I've found some potential bugs regarding enum's when enabling asEP_REQUIRE_ENUM_SCOPE:

Declaring enum with value that has same name as other script declared enum value results in: "Name conflict "xxx" is a global property.", using c++ registered enum value name is ok.

initializing global variable of script declared enum don't need scope (::) operator, and gives error instead: "'TYPE::VALUE' is not declared." Local variables and c++ registered enums are ok.

RegisterEnumValue accepts everything as 'name', even things like "@#$%".
It is also possible to register same enum value name with different enum types without asEP_REQUIRE_ENUM_SCOPE, but this results with error when using enum value without scope, so that might not be a bug.

[source lang="cpp"]

//paste at the end of TestEnum()
{
COutStream out;
engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
r = engine->SetEngineProperty(asEP_REQUIRE_ENUM_SCOPE, 1); assert(r >= 0);

r = engine->RegisterEnum("RENUM_1"); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_1", "R_GLOBAL", 0); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_1", "RE1_1", 1); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_1", "RE1_2", 2); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_1", "@#$%", 777);
if(r < 0)
TEST_FAILED;

r = engine->RegisterEnum("RENUM_2"); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_2", "R_GLOBAL", 13); // that always works (regardless asEP_REQUIRE_ENUM_SCOPE state)
if(r < 0)
TEST_FAILED;
r = engine->RegisterEnumValue("RENUM_2", "RE2_1", 1); assert(r >= 0);
r = engine->RegisterEnumValue("RENUM_2", "RE2_2", 2); assert(r >= 0);

r = engine->RegisterGlobalFunction("void output(int val1)", asFUNCTION(scriptOutput), asCALL_CDECL); assert(r >= 0);

asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
mod->AddScriptSection("script", "enum ENUM_1 \n"
"{ \n"
" TEST_GLOBAL = 0, \n"
" E1_VAL1, \n"
" E1_VAL2, \n"
" RE1_2 \n"
"} \n"
"enum ENUM_2 \n"
"{ \n"
//error: name conflict " TEST_GLOBAL = 0, \n"
" E2_VAL1, \n"
" E2_VAL2 \n"
"} \n"
//that doesn't work -> "ENUM_1 g_e1 = ENUM_1::E1_VAL1; \n"
"ENUM_1 g_e1 = E1_VAL1; \n" // <- that shouldn't (?)
"RENUM_1 rg_e1 = RENUM_1::RE1_2; \n" // <- that's ok
" \n"
"void main() \n"
"{ \n"
" ENUM_1 l_e1 = ENUM_1::E1_VAL1; \n"
" g_e1 = ENUM_1::E1_VAL1; \n"
" rg_e1 = RENUM_1::R_GLOBAL; \n"
" RENUM_2 rl_e2 = RENUM_2::R_GLOBAL; \n"
" output(rg_e1); \n"
" output(rl_e2); \n"
"} \n"
);

r = mod->Build();
if( r < 0 )
TEST_FAILED;

buffer = "";
r = ExecuteString(engine, "main();", mod);
if( r != asEXECUTION_FINISHED )
TEST_FAILED;
if( buffer != "0\n13\n" )
TEST_FAILED;

engine->Release();
}
[/source]
Advertisement
Thanks. I'll look into this and fix what needs fixing.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I've fixed the problems you reported in revision 854. Thanks for preparing the test case that made it so easy to find and fix the bugs.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

[font=arial, verdana, tahoma, sans-serif][size=2]Thanks for quick fix.

I also found that TestExecute fails in release mode (it is unrelated to enums). ctx->SetUserData is never called as assert are discarded in release mode, and without user data, cleanContext is not called, reporting everything as failure (while this is expected behavior). You may want to rewrite this like:[/font]
[source lang="cpp"]

void* prevUserData;
asIScriptContext *ctx = engine->CreateContext();
prevUserData = ctx->SetUserData((void*)(size_t)0xDEADF00D); assert(prevUserData == 0);
prevUserData = ctx->GetUserData(); assert(prevUserData == (void*)(size_t)0xDEADF00D);
prevUserData = ctx->SetUserData(0); assert(prevUserData == (void*)(size_t)0xDEADF00D);
prevUserData = ctx->SetUserData((void*)(size_t)0xDEADF00D); assert(prevUserData == 0);
engine->SetContextUserDataCleanupCallback(cleanContext);
called = false;
ctx->Release();
if( !called )
TEST_FAILED;
[/source]
Thanks. I'll have that corrected too.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement