text: //
  // sq with import
  //
  // This is a modified version of sq that includes the import command.
  // Aside from the inclusion of import no other changes have been made.
  //
  
  //
  // Copyright (c) 2009 Alberto Demichelis, Brandon Jones
  //
  // This software is provided 'as-is', without any express or implied
  // warranty. In no event will the authors be held liable for any damages
  // arising from the use of this software.
  //
  // Permission is granted to anyone to use this software for any purpose,
  // including commercial applications, and to alter it and redistribute it
  // freely, subject to the following restrictions:
  //
  //	1. The origin of this software must not be misrepresented; you must not
  //	claim that you wrote the original software. If you use this software
  //	in a product, an acknowledgment in the product documentation would be
  //	appreciated but is not required.
  //
  //	2. Altered source versions must be plainly marked as such, and must not be
  //	misrepresented as being the original software.
  //
  //	3. This notice may not be removed or altered from any source
  //	distribution.
  //
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <stdarg.h>
  
  #if defined(_MSC_VER) && defined(_DEBUG)
  #include <crtdbg.h>
  #include <conio.h>
  #endif
  #include <squirrel.h>
  #include <sqstdblob.h>
  #include <sqstdsystem.h>
  #include <sqstdio.h>
  #include <sqstdmath.h>	
  #include <sqstdstring.h>
  #include <sqstdaux.h>
  
  // IMPORT SPECIFIC
  #include <sqratimport.h>
  
  #ifdef SQUNICODE
  #define scfprintf fwprintf
  #define scfopen	_wfopen
  #define scvprintf vwprintf
  #else
  #define scfprintf fprintf
  #define scfopen	fopen
  #define scvprintf vprintf
  #endif
  
  
  void PrintVersionInfos();
  
  #if defined(_MSC_VER) && defined(_DEBUG)
  int MemAllocHook( int allocType, void *userData, size_t size, int blockType, 
     long requestNumber, const unsigned char *filename, int lineNumber)
  {
  //	if(requestNumber==585)_asm int 3;
  	return 1;
  }
  #endif
  
  SQInteger quit(HSQUIRRELVM v)
  {
  	int *done;
  	sq_getuserpointer(v,-1,(SQUserPointer*)&done);
  	*done=1;
  	return 0;
  }
  
  void printfunc(HSQUIRRELVM v,const SQChar *s,...)
  {
  	va_list vl;
  	va_start(vl, s);
  	scvprintf( s, vl);
  	va_end(vl);
  }
  
  void PrintVersionInfos()
  {
  	scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,sizeof(SQInteger)*8);
  	if(sizeof(SQFloat) != sizeof(float)) {
  		scfprintf(stdout,_SC("[%d bits floats]\n"),sizeof(SQFloat)*8);
  	}
  }
  
  void PrintUsage()
  {
  	scfprintf(stderr,_SC("usage: sq <options> <scriptpath [args]>.\n")
  		_SC("Available options are:\n")
  		_SC("   -c              compiles the file to bytecode(default output 'out.cnut')\n")
  		_SC("   -o              specifies output file for the -c option\n")
  		_SC("   -c              compiles only\n")
  		_SC("   -d              generates debug infos\n")
  		_SC("   -v              displays version infos\n")
  		_SC("   -h              prints help\n"));
  }
  
  #define _INTERACTIVE 0
  #define _DONE 2
  //<<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;
  	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 'v':
  					PrintVersionInfos();
  					return _DONE;
  				
  				case 'h':
  					PrintVersionInfos();
  					PrintUsage();
  					return _DONE;
  				default:
  					PrintVersionInfos();
  					scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]);
  					PrintUsage();
  					return _DONE;
  				}
  			}else break;
  			arg++;
  		}
  
  		// 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)))
  						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 _DONE;
  				}
  			}
  			
  		}
  	}
  
  	return _INTERACTIVE;
  }
  
  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);
  		}
  	}
  }
  
  int main(int argc, char* argv[])
  {
  	HSQUIRRELVM v;
  	
  	const SQChar *filename=NULL;
  #if defined(_MSC_VER) && defined(_DEBUG)
  	_CrtSetAllocHook(MemAllocHook);
  #endif
  	
  	v=sq_open(1024);
      #if SQUIRREL_VERSION_NUMBER >= 300
      sq_setprintfunc(v,printfunc,printfunc);
      #else
      sq_setprintfunc(v,printfunc);
      #endif
  
  	sq_pushroottable(v);
  
  	sqstd_register_bloblib(v);
  	sqstd_register_iolib(v);
  	sqstd_register_systemlib(v);
  	sqstd_register_mathlib(v);
  	sqstd_register_stringlib(v);
  
  	// IMPORT SPECIFIC
  	sqrat_register_importlib(v);
  
  	//aux library
  	//sets error handlers
  	sqstd_seterrorhandlers(v);
  
  	//gets arguments
  	switch(getargs(v,argc,argv))
  	{
  	case _INTERACTIVE:
  		Interactive(v);
  		break;
  	case _DONE:
  	default: 
  		break;
  	}
  
  	sq_close(v);
  	
  #if defined(_MSC_VER) && defined(_DEBUG)
  	_getch();
  	_CrtMemDumpAllObjectsSince( NULL );
  #endif
  	return 0;
  }
  
  