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;
}
Example #2
0
	/**
	 * Get the real-instance pointer.
	 * @note This will only work just after a function-call from within Squirrel
	 *  to your C++ function.
	 */
	static bool GetRealInstance(HSQUIRRELVM vm, SQUserPointer *ptr) { return SQ_SUCCEEDED(sq_getinstanceup(vm, 1, ptr, 0)); }
Example #3
0
static SQInteger array_pop(HSQUIRRELVM v)
{
	return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
}
ScriptBehavior::ScriptBehavior( HSQUIRRELVM vm,HSQOBJECT classObject,const std::map< tstring_symbol,ScriptParameterInterfacePtr >& scriptParameters  )
    : m_vm(vm)
    , m_start(false)
{
    int top = sq_gettop(m_vm);

    sq_pushobject(m_vm, classObject);

    sq_pushroottable( m_vm );

    m_initialize = false;
    m_haveAwake = false;
    m_haveStart = false;
    m_haveUpdate = false;

    if( SQ_SUCCEEDED( sq_call( m_vm,1,SQTrue,SQTrue) ) )
    {
        if( SQ_SUCCEEDED( sq_getstackobj(m_vm, -1, &m_instance) ) )
        {
            sq_addref( m_vm,&m_instance );

            m_initialize = true;

            sq_pushstring( m_vm,_SC("Awake"),-1 );
            if( SQ_SUCCEEDED( sq_get(m_vm,-2 ) ) )
            {
                if( SQ_SUCCEEDED( sq_getstackobj(m_vm, -1, &m_awakeFunction) ) )
                {
                    sq_addref( m_vm,&m_awakeFunction );
                    m_haveAwake = true;
                }
            }
            sq_pop(m_vm,1);

            sq_pushstring( m_vm,_SC("Start"),-1 );
            if( SQ_SUCCEEDED( sq_get(m_vm,-2 ) ) )
            {
                if( SQ_SUCCEEDED( sq_getstackobj(m_vm, -1, &m_startFunction) ) )
                {
                    sq_addref( m_vm,&m_startFunction );
                    m_haveStart = true;
                }
            }
            sq_pop(m_vm,1);

            sq_pushstring( m_vm,_SC("Update"),-1 );
            if( SQ_SUCCEEDED( sq_get(m_vm,-2 ) ) )
            {
                if( SQ_SUCCEEDED( sq_getstackobj(m_vm, -1, &m_updateFunction) ) )
                {
                    sq_addref( m_vm,&m_updateFunction );
                    m_haveUpdate = true;
                }
            }
            sq_pop(m_vm,1);

            std::map< tstring_symbol,ScriptParameterInterfacePtr >::const_iterator it = scriptParameters.begin();
            while( it!=scriptParameters.end() )
            {
                it->second->SetParameter( m_vm );
                it++;
            }
        }
    }

    sq_settop( m_vm,top );
}
Example #5
0
static SQInteger class_instance(HSQUIRRELVM v)
{
	if(SQ_SUCCEEDED(sq_createinstance(v,-1)))
		return 1;
	return SQ_ERROR;
}
bool CSquirrelArgument::pushFromStack(SQVM * pVM, int idx)
{
	reset();
	SQObjectPtr obj = stack_get(pVM, idx);

	switch(obj._type)
	{
	case OT_NULL:
		// Nothing needed
		break;
	case OT_INTEGER:
		data.i = obj._unVal.nInteger;
		break;
	case OT_BOOL:
		data.b = (obj._unVal.nInteger != 0);
		break;
	case OT_FLOAT:
		data.f = obj._unVal.fFloat;
		break;
	case OT_STRING:
		data.str = new String(obj._unVal.pString->_val);
		break;
	case OT_TABLE:
		{
			CSquirrelArguments * pArguments = new CSquirrelArguments();
			sq_push(pVM, idx);
			sq_pushnull(pVM);

			while(SQ_SUCCEEDED(sq_next(pVM, -2)))
			{
				if(!pArguments->pushFromStack(pVM, -2) || !pArguments->pushFromStack(pVM, -1))
				{
					sq_pop(pVM, 4);
					delete pArguments;
					return false;
				}

				sq_pop(pVM, 2);
			}

			sq_pop(pVM, 2);
			data.pArray = pArguments;
		}
		break;
	case OT_ARRAY:
		{
			CSquirrelArguments * pArguments = new CSquirrelArguments();
			sq_push(pVM, idx);
			sq_pushnull(pVM);

			while(SQ_SUCCEEDED(sq_next(pVM, -2)))
			{
				if(!pArguments->pushFromStack(pVM, -1))
				{
					sq_pop(pVM, 4);
					delete pArguments;
					return false;
				}

				sq_pop(pVM, 2);
			}

			sq_pop(pVM, 2);
			data.pArray = pArguments;
		}
		break;
	case OT_CLOSURE:
	case OT_NATIVECLOSURE:
		data.sqObject = SQObject(obj);
		break;
	case OT_INSTANCE:
		data.pInstance = obj._unVal.pInstance;
		break;
	default:
		return false;
		break;
	}

	type = obj._type;
	return true;
}
Example #7
0
bool ScriptObject::_getSlot(const char* name) const
{
	sq_pushobject(mSqvm, mObj);
	sq_pushstring(mSqvm, name, -1);
	return SQ_SUCCEEDED(sq_get(mSqvm, -2));
}
void
ConsoleImpl::eval_command_line()
{
  if (!command_line.empty() && (history.empty() || history.back() != command_line))
    {
      history.push_back(command_line);
      history_position = history.size();
    }
                      
  console << ">" << command_line << std::endl;

  if (command_line == "quit" || command_line == "exit")
    {
      console.deactive();
    }
  else if (command_line == "help")
    {
      console << "This is a script console, can enter stuff in here that will then be evaluated.\n"
              << "Type 'quit' to exit the console." << std::endl;
    }
  else if (command_line == "reset")
    {
      GameSession::current()->set_sector("levels/newformat2.wst");
    }
  else if (command_line == "show")
    {
      HSQUIRRELVM v = script_manager->get_vm();

      int size = sq_getsize(v, -1);
      console << size << " elements on the root table" << std::endl;

      sq_pushroottable(v);

      //push your table/array here
      sq_pushnull(v);  //null iterator
      while(SQ_SUCCEEDED(sq_next(v,-2)))
        {
          //here -1 is the value and -2 is the key
          const SQChar *s;
          if (SQ_SUCCEEDED(sq_getstring(v,-2, &s)))
            {
              console << s << " -> " << squirrel2string(v, -1) << std::endl;
            }
          else
            {
              console << "Unknown key type for element" << std::endl;
            }
                              
          sq_pop(v,2); //pops key and val before the nex iteration
        }
                          
      sq_pop(v, 1);
    }
  else
    {
      execute(command_line);
      maybe_newline();
    }
  command_line = "";
  cursor_pos = 0;
}
Example #9
0
/**
 * スレッドのメイン処理
 * @param diff 経過時間
 * @return スレッド実行終了なら true
 */
bool
Thread::_main(long diff)
{
	// スレッドとして動作できてない場合は即終了
	if (_status == THREAD_NONE) {
		return true;
	}

	if (_status == THREAD_LOADING_FILE) {
		// ファイル読み込み処理
		const char *dataAddr;
		int dataSize;
		if (sqobjCheckFile(_fileHandler, &dataAddr, &dataSize)) {
			_init();
			SQRESULT ret = sqstd_loadmemory(_thread, dataAddr, dataSize, _scriptName.getString(), SQTrue);
			sqobjCloseFile(_fileHandler);
			_fileHandler = NULL;
			if (SQ_SUCCEEDED(ret)) {
				_status = THREAD_RUN;
			} else {
				// exit相当
				printError();
				_exit();
				return true;
			}
		} else {
			// 読み込み完了待ち
			return false;
		}
	} else if (_status == THREAD_LOADING_FUNC) {
		// スクリプト読み込み処理
		_init();
		_func.push(_thread);
		_func.clear();
		_status = THREAD_RUN;
	}

	_currentTick += diff;
	
	// タイムアウト処理
	if (_waitTimeout >= 0) {
		_waitTimeout -= diff;
		if (_waitTimeout < 0) {
			_clearWait();
		}
	}
		
	// スレッド実行
	if (!isWait() && _status == THREAD_RUN) {
		SQRESULT result;
		if (sq_getvmstate(_thread) == SQ_VMSTATE_SUSPENDED) {
			_waitResult.push(_thread);
			_waitResult.clear();
			result = sq_wakeupvm(_thread, SQTrue, SQTrue, SQTrue, SQFalse);
		} else {
			sq_pushroottable(_thread);
			SQInteger n = _args.pushArray(_thread) + 1;
			_args.clear();
			result = sq_call(_thread, n, SQTrue, SQTrue);
		}
		if (SQ_FAILED(result)) {
			// スレッドがエラー終了
			printError();
			_exit();
		} else {
			// 終了コード取得。return/suspend の値が格納される
			_exitCode.getStack(_thread, -1);
			sq_pop(_thread, 1);
			if (sq_getvmstate(_thread) == SQ_VMSTATE_IDLE) {
				// スレッドが終了
				_exit();
			}
		}
	}
	
	return _status == THREAD_NONE;
}
Example #10
0
void Interactive(HSQUIRRELVM v)
{
	
#define MAXINPUT 1024
	SQChar buffer[MAXINPUT];
	SQInteger blocks =0;
	SQInteger string=0;
	SQInteger retval=0;
	SQInteger done=0;
	PrintVersionInfos();
		
	sq_pushroottable(v);
	sq_pushstring(v,_SC("quit"),-1);
	sq_pushuserpointer(v,&done);
	sq_newclosure(v,quit,1);
	sq_setparamscheck(v,1,NULL);
	sq_createslot(v,-3);
	sq_pop(v,1);

    while (!done) 
	{
		SQInteger i = 0;
		scprintf(_SC("\nsq>"));
		for(;;) {
			int c;
			if(done)return;
			c = getchar();
			if (c == _SC('\n')) {
				if (i>0 && buffer[i-1] == _SC('\\'))
				{
					buffer[i-1] = _SC('\n');
				}
				else if(blocks==0)break;
				buffer[i++] = _SC('\n');
			}
			else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;}
			else if(c==_SC('{') && !string){
					blocks++;
					buffer[i++] = (SQChar)c;
			}
			else if(c==_SC('"') || c==_SC('\'')){
					string=!string;
					buffer[i++] = (SQChar)c;
			}
			else if (i >= MAXINPUT-1) {
				scfprintf(stderr, _SC("sq : input line too long\n"));
				break;
			}
			else{
				buffer[i++] = (SQChar)c;
			}
		}
		buffer[i] = _SC('\0');
		
		if(buffer[0]==_SC('=')){
			scsprintf(sq_getscratchpad(v,MAXINPUT),_SC("return (%s)"),&buffer[1]);
			memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar));
			retval=1;
		}
		i=scstrlen(buffer);
		if(i>0){
			SQInteger oldtop=sq_gettop(v);
			if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){
				sq_pushroottable(v);
				if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) &&	retval){
					scprintf(_SC("\n"));
					sq_pushroottable(v);
					sq_pushstring(v,_SC("print"),-1);
					sq_get(v,-2);
					sq_pushroottable(v);
					sq_push(v,-4);
					sq_call(v,2,SQFalse,SQTrue);
					retval=0;
					scprintf(_SC("\n"));
				}
			}
			
			sq_settop(v,oldtop);
		}
	}
}
Example #11
0
//<<FIXME>> this func is a mess
int getargs(HSQUIRRELVM v,int argc, char* argv[])
{
	int i;
	int compiles_only = 0;
	static SQChar temp[500];
	const SQChar *ret=NULL;
	char * output = NULL;
	int lineinfo=0;
	int endian=0;
	const char *precompile = NULL;
	if(argc>1)
	{
		int arg=1,exitloop=0;
		while(arg < argc && !exitloop)
		{

			if(argv[arg][0]=='-')
			{
				switch(argv[arg][1])
				{
				case 'd': //DEBUG(debug infos)
					sq_enabledebuginfo(v,1);
					break;
				case 'c':
					compiles_only = 1;
					break;
				case 'o':
					if(arg < argc) {
						arg++;
						output = argv[arg];
					}
					break;
				case 'e':
					if(arg < argc) {
						arg++;
						endian = atoi(argv[arg]);
					}
					break;
				case 'v':
					PrintVersionInfos();
					return _DONE;
				
				case 'h':
					PrintVersionInfos();
					PrintUsage();
					return _DONE;
				case 'p':
					if (arg < argc) {
						arg++;
						precompile = argv[arg];
					}
					break;
				default:
					PrintVersionInfos();
					scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]);
					PrintUsage();
					return _ERROR;
				}
			}else break;
			arg++;
		}

		// precompile header
		if (precompile) {
			const SQChar *a;
#ifdef SQUNICODE
			int alen=(int)strlen(precompile);
			a=sq_getscratchpad(v,(int)(alen*sizeof(SQChar)));
			mbstowcs(sq_getscratchpad(v,-1),precompile,alen);
			sq_getscratchpad(v,-1)[alen] = _SC('\0');
#else
			a=precompile;
#endif
			if(SQ_FAILED(sqstd_dofile(v,a,SQFalse,SQTrue))) {
				const SQChar *err;
				sq_getlasterror(v);
				if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
					scprintf(_SC("Error [%s]\n"),err);
					return _ERROR;
				}
			}
		}
		
		// src file
		
		if(arg<argc) {
			const SQChar *filename=NULL;
#ifdef SQUNICODE
			mbstowcs(temp,argv[arg],strlen(argv[arg]));
			filename=temp;
#else
			filename=argv[arg];
#endif

			arg++;
			sq_pushroottable(v);
			sq_pushstring(v,_SC("ARGS"),-1);
			sq_newarray(v,0);
			for(i=arg;i<argc;i++)
			{
				const SQChar *a;
#ifdef SQUNICODE
				int alen=(int)strlen(argv[i]);
				a=sq_getscratchpad(v,(int)(alen*sizeof(SQChar)));
				mbstowcs(sq_getscratchpad(v,-1),argv[i],alen);
				sq_getscratchpad(v,-1)[alen] = _SC('\0');
#else
				a=argv[i];
#endif
				sq_pushstring(v,a,-1);

				sq_arrayappend(v,-2);
			}
			sq_createslot(v,-3);
			sq_pop(v,1);
			if(compiles_only) {
				if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))){
					SQChar *outfile = _SC("out.cnut");
					if(output) {
#ifdef SQUNICODE
						int len = (int)(strlen(output)+1);
						mbstowcs(sq_getscratchpad(v,len*sizeof(SQChar)),output,len);
						outfile = sq_getscratchpad(v,-1);
#else
						outfile = output;
#endif
					}
					if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,outfile,endian)))
						return _DONE;
				}
			}
			else {
				if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQFalse,SQTrue))) {
					return _DONE;
				}
			}
			//if this point is reached an error occured
			{
				const SQChar *err;
				sq_getlasterror(v);
				if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
					scprintf(_SC("Error [%s]\n"),err);
					return _ERROR;
				}
			}
			
		}
	}

	return _INTERACTIVE;
}
Example #12
0
int app_sqlang_run_ex(sip_msg_t *msg, char *func, char *p1, char *p2,
		char *p3, int emode)
{
	int n;
	int ret;
	int top;
	sip_msg_t *bmsg;
	SQInteger rv;

	if(_sr_J_env.JJ==NULL) {
		LM_ERR("sqlang loading state not initialized (call: %s)\n", func);
		return -1;
	}
	/* check the script version loaded */
	sqlang_kemi_reload_script();

	top = sqlang_gettop(_sr_J_env.JJ);

	LM_DBG("sqlang top index is: %d\n", top);
	sq_pushroottable(_sr_J_env.JJ); /* pushes the global table */
	sq_pushstring(_sr_J_env.JJ, _SC(func), -1);
	if(!SQ_SUCCEEDED(sq_get(_sr_J_env.JJ, -2))) {
		/* failed to gets the func field from the global table */
		sq_settop(_sr_J_env.JJ, (top<=0)?1:top); /* restores the original stack size */
		LM_ERR("sqlang failed to find symbol (call: %s)\n", func);
		return -1;
	}

	if(!sqlang_isfunction(_sr_J_env.JJ, -1))
	{
		LM_ERR("no such function [%s] in sqlang scripts\n", func);
		LM_ERR("top stack type [%d]\n",
			sqlang_gettype(_sr_J_env.JJ, -1));
	}
	/* push the 'this' (in this case is the global table) */
	sq_pushroottable(_sr_J_env.JJ);
	n = 1;
	if(p1!=NULL)
	{
		sqlang_pushstring(_sr_J_env.JJ, p1);
		n++;
		if(p2!=NULL)
		{
			sqlang_pushstring(_sr_J_env.JJ, p2);
			n++;
			if(p3!=NULL)
			{
				sqlang_pushstring(_sr_J_env.JJ, p3);
				n++;
			}
		}
	}
	LM_DBG("executing sqlang function: [[%s]] (n: %d)\n", func, n);
	bmsg = _sr_J_env.msg;
	_sr_J_env.msg = msg;
	_sr_J_env.JJ_exit = 0;
	/* call the function */
	rv = sq_call(_sr_J_env.JJ, n, SQFalse, SQTrue);
	if(SQ_SUCCEEDED(rv)) {
		ret = 1;
	} else {
		if(_sr_J_env.JJ_exit==0) {
			LM_ERR("failed to execute the func: %s (%d)\n", func, (int)rv);
			sqstd_printcallstack(_sr_J_env.JJ);
			ret = -1;
		} else {
			LM_DBG("script execution exit\n");
			ret = 1;
		}
	}
	_sr_J_env.msg = bmsg;
	_sr_J_env.JJ_exit = 0;
	sq_settop(_sr_J_env.JJ, (top<=0)?1:top); /* restores the original stack size */

	return ret;
}
Example #13
0
SQInteger AIInfo::AddSetting(HSQUIRRELVM vm)
{
	AIConfigItem config;
	memset(&config, 0, sizeof(config));
	config.max_value = 1;
	config.step_size = 1;
	uint items = 0;

	/* Read the table, and find all properties we care about */
	sq_pushnull(vm);
	while (SQ_SUCCEEDED(sq_next(vm, -2))) {
		const SQChar *sqkey;
		if (SQ_FAILED(sq_getstring(vm, -2, &sqkey))) return SQ_ERROR;
		const char *key = SQ2OTTD(sqkey);

		if (strcmp(key, "name") == 0) {
			const SQChar *sqvalue;
			if (SQ_FAILED(sq_getstring(vm, -1, &sqvalue))) return SQ_ERROR;
			char *name = strdup(SQ2OTTD(sqvalue));
			char *s;
			/* Don't allow '=' and ',' in configure setting names, as we need those
			 *  2 chars to nicely store the settings as a string. */
			while ((s = strchr(name, '=')) != NULL) *s = '_';
			while ((s = strchr(name, ',')) != NULL) *s = '_';
			config.name = name;
			items |= 0x001;
		} else if (strcmp(key, "description") == 0) {
			const SQChar *sqdescription;
			if (SQ_FAILED(sq_getstring(vm, -1, &sqdescription))) return SQ_ERROR;
			config.description = strdup(SQ2OTTD(sqdescription));
			items |= 0x002;
		} else if (strcmp(key, "min_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.min_value = res;
			items |= 0x004;
		} else if (strcmp(key, "max_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.max_value = res;
			items |= 0x008;
		} else if (strcmp(key, "easy_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.easy_value = res;
			items |= 0x010;
		} else if (strcmp(key, "medium_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.medium_value = res;
			items |= 0x020;
		} else if (strcmp(key, "hard_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.hard_value = res;
			items |= 0x040;
		} else if (strcmp(key, "random_deviation") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.random_deviation = res;
			items |= 0x200;
		} else if (strcmp(key, "custom_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.custom_value = res;
			items |= 0x080;
		} else if (strcmp(key, "step_size") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.step_size = res;
		} else if (strcmp(key, "flags") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.flags = (AIConfigFlags)res;
			items |= 0x100;
		} else {
			char error[1024];
			snprintf(error, sizeof(error), "unknown setting property '%s'", key);
			this->engine->ThrowError(error);
			return SQ_ERROR;
		}

		sq_pop(vm, 2);
	}
	sq_pop(vm, 1);

	/* Don't allow both random_deviation and AICONFIG_RANDOM to
	 * be set for the same config item. */
	if ((items & 0x200) != 0 && (config.flags & AICONFIG_RANDOM) != 0) {
		char error[1024];
		snprintf(error, sizeof(error), "Setting both random_deviation and AICONFIG_RANDOM is not allowed");
		this->engine->ThrowError(error);
		return SQ_ERROR;
	}
	/* Reset the bit for random_deviation as it's optional. */
	items &= ~0x200;

	/* Make sure all properties are defined */
	uint mask = (config.flags & AICONFIG_BOOLEAN) ? 0x1F3 : 0x1FF;
	if (items != mask) {
		char error[1024];
		snprintf(error, sizeof(error), "please define all properties of a setting (min/max not allowed for booleans)");
		this->engine->ThrowError(error);
		return SQ_ERROR;
	}

	this->config_list.push_back(config);
	return 0;
}
Example #14
0
std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
{
  std::ostringstream os;
  switch(sq_gettype(v, i))
  {
    case OT_NULL:
      os << "<null>";
      break;
    case OT_BOOL: {
      SQBool p;
      if (SQ_SUCCEEDED(sq_getbool(v, i, &p))) {
        if (p)
          os << "true";
        else
          os << "false";
      }
      break;
    }
    case OT_INTEGER: {
      SQInteger val;
      sq_getinteger(v, i, &val);
      os << val;
      break;
    }
    case OT_FLOAT: {
      SQFloat val;
      sq_getfloat(v, i, &val);
      os << val;
      break;
    }
    case OT_STRING: {
      const SQChar* val;
      sq_getstring(v, i, &val);
      os << "\"" << val << "\"";
      break;
    }
    case OT_TABLE: {
      bool first = true;
      os << "{";
      sq_pushnull(v);  //null iterator
      while(SQ_SUCCEEDED(sq_next(v,i-1)))
      {
        if (!first) {
          os << ", ";
        }
        first = false;

        //here -1 is the value and -2 is the key
        os << squirrel2string(v, -2) << " => "
           << squirrel2string(v, -1);

        sq_pop(v,2); //pops key and val before the nex iteration
      }
      sq_pop(v, 1);
      os << "}";
      break;
    }
    case OT_ARRAY: {
      bool first = true;
      os << "[";
      sq_pushnull(v);  //null iterator
      while(SQ_SUCCEEDED(sq_next(v,i-1)))
      {
        if (!first) {
          os << ", ";
        }
        first = false;

        //here -1 is the value and -2 is the key
        // we ignore the key, since that is just the index in an array
        os << squirrel2string(v, -1);

        sq_pop(v,2); //pops key and val before the nex iteration
      }
      sq_pop(v, 1);
      os << "]";
      break;
    }
    case OT_USERDATA:
      os << "<userdata>";
      break;
    case OT_CLOSURE:
      os << "<closure>";
      break;
    case OT_NATIVECLOSURE:
      os << "<native closure>";
      break;
    case OT_GENERATOR:
      os << "<generator>";
      break;
    case OT_USERPOINTER:
      os << "userpointer";
      break;
    case OT_THREAD:
      os << "<thread>";
      break;
    case OT_CLASS:
      os << "<class>";
      break;
    case OT_INSTANCE:
      os << "<instance>";
      break;
    case OT_WEAKREF:
      os << "<weakref>";
      break;
    default:
      os << "<unknown>";
      break;
  }
  return os.str();
}
Example #15
0
static SQInteger class_getbase(HSQUIRRELVM v)
{
	return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR;
}
static SQInteger squirrel_errorhandler(HSQUIRRELVM v) {
  /* Detect whether this error is just propagating through, or it originated
   * here. To do so, we store the last error we saw in the registry and compare
   * it to the current error. If they are the equal, we've already handled this
   * error.
   *
   * Without this check, we'll call the error handler for every transition
   * between the Squirrel and Wasm VMs. */
  /* TODO(binji): It seems like there should be a better way to handle this */
  SQInteger top = sq_gettop(v);
  WasmBool is_new_error = WASM_TRUE;
  /* get the last error we saw */
  sq_pushregistrytable(v);
  sq_pushstring(v, WASM_LAST_ERROR_NAME, -1);
  if (SQ_SUCCEEDED(sq_get(v, -2))) {
    /* STACK: error registry_table last_error */
    sq_push(v, -3);

    HSQOBJECT last_error;
    HSQOBJECT error;
    if (SQ_SUCCEEDED(sq_getstackobj(v, -1, &error)) &&
        SQ_SUCCEEDED(sq_getstackobj(v, -2, &last_error))) {
      /* we don't want to use cmp here, because it will throw if the values are
       * unordered, and because it performs value equality */
      if (squirrel_objects_are_equal_raw(last_error, error))
        is_new_error = WASM_FALSE;
    }

    /* set the last_error in the registry to the new error. */
    /* STACK: registry_table last_error error */
    sq_remove(v, -2);
    sq_pushstring(v, WASM_LAST_ERROR_NAME, -1);
    sq_push(v, -2);
    /* STACK: registry_table error WASM_LAST_ERROR_NAME error */
    SQRESULT r = sq_set(v, -4);
    WASM_USE(r);
    assert(r == SQ_OK);
  }
  sq_settop(v, top);

  if (is_new_error) {
    const char* error_msg = "unknown";
    if (sq_gettop(v) >= 1)
      sq_getstring(v, -1, &error_msg);
    squirrel_error(v, "error: %s\n", error_msg);
    squirrel_error(v, "callstack:\n");
    SQStackInfos stack_info;
    SQInteger depth;
    for (depth = 1; SQ_SUCCEEDED(sq_stackinfos(v, depth, &stack_info));
         depth++) {
      const char* source = stack_info.source ? stack_info.source : "unknown";
      const char* funcname =
          stack_info.funcname ? stack_info.funcname : "unknown";
      SQInteger line = stack_info.line;
      squirrel_error(v,
                     "  #"_PRINT_INT_FMT
                     ": %s:"_PRINT_INT_FMT
                     ": %s()\n",
                     depth, source, line, funcname);
    }
  }
  return 0;
}
Example #17
0
static SQInteger table_getdelegate(HSQUIRRELVM v)
{
	return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR;
}
Example #18
0
/* static */ bool ScriptAdmin::MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data)
{
	if (max_depth == 0) {
		ScriptLog::Error("Send parameters can only be nested to 25 deep. No data sent."); // SQUIRREL_MAX_DEPTH = 25
		return false;
	}

	switch (sq_gettype(vm, index)) {
		case OT_INTEGER: {
			SQInteger res;
			sq_getinteger(vm, index, &res);

			char buf[10];
			snprintf(buf, sizeof(buf), "%d", (int32)res);
			data = buf;
			return true;
		}

		case OT_STRING: {
			const SQChar *res;
			sq_getstring(vm, index, &res);

			/* @bug if a string longer than 512 characters is given to SQ2OTTD, the
			 *  internal buffer overflows. */
			const char *buf = SQ2OTTD(res);
			size_t len = strlen(buf) + 1;
			if (len >= 255) {
				ScriptLog::Error("Maximum string length is 254 chars. No data sent.");
				return false;
			}

			data = std::string("\"") + buf + "\"";
			return true;
		}

		case OT_ARRAY: {
			data = "[ ";

			bool first = true;
			sq_pushnull(vm);
			while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
				if (!first) data += ", ";
				if (first) first = false;

				std::string tmp;

				bool res = MakeJSON(vm, -1, max_depth - 1, tmp);
				sq_pop(vm, 2);
				if (!res) {
					sq_pop(vm, 1);
					return false;
				}
				data += tmp;
			}
			sq_pop(vm, 1);
			data += " ]";
			return true;
		}

		case OT_TABLE: {
			data = "{ ";

			bool first = true;
			sq_pushnull(vm);
			while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
				if (!first) data += ", ";
				if (first) first = false;

				std::string key;
				std::string value;

				/* Store the key + value */
				bool res = MakeJSON(vm, -2, max_depth - 1, key) && MakeJSON(vm, -1, max_depth - 1, value);
				sq_pop(vm, 2);
				if (!res) {
					sq_pop(vm, 1);
					return false;
				}
				data += key + ": " + value;
			}
			sq_pop(vm, 1);
			data += " }";
			return true;
		}

		case OT_BOOL: {
			SQBool res;
			sq_getbool(vm, index, &res);

			if (res) {
				data = "true";
				return true;
			}

			data = "false";
			return true;
		}

		case OT_NULL: {
			data = "null";
			return true;
		}

		default:
			ScriptLog::Error("You tried to send an unsupported type. No data sent.");
			return false;
	}
}
Example #19
0
int main(int argc, char *argv[])
{
	if(argc < 2){
		scprintf(_SC("SQDBG error : no file specified"));
		return -1;
	}

	// RVF +
	int debuggerPort = 0;
	for (int i = 1; i < argc; i++) {
		const char* arg = argv[i];
		if (!strncmp(arg, "-d", 2))
			debuggerPort = std::atoi(arg + 2);
	}

	if (!debuggerPort) {
		scprintf(_SC("SQDBG error : Debugger port not specified. Use the -d<PORT> parameter"));
		return EXIT_FAILURE;
	}
	// RVF -

	HSQUIRRELVM v = sq_open(1024);
	sqstd_seterrorhandlers(v);

	//!! INITIALIZES THE DEBUGGER ON THE TCP PORT 1234
	//!! ENABLES AUTOUPDATE
	HSQREMOTEDBG rdbg = sq_rdbg_init(v,debuggerPort,SQTrue);
	if(rdbg) {

		//!! ENABLES DEBUG INFO GENERATION(for the compiler)
		sq_enabledebuginfo(v,SQTrue);

		sq_setprintfunc(v,printfunc,errorfunc);

		//!! SUSPENDS THE APP UNTIL THE DEBUGGER CLIENT CONNECTS
		if(SQ_SUCCEEDED(sq_rdbg_waitforconnections(rdbg))) {
			scprintf(_SC("connected\n"));

			const SQChar *fname=NULL;
#ifdef _UNICODE
			SQChar sTemp[256];
			mbstowcs(sTemp,argv[argc-1],(int)strlen(argv[1])+1);
			fname=sTemp;
#else
			fname=argv[argc-1];
#endif 
			//!!REGISTERS STANDARDS LIBS
			sq_pushroottable(v);
			sqstd_register_bloblib(v);
			sqstd_register_iolib(v);
			sqstd_register_systemlib(v);
			sqstd_register_mathlib(v);
			sqstd_register_stringlib(v);
			//!!EXECUTE A SCTIPT
			if(SQ_FAILED(sqstd_dofile(v,fname,SQFalse,SQTrue))) {
				PrintError(v);
				_getch();
			}
		}
		//!! CLEANUP
		sq_rdbg_shutdown(rdbg);
	}
	else {
		PrintError(v);
	}
	sq_close(v);
	return 0;
}
Example #20
0
void sqstd_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++;
		}
		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: assert(0); break;
				}
				sq_pop(v,1);
			}
		}
	}
}
Example #21
0
bool ScriptObject::getTypeTag(SQUserPointer* typeTag) const
{
	return SQ_SUCCEEDED(sq_getobjtypetag((HSQOBJECT*)&mObj, typeTag));
}
Example #22
0
/*
 * Load squirrel script from asset
 */
bool loadScriptFromAsset(const char* fname) {
    /*
     * read squirrel script from asset
     */
    AAssetManager* mgr = engine->app->activity->assetManager;
    if (mgr == NULL) {
    	engine->setLastError(ERR_SCRIPT_LOAD);
    	LOGE("loadScriptFromAsset: failed to load AAssetManager");
    	return false;
    }

    AAsset* asset = AAssetManager_open(mgr, fname, AASSET_MODE_UNKNOWN);
    if (asset == NULL) {
    	engine->setLastError(ERR_SCRIPT_OPEN);
    	LOGW("loadScriptFromAsset: failed to open main script file");
        LOGW(fname);
    	return false;
    }

    unsigned short sqtag;
    bool isByteCode = false;
    if (AAsset_read(asset, &sqtag, 2) > 0) {
        if (sqtag == SQ_BYTECODE_STREAM_TAG) {
            isByteCode = true;
        }
        AAsset_seek(asset, 0, SEEK_SET);
    } else {
        AAsset_close(asset);
        return false;
    }

    if (isByteCode && SQ_SUCCEEDED(sq_readclosure(engine->sqvm, sq_lexer_bytecode, asset))) {
        sq_pushroottable(engine->sqvm);
        if (SQ_FAILED(sq_call(engine->sqvm, 1, SQFalse, SQTrue))) {
        	engine->setLastError(ERR_SCRIPT_CALL_ROOT);
            LOGW("loadScriptFromAsset: failed to sq_call");
            LOGW(fname);
            AAsset_close(asset);
            return false;
        }
    } else if(!isByteCode && SQ_SUCCEEDED(sq_compile(engine->sqvm, sq_lexer_asset, asset, fname, SQTrue))) {
        sq_pushroottable(engine->sqvm);
        if (SQ_FAILED(sq_call(engine->sqvm, 1, SQFalse, SQTrue))) {
        	engine->setLastError(ERR_SCRIPT_CALL_ROOT);
            LOGW("loadScriptFromAsset: failed to sq_call");
            LOGW(fname);
            AAsset_close(asset);
            return false;
        }
    } else {
    	engine->setLastError(ERR_SCRIPT_COMPILE);
        LOGW("loadScriptFromAsset: failed to compile squirrel script");
        LOGW(fname);
        AAsset_close(asset);
        return false;
    }

    AAsset_close(asset);

    return true;
}
Example #23
0
static SQInteger class_setattributes(HSQUIRRELVM v)
{
	if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
		return 1;
	return SQ_ERROR;
}
Example #24
0
TextureHandle TextureManager::loadTexture(const std::string& name) {
	// Check if texture has already been loaded.
	TextureHandle existing = getLoadedResource(name);
	if (existing.valid())
		return existing;

	std::string texture_filename;
	Texture::FilterMode filter_mode = Texture::FilterMode::LINEAR;
	Texture::RepeatMode repeat_mode = Texture::RepeatMode::WRAP;
	int channels = 4;

	HSQUIRRELVM vm = ::hw::engine::script_engine->vm;
	sq_pushroottable(vm);
	loadVariablePath(vm, "Resources^TextureInfo^" + name);

	const SQChar* tex_filename_cstr;

	CSQ(getKey(vm, "filename"));
	sq_getstring(vm, -1, &tex_filename_cstr);
	sq_poptop(vm);
	texture_filename = tex_filename_cstr;

	if (SQ_SUCCEEDED(getKey(vm, "channels"))) {
		sq_getinteger(vm, -1, &channels);
		sq_poptop(vm);
	}

	if (SQ_SUCCEEDED(getKey(vm, "filter_mode"))) {
		SQInteger tmp;
		sq_getinteger(vm, -1, &tmp);
		sq_poptop(vm);

		filter_mode = Texture::FilterMode(tmp);
	}

	if (SQ_SUCCEEDED(getKey(vm, "repeat_mode"))) {
		SQInteger tmp;
		sq_getinteger(vm, -1, &tmp);
		sq_poptop(vm);

		repeat_mode = Texture::RepeatMode(tmp);
	}

	texture_filename = "data/" + texture_filename;

	if (texture_filename.empty()) {
		return TextureHandle();
	}

	gl::Texture new_tex;
	glGenTextures(1, &new_tex.name);

	glBindTexture(GL_TEXTURE_2D, new_tex.name);

	setTextureParameters(filter_mode, repeat_mode);

	assert(channels >= 1 && channels <= 4);
	static const GLint internal_formats[4] = {GL_RED, GL_RG, GL_RGB, GL_RGBA};
	GLint gl_format = internal_formats[channels-1];

	int width, height, comp;
	unsigned char* data = stbi_load(texture_filename.c_str(), &width, &height, &comp, channels);
	if (data == nullptr) {
		return TextureHandle();
	}

	glTexImage2D(GL_TEXTURE_2D, 0, gl_format, width, height, 0, gl_format, GL_UNSIGNED_BYTE, data);

	return constructResource(name, Texture(std::move(new_tex), name, width, height));
}
Example #25
0
static SQInteger instance_getclass(HSQUIRRELVM v)
{
	if(SQ_SUCCEEDED(sq_getclass(v,1)))
		return 1;
	return SQ_ERROR;
}
Example #26
0
void CScripts::Call(RakNet::BitStream * bitStream)
{
	for(int i = 0; i < MAX_SCRIPTS; i++) {
		if(m_pScripts[i]) {

			int iArgCount = 0;
			int funcLen = 0;
			CHAR szFunc[256];
			bitStream->Read(funcLen);
			bitStream->Read(iArgCount);
			bitStream->Read(szFunc, funcLen);
			szFunc[funcLen] = '\0';

			// get the script vm pointer
			SQVM * pVM = m_pScripts[i]->GetVM();

			// Get the stack top
			int iTop = sq_gettop(pVM);

			// Push the root table onto the stack
			sq_pushroottable(pVM);

			// Push the function name onto the stack
			sq_pushstring(pVM, szFunc, -1);

			if(SQ_SUCCEEDED(sq_get(pVM, -2)))
			{
				// Push the root table onto the stack
				sq_pushroottable(pVM);

				if(iArgCount > 0)
				{
					for(int j = 0; i < iArgCount; i++)
					{
						int type;
						bitStream->Read(type);
						if(type == OT_INTEGER)
						{
							int val;
							bitStream->Read(val);
							sq_pushinteger(pVM, val);
						}
						else if(type == OT_FLOAT)
						{
							float val;
							bitStream->Read(val);
							sq_pushfloat(pVM, val);
						}
						else if(type == OT_BOOL)
						{
							bool val;
							bitStream->Read(val);
							sq_pushbool(pVM, val);
						}
						else if(type == OT_STRING)
						{
							int len;
							bitStream->Read(len);
							CHAR szStr[256];
							bitStream->Read(szStr, len);
							szStr[len] = '\0';
							std::string str = szStr;
							sq_pushstring(pVM, str.c_str(), -1);
						}
					}
				}
				sq_call(pVM, iArgCount + 1, true, true);
			}
			// Restore the stack top
			sq_settop(pVM, iTop);
			bitStream->ResetReadPointer();
		}
	}
}
Example #27
0
static SQInteger table_rawget(HSQUIRRELVM v)
{
	return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
}
Example #28
0
static SQInteger class_getattributes(HSQUIRRELVM v)
{
	return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR;
}
Example #29
0
static SQInteger closure_call(HSQUIRRELVM v)
{
	return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
}
Example #30
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);
			}
		}
	}
}