Updated addon repository URL and improved debug output on download
[supertux.git] / external / squirrel / squirrel / sqdebug.cpp
1 /*\r
2         see copyright notice in squirrel.h\r
3 */\r
4 #include "sqpcheader.h"\r
5 #include <stdarg.h>\r
6 #include "sqvm.h"\r
7 #include "sqfuncproto.h"\r
8 #include "sqclosure.h"\r
9 #include "sqstring.h"\r
10 \r
11 SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi)\r
12 {\r
13         SQInteger cssize = v->_callsstacksize;\r
14         if (cssize > level) {\r
15                 SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];\r
16                 if(sq_isclosure(ci._closure)) {\r
17                         SQClosure *c = _closure(ci._closure);\r
18                         SQFunctionProto *proto = c->_function;\r
19                         fi->funcid = proto;\r
20                         fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");\r
21                         fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");\r
22                         return SQ_OK;\r
23                 }\r
24         }\r
25         return sq_throwerror(v,_SC("the object is not a closure"));\r
26 }\r
27 \r
28 SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)\r
29 {\r
30         SQInteger cssize = v->_callsstacksize;\r
31         if (cssize > level) {\r
32                 memset(si, 0, sizeof(SQStackInfos));\r
33                 SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];\r
34                 switch (type(ci._closure)) {\r
35                 case OT_CLOSURE:{\r
36                         SQFunctionProto *func = _closure(ci._closure)->_function;\r
37                         if (type(func->_name) == OT_STRING)\r
38                                 si->funcname = _stringval(func->_name);\r
39                         if (type(func->_sourcename) == OT_STRING)\r
40                                 si->source = _stringval(func->_sourcename);\r
41                         si->line = func->GetLine(ci._ip);\r
42                                                 }\r
43                         break;\r
44                 case OT_NATIVECLOSURE:\r
45                         si->source = _SC("NATIVE");\r
46                         si->funcname = _SC("unknown");\r
47                         if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)\r
48                                 si->funcname = _stringval(_nativeclosure(ci._closure)->_name);\r
49                         si->line = -1;\r
50                         break;\r
51                 default: break; //shutup compiler\r
52                 }\r
53                 return SQ_OK;\r
54         }\r
55         return SQ_ERROR;\r
56 }\r
57 \r
58 void SQVM::Raise_Error(const SQChar *s, ...)\r
59 {\r
60         va_list vl;\r
61         va_start(vl, s);\r
62         SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2);\r
63         scvsprintf(_sp(rsl(buffersize)),buffersize, s, vl);\r
64         va_end(vl);\r
65         _lasterror = SQString::Create(_ss(this),_spval,-1);\r
66 }\r
67 \r
68 void SQVM::Raise_Error(const SQObjectPtr &desc)\r
69 {\r
70         _lasterror = desc;\r
71 }\r
72 \r
73 SQString *SQVM::PrintObjVal(const SQObjectPtr &o)\r
74 {\r
75         switch(type(o)) {\r
76         case OT_STRING: return _string(o);\r
77         case OT_INTEGER:\r
78                 scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _PRINT_INT_FMT, _integer(o));\r
79                 return SQString::Create(_ss(this), _spval);\r
80                 break;\r
81         case OT_FLOAT:\r
82                 scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));\r
83                 return SQString::Create(_ss(this), _spval);\r
84                 break;\r
85         default:\r
86                 return SQString::Create(_ss(this), GetTypeName(o));\r
87         }\r
88 }\r
89 \r
90 void SQVM::Raise_IdxError(const SQObjectPtr &o)\r
91 {\r
92         SQObjectPtr oval = PrintObjVal(o);\r
93         Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));\r
94 }\r
95 \r
96 void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)\r
97 {\r
98         SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);\r
99         Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));\r
100 }\r
101 \r
102 \r
103 void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)\r
104 {\r
105         SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);\r
106         SQInteger found = 0;    \r
107         for(SQInteger i=0; i<16; i++)\r
108         {\r
109                 SQInteger mask = 0x00000001 << i;\r
110                 if(typemask & (mask)) {\r
111                         if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);\r
112                         found ++;\r
113                         StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);\r
114                 }\r
115         }\r
116         Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));\r
117 }\r