Copyright update to 2015
[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         scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);\r
63         va_end(vl);\r
64         _lasterror = SQString::Create(_ss(this),_spval,-1);\r
65 }\r
66 \r
67 void SQVM::Raise_Error(const SQObjectPtr &desc)\r
68 {\r
69         _lasterror = desc;\r
70 }\r
71 \r
72 SQString *SQVM::PrintObjVal(const SQObjectPtr &o)\r
73 {\r
74         switch(type(o)) {\r
75         case OT_STRING: return _string(o);\r
76         case OT_INTEGER:\r
77                 scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _PRINT_INT_FMT, _integer(o));\r
78                 return SQString::Create(_ss(this), _spval);\r
79                 break;\r
80         case OT_FLOAT:\r
81                 scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));\r
82                 return SQString::Create(_ss(this), _spval);\r
83                 break;\r
84         default:\r
85                 return SQString::Create(_ss(this), GetTypeName(o));\r
86         }\r
87 }\r
88 \r
89 void SQVM::Raise_IdxError(const SQObjectPtr &o)\r
90 {\r
91         SQObjectPtr oval = PrintObjVal(o);\r
92         Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));\r
93 }\r
94 \r
95 void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)\r
96 {\r
97         SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);\r
98         Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));\r
99 }\r
100 \r
101 \r
102 void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)\r
103 {\r
104         SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);\r
105         SQInteger found = 0;    \r
106         for(SQInteger i=0; i<16; i++)\r
107         {\r
108                 SQInteger mask = 0x00000001 << i;\r
109                 if(typemask & (mask)) {\r
110                         if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);\r
111                         found ++;\r
112                         StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);\r
113                 }\r
114         }\r
115         Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));\r
116 }\r