1
/* ------------------------------------------------------------------------- */
2
/* "errors" : Warnings, errors and fatal errors */
3
/* (with error throwback code for RISC OS machines) */
5
/* Part of Inform 6.30 */
6
/* copyright (c) Graham Nelson 1993 - 2004 */
8
/* ------------------------------------------------------------------------- */
12
static char error_message_buff[256];
14
/* ------------------------------------------------------------------------- */
15
/* Error preamble printing. */
16
/* ------------------------------------------------------------------------- */
18
ErrorPosition ErrorReport; /* Maintained by "lexer.c" */
20
static void print_preamble(void)
22
/* Only really prints the preamble to an error or warning message:
24
e.g. "jigsaw.apollo", line 24:
26
The format is controllable (from an ICL switch) since this assists
27
the working of some development environments. */
29
int j, with_extension_flag = FALSE; char *p;
31
j = ErrorReport.file_number;
32
if (j <= 0) p = ErrorReport.source;
33
else p = InputFiles[j-1].filename;
35
if (!p) p = ""; /* ###-call me paranoid */
39
case 0: /* RISC OS error message format */
41
if (!(ErrorReport.main_flag)) printf("\"%s\", ", p);
42
printf("line %d: ", ErrorReport.line_number);
45
case 1: /* Microsoft error message format */
47
for (j=0; p[j]!=0; j++)
48
{ if (p[j] == FN_SEP) with_extension_flag = TRUE;
49
if (p[j] == '.') with_extension_flag = FALSE;
52
if (with_extension_flag) printf("%s", Source_Extension);
53
printf("(%d): ", ErrorReport.line_number);
56
case 2: /* Macintosh Programmer's Workshop error message format */
58
printf("File \"%s\"; Line %d\t# ", p, ErrorReport.line_number);
63
static char trimmed_text[128];
65
static void trim_text(char *s)
67
if (strlen(s) < 128) { strcpy(trimmed_text, s); return; }
68
for (i=0; i<120; i++) trimmed_text[i] = s[i];
69
trimmed_text[i++] = '.';
70
trimmed_text[i++] = '.';
71
trimmed_text[i++] = '.';
72
trimmed_text[i++] = 0;
76
/* ------------------------------------------------------------------------- */
77
/* Fatal errors (which have style 0) */
78
/* ------------------------------------------------------------------------- */
80
extern void fatalerror(char *s)
83
printf("Fatal error: %s\n",s);
84
if (no_compiler_errors > 0) print_sorry_message();
92
if (temporary_files_switch) remove_temp_files();
93
abort_transcript_file();
96
my_free(&all_text,"transcription text");
97
longjmp(g_fallback, 1);
102
extern void fatalerror_named(char *m, char *fn)
104
sprintf(error_message_buff, "%s \"%s\"", m, trimmed_text);
105
fatalerror(error_message_buff);
108
extern void memory_out_error(int32 size, int32 howmany, char *name)
110
sprintf(error_message_buff,
111
"Run out of memory allocating %d bytes for %s", size, name);
113
sprintf(error_message_buff,
114
"Run out of memory allocating array of %dx%d bytes for %s",
115
howmany, size, name);
116
fatalerror(error_message_buff);
119
extern void memoryerror(char *s, int32 size)
121
sprintf(error_message_buff,
122
"The memory setting %s (which is %ld at present) has been \
123
exceeded. Try running Inform again with $%s=<some-larger-number> on the \
124
command line.",s,(long int) size,s);
125
fatalerror(error_message_buff);
128
/* ------------------------------------------------------------------------- */
129
/* Survivable diagnostics: */
130
/* compilation errors style 1 */
131
/* warnings style 2 */
132
/* linkage errors style 3 */
133
/* compiler errors style 4 (these should never happen and */
134
/* indicate a bug in Inform) */
135
/* ------------------------------------------------------------------------- */
137
static int errors[MAX_ERRORS];
139
int no_errors, no_warnings, no_suppressed_warnings, no_link_errors,
142
char *forerrors_buff;
143
int forerrors_pointer;
145
static void message(int style, char *s)
146
{ int throw_style = style;
147
if (hash_printed_since_newline) printf("\n");
148
hash_printed_since_newline = FALSE;
151
{ case 1: printf("Error: "); no_errors++; break;
152
case 2: printf("Warning: "); no_warnings++; break;
153
case 3: printf("Error: [linking '%s'] ", current_module_filename);
154
no_link_errors++; no_errors++; throw_style=1; break;
155
case 4: printf("*** Compiler error: ");
156
no_compiler_errors++; throw_style=1; break;
160
throwback(throw_style, s);
163
ProcessEvents (&g_proc);
167
my_free(&all_text,"transcription text");
169
if (temporary_files_switch) remove_temp_files();
170
abort_transcript_file();
171
longjmp (g_fallback, 1);
174
if ((!concise_switch) && (forerrors_pointer > 0) && (style <= 2))
175
{ forerrors_buff[forerrors_pointer] = 0;
176
sprintf(forerrors_buff+68," ...etc");
177
printf("> %s\n",forerrors_buff);
181
/* ------------------------------------------------------------------------- */
182
/* Style 1: Error message routines */
183
/* ------------------------------------------------------------------------- */
185
extern void error(char *s)
186
{ if (no_errors == MAX_ERRORS)
187
fatalerror("Too many errors: giving up");
188
errors[no_errors] = no_syntax_lines;
192
extern void error_named(char *s1, char *s2)
194
sprintf(error_message_buff,"%s \"%s\"",s1,trimmed_text);
195
error(error_message_buff);
198
extern void error_numbered(char *s1, int val)
200
sprintf(error_message_buff,"%s %d.",s1,val);
201
error(error_message_buff);
204
extern void error_named_at(char *s1, char *s2, int32 report_line)
207
ErrorPosition E = ErrorReport;
208
if (report_line != -1)
209
{ ErrorReport.file_number = report_line/0x10000;
210
ErrorReport.line_number = report_line%0x10000;
211
ErrorReport.main_flag = (ErrorReport.file_number == 1);
215
sprintf(error_message_buff,"%s \"%s\"",s1,trimmed_text);
217
i = concise_switch; concise_switch = TRUE;
218
error(error_message_buff);
219
ErrorReport = E; concise_switch = i;
222
extern void no_such_label(char *lname)
223
{ error_named("No such label as",lname);
226
extern void ebf_error(char *s1, char *s2)
228
sprintf(error_message_buff, "Expected %s but found %s", s1, trimmed_text);
229
error(error_message_buff);
232
extern void char_error(char *s, int ch)
235
uni = iso_to_unicode(ch);
238
{ sprintf(error_message_buff,
239
"%s (unicode) $%04x = (ISO %s) $%02x", s, uni,
240
name_of_iso_set(character_set_setting), ch);
243
sprintf(error_message_buff, "%s (ISO Latin1) $%02x", s, uni);
245
if (((uni>=32) && (uni<127))
246
|| (((uni >= 0xa1) && (uni <= 0xff)) && (character_set_setting==1)))
247
sprintf(error_message_buff+strlen(error_message_buff),
248
", i.e., '%c'", uni);
250
error(error_message_buff);
253
extern void unicode_char_error(char *s, int32 uni)
256
sprintf(error_message_buff, "%s (unicode) $%04x", s, uni);
258
sprintf(error_message_buff, "%s (ISO Latin1) $%02x", s, uni);
260
if (((uni>=32) && (uni<127))
261
|| (((uni >= 0xa1) && (uni <= 0xff)) && (character_set_setting==1)))
262
sprintf(error_message_buff+strlen(error_message_buff),
263
", i.e., '%c'", uni);
265
error(error_message_buff);
268
/* ------------------------------------------------------------------------- */
269
/* Style 2: Warning message routines */
270
/* ------------------------------------------------------------------------- */
272
extern void warning(char *s1)
273
{ if (nowarnings_switch) { no_suppressed_warnings++; return; }
277
extern void warning_numbered(char *s1, int val)
278
{ if (nowarnings_switch) { no_suppressed_warnings++; return; }
279
sprintf(error_message_buff,"%s %d.", s1, val);
280
message(2,error_message_buff);
283
extern void warning_named(char *s1, char *s2)
286
if (nowarnings_switch) { no_suppressed_warnings++; return; }
287
sprintf(error_message_buff,"%s \"%s\"", s1, trimmed_text);
288
message(2,error_message_buff);
291
extern void dbnu_warning(char *type, char *name, int32 report_line)
293
ErrorPosition E = ErrorReport;
294
if (nowarnings_switch) { no_suppressed_warnings++; return; }
295
if (report_line != -1)
296
{ ErrorReport.file_number = report_line/0x10000;
297
ErrorReport.line_number = report_line%0x10000;
298
ErrorReport.main_flag = (ErrorReport.file_number == 1);
300
sprintf(error_message_buff, "%s \"%s\" declared but not used", type, name);
301
i = concise_switch; concise_switch = TRUE;
302
message(2,error_message_buff);
307
extern void obsolete_warning(char *s1)
308
{ if (is_systemfile()==1) return;
309
if (obsolete_switch || nowarnings_switch)
310
{ no_suppressed_warnings++; return; }
311
sprintf(error_message_buff, "Obsolete usage: %s",s1);
312
message(2,error_message_buff);
315
/* ------------------------------------------------------------------------- */
316
/* Style 3: Link error message routines */
317
/* ------------------------------------------------------------------------- */
319
extern void link_error(char *s)
320
{ if (no_errors==MAX_ERRORS) fatalerror("Too many errors: giving up");
321
errors[no_errors] = no_syntax_lines;
325
extern void link_error_named(char *s1, char *s2)
327
sprintf(error_message_buff,"%s \"%s\"",s1,trimmed_text);
328
link_error(error_message_buff);
331
/* ------------------------------------------------------------------------- */
332
/* Style 4: Compiler error message routines */
333
/* ------------------------------------------------------------------------- */
335
extern void print_sorry_message(void)
337
"***********************************************************************\n\
338
* 'Compiler errors' should never occur if Inform is working properly. *\n\
339
* This is version %d.%02d of Inform, dated %20s: so *\n\
340
* if that was more than six months ago, there may be a more recent *\n\
341
* version available, from which the problem may have been removed. *\n\
342
* If not, please report this fault to: graham@gnelson.demon.co.uk *\n\
343
* and if at all possible, please include your source code, as faults *\n\
344
* such as these are rare and often difficult to reproduce. Sorry. *\n\
345
***********************************************************************\n",
346
(RELEASE_NUMBER/100)%10, RELEASE_NUMBER%100, RELEASE_DATE);
349
extern int compiler_error(char *s)
350
{ if (no_link_errors > 0) return FALSE;
351
if (no_errors > 0) return FALSE;
352
if (no_compiler_errors==MAX_ERRORS)
353
fatalerror("Too many compiler errors: giving up");
358
extern int compiler_error_named(char *s1, char *s2)
359
{ if (no_link_errors > 0) return FALSE;
360
if (no_errors > 0) return FALSE;
362
sprintf(error_message_buff,"%s \"%s\"",s1,trimmed_text);
363
compiler_error(error_message_buff);
367
/* ------------------------------------------------------------------------- */
368
/* Code for the Acorn RISC OS operating system, donated by Robin Watts, */
369
/* to provide error throwback under the DDE environment */
370
/* ------------------------------------------------------------------------- */
374
#define DDEUtils_ThrowbackStart 0x42587
375
#define DDEUtils_ThrowbackSend 0x42588
376
#define DDEUtils_ThrowbackEnd 0x42589
380
extern void throwback_start(void)
381
{ _kernel_swi_regs regs;
382
if (throwback_switch)
383
_kernel_swi(DDEUtils_ThrowbackStart, ®s, ®s);
386
extern void throwback_end(void)
387
{ _kernel_swi_regs regs;
388
if (throwback_switch)
389
_kernel_swi(DDEUtils_ThrowbackEnd, ®s, ®s);
392
int throwback_started = FALSE;
394
extern void throwback(int severity, char * error)
395
{ _kernel_swi_regs regs;
396
if (!throwback_started)
397
{ throwback_started = TRUE;
400
if (throwback_switch)
402
if ((ErrorReport.file_number == -1)
403
|| (ErrorReport.file_number == 0))
404
regs.r[2] = (int) (InputFiles[0].filename);
405
else regs.r[2] = (int) (InputFiles[ErrorReport.file_number-1].filename);
406
regs.r[3] = ErrorReport.line_number;
407
regs.r[4] = (2-severity);
408
regs.r[5] = (int) error;
409
_kernel_swi(DDEUtils_ThrowbackSend, ®s, ®s);
415
/* ========================================================================= */
416
/* Data structure management routines */
417
/* ------------------------------------------------------------------------- */
419
extern void init_errors_vars(void)
420
{ forerrors_buff = NULL;
421
no_errors = 0; no_warnings = 0; no_suppressed_warnings = 0;
422
no_compiler_errors = 0;
425
extern void errors_begin_pass(void)
426
{ ErrorReport.line_number = 0;
427
ErrorReport.file_number = -1;
428
ErrorReport.source = "<no text read yet>";
429
ErrorReport.main_flag = FALSE;
432
extern void errors_allocate_arrays(void)
433
{ forerrors_buff = my_malloc(512, "errors buffer");
436
extern void errors_free_arrays(void)
437
{ my_free(&forerrors_buff, "errors buffer");
440
/* ========================================================================= */