/* l2xierr.c LTX2X interpreter error handler */ /* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */ /* This code is partly based on algorithms presented by Ronald Mak in */ /* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */ #include #include "l2xicmon.h" #include "l2xierr.h" /* externals */ extern char *tokenp; extern BOOLEAN print_flag; extern char source_buffer[]; extern char *bufferp; /* error messages: keyed to enum types in error.h from l2xiertc.h */ char *error_messages[] = { #define petc(a, b) b, #define pwtc(a, b) #define rtetc(a, b) #define rtwtc(a, b) #include "l2xiertc.h" #undef petc #undef pwtc #undef rtetc #undef rtwtc }; char *warning_messages[] = { #define petc(a, b) #define pwtc(a, b) b, #define rtetc(a, b) #define rtwtc(a, b) #include "l2xiertc.h" #undef petc #undef pwtc #undef rtetc #undef rtwtc }; char *runtime_error_messages[] = { #define petc(a, b) #define pwtc(a, b) #define rtetc(a, b) b, #define rtwtc(a, b) #include "l2xiertc.h" #undef petc #undef pwtc #undef rtetc #undef rtwtc }; char *runtime_warning_messages[] = { #define petc(a, b) #define pwtc(a, b) #define rtetc(a, b) #define rtwtc(a, b) b, #include "l2xiertc.h" #undef petc #undef pwtc #undef rtetc #undef rtwtc }; /* stack types */ typedef enum { #define fotc(a, b, c, d) #define sotc(a, b, c, d) a, #define sftc(a, b, c, d) a, #include "l2xisftc.h" #undef fotc #undef sotc #undef sftc } STACK_TYPE; /* LOCALS */ #define EOS '\0' /* GLOBALS */ int isynt_error_count = 0; /* number of syntax errors */ int isynt_warn_count = 0; /* number of syntax warnings */ int irun_error_count = 0; /* number of runtime errors */ int irun_warn_count = 0; /* number of runtime warnings */ char message_buffer[MAX_PRINT_LINE_LENGTH]; /***************************************************************************/ /* error(code) Print an arrow under the error, then the error message */ error(code) ERROR_CODE code; /* error code */ { extern int buffer_offset; char *message = error_messages[code]; int offset = buffer_offset - 2; ++isynt_error_count; /* print the arrow pointing to just scanned token */ if (print_flag) offset += 8; sprintf(message_buffer, "%*s^\n", offset, " "); if (print_flag) { print_line(message_buffer); } else { print_error(message_buffer); } /* print the error message */ sprintf(message_buffer, " ***ERROR: %s.\n", message); if (print_flag) { print_line(message_buffer); } else { print_error(message_buffer); } *tokenp = EOS; if (isynt_error_count > MAX_SYNTAX_ERRORS) { sprintf(message_buffer, "Too many syntax errors.\n"); if (print_flag) { print_line(message_buffer); } else { print_error(message_buffer); } exit(-TOO_MANY_SYNTAX_ERRORS); } } /* end error */ /***************************************************************************/ /***************************************************************************/ /* compile_warning(code) Print an arrow under the error, then the */ /* warning message */ compile_warning(code) WARNING_CODE code; /* warning code */ { extern int buffer_offset; char *message = warning_messages[code]; int offset = buffer_offset - 2; ++isynt_warn_count; /* print the arrow pointing to just scanned token */ if (print_flag) offset += 8; sprintf(message_buffer, "%*s^\n", offset, " "); if (print_flag) { print_line(message_buffer); } else { print_error(message_buffer); } /* print the warning message */ sprintf(message_buffer, " ***WARNING: %s.\n", message); if (print_flag) { print_line(message_buffer); } else { print_error(message_buffer); } *tokenp = EOS; } /* end warning */ /***************************************************************************/ /***************************************************************************/ /* runtime_error(code) Print a runtime error message and then debug */ runtime_error(code) RUNTIME_ERROR_CODE code; /* error code */ { extern int exec_line_number; extern long exec_stmt_count; char *message = runtime_error_messages[code]; extern BOOLEAN debugger_command_flag; ++irun_error_count; if (SLD_OFF) { /* source level debugger disabled -- abort */ sprintf(message_buffer, "\n*** RUNTIME ERROR in line %d: %s\n", exec_line_number, message); print_error(message_buffer); sprintf(message_buffer, "\nUnsuccessful completion. %ld statements executed.\n\n", exec_stmt_count); print_error(message_buffer); exit(-code); } if (debugger_command_flag) { print_error(message); print_error("\n"); } else { sprintf(message_buffer, "\n*** RUNTIME ERROR in line %d: %s\n", exec_line_number, message); print_error(message_buffer); read_debugger_command(); } } /* end runtime_error */ /***************************************************************************/ /***************************************************************************/ /* runtime_warning(code) Print a runtime warning message and then debug */ runtime_warning(code) RUNTIME_WARNING_CODE code; /* warning code */ { extern int exec_line_number; extern long exec_stmt_count; char *message = runtime_warning_messages[code]; extern BOOLEAN debugger_command_flag; if (INVALID_STACK_ACCESS == code) return; ++irun_warn_count; if (SLD_OFF) { /* source level debugger disabled */ sprintf(message_buffer, "\n*** RUNTIME WARNING in line %d: %s\n", exec_line_number, message); print_error(message_buffer); return; } if (debugger_command_flag) { print_error(message); print_error("\n"); } else { sprintf(message_buffer, "\n*** RUNTIME WARNING in line %d: %s\n", exec_line_number, message); print_error(message_buffer); read_debugger_command(); } return; } /* end runtime_warning */ /***************************************************************************/ /***************************************************************************/ /* stack_warning(etype, ftype) Print a runtime warning message about */ /* stack access and then debug */ stack_warning(etype, ftype) STACK_TYPE etype; /* expected type */ STACK_TYPE ftype; /* type actually found */ { extern int exec_line_number; extern long exec_stmt_count; RUNTIME_WARNING_CODE code1, code2; extern BOOLEAN debugger_command_flag; code1 = RUNTIME_WARN; switch (etype) { /* report the expected type */ case STKINT: case STKREA: { code1 = EXPECTED_NUMBER; break; } case STKLOG: { code1 = EXPECTED_LOGICAL; break; } case STKADD: { code1 = EXPECTED_ADDRESS; break; } case STKARY: { code1 = EXPECTED_ARRAY; break; } case STKBAG: { code1 = EXPECTED_BAG; break; } case STKLST: { code1 = EXPECTED_LIST; break; } case STKSET: { code1 = EXPECTED_SET; break; } case STKSTR: { code1 = EXPECTED_STRING; break; } case STKENT: { code1 = EXPECTED_ENTITY; break; } case STKUDF: { code1 = EXPECTED_UDF; break; } } /* finished expected type */ code2 = RUNTIME_WARN; switch (ftype) { /* report the found type */ case STKINT: case STKREA: { code2 = FOUND_NUMBER; break; } case STKLOG: { code2 = FOUND_LOGICAL; break; } case STKADD: { code2 = FOUND_ADDRESS; break; } case STKARY: { code2 = FOUND_ARRAY; break; } case STKBAG: { code2 = FOUND_BAG; break; } case STKLST: { code2 = FOUND_LIST; break; } case STKSET: { code2 = FOUND_SET; break; } case STKSTR: { code2 = FOUND_STRING; break; } case STKENT: { code2 = FOUND_ENTITY; break; } case STKUDF: { code2 = FOUND_UDF; break; } } /* finished found type */ if (SLD_OFF) { /* source level debugger disabled */ sprintf(message_buffer, "\n*** RUNTIME WARNING in line %d:\n %s\n %s\n", exec_line_number, runtime_warning_messages[code1], runtime_warning_messages[code2]); print_error(message_buffer); return; } if (debugger_command_flag) { sprintf(message_buffer, "\n %s\n %s\n", runtime_warning_messages[code1], runtime_warning_messages[code2]); print_error(message_buffer); } else { sprintf(message_buffer, "\n*** RUNTIME WARNING in line %d:\n %s\n %s\n", exec_line_number, runtime_warning_messages[code1], runtime_warning_messages[code2]); print_error(message_buffer); read_debugger_command(); } return; } /* end STACK_WARNING */ /***************************************************************************/ /***************************************************************************/ /* print_error(string) Prints to error file(s) */ print_error(string) char string[]; { fprintf(ferr, "%s", string); fflush(ferr); fprintf(stderr, "%s", string); fflush(stderr); if (filout != stdout) { fprintf(filout, "%s", string); fflush(filout); } return; } /* end print_error */ /***************************************************************************/