Beispiel #1
0
static SQInteger base_getstackinfos(HSQUIRRELVM v)
{
	SQInteger level;
	SQStackInfos si;
	SQInteger seq = 0;
	const SQChar *name = NULL;
	sq_getinteger(v, -1, &level);
	if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
	{
		const SQChar *fn = _SC("unknown");
		const SQChar *src = _SC("unknown");
		if(si.funcname)fn = si.funcname;
		if(si.source)src = si.source;
		sq_newtable(v);
		sq_pushstring(v, _SC("func"), -1);
		sq_pushstring(v, fn, -1);
		sq_createslot(v, -3);
		sq_pushstring(v, _SC("src"), -1);
		sq_pushstring(v, src, -1);
		sq_createslot(v, -3);
		sq_pushstring(v, _SC("line"), -1);
		sq_pushinteger(v, si.line);
		sq_createslot(v, -3);
		sq_pushstring(v, _SC("locals"), -1);
		sq_newtable(v);
		seq=0;
		while ((name = sq_getlocal(v, level, seq))) {
			sq_pushstring(v, name, -1);
			sq_push(v, -2);
			sq_createslot(v, -4);
			sq_pop(v, 1);
			seq++;
		}
		sq_createslot(v, -3);
		return 1;
	}

	return 0;
}
void PrintCallStack(HSQUIRRELVM v)
{
	SQPRINTFUNCTION pf = sq_geterrorfunc(v);
	if(pf) {
		SQStackInfos si;
		SQInteger i;
		SQFloat f;
		const SQChar *s;
		SQInteger level=1; //1 is to skip this function that is level 0
		const SQChar *name=0; 
		SQInteger seq=0;
		pf(v,_SC("\nCALLSTACK\n"));
		while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
		{
			const SQChar *fn=_SC("unknown");
			const SQChar *src=_SC("unknown");
			if(si.funcname)fn=si.funcname;
			if(si.source)src=si.source;
			pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
			level++;
		}

		return;
		level=0;
		pf(v,_SC("\nLOCALS\n"));

		for(level=0;level<10;level++){
			seq=0;
			while((name = sq_getlocal(v,level,seq)))
			{
				seq++;
				switch(sq_gettype(v,-1))
				{
				case OT_NULL:
					pf(v,_SC("[%s] NULL\n"),name);
					break;
				case OT_INTEGER:
					sq_getinteger(v,-1,&i);
					pf(v,_SC("[%s] %d\n"),name,i);
					break;
				case OT_FLOAT:
					sq_getfloat(v,-1,&f);
					pf(v,_SC("[%s] %.14g\n"),name,f);
					break;
				case OT_USERPOINTER:
					pf(v,_SC("[%s] USERPOINTER\n"),name);
					break;
				case OT_STRING:
					sq_getstring(v,-1,&s);
					pf(v,_SC("[%s] \"%s\"\n"),name,s);
					break;
				case OT_TABLE:
					pf(v,_SC("[%s] TABLE\n"),name);
					break;
				case OT_ARRAY:
					pf(v,_SC("[%s] ARRAY\n"),name);
					break;
				case OT_CLOSURE:
					pf(v,_SC("[%s] CLOSURE\n"),name);
					break;
				case OT_NATIVECLOSURE:
					pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
					break;
				case OT_GENERATOR:
					pf(v,_SC("[%s] GENERATOR\n"),name);
					break;
				case OT_USERDATA:
					pf(v,_SC("[%s] USERDATA\n"),name);
					break;
				case OT_THREAD:
					pf(v,_SC("[%s] THREAD\n"),name);
					break;
				case OT_CLASS:
					pf(v,_SC("[%s] CLASS\n"),name);
					break;
				case OT_INSTANCE:
					pf(v,_SC("[%s] INSTANCE\n"),name);
					break;
				case OT_WEAKREF:
					pf(v,_SC("[%s] WEAKREF\n"),name);
					break;
				case OT_BOOL:{
					sq_getinteger(v,-1,&i);
					pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));
								}
					break;
				default: ROCKETSQUIRREL_ASSERT(0); break;
				}
				sq_pop(v,1);
			}
		}
	}
}
SQInteger CSquirrel::PrintErrorFunction(SQVM * pVM)
{
	if(sq_gettop(pVM) >= 1)
	{
		const SQChar * szError = NULL;
		sq_getstring(pVM, 2, &szError);
				
		ErrorInfo info;
		info.strError = szError;

		SQStackInfos si;
		SQInteger level = 1; // 1 is to skip this function that is level 0
		const SQChar *name = 0; 
		SQInteger seq = 0;

		while(SQ_SUCCEEDED(sq_stackinfos(pVM, level, &si)))
		{
			const SQChar * fn = _SC("unknown");
			const SQChar * src = _SC("unknown");
			if(si.funcname) fn = si.funcname;
			if(si.source) src = si.source;
			info.callstack.push_back(ErrorCallstackPair(fn, ErrorSourcePair(src, si.line)));
			level++;
		}

		for(level = 0; level < 10; level++)
		{
			seq = 0;

			while((name = sq_getlocal(pVM, level, seq)))
			{
				seq++;
				CSquirrelArgument arg;
				arg.pushFromStack(pVM, -1);
				info.locals.push_back(ErrorLocalPair(name, arg));
				sq_pop(pVM, 1);
			}
		}

		CSquirrel * pScript = CScriptingManager::GetInstance()->Get(pVM);

		if(pScript)
		{
			CSquirrelArguments arguments;
			CSquirrelArguments tempArray;
			CSquirrelArguments callstackTable;
			CSquirrelArguments localsTable;
			arguments.push(info.strError);

			for(ErrorCallstackList::iterator iter = info.callstack.begin(); iter != info.callstack.end(); iter++)
			{
				String strFunction = iter->first;
				String strSource = iter->second.first;
				int iLine = iter->second.second;
				callstackTable.push(strFunction);
				tempArray.reset();
				tempArray.push(strSource);
				tempArray.push(iLine);
				callstackTable.push(tempArray, true);
			}

			arguments.push(callstackTable, false);

			for(ErrorLocalsList::iterator iter = info.locals.begin(); iter != info.locals.end(); iter++)
			{
				String strName = iter->first;
				CSquirrelArgument arg = iter->second;
				localsTable.push(strName);
				localsTable.push(arg);
			}

			arguments.push(localsTable, false);

			if(CEvents::GetInstance()->Call("scriptError", &arguments, pScript).GetInteger() == 1)
			{
				CLogFile::Printf("<Error (%s)>", info.strError.Get());

				CLogFile::Printf("<Callstack>");
				for(ErrorCallstackList::iterator iter = info.callstack.begin(); iter != info.callstack.end(); iter++)
				{
					String strFunction = iter->first;
					String strSource = iter->second.first;
					int iLine = iter->second.second;
					CLogFile::Printf("<%s (%s, %d)>", strFunction.Get(), strSource.Get(), iLine);
				}
				CLogFile::Printf("</Callstack>");

				CLogFile::Printf("<Locals>");
				for(ErrorLocalsList::iterator iter = info.locals.begin(); iter != info.locals.end(); iter++)
				{
					String strName = iter->first;
					CSquirrelArgument arg = iter->second;
					CLogFile::Printf("<%s (%s)>", strName.Get(), arg.GetTypeString().Get());
				}
				CLogFile::Printf("</Locals>");

				CLogFile::Printf("</Error>");
			}
		}
	}

	return 0;
}
Beispiel #4
0
void sqstd_printcallstack(HSQUIRRELVM v)
{
	SQPRINTFUNCTION pf = sq_getprintfunc(v);
	if(pf) {
		SQStackInfos si;
		SQInteger i;
		SQBool b;
		SQFloat f;
		const SQChar *s;
		SQInteger level=1; //1 is to skip this function that is level 0
		const SQChar *name=0;
		SQInteger seq=0;
		pf(v,_SC("\nCALLSTACK\n"));
		while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
		{
			const SQChar *fn=_SC("unknown");
			const SQChar *src=_SC("unknown");
			if(si.funcname)fn=si.funcname;
			if(si.source) {
				/* We don't want to bother users with absolute paths to all AI files.
				 * Since the path only reaches NoAI code in a formatted string we have
				 * to strip it here. Let's hope nobody installs openttd in a subdirectory
				 * of a directory named /ai/. */
				src = scstrstr(si.source, _SC("\\ai\\"));
				if (!src) src = scstrstr(si.source, _SC("/ai/"));
				if (src) {
					src += 4;
				} else {
					src = si.source;
				}
			}
			pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
			level++;
		}
		level=0;
		pf(v,_SC("\nLOCALS\n"));

		for(level=0;level<10;level++){
			seq=0;
			while((name = sq_getlocal(v,level,seq)))
			{
				seq++;
				switch(sq_gettype(v,-1))
				{
				case OT_NULL:
					pf(v,_SC("[%s] NULL\n"),name);
					break;
				case OT_INTEGER:
					sq_getinteger(v,-1,&i);
					pf(v,_SC("[%s] %d\n"),name,i);
					break;
				case OT_FLOAT:
					sq_getfloat(v,-1,&f);
					pf(v,_SC("[%s] %.14g\n"),name,f);
					break;
				case OT_USERPOINTER:
					pf(v,_SC("[%s] USERPOINTER\n"),name);
					break;
				case OT_STRING:
					sq_getstring(v,-1,&s);
					pf(v,_SC("[%s] \"%s\"\n"),name,s);
					break;
				case OT_TABLE:
					pf(v,_SC("[%s] TABLE\n"),name);
					break;
				case OT_ARRAY:
					pf(v,_SC("[%s] ARRAY\n"),name);
					break;
				case OT_CLOSURE:
					pf(v,_SC("[%s] CLOSURE\n"),name);
					break;
				case OT_NATIVECLOSURE:
					pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
					break;
				case OT_GENERATOR:
					pf(v,_SC("[%s] GENERATOR\n"),name);
					break;
				case OT_USERDATA:
					pf(v,_SC("[%s] USERDATA\n"),name);
					break;
				case OT_THREAD:
					pf(v,_SC("[%s] THREAD\n"),name);
					break;
				case OT_CLASS:
					pf(v,_SC("[%s] CLASS\n"),name);
					break;
				case OT_INSTANCE:
					pf(v,_SC("[%s] INSTANCE\n"),name);
					break;
				case OT_WEAKREF:
					pf(v,_SC("[%s] WEAKREF\n"),name);
					break;
				case OT_BOOL:{
					sq_getbool(v,-1,&b);
					pf(v,_SC("[%s] %s\n"),name,b?_SC("true"):_SC("false"));
							 }
					break;
				default: assert(0); break;
				}
				sq_pop(v,1);
			}
		}
	}
}