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. \*/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "error.h" #include "interpret.h" #include "stralloc.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "builtin_functions.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "array.h" #include "object.h"
e9f9141996-09-29Fredrik Hübinette (Hubbe) #undef ATTRIBUTE #define ATTRIBUTE(X)
cb22561995-10-11Fredrik Hübinette (Hubbe) JMP_BUF *recoveries=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e9f9141996-09-29Fredrik Hübinette (Hubbe) JMP_BUF *init_recovery(JMP_BUF *r)
5267b71995-08-09Fredrik Hübinette (Hubbe) { r->fp=fp;
f0cd981996-06-21Fredrik Hübinette (Hubbe)  r->sp=sp-evaluator_stack; r->mark_sp=mark_sp - mark_stack;
5267b71995-08-09Fredrik Hübinette (Hubbe)  r->previous=recoveries;
07513e1996-10-04Fredrik Hübinette (Hubbe)  r->onerror=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  recoveries=r;
e9f9141996-09-29Fredrik Hübinette (Hubbe)  return r;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
e9f9141996-09-29Fredrik Hübinette (Hubbe) void throw() ATTRIBUTE((noreturn))
5267b71995-08-09Fredrik Hübinette (Hubbe) { if(!recoveries) fatal("No error recovery context.\n"); #ifdef DEBUG
f0cd981996-06-21Fredrik Hübinette (Hubbe)  if(sp - evaluator_stack < recoveries->sp)
5267b71995-08-09Fredrik Hübinette (Hubbe)  fatal("Error in error.\n"); #endif while(fp != recoveries->fp) { #ifdef DEBUG if(!fp) fatal("Popped out of stack frames.\n"); #endif free_object(fp->current_object); free_program(fp->context.prog); fp = fp->parent_frame; }
f0cd981996-06-21Fredrik Hübinette (Hubbe)  pop_n_elems(sp - evaluator_stack - recoveries->sp); mark_sp = mark_stack + recoveries->mark_sp;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
07513e1996-10-04Fredrik Hübinette (Hubbe)  while(recoveries->onerror)
cb22561995-10-11Fredrik Hübinette (Hubbe)  {
07513e1996-10-04Fredrik Hübinette (Hubbe)  (*recoveries->onerror->func)(recoveries->onerror->arg); recoveries->onerror=recoveries->onerror->previous;
cb22561995-10-11Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  longjmp(recoveries->recovery,1); } struct svalue throw_value = { T_INT };
e9f9141996-09-29Fredrik Hübinette (Hubbe) void va_error(char *fmt, va_list args) ATTRIBUTE((noreturn))
5267b71995-08-09Fredrik Hübinette (Hubbe) { char buf[2000];
5fe7a71995-11-06Fredrik Hübinette (Hubbe)  static char *in_error;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(in_error) {
5fe7a71995-11-06Fredrik Hübinette (Hubbe)  char *tmp=in_error;
5267b71995-08-09Fredrik Hübinette (Hubbe)  in_error=0;
5fe7a71995-11-06Fredrik Hübinette (Hubbe)  fatal("Recursive error() calls, original error: %s",tmp);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5fe7a71995-11-06Fredrik Hübinette (Hubbe)  in_error=buf;
5267b71995-08-09Fredrik Hübinette (Hubbe)  VSPRINTF(buf, fmt, args);
dceabb1996-10-09Fredrik Hübinette (Hubbe)  if(!recoveries)
06983f1996-09-22Fredrik Hübinette (Hubbe)  { #ifdef DEBUG dump_backlog(); #endif
dceabb1996-10-09Fredrik Hübinette (Hubbe)  fprintf(stderr,"No error recovery context!\n%s",buf);
06983f1996-09-22Fredrik Hübinette (Hubbe)  exit(99); }
6b92161996-05-16Fredrik Hübinette (Hubbe)  if((long)strlen(buf) >= (long)sizeof(buf))
5267b71995-08-09Fredrik Hübinette (Hubbe)  fatal("Buffer overflow in error()\n"); push_string(make_shared_string(buf)); f_backtrace(0); f_aggregate(2); free_svalue(& throw_value); sp--; throw_value = *sp; in_error=0; throw(); /* Hope someone is catching, or we will be out of balls. */ }
dceabb1996-10-09Fredrik Hübinette (Hubbe) void exit_on_error(void *msg) { #ifdef DEBUG dump_backlog(); #endif fprintf(stderr,"%s\n",(char *)msg); exit(1); } void fatal_on_error(void *msg) { #ifdef DEBUG dump_backlog(); #endif fprintf(stderr,"%s\n",(char *)msg); abort(); }
e9f9141996-09-29Fredrik Hübinette (Hubbe) void error(char *fmt,...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
5267b71995-08-09Fredrik Hübinette (Hubbe) { va_list args; va_start(args,fmt); va_error(fmt,args); va_end(args); }
e9f9141996-09-29Fredrik Hübinette (Hubbe) void fatal(char *fmt, ...) ATTRIBUTE((noreturn,format (printf, 1, 2)))
5267b71995-08-09Fredrik Hübinette (Hubbe) { va_list args; static int in_fatal = 0; va_start(args,fmt); /* Prevent double fatal. */ if (in_fatal) { (void)VFPRINTF(stderr, fmt, args); abort(); } in_fatal = 1; #ifdef DEBUG dump_backlog(); #endif (void)VFPRINTF(stderr, fmt, args); /* Insert dump routine call here */ fflush(stderr); abort(); }