Ejemplo n.º 1
0
SQInteger SquirrelStd::require(HSQUIRRELVM vm)
{
	SQInteger top = sq_gettop(vm);
	const SQChar *filename;
	SQChar *real_filename;

	sq_getstring(vm, 2, &filename);

	/* Get the script-name of the current file, so we can work relative from it */
	SQStackInfos si;
	sq_stackinfos(vm, 1, &si);
	if (si.source == NULL) {
		DEBUG(misc, 0, "[squirrel] Couldn't detect the script-name of the 'require'-caller; this should never happen!");
		return SQ_ERROR;
	}
	real_filename = scstrdup(si.source);
	/* Keep the dir, remove the rest */
	SQChar *s = scstrrchr(real_filename, PATHSEPCHAR);
	if (s != NULL) {
		/* Keep the PATHSEPCHAR there, remove the rest */
		s++;
		*s = '\0';
	}
	/* And now we concat, so we are relative from the current script
	 * First, we have to make sure we have enough space for the full path */
	real_filename = ReallocT(real_filename, scstrlen(real_filename) + scstrlen(filename) + 1);
	scstrcat(real_filename, filename);
	/* Tars dislike opening files with '/' on Windows.. so convert it to '\\' ;) */
	char *filen = strdup(SQ2OTTD(real_filename));
#if (PATHSEPCHAR != '/')
	for (char *n = filen; *n != '\0'; n++) if (*n == '/') *n = PATHSEPCHAR;
#endif

	bool ret = Squirrel::LoadScript(vm, filen);

	/* Reset the top, so the stack stays correct */
	sq_settop(vm, top);
	free(real_filename);
	free(filen);

	return ret ? 0 : SQ_ERROR;
}
Ejemplo n.º 2
0
void CSquirrelVM::Call(stScriptFunction function, CScriptArguments * pArguments)
{
	if (function.function._type != SQObjectType::OT_CLOSURE || function.function._unVal.pClosure == 0)
		return;

	SQObjectPtr res;
	int iTop = sq_gettop(m_pVM);
	if (pArguments)
	{
		for (auto it : pArguments->m_Arguments)
			it->Push(this);
		
		m_pVM->Call(function.function, pArguments->m_Arguments.size() + 1, m_pVM->_top - (pArguments->m_Arguments.size() + 1), res, true);
	}
	else
	{
		m_pVM->Call(function.function, 1, m_pVM->_top - 1, res, true);
	}
	sq_settop(m_pVM, iTop);
}
Ejemplo n.º 3
0
/*
 * Call Squirrel function with one float parameter
 * Returns SQTrue if sq_call succeeds.
 */
SQBool callSqFunction_Bool_Float(HSQUIRRELVM v, const SQChar* nname, const SQChar* name, SQFloat value, SQBool defaultValue) {
	SQBool   result = SQFalse;

	SQInteger top = sq_gettop(v);
	sq_pushroottable(v);
	sq_pushstring(v, nname, -1);
	if (SQ_SUCCEEDED(sq_get(v, -2))) {
		sq_pushstring(v, name, -1);
		if(SQ_SUCCEEDED(sq_get(v, -2))) {
			sq_pushroottable(v);
			sq_pushfloat(v, value);
			if (SQ_SUCCEEDED(sq_call(v, 2, SQTrue, SQTrue))) {
				sq_getbool(v, sq_gettop(v), &result);
			}
		}
	}
	sq_settop(v,top);

	return result;
}
Ejemplo n.º 4
0
//QSORT ala Sedgewick
bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
{
	if(func < 0) {
		if(!v->ObjCmp(a,b,ret)) return false;
	}
	else {
		SQInteger top = sq_gettop(v);
		sq_push(v, func);
		sq_pushroottable(v);
		v->Push(a);
		v->Push(b);
		if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
			if(!sq_isstring( v->_lasterror)) 
				v->Raise_Error(_SC("compare func failed"));
			return false;
		}
		sq_getinteger(v, -1, &ret);
		sq_settop(v, top);
		return true;
	}
	return true;
}
Ejemplo n.º 5
0
/*
 * Call Squirrel function with strings parameter
 * Returns SQTrue if sq_call succeeds.
 */
SQBool callSqFunction_Bool_Strings(HSQUIRRELVM v, const SQChar* nname, const SQChar* name, 
			const SQChar* value1, const SQChar* value2,
			const SQChar* value3, const SQChar* value4, SQBool defaultValue) {
	SQBool result = defaultValue;
	SQInteger top = sq_gettop(v);
	sq_pushroottable(v);
	sq_pushstring(v, nname, -1);
	if (SQ_SUCCEEDED(sq_get(v, -2))) {
		sq_pushstring(v, name, -1);
		if(SQ_SUCCEEDED(sq_get(v, -2))) {
			sq_pushroottable(v);
			sq_pushstring(v, value1, -1);
			sq_pushstring(v, value2, -1);
			sq_pushstring(v, value3, -1);
			sq_pushstring(v, value4, -1);
			result = SQ_SUCCEEDED(sq_call(v, 5, SQFalse, SQTrue));
		}
	}
	sq_settop(v,top);
	
	return result;
}
Ejemplo n.º 6
0
/*
 * Call Squirrel function with multiple float parameters, returns boolean
 * Returns default value if sq_call failed.
 */
SQBool callSqFunction_Bool_Floats(HSQUIRRELVM v, const SQChar* nname, const SQChar* name, SQFloat param[], int count, SQBool defaultValue) {
	SQBool   result = defaultValue;

	SQInteger top = sq_gettop(v);
	sq_pushroottable(v);
	sq_pushstring(v, nname, -1);
	if (SQ_SUCCEEDED(sq_get(v, -2))) {
		sq_pushstring(v, name, -1);
		if(SQ_SUCCEEDED(sq_get(v, -2))) {
			sq_pushroottable(v);
			for (int i = 0; i < count; i++) {
				sq_pushfloat(v, param[i]);
			}
			if (SQ_SUCCEEDED(sq_call(v, count + 1, SQTrue, SQTrue))) {
				sq_getbool(v, sq_gettop(v), &result);
			}
		}
	}
	sq_settop(v,top);

	return result;
}
Ejemplo n.º 7
0
static SQRESULT sq_slave_vm_get(HSQUIRRELVM v)
{
    GET_sq_slave_vm_INSTANCE(v, 1);
    SQInteger top = sq_gettop(self);
    SQRESULT result = SQ_ERROR;
    sq_pushroottable(self);
    if(copy_values_between_vms(self, v, 1, 2) == SQ_OK)
    {
        if(sq_get(self, -2) == SQ_OK
                && copy_values_between_vms(v, self, 1, sq_gettop(self)) == SQ_OK)
        {
            result = 1;
        }
        else
        {
            if(sq_gettop(v) == 3) result = 1; //we have a default value
            else sq_throwerror(v, sq_getlasterror_str(self));
        }
    }
    sq_settop(self, top);
    return result;
}
Ejemplo n.º 8
0
void CScripts::onVehicleDamage(int vehicleId, float oldhp, float newhp)
{
	for(int i = 0; i < MAX_SCRIPTS; i++) {
		if(m_pScripts[i]) {
			// 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, "onVehicleDamage", -1);

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

				// Push the vehicle id onto the stack
				sq_pushinteger(pVM, vehicleId);

				// Push the player old health onto the stack
				sq_pushfloat(pVM, oldhp);

				// Push the player new health onto the stack
				sq_pushfloat(pVM, newhp);

				// Call the function
				sq_call(pVM, 4, true, true);
			}

			// Restore the stack top
			sq_settop(pVM, iTop);
		}
	}
}
Ejemplo n.º 9
0
void CScripts::onPlayerDeath(int playerId, int killerId, int reason)
{
	for(int i = 0; i < MAX_SCRIPTS; i++) {
		if(m_pScripts[i]) {
			// 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, "onPlayerDeath", -1);

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

				// Push the player id onto the stack
				sq_pushinteger(pVM, playerId);

				// Push the killer id onto the stack
				sq_pushinteger(pVM, killerId);

				// Push the death reason onto the stack
				sq_pushinteger(pVM, reason);

				// Call the function
				sq_call(pVM, 4, true, true);
			}

			// Restore the stack top
			sq_settop(pVM, iTop);
		}
	}
}
Ejemplo n.º 10
0
	/*
	 * invoke contact event
	 */
	static SQBool invokeContactEvent(HSQUIRRELVM v, ContactPoint cp) {
		SQBool result = false;
		SQInteger top = sq_gettop(v);
		sq_pushroottable(v);
		sq_pushstring(v, "emo", -1);
		if (SQ_SUCCEEDED(sq_get(v, -2))) {
			sq_pushstring(v, "_onContact", -1);
			if(SQ_SUCCEEDED(sq_get(v, -2))) {
				sq_pushroottable(v);
				switch(cp.state) {
					case b2_addState:
						sq_pushinteger(v, PHYSICS_STATE_ADD);
						break;
					case b2_persistState:
						sq_pushinteger(v, PHYSICS_STATE_PERSIST);
						break;
					case b2_removeState:
						sq_pushinteger(v, PHYSICS_STATE_REMOVE);
						break;
					default:
						sq_pushinteger(v, PHYSICS_STATE_NULL);
				}
				sq_pushuserpointer(v, cp.fixtureA);
				sq_pushuserpointer(v, cp.fixtureB);
				sq_pushuserpointer(v, cp.fixtureA->GetBody());
				sq_pushuserpointer(v, cp.fixtureB->GetBody());
				pushVec2(v, cp.position);
				pushVec2(v, cp.normal);
				sq_pushfloat(v, cp.normalImpulse);
				sq_pushfloat(v, cp.tangentImpulse);
				
				result = SQ_SUCCEEDED(sq_call(v, 10, SQFalse, SQTrue));
			}
		}
		sq_settop(v,top);
		
		return result;
	}
Ejemplo n.º 11
0
SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
{
	SQInteger top = sq_gettop(v);
	sq_pushregistrytable(v);
	sq_pushstring(v,_SC("std_file"),-1);
	if(SQ_SUCCEEDED(sq_get(v,-2))) {
		sq_remove(v,-2); //removes the registry
		sq_pushroottable(v); // push the this
		sq_pushuserpointer(v,file); //file
		if(own){
			sq_pushinteger(v,1); //true
		}
		else{
			sq_pushnull(v); //false
		}
		if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
			sq_remove(v,-2);
			return SQ_OK;
		}
	}
	sq_settop(v,top);
	return SQ_OK;
}
Ejemplo n.º 12
0
static SQRESULT sq_slave_vm_dofile(HSQUIRRELVM v)
{
    SQ_FUNC_VARS(v);
    GET_sq_slave_vm_INSTANCE(v, 1);
    SQ_GET_STRING(v, 2, file_name);
    SQ_OPT_BOOL(v, 3, retval, false);
    SQ_OPT_BOOL(v, 4, printerror, false);
    SQ_OPT_BOOL(v, 5, show_warnings, false);
    SQInteger top = sq_gettop(self);
    SQRESULT result = SQ_ERROR;
    sq_pushroottable(self); //important always push the root table, because sqstd_dofile will try to do a sq_push(v, -2)
    if(sqstd_dofile(self, file_name, retval, printerror, show_warnings) >= 0)
    {
        if(retval)
        {
            if(copy_values_between_vms(v, self, 1, sq_gettop(self)) == SQ_OK) result = 1;
        }
        else result = SQ_OK;
    }
    else sq_throwerror(v, sq_getlasterror_str(self));
    sq_settop(self, top);
    return result;
}
Ejemplo n.º 13
0
void CScripts::onPlayerCommand(int playerId, const char *command)
{
	for(int i = 0; i < MAX_SCRIPTS; i++) {
		if(m_pScripts[i]) {
			// 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, "onPlayerCommand", -1);

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

				// Push the player id onto the stack
				sq_pushinteger(pVM, playerId);

				// Push the text onto the stack
				sq_pushstring(pVM, command, -1);

				// Call the function
				sq_call(pVM, 3, true, true);
			}

			// Restore the stack top
			sq_settop(pVM, iTop);
		}
	}
}
Ejemplo n.º 14
0
void ScriptBehavior::Update( float deltaTime )
{
    if( !m_start )
    {
        Start();
        m_start = true;
    }

    if( !m_initialize || !m_haveUpdate )
    {
        return;
    }

    int top = sq_gettop(m_vm);

    sq_pushobject(m_vm, m_instance);
    sq_pushobject(m_vm, m_updateFunction);

    sq_push( m_vm,-3 );
    sq_pushfloat( m_vm,deltaTime );
    sq_call( m_vm,2,SQFalse,SQTrue );

    sq_settop( m_vm,top );
}
Ejemplo n.º 15
0
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 );
}
Ejemplo n.º 16
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_newslot(v,-3,SQFalse);
	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);
		}
	}
}
Ejemplo n.º 17
0
StackLock::~StackLock()
{
    sq_settop(context_.getHandle(), top_);
}
Ejemplo n.º 18
0
int main (int argc, char** argv)
{
	ENABLE_LEAK_CHECK();

#if defined(SHELL_PLATFORM_WINDOWS)
	SetConsoleTitle("Squirrel Shell " SHELL_VERSION_STR " (" SHELL_CPUARCH ")");
#else
	stderrIsRedirected = !isatty(2);
#endif

	// Parse command line arguments.
	const char* fileName	= NULL;
	bool		interactive = argc == 1;
	int			firstArg	= 0,
				i;
	bool isDebug = false;
	int debuggerPort = 0;
	for (i = 1; argv[i]; ++i)
	{
		char* arg = argv[i];

		if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
		{
			printf("Squirrel Shell %s for %s on %s (" __DATE__ ")\n"
				   SHELL_VERSION_COPYRIGHT "\n"
				   "\n"
				   "This is free software, and comes WITHOUT ANY WARRANTY; without even the implied\n"
				   "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
				   "General Public License for more details.\n"
				   "\n"
				   "MD5 hash calculation code (c) Colin Plumb\n"
				   "PCRE (c) University of Cambridge\n"
				   "Squirrel (c) Alberto Demichelis\n"
				   "zlib (c) Jean-loup Gailly and Mark Adler\n"
				   "\n"
				   "Usage:\n"
				   "   squirrelsh [options] [script_file] [script_arguments]\n"
				   "\n"
				   "Options:\n"
				   "   -h, --help          Display this text\n"
				   "   -d<PORT>            Enable the debugger, in the specified port\n"
				   "   -i, --interactive   Run shell in interactive mode\n"
				   "                       If script file is specified, it will be executed before\n"
				   "                       entering this mode\n"
				   "   -s, --silent        Do not display error and warning messages\n"
				   "   -v, --version       Display shell version number\n"
				   "\n"
				   "Examples:\n"
				   "   squirrelsh                    Run shell in interactive mode\n"
				   "   squirrelsh foo.nut            Run foo.nut script without arguments\n"
				   "   squirrelsh -i foo.nut 1 2 3   Run foo.nut script with arguments \"1\", \"2\"\n"
				   "                                 and \"3\", and switch into interactive mode\n",
				   SHELL_VERSION_STR,
				   SHELL_PLATFORM,
				   SHELL_CPUARCH);

			return EXIT_SUCCESS;
		}
		else if (!strncmp(arg, "-d", 2))
		{
			// RVF +
			isDebug = true;
			debuggerPort = std::atoi(arg + 2);
			if (debuggerPort == 0)
			{
				printf("No debugger port specified\n");
				return EXIT_FAILURE;
			}
			// RVF -
		}
		else if (!strcmp(arg, "-i") || !strcmp(arg, "--interactive"))
			interactive = true;
		else if (!strcmp(arg, "-v") || !strcmp(arg, "--version"))
		{
			printf("%s\n", SHELL_VERSION_STR);
			return EXIT_SUCCESS;
		}
		else if (!strcmp(arg, "-s") || !strcmp(arg, "--silent"))
			silent = true;
		else
		{
			// First unreserved argument will be treated as script file name.
			fileName = arg;
			firstArg = i;
			break;
		}
	}

	if (!fileName && !interactive)
	{
		PrintError("ERROR: Script file not specified.\n");
		return EXIT_FAILURE;
	}

	// Initialize Squirrel.
	sqvm = sq_open(1024);
	if (!sqvm)
	{
		PrintError("ERROR: Failed to create Squirrel VM.\n");
		return EXIT_FAILURE;
	}

	sqstd_seterrorhandlers(sqvm);

	HSQREMOTEDBG rdbg = nullptr;
	if (isDebug)
	{
		rdbg = sq_rdbg_init(sqvm, debuggerPort, SQTrue);
		sq_enabledebuginfo(sqvm, SQTrue);

		//!! SUSPENDS THE APP UNTIL THE DEBUGGER CLIENT CONNECTS
		scprintf("Waiting for the debugger to connect...\n");
		if (!SQ_SUCCEEDED(sq_rdbg_waitforconnections(rdbg)))
		{
			PrintError("ERROR: Failed to connect to the debugger.\n");
			return EXIT_FAILURE;
		}
		scprintf(_SC("Connected to the debugger\n"));
	}


	//sq_setcompilererrorhandler(sqvm, SquirrelCompileError);

	_RPT0(_CRT_WARN, "--- Squirrel initialized\n");

	// Register some globals.
	SetSqString("SHELL_VERSION", SHELL_VERSION_STR, SQTrue);
	SetSqString("SQUIRREL_VERSION", SQUIRREL_VERSION_SHORT, SQTrue);
	SetSqString("PLATFORM", SHELL_PLATFORM, SQTrue);
	SetSqString("CPU_ARCH", SHELL_CPUARCH, SQTrue);

	// Initialize libraries.
	Init_Base();
	Init_IO();
	Init_File();
	Init_Math();
	Init_Util();
	Init_Hash();
	Init_RegExp();

	_RPT0(_CRT_WARN, "--- Libraries initialized\n");

	// Set up global variables...
	sq_pushroottable(sqvm);

	// RVF +
	// Initialize squirrel std libraries
	//sqstd_register_bloblib(sqvm);
	sqstd_register_iolib(sqvm); // We need this one because of the handy "dofile" function
	sqstd_register_stringfunctions(sqvm); // This registers only some string functions that are useful and don't clash with Squirrel Shell
	// NOTE: Not registering the other libraries, because there are name clashing between Squirrel Shell and SqStdLib
	//sqstd_register_systemlib(sqvm);
	//sqstd_register_mathlib(sqvm);
	//sqstd_register_stringlib(sqvm);
	// RVF -


	// ... number of command line arguments...
	sq_pushstring(sqvm, "__argc", -1);
	sq_pushinteger(sqvm, SQInteger(argc - firstArg));
	if (SQ_FAILED(sq_newslot(sqvm, -3, SQFalse)))
	{
		PrintError("ERROR: Failed to create \"__argc\" integer value.\n");
		Shutdown();
		return EXIT_FAILURE;
	}

	// ... and arguments themselves.
	sq_pushstring(sqvm, "__argv", -1);
	sq_newarray(sqvm, 0);
	for (i = firstArg; argv[i]; ++i)
	{
		sq_pushstring(sqvm, argv[i], -1);
		sq_arrayappend(sqvm, -2);
	}
	if (SQ_FAILED(sq_newslot(sqvm, -3, SQFalse)))
	{
		PrintError("ERROR: Failed to create \"__argv\" array.\n");
		Shutdown();
		return EXIT_FAILURE;
	}
	sq_pop(sqvm, 1);

	// Load and run script.
	SQInteger result = EXIT_SUCCESS;
	if (fileName && LoadScript(fileName))
	{
		sq_pushroottable(sqvm);
		if (SQ_FAILED(sq_call(sqvm, 1, SQTrue, isDebug ? SQTrue : SQFalse)))
		{
			if (!silent)
			{
				const SQChar* errMsg = "Unknown error.";
				sq_getlasterror(sqvm);
				if (sq_gettype(sqvm, -1) == OT_STRING)
					sq_getstring(sqvm, -1, &errMsg);

				PrintError("ERROR: %s\n", errMsg);
			}
			Shutdown();
			return EXIT_FAILURE;
		}

		// Get script execution result.
		if (sq_getvmstate(sqvm) == SQ_VMSTATE_SUSPENDED)
			result = retCode;
		else
		{
			if (sq_gettype(sqvm, -1) == OT_INTEGER)
				sq_getinteger(sqvm, -1, &result);
		}

		// Pop everything except root table.
		sq_settop(sqvm, 1);
	}

	// Enter interactive mode (if necessary).
	if (interactive)
	{
		SQChar cmd[MAX_CMD_LENGTH + 1];
		do
		{
#if defined(SHELL_PLATFORM_WINDOWS)
			GetCurrentDirectory(sizeof(cmd), cmd);
#else
			getcwd(cmd, sizeof(cmd));
#endif
			cmd[sizeof(cmd) - 1] = 0;

			printf("%s> ", ConvPath(cmd, SQFalse));
			fgets(cmd, MAX_CMD_LENGTH, stdin);
			if (SQ_FAILED(sq_compilebuffer(sqvm, cmd, SQInteger(strlen(cmd)), "", SQTrue)))
				continue;

			sq_pushroottable(sqvm);
			if (SQ_FAILED(sq_call(sqvm, 1, SQFalse, SQFalse)) && !silent)
			{
				const SQChar* errMsg = "Unknown error.";
				sq_getlasterror(sqvm);
				if (sq_gettype(sqvm, -1) == OT_STRING)
					sq_getstring(sqvm, -1, &errMsg);

				PrintError("ERROR: %s\n", errMsg);
			}
		} while(sq_getvmstate(sqvm) != SQ_VMSTATE_SUSPENDED);
		result = retCode;
	}

	if (isDebug)
	{
		sq_rdbg_shutdown(rdbg);
	}

	Shutdown();
	return int(result);
}
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;
}
Ejemplo n.º 20
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();
		}
	}
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
0
void sq_closethread(HSQUIRRELVM v)
{
	sq_settop(v, 0);
	v->Finalize();
}
Ejemplo n.º 23
0
int Xml_eval(HSQUIRRELVM v) {
    SQ_FUNC_VARS_NO_TOP(v);
	SQChar* str = 0;
	size_t str_size=0;
	if(sq_gettype(v,2) == OT_USERPOINTER) sq_getuserpointer(v, 2, &str);
	else {
	    SQ_GET_STRING(v, 2, sTmp);
		str = (SQChar*)sq_malloc(sTmp_size+(sizeof(SQChar)));
		memcpy(str, sTmp, sTmp_size);
		str[sTmp_size]=0;
		str_size = sTmp_size;
	}
	Tokenizer* tok = Tokenizer_new(str, str_size ? str_size : scstrlen(str));
	sq_settop(v,0);
	const SQChar* token=0;
	int firstStatement = 1;
	while((token=Tokenizer_next(tok))!=0) if(token[0]==OPN) { // new tag found
		if(sq_gettop(v)) {
			int newIndex=sq_size(v,-1)+1;
			sq_pushinteger(v,newIndex);
			sq_newtable(v);
			sq_set(v, -3);
			sq_pushinteger(v,newIndex);
			sq_get(v,-2);
		}
		else {
			if (firstStatement) {
				sq_newtable(v);
				firstStatement = 0;
			}
			else return lua_gettop(L);
		}
		// set metatable:
		sq_newtable(v);
		sq_pushliteral(v, _SC("__index"));
		sq_getglobal(v, "xml");
		lua_settable(v, -3);

		sq_pushliteral(v, _SC("__tostring")); // set __tostring metamethod
		lua_getglobal(L, "xml");
		lua_pushliteral(L,"str");
		lua_gettable(v, -2);
		sq_remove(v, -2);
		sq_set(v, -3);
		lua_setmetatable(L, -2);

		// parse tag and content:
		sq_pushinteger(v,0); // use index 0 for storing the tag
		sq_pushstring(v, Tokenizer_next(tok), -1);
		sq_set(v, -3);

		while(((token = Tokenizer_next(tok))!=0)&&(token[0]!=CLS)&&(token[0]!=ESC)) { // parse tag header
			size_t sepPos=find(token, "=", 0);
			if(token[sepPos]) { // regular attribute
				const SQChar* aVal =token+sepPos+2;
				sq_pushstring(v, token, sepPos);
				size_t lenVal = strlen(aVal)-1;
				if(!lenVal) Xml_pushDecode(v, _SC(""), 0);
				else Xml_pushDecode(v, aVal, lenVal);
				sq_set(v, -3);
			}
		}
		if(!token||(token[0]==ESC)) {
			if(sq_gettop(v)>1) sq_settop(v,-2); // this tag has no content, only attributes
			else break;
		}
	}
	else if(token[0]==ESC) { // previous tag is over
		if(sq_gettop(v)>1) sq_settop(v,-2); // pop current table
		else break;
	}
	else { // read elements
		sq_pushinteger(v,sq_size(v,-1)+1);
		Xml_pushDecode(v, token, 0);
		sq_rawset(v, -3);
	}
	Tokenizer_delete(tok);
	sq_free(str);
	return sq_gettop(v);
}