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; }