1 /* see copyright notice in squirrel.h */
3 #include "../../../stdafx.h"
8 #include "../../fmt/format.h"
9 #include "../../../safeguards.h"
11 void sqstd_printcallstack(HSQUIRRELVM v
)
13 SQPRINTFUNCTION pf
= sq_getprintfunc(v
);
20 SQInteger level
=1; //1 is to skip this function that is level 0
21 const SQChar
*name
=nullptr;
23 pf(v
,"\nCALLSTACK\n");
24 while(SQ_SUCCEEDED(sq_stackinfos(v
,level
,&si
)))
26 const SQChar
*fn
="unknown";
27 const SQChar
*src
="unknown";
28 if(si
.funcname
)fn
=si
.funcname
;
30 /* We don't want to bother users with absolute paths to all AI files.
31 * Since the path only reaches NoAI code in a formatted string we have
32 * to strip it here. Let's hope nobody installs openttd in a subdirectory
33 * of a directory named /ai/. */
34 src
= strstr(si
.source
, "\\ai\\");
35 if (!src
) src
= strstr(si
.source
, "/ai/");
42 pf(v
,fmt::format("*FUNCTION [{}()] {} line [{}]\n",fn
,src
,si
.line
));
48 for(level
=0;level
<10;level
++){
50 while((name
= sq_getlocal(v
,level
,seq
)))
53 switch(sq_gettype(v
,-1))
56 pf(v
,fmt::format("[{}] NULL\n",name
));
59 sq_getinteger(v
,-1,&i
);
60 pf(v
,fmt::format("[{}] {}\n",name
,i
));
64 pf(v
,fmt::format("[{}] {:14g}\n",name
,f
));
67 pf(v
,fmt::format("[{}] USERPOINTER\n",name
));
70 sq_getstring(v
,-1,&s
);
71 pf(v
,fmt::format("[{}] \"{}\"\n",name
,s
));
74 pf(v
,fmt::format("[{}] TABLE\n",name
));
77 pf(v
,fmt::format("[{}] ARRAY\n",name
));
80 pf(v
,fmt::format("[{}] CLOSURE\n",name
));
82 case OT_NATIVECLOSURE
:
83 pf(v
,fmt::format("[{}] NATIVECLOSURE\n",name
));
86 pf(v
,fmt::format("[{}] GENERATOR\n",name
));
89 pf(v
,fmt::format("[{}] USERDATA\n",name
));
92 pf(v
,fmt::format("[{}] THREAD\n",name
));
95 pf(v
,fmt::format("[{}] CLASS\n",name
));
98 pf(v
,fmt::format("[{}] INSTANCE\n",name
));
101 pf(v
,fmt::format("[{}] WEAKREF\n",name
));
105 pf(v
,fmt::format("[{}] {}\n",name
,b
?"true":"false"));
108 default: assert(0); break;
116 static SQInteger
_sqstd_aux_printerror(HSQUIRRELVM v
)
118 SQPRINTFUNCTION pf
= sq_getprintfunc(v
);
120 const SQChar
*sErr
= nullptr;
121 if(sq_gettop(v
)>=1) {
122 if(SQ_SUCCEEDED(sq_getstring(v
,2,&sErr
))) {
123 pf(v
,fmt::format("\nAN ERROR HAS OCCURRED [{}]\n",sErr
));
126 pf(v
,"\nAN ERROR HAS OCCURRED [unknown]\n");
128 sqstd_printcallstack(v
);
134 void _sqstd_compiler_error(HSQUIRRELVM v
,const SQChar
*sErr
,const SQChar
*sSource
,SQInteger line
,SQInteger column
)
136 SQPRINTFUNCTION pf
= sq_getprintfunc(v
);
138 pf(v
,fmt::format("{} line = ({}) column = ({}) : error {}\n",sSource
,line
,column
,sErr
));
142 void sqstd_seterrorhandlers(HSQUIRRELVM v
)
144 sq_setcompilererrorhandler(v
,_sqstd_compiler_error
);
145 sq_newclosure(v
,_sqstd_aux_printerror
,0);
146 sq_seterrorhandler(v
);