コード例 #1
0
ファイル: Script.cpp プロジェクト: ByeDream/pixellight
void Script::PushArgument(const String &sString)
{
	if (m_pAngelScriptContext) {
		CScriptString *pCScriptString = new CScriptString(sString.GetASCII(), sString.GetLength());
		m_pAngelScriptContext->SetArgObject(m_nCurrentArgument++, pCScriptString);
		pCScriptString->Release();	// Destroy our CScriptString instance
	}
}
コード例 #2
0
ファイル: test_scriptstring.cpp プロジェクト: Racenet/racesow
bool Test()
{
	bool fail = false;
	COutStream out;
	asIScriptEngine *engine = 0;
	asIScriptModule *mod = 0;
	int r;

	fail = Test2() || fail;

	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	RegisterScriptString(engine);
	RegisterScriptStringUtils(engine);

	engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(PrintString), asCALL_GENERIC);
	engine->RegisterGlobalFunction("void set(string@)", asFUNCTION(SetString), asCALL_GENERIC);
	engine->RegisterGlobalFunction("void set2(string@&in)", asFUNCTION(SetString2), asCALL_GENERIC);
	engine->RegisterGlobalFunction("const string &getconststringref()", asFUNCTION(GetConstStringRef), asCALL_GENERIC);
	engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);


	// Test index operator for temp strings
	r = engine->ExecuteString(0, "assert('abc'[0] == 97)");
	if( r != asEXECUTION_FINISHED )
		fail = true;

	r = engine->ExecuteString(0, "assert(string('abc')[0] == 97)");
	if( r != asEXECUTION_FINISHED )
		fail = true;

	r = engine->ExecuteString(0, "string a = 'abc'; assert(a[0] == 97)");
	if( r != asEXECUTION_FINISHED )
		fail = true;


	// Test string copy constructor
	r = engine->ExecuteString(0, "string tst(getconststringref()); print(tst);");
	if( r != asEXECUTION_FINISHED ) fail = true;
	if( printOutput != "test" ) fail = true;


	printOutput = "";
	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, script2, strlen(script2), 0);
	mod->Build();

	engine->ExecuteString(0, "testString()");

	if( printOutput != "hello Ida" )
	{
		fail = true;
		printf("%s: Failed to print the correct string\n", TESTNAME);
	}

	engine->ExecuteString(0, "string s = \"test\\\\test\\\\\"");

	// Verify that it is possible to use the string in constructor parameters
	printOutput = "";
	engine->ExecuteString(0, "string a; a = 1; print(a);");
	if( printOutput != "1" ) fail = true;

	printOutput = "";
	engine->ExecuteString(0, "string a; a += 1; print(a);");
	if( printOutput != "1" ) fail = true;

	printOutput = "";
	engine->ExecuteString(0, "string a = \"a\" + 1; print(a);");
	if( printOutput != "a1" ) fail = true;

	printOutput = "";
	engine->ExecuteString(0, "string a = 1 + \"a\"; print(a);");
	if( printOutput != "1a" ) fail = true;

	printOutput = "";
	engine->ExecuteString(0, "string a = 1; print(a);");
	if( printOutput != "1" ) fail = true;

	printOutput = "";
	engine->ExecuteString(0, "print(\"a\" + 1.2)");
	if( printOutput != "a1.2") fail = true;

	printOutput = "";
	engine->ExecuteString(0, "print(1.2 + \"a\")");
	if( printOutput != "1.2a") fail = true;

	// Passing a handle to a function
	printOutput = "";
	engine->ExecuteString(0, "string a; set(@a); print(a);");
	if( printOutput != "Handle to a string" ) fail = true;

	// Implicit conversion to handle
	printOutput = "";
	engine->ExecuteString(0, "string a; set(a); print(a);");
	if( printOutput != "Handle to a string" ) fail = true;

	// Passing a reference to a handle to the function
	printOutput = "";
	engine->ExecuteString(0, "string a; set2(@a); print(a);");
	if( printOutput != "Handle to a string" ) fail = true;

	// Implicit conversion to reference to a handle
	printOutput = "";
	engine->ExecuteString(0, "string a; set2(a); print(a);");
	if( printOutput != "Handle to a string" ) fail = true;

    printOutput = "";
    engine->ExecuteString(0, "string a = \" \"; a[0] = 65; print(a);");
    if( printOutput != "A" ) fail = true;

	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, script3, strlen(script3), 0);
	if( mod->Build() < 0 )
		fail = true;

	printOutput = "";
	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, script4, strlen(script4), 0);
	if( mod->Build() < 0 )
		fail = true;
	engine->ExecuteString(0, "test()");
	if( printOutput != "Heredoc\\x20test!" ) fail = true;

	CScriptString *a = new CScriptString("a");
	engine->RegisterGlobalProperty("string a", a);
	r = engine->ExecuteString(0, "print(a == 'a' ? 't' : 'f')");
	if( r != asEXECUTION_FINISHED )
	{
		fail = true;
		printf("%s: ExecuteString() failed\n", TESTNAME);
	}
	a->Release();

	// test new
	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, script5, strlen(script5), 0);
	if( mod->Build() < 0 ) fail = true;
	r = engine->ExecuteString(0, "Main()");
	if( r != asEXECUTION_FINISHED ) fail = true;

	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection(TESTNAME, script6, strlen(script6), 0);
	if( mod->Build() < 0 ) fail = true;
	r = engine->ExecuteString(0, "Main()");
	if( r != asEXECUTION_FINISHED ) fail = true;


	// Test character literals
	r = engine->SetEngineProperty(asEP_USE_CHARACTER_LITERALS, true); assert( r >= 0 );
	printOutput = "";
	r = engine->ExecuteString(0, "print(\"\" + 'a')");
	if( r != asEXECUTION_FINISHED ) fail = true;
	if( printOutput != "97" ) fail = true;

	printOutput = "";
	r = engine->ExecuteString(0, "print(\"\" + '\\'')");
	if( r != asEXECUTION_FINISHED ) fail = true;
	if( printOutput != "39" ) fail = true;

	printOutput = "";
	r = engine->ExecuteString(0, "print(\"\" + '\xFF')");
	if( r != asEXECUTION_FINISHED ) fail = true;
	if( printOutput != "255" ) fail = true;
 
	CBufferedOutStream bout;
	engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL);
	r = engine->ExecuteString(0, "print(\"\" + '')");
	if( r != -1 ) fail = true;
	r = engine->SetEngineProperty(asEP_USE_CHARACTER_LITERALS, false); assert( r >= 0 );

	//-------------------------------------
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);

	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("test", script7, strlen(script7), 0);
	mod->Build();
	r = engine->ExecuteString(0, "test()");
	if( r != asEXECUTION_FINISHED ) fail = true;

	engine->RegisterObjectType("Http", sizeof(int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE);
	engine->RegisterObjectMethod("Http","bool get(const string &in,string &out)", asFUNCTION(Get),asCALL_GENERIC);

	r = engine->ExecuteString(0, "Http h; string str; h.get('stringtest', str); assert(str == 'output');");
	if( r != asEXECUTION_FINISHED ) fail = true;

	r = engine->ExecuteString(0, "Http h; string a = 'test', b; h.get('string'+a, b); assert(b == 'output');");
	if( r != asEXECUTION_FINISHED ) fail = true;

	// Test the string utils
	engine->ExecuteString(0, "string str = 'abcdef'; assert(findFirst(str, 'def') == 3);");
	engine->ExecuteString(0, "string str = 'abcdef'; assert(findFirstOf(str, 'feb') == 1);");
	engine->ExecuteString(0, "string str = 'a|b||d'; string@[]@ array = split(str, '|'); assert(array.length() == 4); assert(array[1] == 'b');");
	engine->ExecuteString(0, "string@[] array = {'a', 'b', '', 'd'}; assert(join(array, '|') == 'a|b||d');");

	engine->Release();

	//---------------------------------------
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
	RegisterScriptString(engine);

	engine->RegisterGlobalFunction("void TestFunc(int, string&)", asFUNCTION(TestFunc), asCALL_GENERIC);

	// CHKREF was placed incorrectly
	r = engine->ExecuteString(0, "TestFunc(0, 'test');");
	if( r != asEXECUTION_FINISHED )
		fail = true;

	r = engine->ExecuteString(0, "string @s; TestFunc(0, s);");
	if( r != asEXECUTION_EXCEPTION )
		fail = true;

	engine->Release();

	//----------------------------------------
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
	RegisterScriptString(engine);

	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("test", script7, strlen(script7), 0);
	mod->Build();
	r = engine->ExecuteString(0, "test()");
	if( r != asEXECUTION_FINISHED ) fail = true;

	engine->Release();

	//------------------------------------------
	// Test the comparison method
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		RegisterScriptString(engine);

		std::string a = "a";
		std::string b = "b";

		int type = engine->GetTypeIdByDecl("string");
		bool c;
		r = engine->CompareScriptObjects(c, asBEHAVE_EQUAL, &a, &b, type); assert( r >= 0 );
		if( c ) fail = true;
		r = engine->CompareScriptObjects(c, asBEHAVE_NOTEQUAL, &a, &b, type); assert( r >= 0 );
		if( !c ) fail = true;
		r = engine->CompareScriptObjects(c, asBEHAVE_LESSTHAN, &a, &b, type); assert( r >= 0 );
		if( !c ) fail = true;
		r = engine->CompareScriptObjects(c, asBEHAVE_GREATERTHAN, &a, &b, type); assert( r >= 0 );
		if( c ) fail = true;
		r = engine->CompareScriptObjects(c, asBEHAVE_LEQUAL, &a, &b, type); assert( r >= 0 );
		if( !c ) fail = true;
		r = engine->CompareScriptObjects(c, asBEHAVE_GEQUAL, &a, &b, type); assert( r >= 0 );
		if( c ) fail = true;

		engine->Release();
	}

	//-----
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterScriptString(engine);
		engine->RegisterGlobalFunction("void Print(string &str)",asFUNCTION(PrintRef), asCALL_GENERIC);

		const char *script =
			"string str = 'Some String'; \n"
			"void Update() \n"
			"{ \n"
			" Print(str); \n"
			"} \n";

		mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
		mod->AddScriptSection("script", script, strlen(script));
		mod->Build();

		CScriptString *str = (CScriptString*)mod->GetAddressOfGlobalVar(0);
		UNUSED_VAR(str);

		r = engine->ExecuteString(0, "Update()");
		if( r != asEXECUTION_FINISHED )
			fail = true;

		engine->Release();
	}

	//-------
	// Multiline strings
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);
		RegisterScriptString(engine);
		engine->SetEngineProperty(asEP_ALLOW_MULTILINE_STRINGS, true);
		engine->RegisterGlobalFunction("void assert(bool)",asFUNCTION(Assert), asCALL_GENERIC);

		const char *script =
			"string str1 = '1\\n' '2'; \n"
			"string str2 = '1\n2';     \n"
			"assert(str1 == str2);     \n";

		r = engine->ExecuteString(0, script);
		if( r != asEXECUTION_FINISHED )
			fail = true;

		engine->Release();
	}

	return fail;
}
コード例 #3
0
ファイル: test_any.cpp プロジェクト: Kaperstone/warsow
bool Test()
{
	bool fail = false;
	int r;
	COutStream out;
	asIScriptContext *ctx;
	asIScriptEngine *engine;
	CBufferedOutStream bout;

	// ---------------------------------------------
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	RegisterScriptArray(engine, true);
	RegisterScriptString_Generic(engine);
	RegisterScriptAny(engine);
	engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
	r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 );

	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("TestAny", script1, strlen(script1), 0);
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("%s: Failed to compile the script\n", "TestAny");
	}
	ctx = engine->CreateContext();
	r = ExecuteString(engine, "TestAny()", mod, ctx);
	if( r != asEXECUTION_FINISHED )
	{
		if( r == asEXECUTION_EXCEPTION )
			PrintException(ctx);

		TEST_FAILED;
		printf("%s: Execution failed\n", "TestAny");
	}
	if( ctx ) ctx->Release();
	engine->Release();

	//--------------------------------------------------
	// Verify that the GC can handle circles with any structures
 	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	RegisterScriptArray(engine, true);
	RegisterScriptString_Generic(engine);
	RegisterScriptAny(engine);
	engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
	r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 );

	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("TestAny", script2, strlen(script2), 0);
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("%s: Failed to compile the script\n", "TestAny");
	}
	ctx = engine->CreateContext();
	r = ExecuteString(engine, "TestAny()", mod, ctx);
	if( r != asEXECUTION_FINISHED )
	{
		if( r == asEXECUTION_EXCEPTION )
			PrintException(ctx);

		TEST_FAILED;
		printf("%s: Execution failed\n", "TestAny");
	}
	if( ctx ) ctx->Release();
	
	asUINT gcCurrentSize, gcTotalDestroyed, gcTotalDetected;
	engine->GetGCStatistics(&gcCurrentSize, &gcTotalDestroyed, &gcTotalDetected);
	engine->GarbageCollect();
	engine->GetGCStatistics(&gcCurrentSize, &gcTotalDestroyed, &gcTotalDetected);

	if( !fail )
		assert( gcCurrentSize == 8 && gcTotalDestroyed == 8 && gcTotalDetected == 7 );

	engine->Release();

	//-------------------------------------------------------
	// Don't allow const handle to retrieve()
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	RegisterScriptArray(engine, true);
	RegisterScriptString_Generic(engine);
	RegisterScriptAny(engine);
	engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
	r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 );

	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("TestAny", script3, strlen(script3), 0);
	engine->SetMessageCallback(asMETHOD(CBufferedOutStream,Callback), &bout, asCALL_THISCALL);
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("%s: Failed to Build()\n", "TestAny");
	}
	if( bout.buffer != "TestAny (5, 1) : Info    : Compiling void TestAny()\n"
	                   "TestAny (9, 15) : Warning : Argument cannot be assigned. Output will be discarded.\n" )
	{
		printf("%s", bout.buffer.c_str());
		TEST_FAILED;
	}

	engine->Release();

	//--------------------------------------------------------
	// Make sure it is possible to pass any to the application
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	RegisterScriptArray(engine, true);
	RegisterScriptString_Generic(engine);
	RegisterScriptAny(engine);
	engine->RegisterGlobalFunction("void Assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);
	r = engine->RegisterGlobalFunction("void SetMyAny(any@)", asFUNCTION(SetMyAny), asCALL_GENERIC); assert( r >= 0 );

	mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("TestAny", script4, strlen(script4), 0);
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);
	r = mod->Build();
	if( r < 0 )
	{
		TEST_FAILED;
		printf("%s: Failed to compile\n", "TestAny");
	}
	
	r = ExecuteString(engine, "TestAny()", mod);
	if( r != asEXECUTION_FINISHED )
	{
		TEST_FAILED;
		printf("%s: Failed to execute\n", "TestAny");
	}

	if( myAny )
	{
		int typeId = myAny->GetTypeId();

		if( !(typeId & asTYPEID_OBJHANDLE) )
			TEST_FAILED;
		if( (typeId & asTYPEID_MASK_OBJECT) != asTYPEID_APPOBJECT )
			TEST_FAILED;

		const char *decl = engine->GetTypeDeclaration(typeId);
		if( (decl == 0) || (strcmp(decl, "string@") != 0) )
		{
			TEST_FAILED;
			printf("%s: Failed to return the correct type\n", "TestAny");
		}

		int typeId2 = engine->GetTypeIdByDecl("string@");
		if( typeId != typeId2 )
		{
			TEST_FAILED;
			printf("%s: Failed to return the correct type\n", "TestAny");
		}

		CScriptString *str = 0;
		myAny->Retrieve((void*)&str, typeId);

		if( str->buffer != "test" )
		{
			TEST_FAILED;
			printf("%s: Failed to set the string correctly\n", "TestAny");
		}

		if( str ) str->Release();

		myAny->Release();
		myAny = 0;
	}
	else
		TEST_FAILED;

	//--------------------------------------
	// Make sure the any type can store primitives as well
	r = ExecuteString(engine, "any a; a.store(1); int b; a.retrieve(b); Assert(b == 1);");
	if( r != asEXECUTION_FINISHED )
		TEST_FAILED;

	engine->Release();

	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);

		RegisterScriptMath3D(engine);
		RegisterScriptAny(engine);

		engine->RegisterGlobalFunction("void assert(bool)", asFUNCTION(Assert), asCALL_GENERIC);

		mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	
		const char *script =
			"void main() \n"
			"{ \n"
			" any storage; \n"
			" storage.store(vector3(1,1,1)); \n"
			"} \n";

		mod->AddScriptSection("script", script);
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

		ctx = engine->CreateContext();
		r = ExecuteString(engine, "main()", mod, ctx);
		if( r != asEXECUTION_FINISHED )
		{
			if( r == asEXECUTION_EXCEPTION )
				PrintException(ctx);
			TEST_FAILED;
		}
		ctx->Release();

		engine->Release();
	}

	// Success
 	return fail;
}
コード例 #4
0
bool TestException()
{
	bool fail = false;
	int r;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

	COutStream out;
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);

	RegisterScriptString(engine);
	engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_GENERIC);


	asIScriptContext *ctx = engine->CreateContext();
	r = ExecuteString(engine, "int a = 0;\na = 10/a;", 0, ctx); // Throws an exception
	if( r == asEXECUTION_EXCEPTION )
	{
		int func = ctx->GetExceptionFunction();
		int line = ctx->GetExceptionLineNumber();
		const char *desc = ctx->GetExceptionString();

		const asIScriptFunction *function = engine->GetFunctionById(func);
		if( strcmp(function->GetName(), "ExecuteString") != 0 )
		{
			printf("%s: Exception function name is wrong\n", TESTNAME);
			TEST_FAILED;
		}
		if( strcmp(function->GetDeclaration(), "void ExecuteString()") != 0 )
		{
			printf("%s: Exception function declaration is wrong\n", TESTNAME);
			TEST_FAILED;
		}

		if( line != 2 )
		{
			printf("%s: Exception line number is wrong\n", TESTNAME);
			TEST_FAILED;
		}
		if( strcmp(desc, "Divide by zero") != 0 )
		{
			printf("%s: Exception string is wrong\n", TESTNAME);
			TEST_FAILED;
		}
	}
	else
	{
		printf("%s: Failed to raise exception\n", TESTNAME);
		TEST_FAILED;
	}

	ctx->Release();

	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("script", script1, strlen(script1));
	mod->Build();
	r = ExecuteString(engine, "A a; a.Test(\"test\");", mod);
	if( r != asEXECUTION_EXCEPTION )
	{
		TEST_FAILED;
	}

	// A test to validate Unprepare without execution
	{
		asIObjectType *type = mod->GetObjectTypeByIndex(0);
		int funcId = type->GetMethodIdByDecl("void Test(string c)");
		ctx = engine->CreateContext();
		ctx->Prepare(funcId);
		asIScriptContext *obj = (asIScriptContext*)engine->CreateScriptObject(type->GetTypeId());
		ctx->SetObject(obj); // Just sets the address
		CScriptString *str = new CScriptString();
		ctx->SetArgObject(0, str); // Makes a copy of the object
		str->Release();
		ctx->Unprepare(); // Must release the string argument, but not the object
		ctx->Release();
		obj->Release();
	}

	// A test to verify behaviour when exception occurs in script class constructor
	const char *script2 = "class SomeClassA \n"
	"{ \n"
	"	int A; \n"
	" \n"
	"	~SomeClassA() \n"
	"	{ \n"
	"		print('destruct'); \n"
	"	} \n"
	"} \n"
	"class SomeClassB \n"
	"{ \n"
	"	SomeClassA@ nullptr; \n"
	"	SomeClassB(SomeClassA@ aPtr) \n"
	"	{ \n"
	"		this.nullptr.A=100; // Null pointer access. After this class a is destroyed. \n"
	"	} \n"
	"} \n"
	"void test() \n"
	"{ \n"
	"	SomeClassA a; \n"
	"	SomeClassB(a); \n"
	"} \n";
	mod->AddScriptSection("script2", script2);
	r = mod->Build();
	if( r < 0 ) TEST_FAILED;
	r = ExecuteString(engine, "test()", mod);
	if( r != asEXECUTION_EXCEPTION )
	{
		TEST_FAILED;
	}

	engine->GarbageCollect();

	engine->Release();

	// Success
	return fail;
}
コード例 #5
0
bool TestException()
{
	bool fail = false;
	int r;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

	COutStream out;
	engine->SetMessageCallback(asMETHOD(COutStream,Callback), &out, asCALL_THISCALL);

	RegisterScriptString(engine);
	engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_GENERIC);


	asIScriptContext *ctx = engine->CreateContext();
	r = ExecuteString(engine, "int a = 0;\na = 10/a;", 0, ctx); // Throws an exception
	if( r == asEXECUTION_EXCEPTION )
	{
		int line = ctx->GetExceptionLineNumber();
		const char *desc = ctx->GetExceptionString();

		const asIScriptFunction *function = ctx->GetExceptionFunction();
		if( strcmp(function->GetName(), "ExecuteString") != 0 )
		{
			PRINTF("%s: Exception function name is wrong\n", TESTNAME);
			TEST_FAILED;
		}
		if( strcmp(function->GetDeclaration(), "void ExecuteString()") != 0 )
		{
			PRINTF("%s: Exception function declaration is wrong\n", TESTNAME);
			TEST_FAILED;
		}

		if( line != 2 )
		{
			PRINTF("%s: Exception line number is wrong\n", TESTNAME);
			TEST_FAILED;
		}
		if( strcmp(desc, "Divide by zero") != 0 )
		{
			PRINTF("%s: Exception string is wrong\n", TESTNAME);
			TEST_FAILED;
		}
	}
	else
	{
		PRINTF("%s: Failed to raise exception\n", TESTNAME);
		TEST_FAILED;
	}

	ctx->Release();

	asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
	mod->AddScriptSection("script", script1, strlen(script1));
	mod->Build();
	r = ExecuteString(engine, "A a; a.Test(\"test\");", mod);
	if( r != asEXECUTION_EXCEPTION )
	{
		TEST_FAILED;
	}

	// A test to validate Unprepare without execution
	{
		asITypeInfo *type = mod->GetObjectTypeByIndex(0);
		asIScriptFunction *func = type->GetMethodByDecl("void Test(string c)");
		ctx = engine->CreateContext();
		ctx->Prepare(func);
		asIScriptContext *obj = (asIScriptContext*)engine->CreateScriptObject(type);
		ctx->SetObject(obj); // Just sets the address
		CScriptString *str = new CScriptString();
		ctx->SetArgObject(0, str); // Makes a copy of the object
		str->Release();
		ctx->Unprepare(); // Must release the string argument, but not the object
		ctx->Release();
		obj->Release();
	}

	// Another test to validate Unprepare without execution
	{
		asITypeInfo *type = mod->GetObjectTypeByIndex(0);
		// Get the real method, not the virtual method
		asIScriptFunction *func = type->GetMethodByDecl("void Test(string c)", false);
		ctx = engine->CreateContext();
		ctx->Prepare(func);
		// Don't set the object, nor the arguments
		ctx->Unprepare();
		ctx->Release();
	}

	// A test to verify behaviour when exception occurs in script class constructor
	const char *script2 = "class SomeClassA \n"
	"{ \n"
	"	int A; \n"
	" \n"
	"	~SomeClassA() \n"
	"	{ \n"
	"		print('destruct'); \n"
	"	} \n"
	"} \n"
	"class SomeClassB \n"
	"{ \n"
	"	SomeClassA@ nullptr; \n"
	"	SomeClassB(SomeClassA@ aPtr) \n"
	"	{ \n"
	"		this.nullptr.A=100; // Null pointer access. After this class a is destroyed. \n"
	"	} \n"
	"} \n"
	"void test() \n"
	"{ \n"
	"	SomeClassA a; \n"
	"	SomeClassB(a); \n"
	"} \n";
	mod->AddScriptSection("script2", script2);
	r = mod->Build();
	if( r < 0 ) TEST_FAILED;
	r = ExecuteString(engine, "test()", mod);
	if( r != asEXECUTION_EXCEPTION )
	{
		TEST_FAILED;
	}

	engine->GarbageCollect();

	engine->Release();

	// Problem reported by Philip Bennefall
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);

		RegisterStdString(engine);
		RegisterScriptArray(engine, true);

		mod = engine->GetModule("test", asGM_ALWAYS_CREATE);

		mod->AddScriptSection("test",
			"string post_score(string url, string channel, string channel_password, int score, string name, string email, string country) \n"
			"{ \n"
			"  string[] list={'something'}; \n"
			"  return list[1]; \n"
			"} \n"
			"void main() \n"
			"{ \n"
			"  string result=post_score('hello', 'palacepunchup', 'anka', -1, 'Philip', '*****@*****.**', 'Sweden'); \n"
			"}\n");

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

		asIScriptContext *ctx = engine->CreateContext();
		r = ExecuteString(engine, "main()", mod, ctx);
		if( r != asEXECUTION_EXCEPTION )
			TEST_FAILED;
		if( string(ctx->GetExceptionString()) != "Index out of bounds" )
			TEST_FAILED;
		if( string(ctx->GetExceptionFunction()->GetName()) != "post_score" )
			TEST_FAILED;

		ctx->Release();
		engine->Release();
	}

	// Test exception within default constructor
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);

		RegisterStdString(engine);

		mod = engine->GetModule("test", asGM_ALWAYS_CREATE);

		mod->AddScriptSection("test",
			"class Test { \n"
			"  string mem = 'hello'; \n"
			"  int a = 0; \n"
			"  int b = 10/a; \n"
			"}\n");

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

		asIScriptContext *ctx = engine->CreateContext();
		r = ExecuteString(engine, "Test t;", mod, ctx);
		if( r != asEXECUTION_EXCEPTION )
			TEST_FAILED;
		if( string(ctx->GetExceptionString()) != "Divide by zero" )
		{
			PRINTF("%s\n", ctx->GetExceptionString());
			TEST_FAILED;
		}
		if( string(ctx->GetExceptionFunction()->GetName()) != "Test" )
			TEST_FAILED;

		ctx->Release();
		engine->Release();
	}

	// Test exception in for-condition
	// http://www.gamedev.net/topic/638128-bug-with-show-code-line-after-null-pointer-exception-and-for/
	{
		engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);

		mod = engine->GetModule("test", asGM_ALWAYS_CREATE);
		mod->AddScriptSection("test",
			"class A\n"
			"{\n"
			"    int GetCount(){ return 10; }\n"
			"}\n"
			"void startGame()\n"
			"{\n"
			"    A @a = null;\n"
			"    for( int i=0; i < a.GetCount(); i++ )\n"
			"    {\n"
			"        int some_val;\n"
			"    }\n"
			"}\n");

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

		asIScriptContext *ctx = engine->CreateContext();
		r = ExecuteString(engine, "startGame();", mod, ctx);
		if( r != asEXECUTION_EXCEPTION )
			TEST_FAILED;
		if( string(ctx->GetExceptionString()) != "Null pointer access" )
		{
			PRINTF("%s\n", ctx->GetExceptionString());
			TEST_FAILED;
		}
		if( string(ctx->GetExceptionFunction()->GetName()) != "startGame" )
			TEST_FAILED;
		if( ctx->GetExceptionLineNumber() != 8 )
			TEST_FAILED;

		ctx->Release();
		engine->Release();
	}

	// Test exception handler with thiscall
	// http://www.gamedev.net/topic/665587-angelscript-ios-x64/
	{
		asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
		engine->SetMessageCallback(asMETHOD(COutStream, Callback), &out, asCALL_THISCALL);

		mod = engine->GetModule("test", asGM_ALWAYS_CREATE);
		mod->AddScriptSection("test",
			"class SomeClass \n"
			"{ \n"
			"	float some_value; \n"
			"} \n"
			"SomeClass @obj; \n"
			"void test() \n"
			"{\n"
			"	obj.some_value = 3.14f; \n"
			"}\n");
		r = mod->Build();
		if( r < 0 )
			TEST_FAILED;

		ExceptionHandler handler;

		asIScriptContext *ctx = engine->CreateContext();
		ctx->SetExceptionCallback(asMETHOD(ExceptionHandler, Callback), &handler, asCALL_THISCALL);
		ctx->Prepare(mod->GetFunctionByName("test"));
		r = ctx->Execute();
		if( r != asEXECUTION_EXCEPTION )
			TEST_FAILED;
		ctx->Release();
		
		if( handler.ok == false )
			TEST_FAILED;

		engine->Release();
	}

	// Success
	return fail;
}