X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Ferrors.c;h=c7ec13dc29587d2a5f1ccf5ce4947127573c0076;hb=HEAD;hp=b76aa7d5658dbe9398b75280a5d9e228259ac73f;hpb=81ffe9a7de1db0b3a318a053b38882d1b7ab304c;p=inform.git diff --git a/src/errors.c b/src/errors.c index b76aa7d..c7ec13d 100644 --- a/src/errors.c +++ b/src/errors.c @@ -2,9 +2,8 @@ /* "errors" : Warnings, errors and fatal errors */ /* (with error throwback code for RISC OS machines) */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2018 */ -/* */ -/* This file is part of Inform. */ +/* Part of Inform 6.42 */ +/* copyright (c) Graham Nelson 1993 - 2024 */ /* */ /* Inform is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -32,6 +31,8 @@ static char error_message_buff[ERROR_BUFLEN+4]; /* room for ellipsis */ ErrorPosition ErrorReport; /* Maintained by "lexer.c" */ +static char other_pos_buff[ERROR_BUFLEN+1]; /* Used by location_text() */ + static void print_preamble(void) { /* Only really prints the preamble to an error or warning message: @@ -55,6 +56,7 @@ static void print_preamble(void) if (!(ErrorReport.main_flag)) printf("\"%s\", ", p); printf("line %d: ", ErrorReport.line_number); + if (ErrorReport.orig_file) { char *op; if (ErrorReport.orig_file <= 0 || ErrorReport.orig_file > total_files) @@ -80,16 +82,103 @@ static void print_preamble(void) } printf("%s", p); if (with_extension_flag) printf("%s", Source_Extension); - printf("(%d): ", ErrorReport.line_number); + printf("(%d)", ErrorReport.line_number); + + if (ErrorReport.orig_file) { + char *op; + if (ErrorReport.orig_file <= 0 || ErrorReport.orig_file > total_files) + op = ErrorReport.orig_source; + else + op = InputFiles[ErrorReport.orig_file-1].filename; + printf("|%s", op); + if (ErrorReport.orig_line) { + printf("(%d", ErrorReport.orig_line); + if (ErrorReport.orig_char) { + printf(":%d", ErrorReport.orig_char); + } + printf(")"); + } + } + + printf(": "); break; case 2: /* Macintosh Programmer's Workshop error message format */ - printf("File \"%s\"; Line %d\t# ", p, ErrorReport.line_number); + printf("File \"%s\"; Line %d", p, ErrorReport.line_number); + + if (ErrorReport.orig_file) { + char *op; + if (ErrorReport.orig_file <= 0 || ErrorReport.orig_file > total_files) + op = ErrorReport.orig_source; + else + op = InputFiles[ErrorReport.orig_file-1].filename; + printf(": (\"%s\"", op); + if (ErrorReport.orig_line) { + printf("; Line %d", ErrorReport.orig_line); + if (ErrorReport.orig_char) { + printf("; Char %d", ErrorReport.orig_char); + } + } + printf(")"); + } + + printf("\t# "); break; } } +static char *location_text(brief_location report_line) +{ + int j; + char *p; + int len; + + /* Convert the location to a brief string. + (Some error messages need to report a secondary location.) + This uses the static buffer other_pos_buff. */ + + ErrorPosition errpos; + errpos.file_number = -1; + errpos.source = NULL; + errpos.line_number = 0; + errpos.main_flag = 0; + errpos.orig_source = NULL; + export_brief_location(report_line, &errpos); + + j = errpos.file_number; + if (j <= 0 || j > total_files) p = errpos.source; + else p = InputFiles[j-1].filename; + + if (!p && errpos.line_number == 0) { + /* Special case */ + strcpy(other_pos_buff, "compiler setup"); + return other_pos_buff; + } + + if (!p) p = ""; + + len = 0; + + if (!(errpos.main_flag)) { + snprintf(other_pos_buff+len, ERROR_BUFLEN-len, + "\"%s\", ", p); + len = strlen(other_pos_buff); + } + snprintf(other_pos_buff+len, ERROR_BUFLEN-len, + "line %d", errpos.line_number); + + return other_pos_buff; +} + +char *current_location_text(void) +{ + /* Convert the current lexer location to a brief string. + (Called by some trace messages.) + This uses the static buffer other_pos_buff. */ + return location_text(get_brief_location(&ErrorReport)); +} + static void ellipsize_error_message_buff(void) { /* If the error buffer was actually filled up by a message, it was @@ -116,23 +205,30 @@ extern void fatalerror(char *s) #endif #ifdef MAC_FACE close_all_source(); - if (temporary_files_switch) remove_temp_files(); abort_transcript_file(); free_arrays(); - if (store_the_text) - my_free(&all_text,"transcription text"); longjmp(g_fallback, 1); #endif exit(1); } +extern void fatalerror_fmt(const char *format, ...) +{ + va_list argument_pointer; + va_start(argument_pointer, format); + vsnprintf(error_message_buff, ERROR_BUFLEN, format, argument_pointer); + va_end(argument_pointer); + ellipsize_error_message_buff(); + fatalerror(error_message_buff); +} + extern void fatalerror_named(char *m, char *fn) { snprintf(error_message_buff, ERROR_BUFLEN, "%s \"%s\"", m, fn); ellipsize_error_message_buff(); fatalerror(error_message_buff); } -extern void memory_out_error(int32 size, int32 howmany, char *name) +extern void fatalerror_memory_out(int32 size, int32 howmany, char *name) { if (howmany == 1) snprintf(error_message_buff, ERROR_BUFLEN, "Run out of memory allocating %d bytes for %s", size, name); @@ -144,58 +240,41 @@ extern void memory_out_error(int32 size, int32 howmany, char *name) fatalerror(error_message_buff); } -extern void memoryerror(char *s, int32 size) -{ - snprintf(error_message_buff, ERROR_BUFLEN, - "The memory setting %s (which is %ld at present) has been \ -exceeded. Try running Inform again with $%s= on the \ -command line.",s,(long int) size,s); - ellipsize_error_message_buff(); - fatalerror(error_message_buff); -} - /* ------------------------------------------------------------------------- */ /* Survivable diagnostics: */ /* compilation errors style 1 */ /* warnings style 2 */ -/* linkage errors style 3 */ +/* linkage errors style 3 (no longer used) */ /* compiler errors style 4 (these should never happen and */ /* indicate a bug in Inform) */ /* ------------------------------------------------------------------------- */ -static int errors[MAX_ERRORS]; - -int no_errors, no_warnings, no_suppressed_warnings, no_link_errors, - no_compiler_errors; +int no_errors, no_warnings, no_suppressed_warnings, no_compiler_errors; char *forerrors_buff; int forerrors_pointer; static void message(int style, char *s) -{ int throw_style = style; +{ if (hash_printed_since_newline) printf("\n"); hash_printed_since_newline = FALSE; print_preamble(); switch(style) { case 1: printf("Error: "); no_errors++; break; case 2: printf("Warning: "); no_warnings++; break; - case 3: printf("Error: [linking '%s'] ", current_module_filename); - no_link_errors++; no_errors++; throw_style=1; break; + case 3: printf("Error: [linking] "); no_errors++; break; case 4: printf("*** Compiler error: "); - no_compiler_errors++; throw_style=1; break; + no_compiler_errors++; break; } printf(" %s\n", s); #ifdef ARC_THROWBACK - throwback(throw_style, s); + throwback(((style <= 2) ? style : 1), s); #endif #ifdef MAC_FACE ProcessEvents (&g_proc); if (g_proc != true) { free_arrays(); - if (store_the_text) - my_free(&all_text,"transcription text"); close_all_source (); - if (temporary_files_switch) remove_temp_files(); abort_transcript_file(); longjmp (g_fallback, 1); } @@ -214,19 +293,21 @@ static void message(int style, char *s) extern void error(char *s) { if (no_errors == MAX_ERRORS) fatalerror("Too many errors: giving up"); - errors[no_errors] = no_syntax_lines; message(1,s); } -extern void error_named(char *s1, char *s2) -{ snprintf(error_message_buff, ERROR_BUFLEN,"%s \"%s\"",s1,s2); +extern void error_fmt(const char *format, ...) +{ + va_list argument_pointer; + va_start(argument_pointer, format); + vsnprintf(error_message_buff, ERROR_BUFLEN, format, argument_pointer); + va_end(argument_pointer); ellipsize_error_message_buff(); error(error_message_buff); } -extern void error_numbered(char *s1, int val) -{ - snprintf(error_message_buff, ERROR_BUFLEN,"%s %d.",s1,val); +extern void error_named(char *s1, char *s2) +{ snprintf(error_message_buff, ERROR_BUFLEN,"%s \"%s\"",s1,s2); ellipsize_error_message_buff(); error(error_message_buff); } @@ -245,16 +326,41 @@ extern void error_named_at(char *s1, char *s2, brief_location report_line) ErrorReport = E; concise_switch = i; } -extern void no_such_label(char *lname) -{ error_named("No such label as",lname); -} - extern void ebf_error(char *s1, char *s2) { snprintf(error_message_buff, ERROR_BUFLEN, "Expected %s but found %s", s1, s2); ellipsize_error_message_buff(); error(error_message_buff); } +extern void ebf_curtoken_error(char *s) +{ + /* This is "Expected (s) but found (the current token_text)". We use + token_type as a hint for how to display token_text. */ + + if (token_type == DQ_TT) { + snprintf(error_message_buff, ERROR_BUFLEN, "Expected %s but found string \"%s\"", s, token_text); + } + else if (token_type == SQ_TT && strlen(token_text)==1) { + snprintf(error_message_buff, ERROR_BUFLEN, "Expected %s but found char '%s'", s, token_text); + } + else if (token_type == SQ_TT) { + snprintf(error_message_buff, ERROR_BUFLEN, "Expected %s but found dict word '%s'", s, token_text); + } + else { + /* Symbols, unquoted strings, and numbers can be printed directly. EOF will have "" in token_text. */ + snprintf(error_message_buff, ERROR_BUFLEN, "Expected %s but found %s", s, token_text); + } + + ellipsize_error_message_buff(); + error(error_message_buff); +} + +extern void ebf_symbol_error(char *s1, char *name, char *type, brief_location report_line) +{ snprintf(error_message_buff, ERROR_BUFLEN, "\"%s\" is a name already in use and may not be used as a %s (%s \"%s\" was defined at %s)", name, s1, type, name, location_text(report_line)); + ellipsize_error_message_buff(); + error(error_message_buff); +} + extern void char_error(char *s, int ch) { int32 uni; @@ -308,6 +414,30 @@ extern void unicode_char_error(char *s, int32 uni) error(error_message_buff); } +extern void error_max_dynamic_strings(int index) +{ + if (index >= 96 && !glulx_mode) + snprintf(error_message_buff, ERROR_BUFLEN, "Only dynamic strings @(00) to @(95) may be used in Z-code"); + else if (MAX_DYNAMIC_STRINGS == 0) + snprintf(error_message_buff, ERROR_BUFLEN, "Dynamic strings may not be used, because $MAX_DYNAMIC_STRINGS has been set to 0. Increase MAX_DYNAMIC_STRINGS."); + else if (MAX_DYNAMIC_STRINGS == 32 && !glulx_mode) + snprintf(error_message_buff, ERROR_BUFLEN, "Only dynamic strings @(00) to @(%02d) may be used, because $MAX_DYNAMIC_STRINGS has its default value of %d. Increase MAX_DYNAMIC_STRINGS.", MAX_DYNAMIC_STRINGS-1, MAX_DYNAMIC_STRINGS); + else + snprintf(error_message_buff, ERROR_BUFLEN, "Only dynamic strings @(00) to @(%02d) may be used, because $MAX_DYNAMIC_STRINGS has been set to %d. Increase MAX_DYNAMIC_STRINGS.", MAX_DYNAMIC_STRINGS-1, MAX_DYNAMIC_STRINGS); + + ellipsize_error_message_buff(); + error(error_message_buff); +} + +extern void error_max_abbreviations(int index) +{ + /* This is only called for Z-code. */ + if (index >= 96) + error("The number of abbreviations has exceeded 96, the limit in Z-code"); + else + error("The number of abbreviations has exceeded MAX_ABBREVS. Increase MAX_ABBREVS."); +} + /* ------------------------------------------------------------------------- */ /* Style 2: Warning message routines */ /* ------------------------------------------------------------------------- */ @@ -317,9 +447,13 @@ extern void warning(char *s1) message(2,s1); } -extern void warning_numbered(char *s1, int val) -{ if (nowarnings_switch) { no_suppressed_warnings++; return; } - snprintf(error_message_buff, ERROR_BUFLEN,"%s %d.", s1, val); +extern void warning_fmt(const char *format, ...) +{ + va_list argument_pointer; + if (nowarnings_switch) { no_suppressed_warnings++; return; } + va_start(argument_pointer, format); + vsnprintf(error_message_buff, ERROR_BUFLEN, format, argument_pointer); + va_end(argument_pointer); ellipsize_error_message_buff(); message(2,error_message_buff); } @@ -332,6 +466,30 @@ extern void warning_named(char *s1, char *s2) message(2,error_message_buff); } +extern void warning_at(char *name, brief_location report_line) +{ int i; + ErrorPosition E = ErrorReport; + if (nowarnings_switch) { no_suppressed_warnings++; return; } + export_brief_location(report_line, &ErrorReport); + snprintf(error_message_buff, ERROR_BUFLEN, "%s", name); + ellipsize_error_message_buff(); + i = concise_switch; concise_switch = TRUE; + message(2,error_message_buff); + concise_switch = i; + ErrorReport = E; +} + +extern void symtype_warning(char *context, char *name, char *type, char *wanttype) +{ + if (nowarnings_switch) { no_suppressed_warnings++; return; } + if (name) + snprintf(error_message_buff, ERROR_BUFLEN, "In %s, expected %s but found %s \"%s\"", context, wanttype, type, name); + else + snprintf(error_message_buff, ERROR_BUFLEN, "In %s, expected %s but found %s", context, wanttype, type); + ellipsize_error_message_buff(); + message(2,error_message_buff); +} + extern void dbnu_warning(char *type, char *name, brief_location report_line) { int i; ErrorPosition E = ErrorReport; @@ -374,22 +532,6 @@ extern void obsolete_warning(char *s1) message(2,error_message_buff); } -/* ------------------------------------------------------------------------- */ -/* Style 3: Link error message routines */ -/* ------------------------------------------------------------------------- */ - -extern void link_error(char *s) -{ if (no_errors==MAX_ERRORS) fatalerror("Too many errors: giving up"); - errors[no_errors] = no_syntax_lines; - message(3,s); -} - -extern void link_error_named(char *s1, char *s2) -{ snprintf(error_message_buff, ERROR_BUFLEN,"%s \"%s\"",s1,s2); - ellipsize_error_message_buff(); - link_error(error_message_buff); -} - /* ------------------------------------------------------------------------- */ /* Style 4: Compiler error message routines */ /* ------------------------------------------------------------------------- */ @@ -397,19 +539,16 @@ extern void link_error_named(char *s1, char *s2) extern void print_sorry_message(void) { printf( "***********************************************************************\n\ -* 'Compiler errors' should never occur if Inform is working properly. *\n\ -* This is version %d.%02d of Inform, dated %20s: so *\n\ -* if that was more than six months ago, there may be a more recent *\n\ -* version available, from which the problem may have been removed. *\n\ -* If not, please report this fault to: graham@gnelson.demon.co.uk *\n\ -* and if at all possible, please include your source code, as faults *\n\ -* such as these are rare and often difficult to reproduce. Sorry. *\n\ -***********************************************************************\n", - (RELEASE_NUMBER/100)%10, RELEASE_NUMBER%100, RELEASE_DATE); +* 'Compiler errors' should never occur if Inform is working properly. *\n\ +* Check to see if there is a more recent version available, from which *\n\ +* the problem may have been removed. If not, please report this fault *\n\ +* and if at all possible, please include your source code, as faults *\n\ +* such as these are rare and often difficult to reproduce. Sorry. *\n\ +***********************************************************************\n"); } extern int compiler_error(char *s) -{ if (no_link_errors > 0) return FALSE; +{ if (no_errors > 0) return FALSE; if (no_compiler_errors==MAX_ERRORS) fatalerror("Too many compiler errors: giving up"); @@ -418,7 +557,7 @@ extern int compiler_error(char *s) } extern int compiler_error_named(char *s1, char *s2) -{ if (no_link_errors > 0) return FALSE; +{ if (no_errors > 0) return FALSE; snprintf(error_message_buff, ERROR_BUFLEN, "%s \"%s\"",s1,s2); ellipsize_error_message_buff(); @@ -496,7 +635,7 @@ extern void errors_begin_pass(void) } extern void errors_allocate_arrays(void) -{ forerrors_buff = my_malloc(512, "errors buffer"); +{ forerrors_buff = my_malloc(FORERRORS_SIZE, "errors buffer"); } extern void errors_free_arrays(void)