/* l2xierr.c LTX2X interpreter error handler */
/* Written by: Peter Wilson, CUA
[email protected] */
/* This code is partly based on algorithms presented by Ronald Mak in */
/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
#include <stdio.h>
#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 */
/***************************************************************************/