diff --git a/lib/master.pike.in b/lib/master.pike.in
index 050db31fcc830e2e67a2472df7f8e481f8f968fd..5d1b5c3c17f8efec5e02c960875fce88b1728560 100644
--- a/lib/master.pike.in
+++ b/lib/master.pike.in
@@ -1,4 +1,4 @@
-/* $Id: master.pike.in,v 1.65 1999/11/03 23:52:07 grubba Exp $
+/* $Id: master.pike.in,v 1.66 1999/11/04 02:35:31 grubba Exp $
  * 
  * Master-file for Pike.
  *
@@ -234,7 +234,7 @@ mapping (string:program) programs=(["/master":object_program(this_object())]);
 
 #define capitalize(X) (upper_case((X)[..0])+(X)[1..])
 
-static program low_findprog(string pname, string ext)
+static program low_findprog(string pname, string ext, object|void handler)
 {
   program ret;
   array s;
@@ -262,11 +262,17 @@ static program low_findprog(string pname, string ext)
             AUTORELOAD_CHECK_FILE(fname+".o");
 	    return programs[fname]=decode_value(_static_modules.files()->Fd(fname+".o","r")->read(),Codec());
 	  };
-	  if(want_warnings)
-	    werror("Warning: Failed to decode %s.o:\n"
-		   "       : \t%s\n",
-		   fname,
-		   err[0]);
+	  if(want_warnings) {
+	    if (handler) {
+	      handler->compile_warning(fname, 0,
+				       sprintf("Decode failed:\n"
+					       "\t%s", err[0]));
+	    } else {
+	      compile_warning(fname, 0,
+			      sprintf("Decode failed:\n"
+				      "\t%s", err[0]));
+	    }
+	  }
 	}
       }
       
@@ -299,20 +305,20 @@ static program low_findprog(string pname, string ext)
   }
 }
 
-static program findprog(string pname, string ext)
+static program findprog(string pname, string ext, object|void handler)
 {
   switch(ext)
   {
   case ".pike":
   case ".so":
-    return low_findprog(pname,ext);
+    return low_findprog(pname,ext,handler);
 
   default:
     pname+=ext;
     return
-      low_findprog(pname,"") ||
-      low_findprog(pname,".pike") ||
-      low_findprog(pname,".so");
+      low_findprog(pname,"", handler) ||
+      low_findprog(pname,".pike", handler) ||
+      low_findprog(pname,".so", handler);
   }
 }
 
@@ -321,7 +327,7 @@ static program findprog(string pname, string ext)
  * or a implict cast. In the future it might receive more arguments,
  * to aid the master finding the right program.
  */
-program cast_to_program(string pname, string current_file)
+program cast_to_program(string pname, string current_file, object|void handler)
 {
   string ext;
   string nname;
@@ -338,7 +344,7 @@ program cast_to_program(string pname, string current_file)
   if(IS_ABSOLUTE_PATH(pname))
   {
     pname=combine_path("/",pname);
-    return findprog(pname,ext);
+    return findprog(pname,ext,handler);
   }else{
     string cwd;
     if(current_file)
@@ -348,11 +354,11 @@ program cast_to_program(string pname, string current_file)
       cwd=getcwd();
     }
 
-    if(program ret=findprog(combine_path(cwd,pname),ext))
+    if(program ret=findprog(combine_path(cwd,pname),ext,handler))
       return ret;
 
     foreach(pike_program_path, string path)
-      if(program ret=findprog(combine_path(path,pname),ext))
+      if(program ret=findprog(combine_path(path,pname),ext,handler))
 	return ret;
 
     return 0;
@@ -475,9 +481,9 @@ void create()
  * previous_object(), can be virtually anything in this function, as it
  * is called from the compiler.
  */
-program handle_inherit(string pname, string current_file)
+program handle_inherit(string pname, string current_file, object|void handler)
 {
-  return cast_to_program(pname, current_file);
+  return cast_to_program(pname, current_file, handler);
 }
 
 mapping (program:object) objects=([object_program(this_object()):this_object()]);
@@ -705,7 +711,7 @@ object findmodule(string fullname)
   return fc[fullname]=UNDEFINED;
 }
 
-mixed handle_import(string what, string|void current_file)
+mixed handle_import(string what, string|void current_file, object|void handler)
 {
   string *tmp,path;
   if(current_file)
@@ -1043,7 +1049,7 @@ void compile_warning(string file,int line,string err)
   if(!inhibit_compile_errors)
   {
     if(want_warnings)
-      werror(sprintf("%s:%d:%s\n",trim_file_name(file),line,err));
+      werror(sprintf("%s:%d:Warning: %s\n",trim_file_name(file),line,err));
   }
 }
 
diff --git a/src/language.yacc b/src/language.yacc
index a1cd0cc2f5e13d25f20f06f07b073c7eadee2139..9d2e178dd0f6f0bb8ecfc07f5ae21f490200ae5c 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -182,7 +182,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.128 1999/10/23 06:51:25 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.129 1999/11/04 02:35:30 grubba Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -416,7 +416,13 @@ low_program_ref: string_constant
     ref_push_string($1->u.sval.u.string);
     ref_push_string($1->u.sval.u.string);
     ref_push_string(lex.current_file);
-    SAFE_APPLY_MASTER("handle_inherit", 2);
+    
+    if (error_handler && error_handler->prog) {
+      ref_push_object(error_handler);
+      SAFE_APPLY_MASTER("handle_inherit", 3);
+    } else {
+      SAFE_APPLY_MASTER("handle_inherit", 2);
+    }
 
     if(sp[-1].type != T_PROGRAM)
       my_yyerror("Couldn't cast string \"%s\" to program",
@@ -494,7 +500,12 @@ import: F_IMPORT idents ';'
     ref_push_string($2->u.sval.u.string);
     free_node($2);
     ref_push_string(lex.current_file);
-    SAFE_APPLY_MASTER("handle_import",2);
+    if (error_handler && error_handler->prog) {
+      ref_push_object(error_handler);
+      SAFE_APPLY_MASTER("handle_import", 3);
+    } else {
+      SAFE_APPLY_MASTER("handle_import", 2);
+    }
     use_module(sp-1);
     pop_stack();
   }
@@ -1705,7 +1716,12 @@ idents: low_idents
     node *tmp;
     push_text(".");
     ref_push_string(lex.current_file);
-    SAFE_APPLY_MASTER("handle_import",2);
+    if (error_handler && error_handler->prog) {
+      ref_push_object(error_handler);
+      SAFE_APPLY_MASTER("handle_import", 3);
+    } else {
+      SAFE_APPLY_MASTER("handle_import", 2);
+    }
     tmp=mkconstantsvaluenode(sp-1);
     pop_stack();
     $$=index_node(tmp, ".", $2->u.sval.u.string);
@@ -2124,7 +2140,7 @@ void yyerror(char *str)
   num_parse_error++;
   cumulative_parse_error++;
 
-  if ( get_master() )
+  if ((error_handler && error_handler->prog) || get_master())
   {
     if (lex.current_file) {
       ref_push_string(lex.current_file);
@@ -2136,7 +2152,11 @@ void yyerror(char *str)
     }
     push_int(lex.current_line);
     push_text(str);
-    SAFE_APPLY_MASTER("compile_error",3);
+    if (error_handler && error_handler->prog) {
+      safe_apply(error_handler, "compile_error", 3);
+    } else {
+      SAFE_APPLY_MASTER("compile_error", 3);
+    }
     pop_stack();
   }else{
     if (lex.current_file) {
diff --git a/src/program.c b/src/program.c
index e82cc5b55b5078a351f8184b53aedafdd787e7cf..1c51f365f1eb01acfbc0f97d854ac3ffb155b423 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.169 1999/10/29 00:09:47 hubbe Exp $");
+RCSID("$Id: program.c,v 1.170 1999/11/04 02:35:28 grubba Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -111,6 +111,7 @@ static int current_program_id=0;
 struct program *new_program=0;
 struct object *fake_object=0;
 struct program *malloc_size_program=0;
+struct object *error_handler=0;
 
 int compiler_pass;
 int compilation_depth;
@@ -2628,7 +2629,7 @@ void my_yyerror(char *fmt,...)  ATTRIBUTE((format(printf,1,2)))
   va_end(args);
 }
 
-struct program *compile(struct pike_string *prog)
+struct program *compile(struct pike_string *prog, struct object *handler)
 {
 #ifdef PIKE_DEBUG
   JMP_BUF tmp;
@@ -2637,6 +2638,7 @@ struct program *compile(struct pike_string *prog)
   struct lex save_lex;
   int save_depth=compilation_depth;
   int saved_threads_disabled;
+  struct object *saved_handler = error_handler;
   dynamic_buffer used_modules_save = used_modules;
   INT32 num_used_modules_save = num_used_modules;
   extern void yyparse(void);
@@ -2644,6 +2646,8 @@ struct program *compile(struct pike_string *prog)
   CDFPRINTF((stderr, "th(%ld) compile() starting compilation_depth=%d\n",
 	     (long)th_self(),compilation_depth));
 
+  error_handler = handler;
+
   low_init_threads_disable();
   saved_threads_disabled = threads_disabled;
 
@@ -2754,6 +2758,7 @@ struct program *compile(struct pike_string *prog)
   compilation_depth=save_depth;
   used_modules = used_modules_save;
   num_used_modules = num_used_modules_save ;
+  error_handler = saved_handler;
 
 #ifdef PIKE_DEBUG
   UNSETJMP(tmp);
@@ -3270,12 +3275,16 @@ void yywarning(char *fmt, ...) ATTRIBUTE((format(printf,1,2)))
   if(strlen(buf)>sizeof(buf))
     fatal("Buffer overfloat in yywarning!\n");
 
-  if(get_master())
-  {
+  if ((error_handler && error_handler->prog) || get_master()) {
     ref_push_string(lex.current_file);
     push_int(lex.current_line);
     push_text(buf);
-    SAFE_APPLY_MASTER("compile_warning",3);
+
+    if (error_handler && error_handler->prog) {
+      safe_apply(error_handler, "compile_warning", 3);
+    } else {
+      SAFE_APPLY_MASTER("compile_warning",3);
+    }
     pop_stack();
   }
 }
diff --git a/src/program.h b/src/program.h
index 295701a29237fa22c36b2cdf0b07bda3f1202c2f..acd0e31d9b1b25cb627c39721c73aae4832e9c81 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.64 1999/10/29 03:34:34 mast Exp $
+ * $Id: program.h,v 1.65 1999/11/04 02:35:27 grubba Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -278,6 +278,8 @@ struct program
 #define free_program(p) do{ struct program *_=(p); debug_malloc_touch(_); if(!--_->refs) really_free_program(_); }while(0)
 
 
+extern struct object *error_handler;
+
 extern struct object *fake_object;
 extern struct program *new_program;
 extern struct program *first_program;
@@ -420,7 +422,7 @@ void start_line_numbering(void);
 void store_linenumber(INT32 current_line, struct pike_string *current_file);
 char *get_line(unsigned char *pc,struct program *prog,INT32 *linep);
 void my_yyerror(char *fmt,...)  ATTRIBUTE((format(printf,1,2)));
-struct program *compile(struct pike_string *prog);
+struct program *compile(struct pike_string *prog, struct object *handler);
 int add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags);
 int quick_add_function(char *name,
 		       int name_length,