00001
00002 #include <squirrel.h>
00003 #include <sqstdaux.h>
00004 #include <assert.h>
00005
00006 void sqstd_printcallstack(HSQUIRRELVM v)
00007 {
00008 SQPRINTFUNCTION pf = sq_getprintfunc(v);
00009 if(pf) {
00010 SQStackInfos si;
00011 SQInteger i;
00012 SQFloat f;
00013 const SQChar *s;
00014 SQInteger level=1;
00015 const SQChar *name=0;
00016 SQInteger seq=0;
00017 pf(v,_SC("\nCALLSTACK\n"));
00018 while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
00019 {
00020 const SQChar *fn=_SC("unknown");
00021 const SQChar *src=_SC("unknown");
00022 if(si.funcname)fn=si.funcname;
00023 if(si.source)src=si.source;
00024 pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
00025 level++;
00026 }
00027 level=0;
00028 pf(v,_SC("\nLOCALS\n"));
00029
00030 for(level=0;level<10;level++){
00031 seq=0;
00032 while((name = sq_getlocal(v,level,seq)))
00033 {
00034 seq++;
00035 switch(sq_gettype(v,-1))
00036 {
00037 case OT_NULL:
00038 pf(v,_SC("[%s] NULL\n"),name);
00039 break;
00040 case OT_INTEGER:
00041 sq_getinteger(v,-1,&i);
00042 pf(v,_SC("[%s] %d\n"),name,i);
00043 break;
00044 case OT_FLOAT:
00045 sq_getfloat(v,-1,&f);
00046 pf(v,_SC("[%s] %.14g\n"),name,f);
00047 break;
00048 case OT_USERPOINTER:
00049 pf(v,_SC("[%s] USERPOINTER\n"),name);
00050 break;
00051 case OT_STRING:
00052 sq_getstring(v,-1,&s);
00053 pf(v,_SC("[%s] \"%s\"\n"),name,s);
00054 break;
00055 case OT_TABLE:
00056 pf(v,_SC("[%s] TABLE\n"),name);
00057 break;
00058 case OT_ARRAY:
00059 pf(v,_SC("[%s] ARRAY\n"),name);
00060 break;
00061 case OT_CLOSURE:
00062 pf(v,_SC("[%s] CLOSURE\n"),name);
00063 break;
00064 case OT_NATIVECLOSURE:
00065 pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
00066 break;
00067 case OT_GENERATOR:
00068 pf(v,_SC("[%s] GENERATOR\n"),name);
00069 break;
00070 case OT_USERDATA:
00071 pf(v,_SC("[%s] USERDATA\n"),name);
00072 break;
00073 case OT_THREAD:
00074 pf(v,_SC("[%s] THREAD\n"),name);
00075 break;
00076 case OT_CLASS:
00077 pf(v,_SC("[%s] CLASS\n"),name);
00078 break;
00079 case OT_INSTANCE:
00080 pf(v,_SC("[%s] INSTANCE\n"),name);
00081 break;
00082 case OT_WEAKREF:
00083 pf(v,_SC("[%s] WEAKREF\n"),name);
00084 break;
00085 case OT_BOOL:{
00086 sq_getinteger(v,-1,&i);
00087 pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));
00088 }
00089 break;
00090 default: assert(0); break;
00091 }
00092 sq_pop(v,1);
00093 }
00094 }
00095 }
00096 }
00097
00098 static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
00099 {
00100 SQPRINTFUNCTION pf = sq_getprintfunc(v);
00101 if(pf) {
00102 const SQChar *sErr = 0;
00103 if(sq_gettop(v)>=1) {
00104 if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
00105 pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
00106 }
00107 else{
00108 pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
00109 }
00110 sqstd_printcallstack(v);
00111 }
00112 }
00113 return 0;
00114 }
00115
00116 void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
00117 {
00118 SQPRINTFUNCTION pf = sq_getprintfunc(v);
00119 if(pf) {
00120 pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
00121 }
00122 }
00123
00124 void sqstd_seterrorhandlers(HSQUIRRELVM v)
00125 {
00126 sq_setcompilererrorhandler(v,_sqstd_compiler_error);
00127 sq_newclosure(v,_sqstd_aux_printerror,0);
00128 sq_seterrorhandler(v);
00129 }