1 /* see copyright notice in squirrel.h */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdarg.h>
7
8 #if defined(_MSC_VER) && defined(_DEBUG)
9 #include <crtdbg.h>
10 #include <conio.h>
11 #endif
12 #include <squirrel.h>
13 #include <sqstdblob.h>
14 #include <sqstdsystem.h>
15 #include <sqstdio.h>
16 #include <sqstdmath.h>
17 #include <sqstdstring.h>
18 #include <sqstdaux.h>
19
20 #ifdef SQUNICODE
21 #define scfprintf fwprintf
22 #define scvprintf vfwprintf
23 #else
24 #define scfprintf fprintf
25 #define scvprintf vfprintf
26 #endif
27
28
29 void PrintVersionInfos();
30
31 #if defined(_MSC_VER) && defined(_DEBUG)
MemAllocHook(int allocType,void * userData,size_t size,int blockType,long requestNumber,const unsigned char * filename,int lineNumber)32 int MemAllocHook( int allocType, void *userData, size_t size, int blockType,
33 long requestNumber, const unsigned char *filename, int lineNumber)
34 {
35 //if(requestNumber==769)_asm int 3;
36 return 1;
37 }
38 #endif
39
40
quit(HSQUIRRELVM v)41 SQInteger quit(HSQUIRRELVM v)
42 {
43 int *done;
44 sq_getuserpointer(v,-1,(SQUserPointer*)&done);
45 *done=1;
46 return 0;
47 }
48
printfunc(HSQUIRRELVM SQ_UNUSED_ARG (v),const SQChar * s,...)49 void printfunc(HSQUIRRELVM SQ_UNUSED_ARG(v),const SQChar *s,...)
50 {
51 va_list vl;
52 va_start(vl, s);
53 scvprintf(stdout, s, vl);
54 va_end(vl);
55 (void)v; /* UNUSED */
56 }
57
errorfunc(HSQUIRRELVM SQ_UNUSED_ARG (v),const SQChar * s,...)58 void errorfunc(HSQUIRRELVM SQ_UNUSED_ARG(v),const SQChar *s,...)
59 {
60 va_list vl;
61 va_start(vl, s);
62 scvprintf(stderr, s, vl);
63 va_end(vl);
64 }
65
PrintVersionInfos()66 void PrintVersionInfos()
67 {
68 scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,((int)(sizeof(SQInteger)*8)));
69 }
70
PrintUsage()71 void PrintUsage()
72 {
73 scfprintf(stderr,_SC("usage: sq <options> <scriptpath [args]>.\n")
74 _SC("Available options are:\n")
75 _SC(" -c compiles the file to bytecode(default output 'out.cnut')\n")
76 _SC(" -o specifies output file for the -c option\n")
77 _SC(" -c compiles only\n")
78 _SC(" -d generates debug infos\n")
79 _SC(" -v displays version infos\n")
80 _SC(" -h prints help\n"));
81 }
82
83 #define _INTERACTIVE 0
84 #define _DONE 2
85 #define _ERROR 3
86 //<<FIXME>> this func is a mess
getargs(HSQUIRRELVM v,int argc,char * argv[],SQInteger * retval)87 int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval)
88 {
89 int i;
90 int compiles_only = 0;
91 #ifdef SQUNICODE
92 static SQChar temp[500];
93 #endif
94 char * output = NULL;
95 *retval = 0;
96 if(argc>1)
97 {
98 int arg=1,exitloop=0;
99
100 while(arg < argc && !exitloop)
101 {
102
103 if(argv[arg][0]=='-')
104 {
105 switch(argv[arg][1])
106 {
107 case 'd': //DEBUG(debug infos)
108 sq_enabledebuginfo(v,1);
109 break;
110 case 'c':
111 compiles_only = 1;
112 break;
113 case 'o':
114 if(arg < argc) {
115 arg++;
116 output = argv[arg];
117 }
118 break;
119 case 'v':
120 PrintVersionInfos();
121 return _DONE;
122
123 case 'h':
124 PrintVersionInfos();
125 PrintUsage();
126 return _DONE;
127 default:
128 PrintVersionInfos();
129 scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]);
130 PrintUsage();
131 *retval = -1;
132 return _ERROR;
133 }
134 }else break;
135 arg++;
136 }
137
138 // src file
139
140 if(arg<argc) {
141 const SQChar *filename=NULL;
142 #ifdef SQUNICODE
143 mbstowcs(temp,argv[arg],strlen(argv[arg]));
144 filename=temp;
145 #else
146 filename=argv[arg];
147 #endif
148
149 arg++;
150
151 //sq_pushstring(v,_SC("ARGS"),-1);
152 //sq_newarray(v,0);
153
154 //sq_createslot(v,-3);
155 //sq_pop(v,1);
156 if(compiles_only) {
157 if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))){
158 const SQChar *outfile = _SC("out.cnut");
159 if(output) {
160 #ifdef SQUNICODE
161 int len = (int)(strlen(output)+1);
162 mbstowcs(sq_getscratchpad(v,len*sizeof(SQChar)),output,len);
163 outfile = sq_getscratchpad(v,-1);
164 #else
165 outfile = output;
166 #endif
167 }
168 if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,outfile)))
169 return _DONE;
170 }
171 }
172 else {
173 //if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQFalse,SQTrue))) {
174 //return _DONE;
175 //}
176 if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))) {
177 int callargs = 1;
178 sq_pushroottable(v);
179 for(i=arg;i<argc;i++)
180 {
181 const SQChar *a;
182 #ifdef SQUNICODE
183 int alen=(int)strlen(argv[i]);
184 a=sq_getscratchpad(v,(int)(alen*sizeof(SQChar)));
185 mbstowcs(sq_getscratchpad(v,-1),argv[i],alen);
186 sq_getscratchpad(v,-1)[alen] = _SC('\0');
187 #else
188 a=argv[i];
189 #endif
190 sq_pushstring(v,a,-1);
191 callargs++;
192 //sq_arrayappend(v,-2);
193 }
194 if(SQ_SUCCEEDED(sq_call(v,callargs,SQTrue,SQTrue))) {
195 SQObjectType type = sq_gettype(v,-1);
196 if(type == OT_INTEGER) {
197 *retval = type;
198 sq_getinteger(v,-1,retval);
199 }
200 return _DONE;
201 }
202 else{
203 return _ERROR;
204 }
205
206 }
207 }
208 //if this point is reached an error occured
209 {
210 const SQChar *err;
211 sq_getlasterror(v);
212 if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
213 scprintf(_SC("Error [%s]\n"),err);
214 *retval = -2;
215 return _ERROR;
216 }
217 }
218
219 }
220 }
221
222 return _INTERACTIVE;
223 }
224
Interactive(HSQUIRRELVM v)225 void Interactive(HSQUIRRELVM v)
226 {
227
228 #define MAXINPUT 1024
229 SQChar buffer[MAXINPUT];
230 SQInteger blocks =0;
231 SQInteger string=0;
232 SQInteger retval=0;
233 SQInteger done=0;
234 PrintVersionInfos();
235
236 sq_pushroottable(v);
237 sq_pushstring(v,_SC("quit"),-1);
238 sq_pushuserpointer(v,&done);
239 sq_newclosure(v,quit,1);
240 sq_setparamscheck(v,1,NULL);
241 sq_newslot(v,-3,SQFalse);
242 sq_pop(v,1);
243
244 while (!done)
245 {
246 SQInteger i = 0;
247 scprintf(_SC("\nsq>"));
248 for(;;) {
249 int c;
250 if(done)return;
251 c = getchar();
252 if (c == _SC('\n')) {
253 if (i>0 && buffer[i-1] == _SC('\\'))
254 {
255 buffer[i-1] = _SC('\n');
256 }
257 else if(blocks==0)break;
258 buffer[i++] = _SC('\n');
259 }
260 else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;}
261 else if(c==_SC('{') && !string){
262 blocks++;
263 buffer[i++] = (SQChar)c;
264 }
265 else if(c==_SC('"') || c==_SC('\'')){
266 string=!string;
267 buffer[i++] = (SQChar)c;
268 }
269 else if (i >= MAXINPUT-1) {
270 scfprintf(stderr, _SC("sq : input line too long\n"));
271 break;
272 }
273 else{
274 buffer[i++] = (SQChar)c;
275 }
276 }
277 buffer[i] = _SC('\0');
278
279 if(buffer[0]==_SC('=')){
280 scsprintf(sq_getscratchpad(v,MAXINPUT),(size_t)MAXINPUT,_SC("return (%s)"),&buffer[1]);
281 memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar));
282 retval=1;
283 }
284 i=scstrlen(buffer);
285 if(i>0){
286 SQInteger oldtop=sq_gettop(v);
287 if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){
288 sq_pushroottable(v);
289 if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) && retval){
290 scprintf(_SC("\n"));
291 sq_pushroottable(v);
292 sq_pushstring(v,_SC("print"),-1);
293 sq_get(v,-2);
294 sq_pushroottable(v);
295 sq_push(v,-4);
296 sq_call(v,2,SQFalse,SQTrue);
297 retval=0;
298 scprintf(_SC("\n"));
299 }
300 }
301
302 sq_settop(v,oldtop);
303 }
304 }
305 }
306
main(int argc,char * argv[])307 int main(int argc, char* argv[])
308 {
309 HSQUIRRELVM v;
310 SQInteger retval = 0;
311 #if defined(_MSC_VER) && defined(_DEBUG)
312 _CrtSetAllocHook(MemAllocHook);
313 #endif
314
315 v=sq_open(1024);
316 sq_setprintfunc(v,printfunc,errorfunc);
317
318 sq_pushroottable(v);
319
320 sqstd_register_bloblib(v);
321 sqstd_register_iolib(v);
322 sqstd_register_systemlib(v);
323 sqstd_register_mathlib(v);
324 sqstd_register_stringlib(v);
325
326 //aux library
327 //sets error handlers
328 sqstd_seterrorhandlers(v);
329
330 //gets arguments
331 switch(getargs(v,argc,argv,&retval))
332 {
333 case _INTERACTIVE:
334 Interactive(v);
335 break;
336 case _DONE:
337 case _ERROR:
338 default:
339 break;
340 }
341
342 sq_close(v);
343
344 #if defined(_MSC_VER) && defined(_DEBUG)
345 _getch();
346 _CrtMemDumpAllObjectsSince( NULL );
347 #endif
348 return retval;
349 }
350
351