/* Last edited: Nov 8 13:51 1996 (birney) */ %{ #include "wisebase.h" typedef int Flag; #define MAXERROR 256 #define MAXERRORCALL 32 #define MAXMSGSTACKERROR 64 /* flags on errors */ #define ERRORUSE 1 #define ERRORTOSTDERR 2 #define ERRORTOLOG 4 #define ERRORTOCALL 8 #define LONGERROR 16 /* not used */ /* types of error */ #define FATAL 1 #define WARNING 2 #define PEDANTIC 4 /* deprecated */ #define INFO 8 #define REPORT 16 #define erroroff(type) error_flag_off(type,ERRORUSE) #define erroron(type) error_flag_on (type,ERRORUSE) #define errorcallon(type) error_flag_on (type,ERRORTOCALL) #define errorcalloff(type) error_flag_off(type,ERRORTOCALL) #define errorstderron(type) error_flag_on (type,ERRORTOSTDERR) #define errorstderroff(type) error_flag_off(type,ERRORTOSTDERR) #define errorlogon(type) error_flag_on (type,ERRORTOLOG) #define errorlogoff(type) error_flag_off(type,ERRORTOLOG) %} api func catch_errors func stop_catching_errors func warn func info func fatal endapi %{ #include "wiseerror.h" static Flag fatal_flag = 3; static Flag warning_flag = 3; static Flag info_flag = 3; static Flag report_flag = 3; #define flag_of_type(c) (c == FATAL ? fatal_flag : c == WARNING ? warning_flag :c == INFO ? info_flag : report_flag ) static int eventc=0; static FILE * errlog=NULL; static void (*error_call)(char *,int)= NULL; static char * error_msg_stack[MAXMSGSTACKERROR]; static char * (*((error_msg_call)[MAXMSGSTACKERROR]))(void); static int msg_stack_no=0; %func This adds a function onto the error message stack for stacking errors. this is for decent parsers etc for allowing 'error scope' to be propagated down. It is very very bad form to push an errormsg stack and not pop it at the end. %type internal %% boolean push_errormsg_stack(char * msg, ...) { char buffer[1024]; va_list ap; va_start(ap,msg); vsprintf(buffer,msg,ap); if( msg_stack_no >= MAXMSGSTACKERROR ) { warn("Too many messages held on stack, [%s] discarded\n",buffer); /*** still should up the number ***/ msg_stack_no++; return FALSE; } error_msg_call[msg_stack_no] = NULL; error_msg_stack[msg_stack_no++] = stringalloc(buffer); return TRUE; } %func This adds a function call for people who want to register error handling functions Probably best wrapped by a separate function %% boolean push_errormsg_stack_call( char * (*ecall)(void)) { if( msg_stack_no >= MAXMSGSTACKERROR ) { warn("Too many messages held on stack, Error message call discarded\n"); /*** still should up the number ***/ msg_stack_no++; return FALSE; } error_msg_call[msg_stack_no] = ecall; error_msg_stack[msg_stack_no++] = NULL; return TRUE; } %func This removes a error message from the stack %% void pop_errormsg_stack(void) { if( msg_stack_no < MAXMSGSTACKERROR && msg_stack_no > 0 && error_msg_stack[msg_stack_no-1] != NULL) ckfree(error_msg_stack[msg_stack_no-1]); if( msg_stack_no > 0) msg_stack_no--; } %func This shows the error message set to everyone %type internal %% void show_message_stack(FILE * ofp) { register int i; register int j; register int count; for(i=0;i 0 ) show_message_stack(stderr); fputs("\t",stderr); if( type == FATAL ) fputs(othermsg,stderr); else show_text(othermsg,70,stderr); } if( flag&ERRORTOLOG && errlog != NULL) { fputs(type_to_error(type),errlog); fputc('\n',stderr); if( msg_stack_no > 0 ) show_message_stack(errlog); fputs("\n\t",errlog); show_text(othermsg,70,errlog); } if( flag&ERRORTOCALL && error_call != NULL) { (*(error_call))(othermsg,type); } return; } %}