Lhogho
0.0.027
|
Defines | |
#define | LEFT_DIST 10 |
#define | RIGHT_DIST 40 |
#define | DUMP_BUF_SIZE 128 |
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 | |
void | delete_error (atom_t a) |
deletes error atom | |
int | get_error_position (atom_t data, chars_t *source) |
gets error position | |
void | dump_neighbourhood (chars_t source, int position) |
dumps source around some position | |
void | dump_error (atom_t a, int level) |
dumps error atom | |
void | clear_all_errors () |
clears all errors | |
Variables | |
atom_t | error_texts [LAST_ERROR_CODE+1] |
Texts for error messages. | |
int | last_os_error |
records last OS error code | |
atom_t | all_errors = NULL |
list of all occurred errors |
#define LEFT_DIST 10 |
#define RIGHT_DIST 40 |
#define DUMP_BUF_SIZE 128 |
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))); }
void delete_error | ( | atom_t | a | ) |
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 dump_neighbourhood | ( | chars_t | source, |
int | position | ||
) |
source | source containing the neighbourhood |
position | position marking the neighbourhood |
Dumps a piece of source code containing given position. The dumped neighbourhood starts before the position and end after it in a way that: (1) at most LEFT_DIST chars before the position are included (2) at most RIGHT_DIST chars after the position are included (3) the neightbourhood contains characters from a single line only Dumped neighbourhood is output as a single line with an arrow anove it pointing the exact position.
{ if( !source || position<0 ) return; int left; int right; int ellipses = 1; for( left=0; left<LEFT_DIST; left++ ) { // reached the beginning of the source? if( position-left == 0 ) {ellipses=0; break;} // reached the beginning of the line? char_t ch = *(source+(position-left-1)); if( ch==TEXT('\n') || ch==TEXT('\r') ) {ellipses=0; break;} } while( left && ((*(source+position-left))<=TEXT(' ')) ) left--; for( right=0; right<RIGHT_DIST; right++ ) { // reached the end of the line/file? char_t ch = *(source+(position+right+1)); if( ch=='\n' || ch=='\r' || ch=='\0') break; } int i; chars_t s; if( ellipses ) outter( TEXT("..."), 3 ); for( i=0,s=source+position-left; i<left+right+1; i++,s++ ) outter( s, 1 ); if( *(source+position+right+1)>=TEXT(' ') ) outter( TEXT("..."), 3 ); outter( TEXT("\n"), -1 ); for( i=0; i<left+3*ellipses; i++ ) outter( TEXT(" "), 1 ); outter( TEXT("^"), -1 ); }
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 |
atom_t all_errors = NULL |