cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
24ddc71998-03-28Henrik Grubbström (Grubba)  /*
5196c51998-07-16Fredrik Hübinette (Hubbe)  * $Id: error.h,v 1.23 1998/07/16 23:09:39 hubbe Exp $
24ddc71998-03-28Henrik Grubbström (Grubba)  */
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifndef ERROR_H #define ERROR_H
2d31fb1996-08-12Fredrik Hübinette (Hubbe) #include "machine.h" #ifdef HAVE_SETJMP_H
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <setjmp.h>
2d31fb1996-08-12Fredrik Hübinette (Hubbe) #undef HAVE_SETJMP_H #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <stdarg.h>
2d31fb1996-08-12Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "svalue.h"
cb22561995-10-11Fredrik Hübinette (Hubbe) typedef void (*error_call)(void *);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #ifndef STRUCT_FRAME_DECLARED #define STRUCT_FRAME_DECLARED
5267b71995-08-09Fredrik Hübinette (Hubbe) struct frame;
dfa5b31996-12-05Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
24dd881998-01-27Fredrik Hübinette (Hubbe) #define THROW_ERROR 10 #define THROW_THREAD_EXIT 20 #define THROW_THREAD_KILLED 30 #define THROW_EXIT 40 #define THROW_MAX_SEVERITY 100
61e9a01998-01-25Fredrik Hübinette (Hubbe) 
8e8b9f1998-07-17Henrik Grubbström (Grubba) #ifdef ONERROR_DEBUG #define OED_FPRINTF(X) fprintf X #else /* !ONERROR_DEBUG */ #define OED_FPRINTF(X) #endif /* ONERROR_DEBUG */
cb22561995-10-11Fredrik Hübinette (Hubbe) typedef struct ONERROR { struct ONERROR *previous;
0abfe01998-07-13Henrik Grubbström (Grubba) #ifdef DEBUG const char *file; int line; #endif /* DEBUG */
cb22561995-10-11Fredrik Hübinette (Hubbe)  error_call func; void *arg; } ONERROR;
5267b71995-08-09Fredrik Hübinette (Hubbe) typedef struct JMP_BUF {
5196c51998-07-16Fredrik Hübinette (Hubbe) #ifdef DEBUG int line; char *file; #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct JMP_BUF *previous;
e9f9141996-09-29Fredrik Hübinette (Hubbe)  jmp_buf recovery;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct frame *fp;
f0cd981996-06-21Fredrik Hübinette (Hubbe)  INT32 sp; INT32 mark_sp;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  INT32 severity;
cb22561995-10-11Fredrik Hübinette (Hubbe)  ONERROR *onerror;
5267b71995-08-09Fredrik Hübinette (Hubbe) } JMP_BUF; extern JMP_BUF *recoveries; extern struct svalue throw_value;
61e9a01998-01-25Fredrik Hübinette (Hubbe) extern int throw_severity;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5196c51998-07-16Fredrik Hübinette (Hubbe) #ifdef DEBUG #define UNSETJMP(X) do{ \ if(recoveries != &X) { \ if(recoveries) \ fatal("UNSETJMP out of sync! (last SETJMP at %s:%d)!\n",recoveries->file,recoveries->line); \ else \ fatal("UNSETJMP out of sync! (recoveries = 0)\n"); \ } \ recoveries=X.previous; \ }while (0) #define DEBUG_LINE_ARGS ,int line, char *file #define SETJMP(X) setjmp((init_recovery(&X,__LINE__,__FILE__)->recovery)) #else #define DEBUG_LINE_ARGS
e9f9141996-09-29Fredrik Hübinette (Hubbe) #define SETJMP(X) setjmp((init_recovery(&X)->recovery))
5267b71995-08-09Fredrik Hübinette (Hubbe) #define UNSETJMP(X) recoveries=X.previous;
5196c51998-07-16Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
0abfe01998-07-13Henrik Grubbström (Grubba) #ifdef DEBUG
cb22561995-10-11Fredrik Hübinette (Hubbe) #define SET_ONERROR(X,Y,Z) \ do{ \
8e8b9f1998-07-17Henrik Grubbström (Grubba)  OED_FPRINTF((stderr, "SET_ONERROR(%p, %p, %p) %s:%d\n", \ &(X), (Y), (Z), __FILE__, __LINE__)); \
3c0c281998-01-26Fredrik Hübinette (Hubbe)  if(!recoveries) break; \
cb22561995-10-11Fredrik Hübinette (Hubbe)  X.func=(error_call)(Y); \ X.arg=(void *)(Z); \
07513e1996-10-04Fredrik Hübinette (Hubbe)  X.previous=recoveries->onerror; \
0abfe01998-07-13Henrik Grubbström (Grubba)  X.file = __FILE__; \ X.line = __LINE__; \
07513e1996-10-04Fredrik Hübinette (Hubbe)  recoveries->onerror=&X; \
cb22561995-10-11Fredrik Hübinette (Hubbe)  }while(0)
9dd1f91997-10-07Fredrik Hübinette (Hubbe) #define UNSET_ONERROR(X) do {\
8e8b9f1998-07-17Henrik Grubbström (Grubba)  OED_FPRINTF((stderr, "UNSET_ONERROR(%p) %s:%d\n", \ &(X), __FILE__, __LINE__)); \
0abfe01998-07-13Henrik Grubbström (Grubba)  if(!recoveries) break; \ if(recoveries->onerror != &(X)) { \
5196c51998-07-16Fredrik Hübinette (Hubbe)  fprintf(stderr,"LAST SETJMP: %s:%d\n",recoveries->file,recoveries->line); \
0abfe01998-07-13Henrik Grubbström (Grubba)  if (recoveries->onerror) { \ fatal("UNSET_ONERROR out of sync.\n" \ "Last SET_ONERROR is from %s:%d\n", \ recoveries->onerror->file, recoveries->onerror->line ); \ } else { \
9435371998-07-16Henrik Grubbström (Grubba)  fatal("UNSET_ONERROR out of sync. No recoveries left.\n"); \
0abfe01998-07-13Henrik Grubbström (Grubba)  } \ } \ recoveries->onerror=(X).previous; \
9dd1f91997-10-07Fredrik Hübinette (Hubbe)  } while(0) #else
0abfe01998-07-13Henrik Grubbström (Grubba) #define SET_ONERROR(X,Y,Z) \ do{ \ if(!recoveries) break; \ X.func=(error_call)(Y); \ X.arg=(void *)(Z); \ X.previous=recoveries->onerror; \ recoveries->onerror=&X; \ }while(0)
eb8c3e1998-02-24Fredrik Hübinette (Hubbe) #define UNSET_ONERROR(X) recoveries && (recoveries->onerror=X.previous)
9dd1f91997-10-07Fredrik Hübinette (Hubbe) #endif
cb22561995-10-11Fredrik Hübinette (Hubbe) 
d8d2521998-04-11Henrik Grubbström (Grubba) #if defined(DEBUG) && 0 /* Works, but probably not interresting for most people * /grubba 1998-04-11 */
aa366d1998-04-16Fredrik Hübinette (Hubbe) #define PIKE_ERROR(NAME, TEXT, SP, ARGS) new_error(NAME, TEXT, SP, ARGS, __FILE__, __LINE__);
0ca9f41998-04-10Henrik Grubbström (Grubba) #else
aa366d1998-04-16Fredrik Hübinette (Hubbe) #define PIKE_ERROR(NAME, TEXT, SP, ARGS) new_error(NAME, TEXT, SP, ARGS, NULL, 0);
0ca9f41998-04-10Henrik Grubbström (Grubba) #endif /* DEBUG */
e9f9141996-09-29Fredrik Hübinette (Hubbe) /* Prototypes begin here */
5196c51998-07-16Fredrik Hübinette (Hubbe) JMP_BUF *init_recovery(JMP_BUF *r DEBUG_LINE_ARGS);
dc7cc91998-01-14Fredrik Hübinette (Hubbe) void pike_throw(void) ATTRIBUTE((noreturn));
4406cf1998-04-13Henrik Grubbström (Grubba) void va_error(const char *fmt, va_list args) ATTRIBUTE((noreturn));
dceabb1996-10-09Fredrik Hübinette (Hubbe) void exit_on_error(void *msg); void fatal_on_error(void *msg);
4406cf1998-04-13Henrik Grubbström (Grubba) void error(const char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2))); void new_error(const char *name, const char *text, struct svalue *oldsp, INT32 args, const char *file, int line) ATTRIBUTE((noreturn)); void debug_fatal(const char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)));
e9f9141996-09-29Fredrik Hübinette (Hubbe) /* Prototypes end here */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5a7ab61998-01-31Fredrik Hübinette (Hubbe) #define fatal \ fprintf(stderr,"Fatal error at %s:%d\n",__FILE__,__LINE__),debug_fatal
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif