bringing SDL 1.2.14 from vendor into the main branch
[AROS-Contrib.git] / regina / error.c
blob7a9f26f8b02babec8134b68a82f996f05d8be5db
1 #ifndef lint
2 static char *RCSid = "$Id$";
3 #endif
5 /*
6 * The Regina Rexx Interpreter
7 * Copyright (C) 1992-1994 Anders Christensen <anders@pvv.unit.no>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "rexx.h"
25 #include <errno.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <stdarg.h>
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33 #include <sys/stat.h>
34 #include "rexxmsg.h"
36 typedef struct /* err_tsd: static variables of this module (thread-safe) */
38 int number_messages;
39 int native_language;
40 FILE *nls_fp;
41 struct textindex nls_tmi[NUMBER_ERROR_MESSAGES]; /* indexes for native language messages */
42 } err_tsd_t; /* thread-specific but only needed by this module. see init_error */
44 typedef struct
46 int errnum;
47 int suberrnum;
48 char *text;
49 } errtext_t;
52 * English message text - generated by makeerror.rexx
54 static const errtext_t errtext[NUMBER_ERROR_MESSAGES] =
56 { 0, 1,"Error %s running %s, line %d:|<value>,<source>,<linenumber>" },
57 { 0, 2,"Error %s in interactive trace:|<value>" },
58 { 0, 3,"Interactive trace. \"Trace Off\" to end debug. ENTER to continue." },
59 { 2, 0,"Failure during finalization" },
60 { 2, 1,"Failure during finalization: %s|<description>" },
61 { 3, 0,"Failure during initialization" },
62 { 3, 1,"Failure during initialization: %s|<description>" },
63 { 4, 0,"Program interrupted" },
64 { 4, 1,"Program interrupted with HALT condition: %s|<description>" },
65 { 5, 0,"System resources exhausted" },
66 { 5, 1,"System resources exhausted: %s|<description>" },
67 { 6, 0,"Unmatched \"/*\" or quote" },
68 { 6, 1,"Unmatched comment delimiter (\"/*\")" },
69 { 6, 2,"Unmatched single quote (')" },
70 { 6, 3,"Unmatched double quote (\")" },
71 { 7, 0,"WHEN or OTHERWISE expected" },
72 { 7, 1,"SELECT on line %d requires WHEN; found \"%s\"|<linenumber>,<token>" },
73 { 7, 2,"SELECT on line %d requires WHEN, OTHERWISE, or END; found \"%s\"|<linenumber>,<token>" },
74 { 7, 3,"All WHEN expressions of SELECT on line %d are false; OTHERWISE expected|<linenumber>" },
75 { 8, 0,"Unexpected THEN or ELSE" },
76 { 8, 1,"THEN has no corresponding IF or WHEN clause" },
77 { 8, 2,"ELSE has no corresponding THEN clause" },
78 { 9, 0,"Unexpected WHEN or OTHERWISE" },
79 { 9, 1,"WHEN has no corresponding SELECT" },
80 { 9, 2,"OTHERWISE has no corresponding SELECT" },
81 { 10, 0,"Unexpected or unmatched END" },
82 { 10, 1,"END has no corresponding DO or SELECT" },
83 { 10, 2,"END corresponding to DO on line %d must have a symbol following that matches the control variable (or no symbol); found \"%s\"|<linenumber>,<token>" },
84 { 10, 3,"END corresponding to DO on line %d must not have a symbol following it because there is no control variable; found \"%s\"|<linenumber>,<token>" },
85 { 10, 4,"END corresponding to SELECT on line %d must not have a symbol following; found \"%s\"|<linenumber>,<token>" },
86 { 10, 5,"END must not immediately follow THEN" },
87 { 10, 6,"END must not immediately follow ELSE" },
88 { 11, 0,"[Control stack full]" },
89 { 12, 0,"[Clause > 1024 characters]" },
90 { 13, 0,"Invalid character in program" },
91 { 13, 1,"Invalid character in program \"('%x'X)\"|<hex-encoding>" },
92 { 14, 0,"Incomplete DO/SELECT/IF" },
93 { 14, 1,"DO instruction requires a matching END" },
94 { 14, 2,"SELECT instruction requires a matching END" },
95 { 14, 3,"THEN requires a following instruction" },
96 { 14, 4,"ELSE requires a following instruction" },
97 { 15, 0,"Invalid hexadecimal or binary string" },
98 { 15, 1,"Invalid location of blank in position %d in hexadecimal string|<position>" },
99 { 15, 2,"Invalid location of blank in position %d in binary string|<position>" },
100 { 15, 3,"Only 0-9, a-f, A-F, and blank are valid in a hexadecimal string; found \"%c\"|<char>" },
101 { 15, 4,"Only 0, 1, and blank are valid in a binary string; found \"%c\"|<char>" },
102 { 16, 0,"Label not found" },
103 { 16, 1,"Label \"%s\" not found|<name>" },
104 { 16, 2,"Cannot SIGNAL to label \"%s\" because it is inside an IF, SELECT or DO group|<name>" },
105 { 16, 3,"Cannot invoke label \"%s\" because it is inside an IF, SELECT or DO group|<name>" },
106 { 17, 0,"Unexpected PROCEDURE" },
107 { 17, 1,"PROCEDURE is valid only when it is the first instruction executed after an internal CALL or function invocation" },
108 { 18, 0,"THEN expected" },
109 { 18, 1,"IF keyword on line %d requires matching THEN clause; found \"%s\"|<linenumber>,<token>" },
110 { 18, 2,"WHEN keyword on line %d requires matching THEN clause; found \"%s\"|<linenumber>,<token>" },
111 { 19, 0,"String or symbol expected" },
112 { 19, 1,"String or symbol expected after ADDRESS keyword; found \"%s\"|<token>" },
113 { 19, 2,"String or symbol expected after CALL keyword; found \"%s\"|<token>" },
114 { 19, 3,"String or symbol expected after NAME keyword; found \"%s\"|<token>" },
115 { 19, 4,"String or symbol expected after SIGNAL keyword; found \"%s\"|<token>" },
116 { 19, 6,"String or symbol expected after TRACE keyword; found \"%s\"|<token>" },
117 { 19, 7,"Symbol expected in parsing pattern; found \"%s\"|<token>" },
118 { 20, 0,"Name expected" },
119 { 20, 1,"Name required; found \"%s\"|<token>" },
120 { 20, 2,"Found \"%s\" where only a name is valid|<token>" },
121 { 21, 0,"Invalid data on end of clause" },
122 { 21, 1,"The clause ended at an unexpected token; found \"%s\"|<token>" },
123 { 22, 0,"Invalid character string" },
124 { 22, 1,"Invalid character string '%s'X|<hex-encoding>" },
125 { 23, 0,"Invalid data string" },
126 { 23, 1,"Invalid data string '%s'X|<hex-encoding>" },
127 { 24, 0,"Invalid TRACE request" },
128 { 24, 1,"TRACE request letter must be one of \"%s\"; found \"%c\"|ACEFILNOR,<value>" },
129 { 25, 0,"Invalid sub-keyword found" },
130 { 25, 1,"CALL ON must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
131 { 25, 2,"CALL OFF must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
132 { 25, 3,"SIGNAL ON must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
133 { 25, 4,"SIGNAL OFF must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
134 { 25, 5,"ADDRESS WITH must be followed by one of the keywords INPUT, OUTPUT or ERROR; found \"%s\"|<token>" },
135 { 25, 6,"INPUT must be followed by one of the keywords STREAM, STEM, LIFO, FIFO or NORMAL; found \"%s\"|<token>" },
136 { 25, 7,"OUTPUT must be followed by one of the keywords STREAM, STEM, LIFO, FIFO, APPEND, REPLACE or NORMAL; found \"%s\"|<token>" },
137 { 25, 8,"APPEND must be followed by one of the keywords STREAM, STEM, LIFO or FIFO; found \"%s\"|<token>" },
138 { 25, 9,"REPLACE must be followed by one of the keywords STREAM, STEM, LIFO or FIFO; found \"%s\"|<token>" },
139 { 25, 11,"NUMERIC FORM must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
140 { 25, 12,"PARSE must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
141 { 25, 13,"UPPER must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
142 { 25, 14,"ERROR must be followed by one of the keywords STREAM, STEM, LIFO, FIFO, APPEND, REPLACE or NORMAL; found \"%s\"|<token>" },
143 { 25, 15,"NUMERIC must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
144 { 25, 16,"FOREVER must be followed by one of the keywords %s; found \"%s\"|<keywords>,<token>" },
145 { 25, 17,"PROCEDURE must be followed by the keyword EXPOSE or nothing; found \"%s\"|<token>" },
146 { 26, 0,"Invalid whole number" },
147 { 26, 1,"Whole numbers must fit within current DIGITS setting(%d); found \"%s\"|<value>,<value>" },
148 { 26, 2,"Value of repetition count expression in DO instruction must be zero or a positive whole number; found \"%s\"|<value>" },
149 { 26, 3,"Value of FOR expression in DO instruction must be zero or a positive whole number; found \"%s\"|<value>" },
150 { 26, 4,"Positional parameter of parsing template must be a whole number; found \"%s\"|<value>" },
151 { 26, 5,"NUMERIC DIGITS value must be zero or a positive whole number; found \"%s\"|<value>" },
152 { 26, 6,"NUMERIC FUZZ value must be zero or a positive whole number; found \"%s\"|<value>" },
153 { 26, 7,"Number used in TRACE setting must be a whole number; found \"%s\"|<value>" },
154 { 26, 8,"Operand to right of power operator (\"**\") must be a whole number; found \"%s\"|<value>" },
155 { 26, 11,"Result of %s %% %s operation would need exponential notation at current NUMERIC DIGITS %d|<value>,<value>,<value>" },
156 { 26, 12,"Result of %% operation used for %s // %s operation would need exponential notation at current NUMERIC DIGITS %d|<value>,<value>,<value>" },
157 { 27, 0,"Invalid DO syntax" },
158 { 27, 1,"Invalid use of keyword \"%s\" in DO clause|<token>" },
159 { 28, 0,"Invalid LEAVE or ITERATE" },
160 { 28, 1,"LEAVE is valid only within a repetitive DO loop" },
161 { 28, 2,"ITERATE is valid only within a repetitive DO loop" },
162 { 28, 3,"Symbol following LEAVE (\"%s\") must either match control variable of a current DO loop or be omitted|<token>" },
163 { 28, 4,"Symbol following ITERATE (\"%s\") must either match control variable of a current DO loop or be omitted|<token>" },
164 { 29, 0,"Environment name too long" },
165 { 29, 1,"Environment name exceeds %d characters; found \"%s\"|#Limit_EnvironmentName,<name>" },
166 { 30, 0,"Name or string too long" },
167 { 30, 1,"Name exceeds %d characters|#Limit_Name" },
168 { 30, 2,"Literal string exceeds %d characters|#Limit_Literal" },
169 { 31, 0,"Name starts with number or \".\"" },
170 { 31, 1,"A value cannot be assigned to a number; found \"%s\"|<token>" },
171 { 31, 2,"Variable symbol must not start with a number; found \"%s\"|<token>" },
172 { 31, 3,"Variable symbol must not start with a \".\"; found \"%s\"|<token>" },
173 { 32, 0,"[Invalid use of stem]" },
174 { 33, 0,"Invalid expression result" },
175 { 33, 1,"Value of NUMERIC DIGITS \"%d\" must exceed value of NUMERIC FUZZ \"(%d)\"|<value>,<value>" },
176 { 33, 2,"Value of NUMERIC DIGITS \"%d\" must not exceed %d|<value>,#Limit_Digits" },
177 { 33, 3,"Result of expression following NUMERIC FORM must start with \"E\" or \"S\"; found \"%s\"|<value>" },
178 { 34, 0,"Logical value not \"0\" or \"1\"" },
179 { 34, 1,"Value of expression following IF keyword must be exactly \"0\" or \"1\"; found \"%s\"|<value>" },
180 { 34, 2,"Value of expression following WHEN keyword must be exactly \"0\" or \"1\"; found \"%s\"|<value>" },
181 { 34, 3,"Value of expression following WHILE keyword must be exactly \"0\" or \"1\"; found \"%s\"|<value>" },
182 { 34, 4,"Value of expression following UNTIL keyword must be exactly \"0\" or \"1\"; found \"%s\"|<value>" },
183 { 34, 5,"Value of expression to left of logical operator \"%s\" must be exactly \"0\" or \"1\"; found \"%s\"|<operator>,<value>" },
184 { 34, 6,"Value of expression to right of logical operator \"%s\" must be exactly \"0\" or \"1\"; found \"%s\"|<operator>,<value>" },
185 { 35, 0,"Invalid expression" },
186 { 35, 1,"Invalid expression detected at \"%s\"|<token>" },
187 { 36, 0,"Unmatched \"(\" in expression" },
188 { 37, 0,"Unexpected \",\" or \")\"" },
189 { 37, 1,"Unexpected \",\"" },
190 { 37, 2,"Unmatched \")\" in expression" },
191 { 38, 0,"Invalid template or pattern" },
192 { 38, 1,"Invalid parsing template detected at \"%s\"|<token>" },
193 { 38, 2,"Invalid parsing position detected at \"%s\"|<token>" },
194 { 38, 3,"PARSE VALUE instruction requires WITH keyword" },
195 { 39, 0,"[Evaluation stack overflow]" },
196 { 40, 0,"Incorrect call to routine" },
197 { 40, 1,"External routine \"%s\" failed|<name>" },
198 { 40, 3,"Not enough arguments in invocation of \"%s\"; minimum expected is %d|<bif>,<argnumber>" },
199 { 40, 4,"Too many arguments in invocation of \"%s\"; maximum expected is %d|<bif>,<argnumber>" },
200 { 40, 5,"Missing argument in invocation of \"%s\"; argument %d is required|<bif>,<argnumber>" },
201 { 40, 9,"%s argument %d exponent exceeds %d digits; found \"%s\"|<bif>,<argnumber>,#Limit_ExponentDigits,<value>" },
202 { 40, 11,"%s argument %d must be a number; found \"%s\"|<bif>,<argnumber>,<value>" },
203 { 40, 12,"%s argument %d must be a whole number; found \"%s\"|<bif>,<argnumber>,<value>" },
204 { 40, 13,"%s argument %d must be zero or positive; found \"%s\"|<bif>,<argnumber>,<value>" },
205 { 40, 14,"%s argument %d must be positive; found \"%s\"|<bif>,<argnumber>,<value>" },
206 { 40, 17,"%s argument 1, must have an integer part in the range 0:90 and a decimal part no larger than .9; found \"%s\"|<bif>,<value>" },
207 { 40, 18,"%s conversion must have a year in the range 0001 to 9999|<bif>" },
208 { 40, 19,"%s argument 2, \"%s\", is not in the format described by argument 3, \"%s\"|<bif>,<value>,<value>" },
209 { 40, 21,"%s argument %d must not be null|<bif>,<argnumber>" },
210 { 40, 23,"%s argument %d must be a single character; found \"%s\"|<bif>,<argnumber>,<value>" },
211 { 40, 24,"%s argument 1 must be a binary string; found \"%s\"|<bif>,<value>" },
212 { 40, 25,"%s argument 1 must be a hexadecimal string; found \"%s\"|<bif>,<value>" },
213 { 40, 26,"%s argument 1 must be a valid symbol; found \"%s\"|<bif>,<value>" },
214 { 40, 27,"%s argument 1, must be a valid stream name; found \"%s\"|<bif>,<value>" },
215 { 40, 28,"%s argument %d, option must start with one of \"%s\"; found \"%s\"|<bif>,<argnumber>,<optionslist>,<value>" },
216 { 40, 29,"%s conversion to format \"%s\" is not allowed|<bif>,<value>" },
217 { 40, 31,"%s argument 1 (\"%d\") must not exceed 100000|<bif>,<value>" },
218 { 40, 32,"%s the difference between argument 1 (\"%d\") and argument 2 (\"%d\") must not exceed 100000|<bif>,<value>,<value>" },
219 { 40, 33,"%s argument 1 (\"%d\") must be less than or equal to argument 2 (\"%d\")|<bif>,<value>,<value>" },
220 { 40, 34,"%s argument 1 (\"%d\") must be less than or equal to the number of lines in the program (%d)|<bif>,<value>,<sourceline()>" },
221 { 40, 35,"%s argument 1 cannot be expressed as a whole number; found \"%s\"|<bif>,<value>" },
222 { 40, 36,"%s argument 1 must be a name of a variable in the pool; found \"%s\"|<bif>,<value>" },
223 { 40, 37,"%s argument 3 must be the name of a pool; found \"%s\"|<bif>,<value>" },
224 { 40, 38,"%s argument %d is not large enough to format \"%s\"|<bif>,<argnumber>,<value>" },
225 { 40, 39,"%s argument 3 is not zero or one; found \"%s\"|<bif>,<value>" },
226 { 40, 41,"%s argument %d must be within the bounds of the stream; found \"%s\"|<bif>,<argnumber>,<value>" },
227 { 40, 42,"%s argument 1; cannot position on this stream; found \"%s\"|<bif>,<value>" },
228 { 40,914,"[%s argument %d, must be one of \"%s\"; found \"%s\"]|<bif>,<argnumber>,<optionslist>,<value>" },
229 { 40,920,"[%s: low-level stream I/O error; %s]|<bif>,<description>" },
230 { 40,921,"[%s argument %d, stream positioning mode \"%s\"; incompatible with stream open mode]|<bif>,<argnumber>,<value>" },
231 { 40,922,"[%s argument %d, too few sub-commands; minimum expected is %d; found %d]|<bif>,<argnumber>,<value>,<value>" },
232 { 40,923,"[%s argument %d, too many sub-commands; maximum expected is %d; found %d]|<bif>,<argnumber>,<value>,<value>" },
233 { 40,924,"[%s argument %d, invalid positional specification; expecting one of \"%s\"; found \"%s\"]|<bif>,<argnumber>,<value>,<value>" },
234 { 41, 0,"Bad arithmetic conversion" },
235 { 41, 1,"Non-numeric value (\"%s\") to left of arithmetic operation \"%s\"|<value>,<operator>" },
236 { 41, 2,"Non-numeric value (\"%s\") to right of arithmetic operation \"%s\"|<value>,<operator>" },
237 { 41, 3,"Non-numeric value (\"%s\") used with prefix operator \"%s\"|<value>,<operator>" },
238 { 41, 4,"Value of TO expression in DO instruction must be numeric; found \"%s\"|<value>" },
239 { 41, 5,"Value of BY expression in DO instruction must be numeric; found \"%s\"|<value>" },
240 { 41, 6,"Value of control variable expression of DO instruction must be numeric; found \"%s\"|<value>" },
241 { 41, 7,"Exponent exceeds %d digits; found \"%s\"|#Limit_ExponentDigits,<value>" },
242 { 42, 0,"Arithmetic overflow/underflow" },
243 { 42, 1,"Arithmetic overflow detected at \"%s %s %s\"; exponent of result requires more than %d digits|<value>,<operator>,<value>,#Limit_ExponentDigits" },
244 { 42, 2,"Arithmetic underflow detected at \"%s %s %s\"; exponent of result requires more than %d digits|<value>,<operator>,<value>,#Limit_ExponentDigits" },
245 { 42, 3,"Arithmetic overflow; divisor must not be zero" },
246 { 43, 0,"Routine not found" },
247 { 43, 1,"Could not find routine \"%s\"|<name>" },
248 { 44, 0,"Function did not return data" },
249 { 44, 1,"No data returned from function \"%s\"|<name>" },
250 { 45, 0,"No data specified on function RETURN" },
251 { 45, 1,"Data expected on RETURN instruction because routine \"%s\" was called as a function|<name>" },
252 { 46, 0,"Invalid variable reference" },
253 { 46, 1,"Extra token (\"%s\") found in variable reference; \")\" expected|<token>" },
254 { 47, 0,"Unexpected label" },
255 { 47, 1,"INTERPRET data must not contain labels; found \"%s\"|<name>" },
256 { 48, 0,"Failure in system service" },
257 { 48, 1,"Failure in system service: %s|<description>" },
258 { 48,920,"Low-level stream I/O error: %s %s: %s|<description>,<stream>,<description>" },
259 { 49, 0,"Interpretation Error" },
260 { 49, 1,"Interpretation Error: Failed in %s, line %d: \"%s\". Please report error!|<module>,<linenumber>,<description>" },
261 { 50, 0,"Unrecognized reserved symbol" },
262 { 50, 1,"Unrecognized reserved symbol \"%s\"|<token>" },
263 { 51, 0,"Invalid function name" },
264 { 51, 1,"Unquoted function names must not end in a period; found \"%s\"|<token>" },
265 { 52, 0,"Result returned by \"%s\" is longer than %d characters|<name>,#Limit_String" },
266 { 53, 0,"Invalid option" },
267 { 53, 1,"String or symbol expected after STREAM keyword; found \"%s\"|<token>" },
268 { 53, 2,"Variable reference expected after STEM keyword; found \"%s\"|<token>" },
269 { 53, 3,"Argument to STEM must have one period, as its last character; found \"%s\"|<name>" },
270 { 53,100,"String or symbol expected after LIFO keyword; found \"%s\"|<token>" },
271 { 53,101,"String or symbol expected after FIFO keyword; found \"%s\"|<token>" },
272 { 54, 0,"Invalid STEM value" },
273 { 54, 1,"For this STEM APPEND, the value of \"%s\" must be a count of lines; found \"%s\"|<name>,<value>" },
274 { 60, 0,"[Can't rewind transient file]" },
275 { 61, 0,"[Improper seek operation on file]" },
276 { 64, 0,"[Syntax error while parsing]" },
277 { 64, 1,"[Syntax error at line %d]" },
278 { 64, 2,"[General syntax error at line %d, column %d]|<linenumber>,<columnnumber>" },
279 { 90, 0,"[Non-ANSI feature used with \"OPTIONS STRICT_ANSI\"]" },
280 { 90, 1,"[%s is a Regina extension BIF]|<bif>" },
281 { 90, 2,"[%s is a Regina extension instruction]|<token>" },
282 { 90, 3,"[%s argument %d, option must start with one of \"%s\" with \"OPTIONS STRICT_ANSI\"; found \"%s\"; a Regina extension]|<bif>,<argnumber>,<optionslist>,<value>" },
283 { 93, 0,"[Incorrect call to routine]" },
284 { 93, 1,"[STREAM command %s must be followed by one of \"%s\"; found \"%s\"]|<token>,<value>,<value>" },
285 { 93, 3,"[STREAM command must be one of \"%s\"; found \"%s\"]|<value>,<value>" },
286 { 94, 0,"[External queue interface error]" },
287 { 94, 99,"[Internal error with external queue interface: %d \"%s\"]|<description>,<systemerror>" },
288 { 94,100,"[General system error with external queue interface. %s. %s]|<description>,<systemerror>" },
289 { 94,101,"[Error connecting to %s on port %d: \"%s\"]|<machine>,<portnumber>,<systemerror>" },
290 { 94,102,"[Unable to obtain IP address for %s]|<machine>" },
291 { 94,103,"[Invalid format for server in specified queue name: \"%s\"]|<queuename>" },
292 { 94,104,"[Invalid format for queue name: \"%s\"]|<queuename>" },
293 { 94,105,"[Unable to start Windows Socket interface: %s]|<systemerror>" },
294 { 94,106,"[Maximum number of external queues exceeded: %d]|<maxqueues>" },
295 { 94,107,"[Error occured reading socket: %s]|<systemerror>" },
296 { 94,108,"[Invalid switch passed. Must be one of \"%s\"]|<switch>" },
297 { 95, 0,"[Restricted feature used in \"safe\" mode]" },
298 { 95, 1,"[%s invalid in \"safe\" mode]|<token>" },
299 { 95, 2,"[%s argument %d invalid in \"safe\" mode]|<bif>,<argnumber>" },
300 { 95, 3,"[%s argument %d: \"%s\", invalid in \"safe\" mode]|<bif>,<argnumber>,<token>" },
301 { 95, 4,"[STREAM argument 3: Opening files for WRITE access invalid in \"safe\" mode]" },
302 { 95, 5,"[Running external commands invalid in \"safe\" mode]" },
303 { 100, 0,"[Unknown filesystem error]" },
307 * Static pointers to language-specific error messages
308 * IF THIS EVER CHANGES, ALSO CHANGE THE SAME TABLE IN msgcmp.c
310 static const char *errlang[] =
312 "en", /* english */
313 "de", /* german */
314 "es", /* spanish */
315 "no", /* norwegian */
316 "pt", /* portuguese */
319 static const char *err1prefix[] =
321 /*en*/ "Error %d running \"%.*s\", line %d: %s",
322 /*de*/ "Fehler %d während des Ausführens von \"%.*s\", Zeile %d: %s",
323 /*es*/ "Error %d ejecutando \"%.*s\" línea %d: %s",
324 /*no*/ "Feil %d under kjøring av \"%.*s\" linje %d: %s",
325 /*pt*/ "Erro %d ao executar \"%.*s\", linha %d: %s",
328 static const char *suberrprefix[] =
330 /*en*/ "Error %d.%d: %s",
331 /*de*/ "Fehler %d.%d: %s",
332 /*es*/ "Error %d.%d: %s",
333 /*no*/ "Feil %d.%d: %s",
334 /*pt*/ "Erro %d.%d: %s",
337 static const char *err2prefix[] =
339 /*en*/ "Error %d running \"%.*s\": %s",
340 /*de*/ "Fehler %d während des Ausführens von \"%.*s\": %s",
341 /*es*/ "Error %d ejecutando \"%.*s\": %s",
342 /*no*/ "Feil %d under kjøring av \"%.*s\": %s",
343 /*pt*/ "Erro %d ao executar \"%.*s\": %s",
346 #if 0
347 static const char *errunavial[] =
349 "language file: %s not available",
350 /*pt*/ "arquivo de linguagem: %s nao estah disponivel",
351 /*no*/ "språkfil: %s ikke tilgjengelig",
352 /*de*/ "Sprachspezifische Datei %s nicht verfügbar"
353 /*es*/ "Fichero de lenguaje: %s no disponible"
355 #endif
357 static const char *erropen[] =
359 /*en*/ "Unable to open language file: %s",
360 /*de*/ "Kann die sprachspezifische Datei nicht öffnen: %s",
361 /*es*/ "Incapaz de abrir el fichero de lenguaje: %s",
362 /*no*/ "Ikke i stand til å åpne språkfil: %s",
363 /*pt*/ "nao eh possivel abrir arquivo de linguagem: %s",
366 static const char *errcount[] =
368 /*en*/ "Incorrect number of messages in language file: %s",
369 /*de*/ "Ungültige Anzahl von Meldungen in der sprachspezifischen Datei: %s",
370 /*es*/ "Número incorrecto de mensajes en el fichero de lenguaje: %s",
371 /*no*/ "Uriktig antall meldinger i språkfil: %s",
372 /*pt*/ "numero incorreto de mensagens no arquivo de linguagem: %s",
375 static const char *errread[] =
377 /*en*/ "Unable to read from language file: %s",
378 /*de*/ "Kann von der sprachspezifischen Datei nicht lesen: %s",
379 /*es*/ "Incapaz de leer el fichero de lenguaje: %s",
380 /*no*/ "Ikke i stand til å lese fra språkfil: %s",
381 /*pt*/ "nao eh possivel ler o arquivo de linguagem: %s",
384 static const char *errmissing[] =
386 /*en*/ "Text missing from language file: %s.mtb",
387 /*de*/ "Text fehlt in der sprachspezifischen Datei: %s.mtb",
388 /*es*/ "Falta el texto del fichero de lenguaje: %s.mtb",
389 /*no*/ "tekst mangler i språkfil: %s.mtb",
390 /*pt*/ "falta texto no arquivo de linguagem: %s.mtb",
393 static const char *errcorrupt[] =
395 /*en*/ "Language file: %s.mtb is corrupt",
396 /*de*/ "Sprachspezifische Datei %s.mtb ist beschädigt",
397 /*es*/ "Fichero de lenguaje: %s.mtb está corrupto",
398 /*no*/ "språkfil: %s.mtb er ødelagt",
399 /*pt*/ "arquivo de linguagem: %s.mtb estah corrompido",
402 /* init_error initializes the module.
403 * Currently, we set up the thread specific data.
404 * The function returns 1 on success, 0 if memory is short.
406 int init_error( tsd_t *TSD )
408 err_tsd_t *et;
410 if (TSD->err_tsd != NULL)
411 return(1);
413 if ((et = TSD->err_tsd = MallocTSD(sizeof(err_tsd_t))) == NULL)
414 return(0);
415 memset(et,0,sizeof(err_tsd_t));
416 et->nls_fp = NULL;
417 return(1);
420 int lineno_of( cnodeptr node )
422 if (node)
423 return (node->lineno>=0) ? node->lineno : 0 ;
424 else
425 return 0 ;
428 static int charno_of( cnodeptr node )
430 if (node)
431 return (node->charnr>=0) ? node->charnr : 0 ;
432 else
433 return 0 ;
437 /* only to be used by syntax and runtime errors, and the halt condition
438 * FIXME: FGC: This function is used while initializing the runtime system.
439 * Maybe, we don't have a functional tsd_t!
440 * What shall we do?
442 void exiterror( int errorno, int suberrorno, ... )
444 va_list argptr;
445 int lineno=0, charno=0, signtype=0 ;
446 streng *inputfile=NULL ;
447 streng *suberror_streng=NULL;
448 streng *errmsg=NULL ;
449 int ok=0 ;
450 const char *fmt = NULL, *etext ;
451 FILE *fp = stderr ;
452 err_tsd_t *et;
453 tsd_t *TSD = __regina_get_tsd(); /* The TSD should be fetched directly. This
454 * will help if someone corrupted a TSD as
455 * an argument.
456 * A "fresh" value is always better for
457 * tracking down ugly errors.
458 * Speed advantage is no reason here! */
459 et = TSD->err_tsd;
461 if (TSD->currentnode)
463 lineno = lineno_of( TSD->currentnode ) ;
464 charno = charno_of( TSD->currentnode ) ;
466 else
468 charno = 0 ;
469 lineno = parser_data.tline ;
472 signtype = SIGNAL_SYNTAX ;
473 if ( errorno==ERR_PROG_INTERRUPT )
474 signtype = SIGNAL_HALT ;
475 #ifdef HAVE_VSPRINTF
477 * Expanded the sub-error text and pass this to condition_hook for
478 * condition('D') to return the expanded string.
480 if (errorno <= ERR_MAX_NUMBER
481 && suberrorno != 0)
483 suberror_streng = Str_makeTSD( 1024 );
484 if (suberror_streng)
486 char tmp[256];
487 fmt = errortext( TSD, errorno, suberrorno, 0, 0 );
488 va_start( argptr, suberrorno );
490 * Saved the errno and suberrno so that later when
491 * a request for the expanded message is made, it
492 * can be matched against the errorno and suberrno.
494 sprintf( tmp, suberrprefix[et->native_language], errorno, suberrorno, fmt );
495 vsprintf( suberror_streng->value, tmp, argptr );
496 va_end( argptr );
497 suberror_streng->len = strlen(suberror_streng->value);
500 #endif
502 /* Here we should set sigtype to SIGNAL_FATAL for some 'errno's */
504 /* Get the text for the base errorno */
505 etext = errortext( TSD, errorno, 0, 0, 0 ) ;
507 /* enable a hook into the condition system */
508 if (condition_hook( TSD, signtype, errorno, suberrorno, lineno, Str_creTSD(etext), suberror_streng))
510 if (suberror_streng)
511 Free_stringTSD(suberror_streng);
512 suberror_streng = NULL;
513 return ; /* if CALL ON */
516 inputfile = TSD->systeminfo->input_file ;
517 errmsg = Str_makeTSD( 80 + strlen( etext ) + Str_len( inputfile ) ) ;
518 ok = HOOK_GO_ON ;
519 if (lineno>0)
521 traceback(TSD) ;
522 sprintf( errmsg->value, err1prefix[et->native_language], errorno, Str_len( inputfile ), inputfile->value, lineno, etext ) ;
524 else
525 sprintf(errmsg->value, err2prefix[et->native_language], errorno, Str_len( inputfile ), inputfile->value, etext);
527 errmsg->len = strlen( errmsg->value ) ;
528 assert( errmsg->len < errmsg->max ) ;
530 * If we have a system exit installed to handle errors, call it here...
532 if (TSD->systeminfo->hooks & HOOK_MASK(HOOK_STDERR))
533 ok = (hookup_output(TSD, HOOK_STDERR, errmsg) == HOOK_GO_ON) ;
535 if (ok==HOOK_GO_ON)
538 * To get here we either don't have an exit handler or the exit
539 * handler refused to handle the message, so write it to the
540 * error (or output) stream.
542 if ( get_options_flag( TSD->currlevel, EXT_STDOUT_FOR_STDERR ) )
543 fp = stdout ;
544 fwrite( errmsg->value, Str_len(errmsg), 1, fp ) ;
545 #if defined(DOS) || defined(OS2) || defined(WIN32)
547 * stdout is open in binary mode, so we need to add the
548 * extra CR to the end of the line.
550 fputc( REGINA_CR, fp ) ;
551 #endif
552 fputc( REGINA_EOL, fp ) ;
555 * Display the sub-error text if there is one.
557 if (errorno <= ERR_MAX_NUMBER
558 && suberrorno != 0
559 && suberror_streng)
561 if (TSD->systeminfo->hooks & HOOK_MASK(HOOK_STDERR))
562 ok = (hookup_output(TSD, HOOK_STDERR, suberror_streng) == HOOK_GO_ON) ;
563 if (ok==HOOK_GO_ON)
565 fwrite( suberror_streng->value, Str_len(suberror_streng), 1, fp ) ;
566 #if defined(DOS) || defined(OS2) || defined(WIN32)
568 * stdout is open in binary mode, so we need to add the
569 * extra CR to the end of the line.
571 fputc( REGINA_CR, fp ) ;
572 #endif
573 fputc( REGINA_EOL, fp ) ;
576 if (ok==HOOK_GO_ON)
577 fflush( fp );
578 if (suberror_streng)
579 Free_stringTSD(suberror_streng);
581 #ifndef NDEBUG
582 if (errorno == ERR_INTERPRETER_FAILURE)
583 abort() ;
584 #endif
586 Free_stringTSD( errmsg ) ;
587 if (TSD->systeminfo->panic)
589 TSD->systeminfo->result = NULL ;
590 if (TSD->in_protected)
592 TSD->delayed_error_type = PROTECTED_DelayedSetjmpPanic;
593 longjmp( TSD->protect_return, 1 ) ;
595 longjmp( *(TSD->systeminfo->panic), 1 ) ;
597 CloseOpenFiles( TSD );
599 if (TSD->in_protected)
601 #ifdef VMS
602 TSD->expected_exit_error = EXIT_SUCCESS;
603 #else
604 TSD->expected_exit_error = errorno;
605 #endif
606 TSD->delayed_error_type = PROTECTED_DelayedExit;
607 longjmp( TSD->protect_return, 1 ) ;
609 #ifdef VMS
610 TSD->MTExit( EXIT_SUCCESS ) ;
611 #else
612 TSD->MTExit( errorno ) ;
613 #endif
616 /* This function is called by the parser (syntactical interpreter) if an error
617 * occurs.
619 void __reginaerror(char *dummy)
621 /* We ignore the message although it may contain useful informations. */
622 dummy = dummy; /* keep compiler happy */
623 return ;
626 static char *read_index_header( const tsd_t *TSD, char *errfn, int native_language, FILE **fp, int *number_messages, int *file_lang )
628 err_tsd_t *et;
629 static char tmp[256];
631 et = TSD->err_tsd;
633 * Read the language file header...
635 *fp = fopen( errfn, "rb" );
636 if ( *fp == NULL )
638 sprintf( tmp, erropen[native_language], errfn );
639 return tmp;
641 if ( fread( &et->number_messages, sizeof(unsigned int), 1, *fp ) != 1 )
643 fclose( *fp );
644 sprintf( tmp, errread[native_language], errfn );
645 return tmp;
647 if ( fread( file_lang, sizeof(unsigned int), 1, *fp ) != 1 )
649 fclose( *fp );
650 sprintf( tmp, errread[native_language], errfn );
651 return tmp;
653 return NULL;
656 static char *read_index_file( const tsd_t *TSD, char *errfn, int native_language, int language_file, FILE **fp, struct textindex *tmi )
658 err_tsd_t *et;
659 static char tmp[256];
660 char *ptr;
661 int file_lang;
663 et = TSD->err_tsd;
665 * Read the language file header...
667 if ( ( ptr = read_index_header( TSD, errfn, native_language, fp, &et->number_messages, &file_lang ) ) != NULL )
669 et->number_messages = 0;
670 return ptr;
673 * Eunsure that the number of messages in the file matches the number defined as
674 * NUMBER_ERROR_MESSAGE in rexxmsg.h
676 if ( et->number_messages != NUMBER_ERROR_MESSAGES )
678 fclose( *fp );
679 et->number_messages = 0;
680 sprintf( tmp, errcount[native_language], errfn );
681 return tmp;
683 if ( fread( tmi, sizeof(struct textindex), NUMBER_ERROR_MESSAGES, *fp ) != NUMBER_ERROR_MESSAGES )
685 fclose( *fp );
686 et->number_messages = 0;
687 sprintf( tmp, errread[native_language], errfn );
688 return tmp;
690 return NULL;
693 * Called the first time we need to access an error message
694 * Determines which language file to open and read (always does English as well)
695 * Returns NULL on success, otherwise a pointer to an error message
697 static char *get_message_indexes( const tsd_t *TSD )
699 char *ptr;
700 char fn[REXX_PATH_MAX+1];
701 err_tsd_t *et;
702 char *errpath=NULL;
703 #if defined(__EPOC32__) || defined(__WINS__)
704 FILE *fp;
705 int number_messages, file_lang;
706 struct stat buffer ;
707 #else
708 int i, found=0;
709 static char tmp[256];
710 #endif
712 et = TSD->err_tsd;
714 #if defined(__EPOC32__) || defined(__WINS__)
716 * Open the default.mtb and read the language type from it.
718 errpath = "c:\\system\\apps\\reginarexx";
719 sprintf( fn, "%s\\default.mtb", errpath );
721 * If there is no default.mtb file, then default to English
723 if ( stat( fn, &buffer ) != 0 )
725 et->native_language = LANGUAGE_ENGLISH;
726 return NULL;
729 * We do have a default.mtb file, so read it to determine the language
731 if ( ( ptr = read_index_header( TSD, fn, LANGUAGE_ENGLISH, &fp, &number_messages, &file_lang ) ) != NULL )
733 et->number_messages = 0;
734 return ptr;
736 if ( fp )
737 fclose( fp );
738 et->native_language = file_lang;
739 #else
740 ptr = getenv( "REGINA_LANG" );
741 if ( ptr == NULL )
743 et->native_language = LANGUAGE_ENGLISH;
745 else
747 for ( i = 0; i < LANGUAGE_MAXIMUM; i++ )
749 if ( strcmp( ptr, errlang[i] ) == 0 )
751 et->native_language = i;
752 found = 1;
753 break;
756 if ( found == 0 )
758 sprintf( tmp, "Unsupported native language \"%s\"", ptr );
759 return tmp;
762 if ( et->native_language != LANGUAGE_ENGLISH )
764 errpath = getenv( "REGINA_LANG_DIR" );
765 if ( errpath == NULL )
767 # if defined(REGINA_SHARE_DIRECTORY)
768 errpath = REGINA_SHARE_DIRECTORY;
769 # else
770 sprintf( tmp, "Unable to determine where Regina language files (*.mtb) are located. Set REGINA_LANG_DIR." );
771 return tmp;
772 # endif
775 #endif
777 * Now read the native language file. If the native language is
778 * English, don't do anything.
780 if ( et->native_language != LANGUAGE_ENGLISH)
782 #if defined(__EPOC32__) || defined(__WINS__)
783 sprintf( fn, "%s\\default.mtb", errpath );
784 #else
785 sprintf( fn, "%s%c%s.mtb", errpath, FILE_SEPARATOR, errlang[et->native_language] );
786 #endif
787 if ( ( ptr = read_index_file( TSD, fn, et->native_language, et->native_language, &et->nls_fp, (struct textindex *)&et->nls_tmi ) ) != NULL )
788 return ptr;
790 return NULL;
793 static char *get_text_message( const tsd_t *TSD, FILE *fp, unsigned int fileoffset, unsigned int textlength, int errorno, int suberrorno, char *tmp, int *is_fmt )
795 err_tsd_t *et;
796 const char *errfn;
798 et = TSD->err_tsd;
800 #if defined(__EPOC32__) || defined(__WINS__)
801 errfn="default";
802 #else
803 errfn=errlang[et->native_language];
804 #endif
805 if ( fseek( fp, fileoffset, SEEK_SET ) == -1 )
807 sprintf( tmp, errcorrupt[et->native_language], errfn );
808 *is_fmt = 0;
810 else
812 if ( fread( tmp, 1, textlength, fp ) != textlength )
814 sprintf( tmp, errcorrupt[et->native_language], errfn );
815 *is_fmt = 0;
817 else
818 tmp[textlength] = '\0';
820 return tmp;
823 static char *get_embedded_text_message( const tsd_t *TSD, int errorno, int suberrorno, char *tmp )
825 int i;
827 for ( i = 0; i < NUMBER_ERROR_MESSAGES; i++ )
829 if ( errtext[i].errnum == errorno
830 && errtext[i].suberrnum == suberrorno )
832 strcpy( tmp, errtext[i].text );
833 return tmp;
836 strcpy( tmp, "" );
837 return tmp;
841 const char *errortext( const tsd_t *TSD, int errorno, int suberrorno, int request_english, int apply_inserts )
843 int low=0, mid=0, end=1, up, have_inserts=0, num_inserts=0;
844 int this_errorno, this_suberrorno;
845 err_tsd_t *et;
846 static char tmp[256];
847 static char new[256];
848 char *ptr=NULL;
849 const char *errfn;
850 char *ins;
851 char *insert[5]; /* maximum of 5 inserts allowed for any one message */
852 int is_fmt=1;
855 * If the supplied errorno is > 100 (the internal limit for interpreter
856 * errors), assume that a system error message is required.
858 if (errorno>100)
860 return( strerror(errorno-100) ) ;
863 et = TSD->err_tsd;
865 #if defined(__EPOC32__) || defined(__WINS__)
866 errfn="default";
867 #else
868 errfn=errlang[et->native_language];
869 #endif
871 * The first time this is called, determine the language and read the message file
872 * indexes into memory from the message file.
874 if ( et->number_messages == 0 )
876 if ( ( ptr = get_message_indexes( TSD ) ) != NULL )
879 * Corrupt or missing language file. Prepend the returned message to the
880 * embedded error message format.
882 sprintf( new, "(%s) %s", ptr, get_embedded_text_message( TSD, errorno, suberrorno, tmp ) );
883 strcpy( tmp, new );
884 ptr = tmp;
888 * If we don't already have an error message,
889 * and we are explicitly requesting an english message, or the native
890 * language is English, then simply get the message from the internal
891 * array.
893 if ( !ptr )
895 if ( request_english
896 || et->native_language == LANGUAGE_ENGLISH )
898 ptr = get_embedded_text_message( TSD, errorno, suberrorno, tmp );
900 else
902 up = et->number_messages-1;
904 while ((end)&&(up>=low))
906 mid = (up+low)/2 ;
907 this_errorno = et->nls_tmi[mid].errorno;
908 this_suberrorno = et->nls_tmi[mid].suberrorno;
909 if ( errorno == this_errorno
910 && suberrorno == this_suberrorno )
912 end = 0;
913 break;
915 if ( ( errorno > this_errorno )
916 || ( errorno == this_errorno
917 && suberrorno > this_suberrorno ) )
918 low = mid + 1;
919 else
920 up = mid - 1;
922 if (end)
924 char buf[50];
926 * We couldn't find our message...
928 sprintf( buf, errmissing[et->native_language], errfn );
929 sprintf( tmp, "(%s) %s", buf, get_embedded_text_message( TSD, errorno, suberrorno, new ) );
930 ptr = tmp;
932 else
934 ptr = get_text_message( TSD, et->nls_fp, et->nls_tmi[mid].fileoffset, et->nls_tmi[mid].textlength, errorno, suberrorno, tmp, &is_fmt );
935 if ( !is_fmt )
937 sprintf( new, "(%s) %s", ptr, get_embedded_text_message( TSD, errorno, suberrorno, tmp ) );
938 strcpy( tmp, new );
939 ptr = tmp;
944 for ( low = 0; low < (int) strlen( ptr ); low++ )
946 if ( ptr[low] == '|' )
948 ptr[low] = '\0';
949 have_inserts = 1;
950 break;
954 * If we need to apply insert, then:
955 * - adjust the returned fmt string replacing %c, %d, %x with %s
956 * - iterate through the inserts ( ptr+low+1 )
958 if ( apply_inserts
959 && have_inserts )
962 * The code below makes several assumptions about the format
963 * of each message. All assumptions are based on having checked
964 * the format of the messages using the checkmts.rexx script.
966 for ( end = 0; end < (int) strlen( ptr ); end++ )
968 if ( ptr[end] == '%' )
970 switch( ptr[end+1] ) /* assumes no message ends in % */
972 case 's':
973 num_inserts++;
974 break;
975 case 'c':
976 case 'x':
977 case 'd':
978 ptr[end+1] = 's';
979 num_inserts++;
980 break;
981 default:
982 break;
986 ins = ptr+low+1;
987 insert[0] = ins;
988 low = strlen( ins );
989 for ( mid = 0,end = 0; end < low; end++ )
991 if ( ins[end] == ',' )
993 ins[end] = '\0';
994 insert[++mid] = ins+end+1;
997 switch( num_inserts )
999 case 1:
1000 sprintf( new, ptr, insert[0] );
1001 break;
1002 case 2:
1003 sprintf( new, ptr, insert[0], insert[1] );
1004 break;
1005 case 3:
1006 sprintf( new, ptr, insert[0], insert[1], insert[2] );
1007 break;
1008 case 4:
1009 sprintf( new, ptr, insert[0], insert[1], insert[2], insert[3] );
1010 break;
1011 case 5:
1012 sprintf( new, ptr, insert[0], insert[1], insert[2], insert[3], insert[4] );
1013 break;
1015 ptr = new;
1018 return ptr;
1021 #ifndef NDEBUG
1023 const char *getsym( int numb )
1025 char *symb=NULL ;
1027 switch (numb)
1030 case X_NULL: symb="Null statement" ; break ;
1031 case X_PROGRAM: symb="Program" ; break ;
1032 case X_STATS: symb="Statements" ; break ;
1033 case X_COMMAND: symb="External command" ; break ;
1034 case X_ADDR_V: symb="ADDRESS (value) statement" ; break ;
1035 case X_ADDR_S: symb="ADDRESS" ; break ;
1036 case X_ADDR_N: symb="ADDRESS (normal) statement" ; break ;
1037 case X_ARG: symb="ARG statement" ; break ;
1038 case X_CALL: symb="CALL statement" ; break ;
1039 case X_DO: symb="DO statement" ; break ;
1040 case X_REP: symb="Repetitor in DO" ; break ;
1041 case X_REP_FOREVER: symb="Forever in DO" ; break ;
1042 case X_REP_COUNT: symb="Counter in DO" ; break ;
1043 case X_DO_TO: symb="Upper limit in DO" ; break ;
1044 case X_DO_BY: symb="Step-size in DO" ; break ;
1045 case X_DO_FOR: symb="Max number in DO" ; break ;
1046 case X_DO_EXPR: symb="Upper limit in DO" ; break ;
1047 case X_WHILE: symb="WHILE expr in DO" ; break ;
1048 case X_UNTIL: symb="UNTIL expr in DO" ; break ;
1049 case X_DROP: symb="DROP statement" ; break ;
1050 case X_EXIT: symb="EXIT statement" ; break ;
1051 case X_IF: symb="IF statement" ; break ;
1052 case X_IPRET: symb="INTERPRET statement" ; break ;
1053 case X_ITERATE: symb="ITERATE statement" ; break ;
1054 case X_LABEL: symb="Label specification" ; break ;
1055 case X_LEAVE: symb="LEAVE statement" ; break ;
1056 case X_NUM_D: symb="NUMERIC DIGIT statement" ; break ;
1057 case X_NUM_F: symb="NUMERIC FORM statement" ; break ;
1058 case X_NUM_FUZZ: symb="NUMERIC FUZZ statement" ; break ;
1059 case X_NUM_SCI: symb="Scientific numeric form" ; break ;
1060 case X_NUM_ENG: symb="Engeenering scientific form" ; break ;
1061 case X_PARSE: symb="PARSE statement" ; break ;
1062 case X_PARSE_U: symb="UPPER PARSE statement" ; break ;
1063 case X_PARSE_ARG: symb="PARSE ARG atatement" ; break ;
1064 case X_PARSE_EXT: symb="External parsing" ; break ;
1065 case X_PARSE_NUM: symb="Numeric parsing" ; break ;
1066 case X_PARSE_PULL: symb="Parse pull" ; break ;
1067 case X_PARSE_SRC: symb="Parse source" ; break ;
1068 case X_PARSE_VAR: symb="Parse variable" ; break ;
1069 case X_PARSE_VAL: symb="Parse value" ; break ;
1070 case X_PARSE_VER: symb="Parse version" ; break ;
1071 case X_PARSE_ARG_U: symb="PARSE UPPER ARG statement" ; break ;
1072 case X_PROC: symb="PROCEDURE statement" ; break ;
1073 case X_PULL: symb="PULL statement" ; break ;
1074 case X_PUSH: symb="PUSH statement" ; break ;
1075 case X_QUEUE: symb="QUEUE statement" ; break ;
1076 case X_RETURN: symb="RETURN statement" ; break ;
1077 case X_SAY: symb="SAY statement" ; break ;
1078 case X_SELECT: symb="SELECT statement" ; break ;
1079 case X_WHENS: symb="WHEN connector" ; break ;
1080 case X_WHEN: symb="WHEN clause" ; break ;
1081 case X_OTHERWISE: symb="OTHERWISE clause" ; break ;
1082 case X_SIG_VAL: symb="SIGNAL VALUE statement" ; break ;
1083 case X_SIG_LAB: symb="SIGNAL (label) statement" ; break ;
1084 case X_SIG_SET: symb="SIGNAL (setting) statement" ; break ;
1085 case X_ON: symb="Setting is ON" ; break ;
1086 case X_OFF: symb="Setting is OFF" ; break ;
1087 case X_S_ERROR: symb="ERROR option" ; break ;
1088 case X_S_HALT: symb="HALT option" ; break ;
1089 case X_S_NOVALUE: symb="NOVALUE option" ; break ;
1090 case X_S_SYNTAX: symb="SYNTAX option" ; break ;
1091 case X_TRACE: symb="TRACE statement" ; break ;
1092 case X_T_ALL: symb="ALL option" ; break ;
1093 case X_T_COMM: symb="COMMAND option" ; break ;
1094 case X_T_ERR: symb="ERROR option" ; break ;
1095 case X_T_INTER: symb="INTERMEDIATE option" ; break ;
1096 case X_T_LABEL: symb="LABEL option" ; break ;
1097 case X_T_NORMAL: symb="NORMAL option" ; break ;
1098 case X_T_OFF: symb="OFF option" ; break ;
1099 case X_T_SCAN: symb="SCAN option" ; break ;
1100 case X_UPPER_VAR: symb="UPPER statement" ; break ;
1101 case X_ASSIGN: symb="Assignment" ; break ;
1102 case X_LOG_NOT: symb="Logical NOT" ; break ;
1103 case X_PLUSS: symb="Plus operator" ; break ;
1104 case X_EQUAL: symb="Equal operator" ; break ;
1105 case X_MINUS: symb="Minus operator" ; break ;
1106 case X_MULT: symb="Multiplication operator" ; break ;
1107 case X_DEVIDE: symb="Division operator" ; break ;
1108 case X_MODULUS: symb="Modulus operator" ; break ;
1109 case X_LOG_OR: symb="Logical or" ; break ;
1110 case X_LOG_AND: symb="Logical and" ; break ;
1111 case X_LOG_XOR: symb="Logical xor" ; break ;
1112 case X_EXP: symb="Exponent operator" ; break ;
1113 case X_CONCAT: symb="String concatenation" ; break ;
1114 case X_SPACE: symb="Space separator" ; break ;
1115 case X_GTE: symb="Greater than or equal operator" ; break ;
1116 case X_LTE: symb="Less than or equal operator" ; break ;
1117 case X_GT: symb="Greater than operator" ; break ;
1118 case X_LT: symb="Less than operator" ; break ;
1119 case X_NEQUAL: symb="Not equal operator" ; break ;
1120 case X_NDIFF: symb="Not different operator" ; break ;
1121 case X_NGT: symb="Not greater than operator" ; break ;
1122 case X_NGTE: symb="Not greater than or equal operator" ; break ;
1123 case X_NLT: symb="Not less than operator" ; break ;
1124 case X_NLTE: symb="Not less than or equal operator" ; break ;
1125 case X_DIFF: symb="Different operator" ; break ;
1126 case X_SEQUAL: symb="Strictly equal operator" ; break ;
1127 case X_SDIFF: symb="Strictly different operator" ; break ;
1128 case X_SGT: symb="Strictly greater than operator" ; break ;
1129 case X_SGTE: symb="Strictly greater than or equal operator" ; break ;
1130 case X_SLT: symb="Strictly less than operator" ; break ;
1131 case X_SLTE: symb="Strictly less than or equal operator" ; break ;
1132 case X_SIM_SYMBOL: symb="Simple symbol" ; break ;
1133 case X_CON_SYMBOL: symb="Constant symbol" ; break ;
1134 case X_HEX_STR: symb="Hexadecimal string" ; break ;
1135 case X_STRING: symb="Constant string" ; break ;
1136 case X_FUNC: symb="Function call" ; break ;
1137 case X_U_MINUS: symb="Unary minus" ; break ;
1138 case X_S_EQUAL: symb="String equal operator" ; break ;
1139 case X_S_DIFF: symb="String different operator" ; break ;
1140 case X_SIMSYMB: symb="Simple symbol (2)" ; break ;
1141 case X_INTDIV: symb="Integer division" ; break ;
1142 case X_EX_FUNC: symb="External function call" ; break ;
1143 case X_IN_FUNC: symb="Internal function call" ; break ;
1144 case X_TPL_SOLID: symb="Solid point in template" ; break ;
1145 case X_TPL_MVE: symb="Constant pattern" ; break ;
1146 case X_TPL_VAR: symb="Variable pattern" ; break ;
1147 case X_TPL_TO: symb="Ehh, what does \"TO\" mean???" ; break ;
1148 case X_TPL_SYMBOL: symb="Variable in template" ; break ;
1149 case X_TPL_SPACE: symb="Space in template" ; break ;
1150 case X_TPL_POINT: symb="Placeholder in template" ; break ;
1151 case X_TMPLS: symb="Template connector" ; break ;
1152 case X_TPL_OFF: symb="Offset in template" ; break ;
1153 case X_TPL_PATT: symb="Pattern in template" ; break ;
1154 case X_NEG_OFFS: symb="Negative offset" ; break ;
1155 case X_POS_OFFS: symb="Positive offset" ; break ;
1156 case X_ABS_OFFS: symb="Absolute offset" ; break ;
1157 case X_EXPRLIST: symb="Expression connector" ; break ;
1158 case X_SYMBOLS: symb="Symbol connector" ; break ;
1159 case X_SYMBOL: symb="Symbol?" ; break ;
1160 case X_END: symb="End statement" ; break ;
1161 case X_IS_INTERNAL: symb="Internal function" ; break ;
1162 case X_IS_BUILTIN: symb="Builtin function" ; break ;
1163 case X_IS_EXTERNAL: symb="External function" ; break ;
1164 case X_CEXPRLIST: symb="Expression list" ; break ;
1165 case X_NASSIGN: symb="Numeric Assignment" ; break ;
1166 case X_VTAIL_SYMBOL: symb="Variable tail symbol" ; break ;
1167 case X_CTAIL_SYMBOL: symb="Constant tail symbol" ; break ;
1168 case X_HEAD_SYMBOL: symb="Compound variable symbol" ; break ;
1169 case X_STEM_SYMBOL: symb="Stem variable symbol" ; break ;
1170 case X_NO_OTHERWISE: symb="No otherwise statement" ; break ;
1171 default: symb="Unrecognized value" ;
1174 return symb ;
1177 #endif /* !NDEBUG */