Update: Translations from eints
[openttd-github.git] / src / 3rdparty / squirrel / sqstdlib / sqstdaux.cpp
blob1bdee97e69e421e1988e03fdf2ec1e70ed2494cf
1 /* see copyright notice in squirrel.h */
3 #include "../../../stdafx.h"
5 #include <squirrel.h>
6 #include <sqstdaux.h>
8 #include "../../fmt/format.h"
9 #include "../../../safeguards.h"
11 void sqstd_printcallstack(HSQUIRRELVM v)
13 SQPRINTFUNCTION pf = sq_getprintfunc(v);
14 if(pf) {
15 SQStackInfos si;
16 SQInteger i;
17 SQBool b;
18 SQFloat f;
19 const SQChar *s;
20 SQInteger level=1; //1 is to skip this function that is level 0
21 const SQChar *name=nullptr;
22 SQInteger seq=0;
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;
29 if(si.source) {
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/");
36 if (src) {
37 src += 4;
38 } else {
39 src = si.source;
42 pf(v,fmt::format("*FUNCTION [{}()] {} line [{}]\n",fn,src,si.line));
43 level++;
45 level=0;
46 pf(v,"\nLOCALS\n");
48 for(level=0;level<10;level++){
49 seq=0;
50 while((name = sq_getlocal(v,level,seq)))
52 seq++;
53 switch(sq_gettype(v,-1))
55 case OT_NULL:
56 pf(v,fmt::format("[{}] NULL\n",name));
57 break;
58 case OT_INTEGER:
59 sq_getinteger(v,-1,&i);
60 pf(v,fmt::format("[{}] {}\n",name,i));
61 break;
62 case OT_FLOAT:
63 sq_getfloat(v,-1,&f);
64 pf(v,fmt::format("[{}] {:14g}\n",name,f));
65 break;
66 case OT_USERPOINTER:
67 pf(v,fmt::format("[{}] USERPOINTER\n",name));
68 break;
69 case OT_STRING:
70 sq_getstring(v,-1,&s);
71 pf(v,fmt::format("[{}] \"{}\"\n",name,s));
72 break;
73 case OT_TABLE:
74 pf(v,fmt::format("[{}] TABLE\n",name));
75 break;
76 case OT_ARRAY:
77 pf(v,fmt::format("[{}] ARRAY\n",name));
78 break;
79 case OT_CLOSURE:
80 pf(v,fmt::format("[{}] CLOSURE\n",name));
81 break;
82 case OT_NATIVECLOSURE:
83 pf(v,fmt::format("[{}] NATIVECLOSURE\n",name));
84 break;
85 case OT_GENERATOR:
86 pf(v,fmt::format("[{}] GENERATOR\n",name));
87 break;
88 case OT_USERDATA:
89 pf(v,fmt::format("[{}] USERDATA\n",name));
90 break;
91 case OT_THREAD:
92 pf(v,fmt::format("[{}] THREAD\n",name));
93 break;
94 case OT_CLASS:
95 pf(v,fmt::format("[{}] CLASS\n",name));
96 break;
97 case OT_INSTANCE:
98 pf(v,fmt::format("[{}] INSTANCE\n",name));
99 break;
100 case OT_WEAKREF:
101 pf(v,fmt::format("[{}] WEAKREF\n",name));
102 break;
103 case OT_BOOL:{
104 sq_getbool(v,-1,&b);
105 pf(v,fmt::format("[{}] {}\n",name,b?"true":"false"));
107 break;
108 default: assert(0); break;
110 sq_pop(v,1);
116 static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
118 SQPRINTFUNCTION pf = sq_getprintfunc(v);
119 if(pf) {
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));
125 else{
126 pf(v,"\nAN ERROR HAS OCCURRED [unknown]\n");
128 sqstd_printcallstack(v);
131 return 0;
134 void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
136 SQPRINTFUNCTION pf = sq_getprintfunc(v);
137 if(pf) {
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);