1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "glk/tads/tads2/error.h"
24 #include "glk/tads/tads2/error_handling.h"
25 #include "glk/tads/tads2/tokenizer.h"
26
27 namespace Glk {
28 namespace TADS {
29 namespace TADS2 {
30
31 /* format an error message, sprintf-style, using an erradef array */
errfmt(char * outbuf,int outbufl,const char * fmt,int argc,const erradef * argv)32 int errfmt(char *outbuf, int outbufl, const char *fmt, int argc, const erradef *argv) {
33 int outlen = 0;
34 int argi = 0;
35 int len = 0;
36 char buf[20];
37 const char *p = nullptr;
38 char fmtchar;
39
40 while (*fmt)
41 {
42 switch(*fmt)
43 {
44 case '\\':
45 ++fmt;
46 len = 1;
47 switch(*fmt)
48 {
49 case '\0':
50 --fmt;
51 break;
52 case '\n':
53 p = "\n";
54 break;
55 case '\t':
56 p = "\t";
57 break;
58 default:
59 p = fmt;
60 break;
61 }
62 break;
63
64 case '%':
65 ++fmt;
66 fmtchar = *fmt;
67 if (argi >= argc) fmtchar = 1; /* too many - ignore it */
68 switch(fmtchar)
69 {
70 case '\0':
71 --fmt;
72 break;
73
74 case '%':
75 p = "%";
76 len = 1;
77 break;
78
79 case 'd':
80 sprintf(buf, "%d", argv[argi].erraint);
81 len = strlen(buf);
82 p = buf;
83 break;
84
85 case 's':
86 p = argv[argi].errastr;
87 len = strlen(p);
88 break;
89
90 case 't':
91 {
92 int i;
93 static struct
94 {
95 int tokid;
96 const char *toknam;
97 } toklist[] =
98 {
99 { TOKTSEM, "semicolon" },
100 { TOKTCOLON, "colon" },
101 { TOKTFUNCTION, "\"function\"" },
102 { TOKTCOMMA, "comma" },
103 { TOKTLBRACE, "left brace ('{')" },
104 { TOKTRPAR, "right paren (')')" },
105 { TOKTRBRACK, "right square bracket (']')" },
106 { TOKTWHILE, "\"while\"" },
107 { TOKTLPAR, "left paren ('(')" },
108 { TOKTEQ, "'='" },
109 { 0, (const char *)nullptr }
110 };
111
112 for (i = 0 ; toklist[i].toknam ; ++i)
113 {
114 if (toklist[i].tokid == argv[argi].erraint)
115 {
116 p = toklist[i].toknam;
117 break;
118 }
119 }
120 if (!toklist[i].toknam)
121 p = "<unknown token>";
122 len = strlen(p);
123 break;
124 }
125
126 default:
127 p = "";
128 len = 0;
129 --argi;
130 break;
131 }
132 ++argi;
133 break;
134
135 default:
136 p = fmt;
137 len = 1;
138 break;
139 }
140
141 /* copy output that was set up above */
142 if (len)
143 {
144 if (outbufl >= len)
145 {
146 memcpy(outbuf, p, (size_t)len);
147 outbufl -= len;
148 outbuf += len;
149 }
150 else if (outbufl)
151 {
152 memcpy(outbuf, p, (size_t)outbufl);
153 outbufl = 0;
154 }
155 outlen += len;
156 }
157 ++fmt;
158 }
159
160 if (outbufl) *outbuf++ = '\0';
161 return(outlen);
162 }
163
164 #ifdef DEBUG
165 void errjmp(buf, e)
166 jmp_buf buf;
167 int e;
168 {
169 longjmp(buf, e);
170 }
171 #endif /* DEBUG */
172
173
174
175 #ifdef ERR_NO_MACRO
176
177 /* base error signal function */
errsign(errcxdef * ctx,int e)178 void errsign(errcxdef *ctx, int e) {
179 ctx->errcxofs = 0;
180 #if 0
181 longjmp(ctx->errcxptr->errbuf, e);
182 #else
183 error("errsign");
184 #endif
185 }
186
187 /* log an error: base function */
errlogn(errcxdef * ctx,int err)188 void errlogn(errcxdef *ctx, int err) {
189 error("errlogn");
190 }
191
192 #endif /* ERR_NO_MACRO */
193
194 } // End of namespace TADS2
195 } // End of namespace TADS
196 } // End of namespace Glk
197