Exemple #1
0
static SQInteger _string_endswith(HSQUIRRELVM v)
{
    const SQChar *str,*cmp;
    sq_getstring(v,2,&str);
    sq_getstring(v,3,&cmp);
    SQInteger len = sq_getsize(v,2);
    SQInteger cmplen = sq_getsize(v,3);
    SQBool ret = SQFalse;
    if(cmplen <= len) {
        ret = memcmp(&str[len - cmplen],cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse;
    }
    sq_pushbool(v,ret);
    return 1;
}
Exemple #2
0
SQInteger _stream_writestr(HSQUIRRELVM v)
{
	SETUP_STREAM(v);
	const SQChar *str,*res;
	SQInteger trgformat = 'a',len = 0;
	sq_getstring(v,2,&str);
	len = sq_getsize(v,2);
	if(sq_gettop(v)>2)
		sq_getinteger(v,3,&trgformat);
	switch(trgformat)
	{
	case 'a':
#ifdef _UNICODE
		res = sq_getscratchpad(v,len*3);
		len = (SQInteger) wcstombs((char *)res, (const wchar_t*)str, len);
#else
		res = str;
#endif
		self->Write((void *)res,len);
		break;
	case 'u':
#ifdef _UNICODE
		res = str;
#else
		res = sq_getscratchpad(v,len*sizeof(wchar_t));
		len = (SQInteger) mbstowcs((wchar_t*)res, str, len);
#endif
		self->Write((void *)res,len*sizeof(wchar_t));
		break;
	default:
		return sq_throwerror(v,_SC("wrong encoding"));
	}
	
	return 0;
}
//------------------------------------------------------------------------------
void SN_API getArray(HSQUIRRELVM vm, Variant & out_v, SQInteger index)
{
	out_v.setArray();
	Variant::Array & a = out_v.getArray();

	SQInteger len = sq_getsize(vm, index);
	SN_ASSERT(len >= 0, "Invalid array size");
	
	if (len > 0)
	{
		a.resize(len);
		s32 i = 0;

		sq_push(vm, index);
		sq_pushnull(vm);

		while (SQ_SUCCEEDED(sq_next(vm, -2)))
		{
			// -1 is the value and -2 is the key

			sq_getinteger(vm, -2, &i);
			Variant & val = a[i];
			getVariant(vm, val, -1);

			sq_pop(vm, 2); //pops key and val before the next iteration
		}

		sq_pop(vm, 2); // Pop the null iterator and array
	}
}
Exemple #4
0
static SQInteger _string_rstrip(HSQUIRRELVM v)
{
	const SQChar *str,*end;
	sq_getstring(v,2,&str);
	SQInteger len = sq_getsize(v,2);
	__strip_r(str,len,&end);
	sq_pushstring(v,str,end - str);
	return 1;
}
Exemple #5
0
static SQInteger _string_escape(HSQUIRRELVM v)
{
	const SQChar *str;
	SQChar *dest,*resstr;
	SQInteger size;
	sq_getstring(v,2,&str);
	size = sq_getsize(v,2);
	if(size == 0) {
		sq_push(v,2);
		return 1;
	}
	SQInteger destcharsize = (size * 6); //assumes every char could be escaped
	resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar));
	SQChar c;
	SQChar escch;
	SQInteger escaped = 0;
	for(int n = 0; n < size; n++){
		c = *str++;
		escch = 0;
		if(scisprint(c) || c == 0) {
			switch(c) {
			case '\a': escch = 'a'; break;
			case '\b': escch = 'b'; break;
			case '\t': escch = 't'; break;
			case '\n': escch = 'n'; break;
			case '\v': escch = 'v'; break;
			case '\f': escch = 'f'; break;
			case '\r': escch = 'r'; break;
			case '\\': escch = '\\'; break;
			case '\"': escch = '\"'; break;
			case '\'': escch = '\''; break;
			case 0: escch = '0'; break;
			}
			if(escch) {
				*dest++ = '\\';
				*dest++ = escch;
				escaped++;
			}
			else {
				*dest++ = c;
			}
		}
		else {
			dest += scsprintf(dest,destcharsize,_SC("\\x%x"),c);
			escaped++;
		}
	}

	if(escaped) {
		sq_pushstring(v,resstr,dest - resstr);
	}
	else {
		sq_push(v,2); //nothing escaped
	}
	return 1;
}
Exemple #6
0
static SQInteger _string_split(HSQUIRRELVM v)
{
	const SQChar *str,*seps;
	SQChar *stemp,*tok;
	sq_getstring(v,2,&str);
	sq_getstring(v,3,&seps);
	if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
	SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
	stemp = sq_getscratchpad(v,memsize);
	memcpy(stemp,str,memsize);
	tok = scstrtok(stemp,seps);
	sq_newarray(v,0);
	while( tok != NULL ) {
		sq_pushstring(v,tok,-1);
		sq_arrayappend(v,-2);
		tok = scstrtok( NULL, seps );
	}
	return 1;
}
Exemple #7
0
int SquirrelObject::Len() /*const*/
{
	int ret = 0;
	if(sq_isarray(_o) || sq_istable(_o) || sq_isstring(_o)) {
		sq_pushobject(m_Vm.GetVMPtr(),_o);
		ret = sq_getsize(m_Vm.GetVMPtr(),-1);
		sq_pop(m_Vm.GetVMPtr(),1);
	}
	return ret;
}
Exemple #8
0
static SQInteger _string_split(HSQUIRRELVM v)
{
	const SQChar *str,*seps;
	SQChar *stemp;
	sq_getstring(v,2,&str);
	sq_getstring(v,3,&seps);
	SQInteger sepsize = sq_getsize(v,3);
	if(sepsize == 0) return sq_throwerror(v,_SC("empty separators string"));
	SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
	stemp = sq_getscratchpad(v,memsize);
	memcpy(stemp,str,memsize);
	SQChar *start = stemp;
	SQChar *end = stemp;
	sq_newarray(v,0);
	while(*end != '\0')
	{
		SQChar cur = *end;
		for(SQInteger i = 0; i < sepsize; i++)
		{
			if(cur == seps[i])
			{
				*end = 0;
				sq_pushstring(v,start,-1);
				sq_arrayappend(v,-2);
				start = end + 1;
				break;
			}
		}
		end++;
	}
	if(end != start)
	{
		sq_pushstring(v,start,-1);
		sq_arrayappend(v,-2);
	}
	return 1;
}
Exemple #9
0
static SQInteger base_compilestring(HSQUIRRELVM v)
{
	SQInteger nargs=sq_gettop(v);
	const SQChar *src=NULL,*name=_SC("unnamedbuffer");
	SQInteger size;
	sq_getstring(v,2,&src);
	size=sq_getsize(v,2);
	if(nargs>2){
		sq_getstring(v,3,&name);
	}
	if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
		return 1;
	else
		return SQ_ERROR;
}
Exemple #10
0
static SQInteger string_find(HSQUIRRELVM v)
{
	SQInteger top,start_idx=0;
	const SQChar *str,*substr,*ret;
	if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
		if(top>2)sq_getinteger(v,3,&start_idx);
		if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
			ret=scstrstr(&str[start_idx],substr);
			if(ret){
				sq_pushinteger(v,(SQInteger)(ret-str));
				return 1;
			}
		}
		return 0;
	}
	return sq_throwerror(v,_SC("invalid param"));
}
Exemple #11
0
static SQInteger sq_lib_bind_func(HSQUIRRELVM v)
{
    void **modbuf;
    void *mod;
    void *sym;
    const SQChar *symname;
    const char *rettype;

    sq_getuserdata(v, 1, (void**)&modbuf, NULL);
    mod = *modbuf;

    sq_getstring(v, 2, &rettype);

    sq_getstring(v, 3, &symname);
    sym = GET_SYM(mod, symname);
    if (!sym)
        return sq_throwerror(v, "Cannot find symbol");

    int nparam = sq_getsize(v, 4);

    int size = sizeof(FFIFunc) + sizeof(ffi_type*) * nparam;
    FFIFunc *ffibuf = (FFIFunc*)sq_newuserdata(v, size);
    sq_push_delegate_table(v, FFI_LIB_FUNC_TAG);
    sq_setdelegate(v, -2);

//    printf("Allocated %d bytes at %p\n", size, ffibuf);
    ffibuf->func = sym;
    ffibuf->rettype = *rettype;

    int i;
    for (i = 0; i < nparam; i++) {
        sq_pushinteger(v, i);
        sq_get(v, 4);
        ffibuf->params[i] = get_ffi_type(v, -1);
        if (!ffibuf->params[i])
            return SQ_ERROR;
        sq_poptop(v);
    }
    int res = ffi_prep_cif(&ffibuf->cif, FFI_DEFAULT_ABI, nparam, char2ffi_type(*rettype), ffibuf->params);
    if (res != FFI_OK)
        return sq_throwerror(v, "Error in ffi_prep_cif");
    return 1;
}
Exemple #12
0
static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
{
	SQInteger top = sq_gettop(v);
	sidx=0;
	eidx=0;
	o=stack_get(v,1);
	SQObjectPtr &start=stack_get(v,2);
	if(type(start)!=OT_NULL && sq_isnumeric(start)){
		sidx=tointeger(start);
	}
	if(top>2){
		SQObjectPtr &end=stack_get(v,3);
		if(sq_isnumeric(end)){
			eidx=tointeger(end);
		}
	}
	else {
		eidx = sq_getsize(v,1);
	}
	return 1;
}
Exemple #13
0
static SQInteger default_delegate_len(HSQUIRRELVM v)
{
	v->Push(SQInteger(sq_getsize(v,1)));
	return 1;
}
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;
}
Exemple #15
0
static SQInteger _string_format( HSQUIRRELVM v ) {
	const SQChar *format;
	SQChar *dest;
	SQChar fmt[MAX_FORMAT_LEN];
	sq_getstring( v, 2, &format );
	SQInteger allocated = ( sq_getsize( v, 2 ) + 1 ) * sizeof( SQChar );
	dest = sq_getscratchpad( v, allocated );
	SQInteger n = 0, i = 0, nparam = 3, w = 0;
	while ( format[n] != '\0' ) {
		if ( format[n] != '%' ) {
			assert( i < allocated );
			dest[i++] = format[n];
			n++;
		} else if ( format[n+1] == '%' ) { //handles %%
			dest[i++] = '%';
			n += 2;
		} else {
			n++;
			if ( nparam > sq_gettop( v ) )
				return sq_throwerror( v, _SC( "not enough paramters for the given format string" ) );
			n = validate_format( v, fmt, format, n, w );
			if ( n < 0 ) return -1;
			SQInteger addlen = 0;
			SQInteger valtype = 0;
			const SQChar *ts;
			SQInteger ti;
			SQFloat tf;
			switch ( format[n] ) {
			case 's':
				if ( SQ_FAILED( sq_getstring( v, nparam, &ts ) ) )
					return sq_throwerror( v, _SC( "string expected for the specified format" ) );
				addlen = ( sq_getsize( v, nparam ) * sizeof( SQChar ) ) + ( ( w + 1 ) * sizeof( SQChar ) );
				valtype = 's';
				break;
case 'i': case 'd': case 'c': case 'o':  case 'u':  case 'x':  case 'X':
				if ( SQ_FAILED( sq_getinteger( v, nparam, &ti ) ) )
					return sq_throwerror( v, _SC( "integer expected for the specified format" ) );
				addlen = ( ADDITIONAL_FORMAT_SPACE ) + ( ( w + 1 ) * sizeof( SQChar ) );
				valtype = 'i';
				break;
case 'f': case 'g': case 'G': case 'e':  case 'E':
				if ( SQ_FAILED( sq_getfloat( v, nparam, &tf ) ) )
					return sq_throwerror( v, _SC( "float expected for the specified format" ) );
				addlen = ( ADDITIONAL_FORMAT_SPACE ) + ( ( w + 1 ) * sizeof( SQChar ) );
				valtype = 'f';
				break;
			default:
				return sq_throwerror( v, _SC( "invalid format" ) );
			}
			n++;
			//if((allocated-i) < addlen)
			allocated += addlen;
			dest = sq_getscratchpad( v, allocated );
			switch ( valtype ) {
			case 's': i += scsprintf( &dest[i], fmt, ts ); break;
			case 'i': i += scsprintf( &dest[i], fmt, ti ); break;
			case 'f': i += scsprintf( &dest[i], fmt, tf ); break;
			};
			nparam ++;
		}
	}
	sq_pushstring( v, dest, i );
	return 1;
}
Exemple #16
0
SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
{
	const SQChar *format;
	SQChar *dest;
	SQChar fmt[MAX_FORMAT_LEN];
	sq_getstring(v,nformatstringidx,&format);
	SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
	dest = sq_getscratchpad(v,allocated);
	SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
	while(format[n] != '\0') {
		if(format[n] != '%') {
			assert(i < allocated);
			dest[i++] = format[n];
			n++;
		}
		else if(format[n+1] == '%') { //handles %%
				dest[i++] = '%';
				n += 2; 
		}
		else {
			n++;
			if( nparam > sq_gettop(v) )
				return sq_throwerror(v,_SC("not enough paramters for the given format string"));
			n = validate_format(v,fmt,format,n,w);
			if(n < 0) return -1;
			SQInteger addlen = 0;
			SQInteger valtype = 0;
			const SQChar *ts;
			SQInteger ti;
			SQFloat tf;
			switch(format[n]) {
			case 's':
				if(SQ_FAILED(sq_getstring(v,nparam,&ts))) 
					return sq_throwerror(v,_SC("string expected for the specified format"));
				addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
				valtype = 's';
				break;
			case 'i': case 'd': case 'o': case 'u':  case 'x':  case 'X':
#ifdef _SQ64
				{
				size_t flen = scstrlen(fmt);
				SQInteger fpos = flen - 1;
				SQChar f = fmt[fpos];
				SQChar *prec = (SQChar *)_PRINT_INT_PREC;
				while(*prec != _SC('\0')) {
					fmt[fpos++] = *prec++;
				}
				fmt[fpos++] = f;
				fmt[fpos++] = _SC('\0');
				}
#endif
			case 'c':
				if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) 
					return sq_throwerror(v,_SC("integer expected for the specified format"));
				addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
				valtype = 'i';
				break;
			case 'f': case 'g': case 'G': case 'e':  case 'E':
				if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) 
					return sq_throwerror(v,_SC("float expected for the specified format"));
				addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
				valtype = 'f';
				break;
			default:
				return sq_throwerror(v,_SC("invalid format"));
			}
			n++;
			allocated += addlen + sizeof(SQChar);
			dest = sq_getscratchpad(v,allocated);
			switch(valtype) {
#pragma warning(push)  
#pragma warning(disable : 4996)  
			case 's': i += scsprintf(&dest[i],fmt,ts); break;
			case 'i': i += scsprintf(&dest[i],fmt,ti); break;
			case 'f': i += scsprintf(&dest[i],fmt,tf); break;
#pragma warning(pop)
			};
			nparam ++;
		}
	}
	*outlen = i;
	dest[i] = '\0';
	*output = dest;
	return SQ_OK;
}
Exemple #17
0
/*
** Copies values from State src to State dst.
*/
static SQRESULT copy_values_between_vms (HSQUIRRELVM dst, HSQUIRRELVM src, int argc, int argIdx)
{
    SQRESULT _rc_;
    sq_reservestack(dst, argc + 20);
    argc += argIdx; //we will work with argc args starting at argIdx
    for (; argIdx < argc; argIdx++)
    {
        switch (sq_gettype(src, argIdx))
        {
        case OT_INTEGER:
            SQ_GET_INTEGER(src, argIdx, vint);
            sq_pushinteger(dst, vint);
            break;

        case OT_FLOAT:
            SQ_GET_FLOAT(src, argIdx, vfloat);
            sq_pushfloat (dst, vfloat);
            break;

        case OT_BOOL:
            SQ_GET_BOOL(src, argIdx, vbool);
            sq_pushbool (dst, vbool);
            break;

        case OT_STRING:
        {
            SQ_GET_STRING(src, argIdx, vstr)
            sq_pushstring (dst, vstr, vstr_size);
        }
        break;

        case OT_ARRAY:
        {
            SQInteger size = sq_getsize(src, argIdx);
            sq_newarray(dst, size);
            for(SQInteger i=0; i<size; ++i)
            {
                sq_pushinteger(src, i);
                sq_get(src, -2);
                sq_pushinteger(dst, i);
                if(copy_values_between_vms(dst, src, 1, sq_gettop(src)) != SQ_OK) return SQ_ERROR;
                sq_poptop(src);
                sq_set(dst, -3);
            }
        }
        break;

        case OT_TABLE:
        {
            sq_newtable(dst);
            sq_pushnull(src);
            while(sq_next(src, -2) == SQ_OK)
            {
                SQInteger src_top = sq_gettop(src);
                if(copy_values_between_vms(dst, src, 1, src_top-1) != SQ_OK
                        || copy_values_between_vms(dst, src, 1, src_top) != SQ_OK) return SQ_ERROR;
                sq_newslot(dst, -3, SQFalse);
                sq_pop(src, 2);
            }
            sq_pop(src,1);
        }
        break;

        case OT_USERPOINTER:
        {
            SQUserPointer ptr;
            sq_getuserpointer(src, argIdx, &ptr);
            sq_pushuserpointer(dst, ptr);
        }
        break;

        case OT_NULL:
            sq_pushnull(dst);
            break;

        default:
            return SQ_ERROR;
        }
    }
    return SQ_OK;
}
Exemple #18
0
SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
{
	const SQChar *format;
	SQChar *dest;
	SQChar fmt[MAX_FORMAT_LEN];
	sq_getstring(v,nformatstringidx,&format);
	SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
	dest = sq_getscratchpad(v,allocated);
	SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
	while(format[n] != '\0') {
		if(format[n] != '%') {
			assert(i < allocated);
			dest[i++] = format[n];
			n++;
		}
		else if(format[n+1] == '%') { //handles %%
				dest[i++] = '%';
				n += 2;
		}
		else {
			n++;
			if( nparam > sq_gettop(v) )
                // C::B patch: Correct misspelled "parameters"
				return sq_throwerror(v,_SC("not enough parameters for the given format string"));
			n = validate_format(v,fmt,format,n,w);
			if(n < 0) return -1;
			SQInteger addlen = 0;
			SQInteger valtype = 0;
			const SQChar *ts;
			SQInteger ti;
			SQFloat tf;
			switch(format[n]) {
			case 's':
				if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
					return sq_throwerror(v,_SC("string expected for the specified format"));
				addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
				valtype = 's';
				break;
			case 'i': case 'd': case 'c':case 'o':  case 'u':  case 'x':  case 'X':
				if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
					return sq_throwerror(v,_SC("integer expected for the specified format"));
				addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
				valtype = 'i';
				break;
			case 'f': case 'g': case 'G': case 'e':  case 'E':
				if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
					return sq_throwerror(v,_SC("float expected for the specified format"));
				addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
				valtype = 'f';
				break;
			default:
				return sq_throwerror(v,_SC("invalid format"));
			}
			n++;
			allocated += addlen + sizeof(SQChar);
			dest = sq_getscratchpad(v,allocated);
			switch(valtype) {
			case 's': i += scsprintf(&dest[i],fmt,ts); break;
			case 'i': i += scsprintf(&dest[i],fmt,ti); break;
			case 'f': i += scsprintf(&dest[i],fmt,tf); break;
			};
			nparam ++;
		}
	}
	*outlen = i;
	dest[i] = '\0';
	*output = dest;
	return SQ_OK;
}
Exemple #19
0
static SQInteger _string_escape(HSQUIRRELVM v)
{
    const SQChar *str;
    SQChar *dest,*resstr;
    SQInteger size;
    sq_getstring(v,2,&str);
    size = sq_getsize(v,2);
    if(size == 0) {
        sq_push(v,2);
        return 1;
    }
#ifdef SQUNICODE
#if WCHAR_SIZE == 2
    const SQChar *escpat = _SC("\\x%04x");
    const SQInteger maxescsize = 6;
#else //WCHAR_SIZE == 4
    const SQChar *escpat = _SC("\\x%08x");
    const SQInteger maxescsize = 10;
#endif
#else
    const SQChar *escpat = _SC("\\x%02x");
    const SQInteger maxescsize = 4;
#endif
    SQInteger destcharsize = (size * maxescsize); //assumes every char could be escaped
    resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar));
    SQChar c;
    SQChar escch;
    SQInteger escaped = 0;
    for(int n = 0; n < size; n++){
        c = *str++;
        escch = 0;
        if(scisprint(c) || c == 0) {
            switch(c) {
            case '\a': escch = 'a'; break;
            case '\b': escch = 'b'; break;
            case '\t': escch = 't'; break;
            case '\n': escch = 'n'; break;
            case '\v': escch = 'v'; break;
            case '\f': escch = 'f'; break;
            case '\r': escch = 'r'; break;
            case '\\': escch = '\\'; break;
            case '\"': escch = '\"'; break;
            case '\'': escch = '\''; break;
            case 0: escch = '0'; break;
            }
            if(escch) {
                *dest++ = '\\';
                *dest++ = escch;
                escaped++;
            }
            else {
                *dest++ = c;
            }
        }
        else {

            dest += scsprintf(dest, destcharsize, escpat, c);
            escaped++;
        }
    }

    if(escaped) {
        sq_pushstring(v,resstr,dest - resstr);
    }
    else {
        sq_push(v,2); //nothing escaped
    }
    return 1;
}