Lhogho
0.0.027
|
Defines | |
#define | FORMAT_ERR_CODE TEXT("{ERR#%d") |
#define | FORMAT_ERR_POS TEXT("@%d}") |
Functions | |
void | init_errors () |
initializes errors | |
void | finit_errors () |
finalizes errors | |
atom_t | new_error (uint_t code, atom_t data) |
creates a new error atom | |
atom_t | new_os_error (chars_t filename) |
creates error atom for OS error | |
atom_t | new_os_error_atom (atom_t filename) |
atom_t | new_parse_error (uint_t code, int position, atom_t source) |
creates error atom for parser's error | |
void | add_error_source (atom_t error, atom_t source) |
adds new error position to an error | |
int | get_error_position (atom_t data, chars_t *source) |
gets error position | |
void | delete_error (atom_t a) |
deletes error atom | |
void | dump_error (atom_t a, int level) |
dumps error atom | |
void | clear_all_errors () |
clears all errors | |
Variables | |
atom_t | error_texts [] |
Texts for error messages. | |
int | last_os_error |
records last OS error code | |
Exit codes | |
See Errors for details | |
#define | ERROR_INCOMPLETE_PAIR 1 |
#define | ERROR_EMPTY_EXPRESSION 2 |
#define | ERROR_CROWDED_EXPRESSION 3 |
#define | ERROR_MISSING_LEFTS 4 |
#define | ERROR_MISSING_RIGHTS 5 |
#define | ERROR_EMPTY_TO_END 6 |
#define | ERROR_MISSING_NAME 7 |
#define | ERROR_DUPLICATE_INPUT 8 |
#define | ERROR_UNKNOWN_OPTION 9 |
#define | ERROR_CROWDED_SOURCES 10 |
#define | ERROR_OS_ERROR 11 |
#define | ERROR_INCOMPATIBLE_REDEFINITION 12 |
#define | ERROR_NOT_A_NUMBER 13 |
#define | ERROR_UNUSED_VALUE 14 |
#define | ERROR_MISSING_VALUE 15 |
#define | ERROR_DO_NOT_KNOW 16 |
#define | ERROR_UNKNOWN_VAR 17 |
#define | ERROR_BOOLEAN_EXPECTED 18 |
#define | ERROR_NOT_AN_INTEGER 19 |
#define | ERROR_NOT_A_LIST 20 |
#define | ERROR_NOT_A_WORD 21 |
#define | ERROR_INCOMPATIBLE_DATA 22 |
#define | ERROR_TOO_BIG_NUMBER 23 |
#define | ERROR_TOO_SMALL_NUMBER 24 |
#define | ERROR_NOT_A_VAR 25 |
#define | EXIT_BY_BYE 26 |
#define | EXIT_BY_THROW_TOPLEVEL 27 |
#define | EXIT_BY_THROW_SYSTEM 28 |
#define | EXIT_BY_THROW_ERROR 29 |
#define | EXIT_BY_THROW_USER_ERROR 30 |
#define | EXIT_BY_THROW_TAG 31 |
#define | EXIT_BY_THROW_TAG_VALUE 32 |
#define | ERROR_NOT_A_TAG 33 |
#define | ERROR_NOT_A_USER_FUNCTION 34 |
#define | ERROR_VAR_HAS_NO_VALUE 35 |
#define | ERROR_NOT_A_FUNCTION 36 |
#define | ERROR_NOT_A_LIST_CONST 37 |
#define | ERROR_NOT_A_WORD_CONST 38 |
#define | ERROR_MISSING_FOR_LIMITS 39 |
#define | ERROR_NOT_A_TYPE_NAME 40 |
#define | ERROR_BAD_PROTOTYPE 41 |
#define | ERROR_NOT_A_MEM 42 |
#define | ERROR_OUT_OF_MEM 43 |
#define | ERROR_FILE_NOT_OPENED 44 |
#define | ERROR_NOT_BLOCK_OR_DEF 45 |
#define | FIRST_EXIT_CODE 26 |
first EXIT_ code | |
#define | LAST_EXIT_CODE 32 |
last EXIT_ code | |
#define | LAST_ERROR_CODE 45 |
last (max) error or exit code | |
Error fields | |
These macros are used to access errors. Error code is in | |
#define | ERRCODE(x) ((x)->unode.s[3]) |
#define | ERRPOS(x) ((x)->unode.a[2]) |
#define | ERRDATA(x) ((x)->unode.a[3]) |
#define | IS_ERROR(x) (ID(x)==ERROR_ID) |
#define ERROR_INCOMPLETE_PAIR 1 |
#define ERROR_EMPTY_EXPRESSION 2 |
#define ERROR_CROWDED_EXPRESSION 3 |
#define ERROR_MISSING_LEFTS 4 |
#define ERROR_MISSING_RIGHTS 5 |
#define ERROR_EMPTY_TO_END 6 |
#define ERROR_MISSING_NAME 7 |
#define ERROR_DUPLICATE_INPUT 8 |
#define ERROR_UNKNOWN_OPTION 9 |
#define ERROR_CROWDED_SOURCES 10 |
#define ERROR_OS_ERROR 11 |
#define ERROR_INCOMPATIBLE_REDEFINITION 12 |
#define ERROR_NOT_A_NUMBER 13 |
#define ERROR_UNUSED_VALUE 14 |
#define ERROR_MISSING_VALUE 15 |
#define ERROR_DO_NOT_KNOW 16 |
#define ERROR_UNKNOWN_VAR 17 |
#define ERROR_BOOLEAN_EXPECTED 18 |
#define ERROR_NOT_AN_INTEGER 19 |
#define ERROR_NOT_A_LIST 20 |
#define ERROR_NOT_A_WORD 21 |
#define ERROR_INCOMPATIBLE_DATA 22 |
#define ERROR_TOO_BIG_NUMBER 23 |
#define ERROR_TOO_SMALL_NUMBER 24 |
#define ERROR_NOT_A_VAR 25 |
#define EXIT_BY_BYE 26 |
#define EXIT_BY_THROW_TOPLEVEL 27 |
#define EXIT_BY_THROW_SYSTEM 28 |
#define EXIT_BY_THROW_ERROR 29 |
#define EXIT_BY_THROW_USER_ERROR 30 |
#define EXIT_BY_THROW_TAG 31 |
#define EXIT_BY_THROW_TAG_VALUE 32 |
#define ERROR_NOT_A_TAG 33 |
#define ERROR_NOT_A_USER_FUNCTION 34 |
#define ERROR_VAR_HAS_NO_VALUE 35 |
#define ERROR_NOT_A_FUNCTION 36 |
#define ERROR_NOT_A_LIST_CONST 37 |
#define ERROR_NOT_A_WORD_CONST 38 |
#define ERROR_MISSING_FOR_LIMITS 39 |
#define ERROR_NOT_A_TYPE_NAME 40 |
#define ERROR_BAD_PROTOTYPE 41 |
#define ERROR_NOT_A_MEM 42 |
#define ERROR_OUT_OF_MEM 43 |
#define ERROR_FILE_NOT_OPENED 44 |
#define ERROR_NOT_BLOCK_OR_DEF 45 |
#define FIRST_EXIT_CODE 26 |
#define LAST_EXIT_CODE 32 |
#define LAST_ERROR_CODE 45 |
#define ERRCODE | ( | x | ) | ((x)->unode.s[3]) |
#define ERRPOS | ( | x | ) | ((x)->unode.a[2]) |
#define ERRDATA | ( | x | ) | ((x)->unode.a[3]) |
#define FORMAT_ERR_CODE TEXT("{ERR#%d") |
#define FORMAT_ERR_POS TEXT("@%d}") |
void init_errors | ( | ) |
Initializes the table with error messages taken from TR_ERRORS.
{ error_texts[0] = unbound; atom_t names = new_word( TR_ERRORS, UNKNOWN ); atom_t tokens = tokenize( names, TOKENIZE_DATA ); atom_t t = tokens; // create error texts int i; for( i = 1; i<=LAST_ERROR_CODE; i++, t=CDR(t) ) { #ifdef SAFEMODE assert( IS_NOT_EMPTY(t) ); // too few words in TR_PRIMITIVES #endif error_texts[i] = USE(CAR(t)); } #ifdef SAFEMODE assert( IS_EMPTY(t) ); // too many words in TR_PRIMITIVES #endif DEUSE( names ); DEUSE( tokens ); }
void finit_errors | ( | ) |
Frees atoms holding error texts.
{ int i; for( i = 1; i<=LAST_ERROR_CODE; i++ ) { DEUSE(error_texts[i]); } }
code | error code |
data | error data |
Creates an error atom with reference count 1. The reference count of data
is increased. Initializes the error position to be a list containing one element, which is the data
parameter itself.
{ //printf("-----------\n"); //printf("new error code=%d\n",code); //printf("new error data="); dumpln(data); //printf("-----------\n"); atom_t a = take_from_pool( &data_pool ); #ifdef SAFEMODE assert( data ); #endif //SAFEMODE REF(a) = 1; ID(a) = ERROR_ID; ERRCODE(a) = code; ERRPOS(a) = new_list( USE(data), empty_list ); ERRDATA(a) = USE(data); #ifdef DEBUG_ATOM printf("<ATOM> [%08x] error=[code=%d]\n",(int)a,code); #endif //DEBUG_ATOM #ifdef ADVANCED stats[ID(a)].allocs++; if( stats[ID(a)].max<(stats[ID(a)].allocs-stats[ID(a)].deallocs) ) stats[ID(a)].max=(stats[ID(a)].allocs-stats[ID(a)].deallocs); stats_free--; #endif //ADVANCED #ifdef DEBUG_RUNTIME_ATOMS if( running_compiled_code ) { outter( TEXT("<RUNTIME> new "), -1 ); dump_atom_address( a ); dump_atom( a, 1 ); outter( TEXT("\n"), -1 ); } #endif #ifdef DEBUG_COMPILETIME_ATOMS if( compiling_code ) { outter( TEXT("<COMPILETIME> new "), -1 ); dump_atom_address( a ); dump_atom( a, 1 ); outter( TEXT("\n"), -1 ); } #endif if( all_errors==NULL ) all_errors = empty_list; all_errors = new_list( a, all_errors ); return a; }
atom_t new_os_error | ( | chars_t | filename | ) |
filename | file name associated with the error |
Creates error atom describing OS error.
{ atom_t wrd = new_word( filename, UNKNOWN ); new_os_error_atom( wrd ); return new_error( ERROR_OS_ERROR, wrd ); }
atom_t new_os_error_atom | ( | atom_t | filename | ) |
{ last_os_error = errno; return new_error( ERROR_OS_ERROR, filename ); }
atom_t new_parse_error | ( | uint_t | code, |
int | position, | ||
atom_t | source | ||
) |
code | error code |
position | character position within the source |
source | (sub)word containing the source |
Creates error atom describing an error generated by the parser.
void add_error_source | ( | atom_t | error, |
atom_t | source | ||
) |
error | error to which new position will be added |
source | error source |
Adds a new error position to an already existing error atom. The error position is simply an atom which may have been extracted from the actual source. The new error position is inserted in the first place of the list of error positions.
{ //printf("register error pos>>>---------------\n"); //printf("register error src>>>"); dumpln(source); //printf("register error err>>>"); dumpln(error); //printf("register error pos>>>---------------\n"); //printf("errpos old ref=%d\n",REF(ERRPOS(error))); ERRPOS(error) = new_list( USE(source), ERRPOS(error) ); //printf("errpos new ref=%d\n",REF(ERRPOS(error))); }
int get_error_position | ( | atom_t | data, |
chars_t * | source | ||
) |
data | data to search for |
source | source where the data is found |
Tries to identify the position of the first (sub)word in the data in the original source. This function returns the character position and the source. If the source cannot be identified, then return -1 and set source
to NULL.
{ // dig in a list to find the first (sub)word while( IS_LIST(data) & IS_NOT_EMPTY(data) ) data = CAR(data); // if it is a word then return we have found something if( IS_WORD(data) ) { *source = STRING(data); return 0; } // if it is a subword then return we have found something if( IS_SUBWORD(data) ) { *source = STRING(WORD(data)); return STRING(data)-STRING(WORD(data)); } // no, could not find the error position *source = NULL; return -1; }
void delete_error | ( | atom_t | a | ) |
void dump_error | ( | atom_t | a, |
int | level | ||
) |
a | atom to dump |
level | dump level |
Dumps error atom through the current outter function.
{ #define DUMP_BUF_SIZE 128 char_t buf[DUMP_BUF_SIZE]; int n; //printf("<<err ref=%d>> ",REF(a)); //printf("temporary dump of an error\n"); //printf(">>>>>>error ref = %d\n",REF(a)); //printf(">>>>>>error code = %d\n",ERRCODE(a)); //printf(">>>>>>error posn = "); dumpln(ERRPOS(a)); //printf(">>>>>>error data = "); dumpln(ERRDATA(a)); //return; int errpos = -1; int errpos2 = -1; int errpos3 = -1; chars_t errsrc = NULL; chars_t errsrc2 = NULL; chars_t errsrc3 = NULL; atom_t p; //printf("errpos="); dump_atom(ERRPOS(a),1); printf("\n------------\n"); for( p=ERRPOS(a); IS_NOT_EMPTY(p); p=CDR(p) ) { //printf("ERRPOS=");dumpln(CAR(p)); chars_t src; int pos = get_error_position( CAR(p), &src ); if( pos>-1 ) { errpos3 = errpos2; errsrc3 = errsrc2; errpos2 = errpos; errsrc2 = errsrc; errpos = pos; errsrc = src; } //printf("pos=%d source=",pos); dumpln(CAR(p)); } if( ERRCODE(a)==EXIT_BY_THROW_USER_ERROR ) { errpos = errpos3; errsrc = errsrc3; } // print error code n = SPRINTF( buf, DUMP_BUF_SIZE, FORMAT_ERR_CODE, ERRCODE(a) ); outter( buf, n ); // print error position n = SPRINTF( buf, DUMP_BUF_SIZE, FORMAT_ERR_POS, errpos ); outter( buf, n ); // print error message if( ERRCODE(a)==EXIT_BY_THROW_USER_ERROR ) { outter( TEXT(" - "), 3 ); dump( ERRDATA(a) ); } else { #ifdef SAFEMODE assert( ERRCODE(a)>0 ); assert( ERRCODE(a)<=LAST_ERROR_CODE ); #endif outter( TEXT(" - "), 3 ); dump( error_texts[ERRCODE(a)] ); } if( ERRCODE(a)==ERROR_OS_ERROR ) { chars_t msg = UNFILENAME(strerror(last_os_error)); outter( TEXT(": "), 2 ); outter( msg, -1 ); DEALLOC( msg ); } outter( TEXT("\n"), -1 ); // print error source dump_neighbourhood( errsrc, errpos ); }
void clear_all_errors | ( | ) |
Clears all errors recorder in all_errors except for the one stored in last_error
{ atom_t err = all_errors; if( err==NULL ) return; //printf("===INSIDE CLEAR_ALL_ERRORS===\n"); //printf("===EXCEPTION(%d): ",REF(last_error)); dumpln(last_error); //printf("===ALL ERRORS (BEFORE): "); dumpln(all_errors); //printf("===START ERROR SCANNING===\n"); while( IS_NOT_EMPTY(err) ) { //printf("===ERROR: [%x]\n",CAR(err)); if( CAR(err)!=last_error ) REF(CAR(err)) = 1; err = CDR(err); } //printf("===END ERROR SCANNING===\n"); USE( last_error ); //printf("AEREF=%d !!!!!!!!!!!!!!!!\n",REF(all_errors)); DEUSE( all_errors ); //printf("AEREF=%d !!!!!!!!!!!!!!!!\n",REF(all_errors)); DEUSE( last_error ); all_errors = empty_list; //printf("===END OF CLEAR_ALL_ERRORS===\n\n"); }
int last_os_error |