diff --git a/src/language.yacc b/src/language.yacc
index db64ccc1c5947ac35c52b6cd584cb86c9186caad..50df3732a7ee0acdbe5b3d5096435d546848e379 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: language.yacc,v 1.349 2004/11/05 15:27:19 grubba Exp $
+|| $Id: language.yacc,v 1.350 2004/11/05 16:21:23 grubba Exp $
 */
 
 %pure_parser
@@ -784,7 +784,8 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
 	      simple_describe_type(s);
 #endif
 	    } else {
-	      my_yyerror("Lost identifier %O (%d).", $4->u.sval, i);
+	      my_yyerror("Lost identifier %S (%d).",
+			 $4->u.sval.u.string, i);
 	    }
 	  } else {
 	    fprintf(stderr, "Not defined.\n");
@@ -814,7 +815,8 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
 #endif
 	  }
 	} else {
-	  my_yyerror("Identifier %S lost after first pass.", $4->u.sval);
+	  my_yyerror("Identifier %S lost after first pass.",
+		     $4->u.sval.u.string);
 	}
       }
 
@@ -1060,7 +1062,8 @@ new_arg_name: type7 optional_dot_dot_dot optional_identifier
 
     if($3->u.sval.u.string->len &&
        islocal($3->u.sval.u.string) >= 0)
-      my_yyerror("Variable %O appears twice in argument list.", $3->u.sval);
+      my_yyerror("Variable %S appears twice in argument list.",
+		 $3->u.sval.u.string);
     
     add_local_name($3->u.sval.u.string, compiler_pop_type(),0);
     free_node($3);
@@ -1349,8 +1352,7 @@ identifier_type: idents
       
       default:
 	if (Pike_compiler->compiler_pass!=1)
-	  my_yyerror("Illegal program identifier (type: %s).",
-		     get_name_of_type(Pike_sp[-1].type));
+	  my_yyerror("Illegal program identifier: %O.", Pike_sp-1);
 	pop_stack();
 	push_int(0);
 	push_object_type(0, 0);
@@ -1480,12 +1482,7 @@ opt_object_type:  /* Empty */ { push_object_type(0, 0); }
 
     if(!p) {
       if (Pike_compiler->compiler_pass!=1) {
-	if ((Pike_sp[-2].type == T_STRING) && (Pike_sp[-2].u.string->len > 0) &&
-	    (Pike_sp[-2].u.string->len < 256)) {
-	  my_yyerror("Not a valid program specifier: %S", Pike_sp[-2]);
-	} else {
-	  yyerror("Not a valid program specifier.");
-	}
+	my_yyerror("Not a valid program specifier: %S", Pike_sp[-2].u.string);
       }
     }
     push_object_type(0, p?(p->id):0);
@@ -2315,8 +2312,8 @@ create_arg: modifiers type_or_error optional_stars optional_dot_dot_dot TOK_IDEN
     type=compiler_pop_type();
 
     if(islocal($5->u.sval.u.string) >= 0)
-      my_yyerror("Variable %O appears twice in create argument list.",
-		 $5->u.sval);
+      my_yyerror("Variable %S appears twice in create argument list.",
+		 $5->u.sval.u.string);
 
     /* Add the identifier both globally and locally. */
     define_variable($5->u.sval.u.string, type,
@@ -3472,7 +3469,7 @@ inherit_specifier: TOK_IDENTIFIER TOK_COLON_COLON
     }
     if (e == -1) {
       if (TEST_COMPAT (7, 2))
-	my_yyerror("No such inherit %O.", $1->u.sval);
+	my_yyerror("No such inherit %S.", $1->u.sval.u.string);
       else {
 	if ($1->u.sval.u.string == this_program_string) {
 	  inherit_state = Pike_compiler;
@@ -3480,7 +3477,8 @@ inherit_specifier: TOK_IDENTIFIER TOK_COLON_COLON
 	  e = 0;
 	}
 	else
-	  my_yyerror("No inherit or surrounding class %O.", $1->u.sval);
+	  my_yyerror("No inherit or surrounding class %S.",
+		     $1->u.sval.u.string);
       }
     }
     free_node($1);
@@ -3508,11 +3506,11 @@ inherit_specifier: TOK_IDENTIFIER TOK_COLON_COLON
 #endif /* 0 */
       if (!e) {
 	if (inherit_state->new_program->inherits[$1].name) {
-	  my_yyerror("No such inherit %S::%O.",
+	  my_yyerror("No such inherit %S::%S.",
 		     inherit_state->new_program->inherits[$1].name,
-		     $2->u.sval);
+		     $2->u.sval.u.string);
 	} else {
-	  my_yyerror("No such inherit %O.", $2->u.sval);
+	  my_yyerror("No such inherit %S.", $2->u.sval.u.string);
 	}
 	$$ = -1;
       } else {
@@ -3649,9 +3647,9 @@ low_idents: TOK_IDENTIFIER
       {
 	if (Pike_compiler->compiler_pass == 2) {
 	  if (TEST_COMPAT(7,2)) {
-	    yywarning("Undefined identifier ::%O.", $2->u.sval);
+	    yywarning("Undefined identifier ::%S.", $2->u.sval.u.string);
 	  } else {
-	    my_yyerror("Undefined identifier ::%O.", $2->u.sval);
+	    my_yyerror("Undefined identifier ::%S.", $2->u.sval.u.string);
 	  }
 	}
 	$$=mkintnode(0);
diff --git a/src/las.c b/src/las.c
index 7bdf2c9c7394c40bd12aa959c878ca7c541f8132..03d02dac6a5e894fe5c4e665adf109bc0bdafa17 100644
--- a/src/las.c
+++ b/src/las.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: las.c,v 1.351 2004/10/30 11:38:26 mast Exp $
+|| $Id: las.c,v 1.352 2004/11/05 16:21:23 grubba Exp $
 */
 
 #include "global.h"
@@ -3506,7 +3506,7 @@ void yytype_error(char *msg, struct pike_type *expected_t,
     if (flags & YYTE_IS_WARNING)
       yywarning("%s", msg);
     else
-      my_yyerror("%s", msg);
+      yyerror(msg);
   }
 
   yyexplain_nonmatching_types(expected_t, got_t, flags);
@@ -3569,7 +3569,7 @@ void fix_type_field(node *n)
 
   case F_ASSIGN:
     if (!CAR(n) || (CAR(n)->type == void_type_string)) {
-      my_yyerror("Assigning a void expression.");
+      yyerror("Assigning a void expression.");
       copy_pike_type(n->type, void_type_string);
       break;
     } else if(CAR(n) && CDR(n)) {
@@ -3647,7 +3647,7 @@ void fix_type_field(node *n)
   case F_INDEX:
   case F_ARROW:
     if (!CAR(n) || (CAR(n)->type == void_type_string)) {
-      my_yyerror("Indexing a void expression.");
+      yyerror("Indexing a void expression.");
       /* The optimizer converts this to an expression returning 0. */
       copy_pike_type(n->type, zero_type_string);
     } else {
@@ -3655,7 +3655,7 @@ void fix_type_field(node *n)
       type_b=CDR(n)->type;
       if(!check_indexing(type_a, type_b, n))
 	if(!Pike_compiler->catch_level)
-	  my_yyerror("Indexing on illegal type.");
+	  yyerror("Indexing on illegal type.");
       n->type=index_type(type_a, type_b,n);
     }
     break;
@@ -3677,14 +3677,14 @@ void fix_type_field(node *n)
 
   case F_AUTO_MAP_MARKER:
     if (!CAR(n) || (CAR(n)->type == void_type_string)) {
-      my_yyerror("Indexing a void expression.");
+      yyerror("Indexing a void expression.");
       /* The optimizer converts this to an expression returning 0. */
       copy_pike_type(n->type, zero_type_string);
     } else {
       type_a=CAR(n)->type;
       if(!match_types(type_a, array_type_string))
 	if(!Pike_compiler->catch_level)
-	  my_yyerror("[*] on non-array.");
+	  yyerror("[*] on non-array.");
       n->type=index_type(type_a, int_type_string, n);
     }
     break;
@@ -3692,11 +3692,12 @@ void fix_type_field(node *n)
   case F_AUTO_MAP:
   case F_APPLY:
     if (!CAR(n) || (CAR(n)->type == void_type_string)) {
-      my_yyerror("Calling a void expression.");
+      yyerror("Calling a void expression.");
     } else {
       struct pike_type *f;	/* Expected type. */
       struct pike_type *s;	/* Actual type */
-      char *name;
+      struct pike_string *name = NULL;
+      char *alternate_name;
       INT32 max_args,args;
 
 #ifdef NEW_ARG_CHECK
@@ -3771,7 +3772,7 @@ void fix_type_field(node *n)
       case F_TRAMPOLINE:
 #endif
       case F_IDENTIFIER:
-	name=ID_FROM_INT(Pike_compiler->new_program, CAR(n)->u.id.number)->name->str;
+	name=ID_FROM_INT(Pike_compiler->new_program, CAR(n)->u.id.number)->name;
 	break;
 
 	case F_ARROW:
@@ -3779,9 +3780,9 @@ void fix_type_field(node *n)
 	  if(CDAR(n)->token == F_CONSTANT &&
 	     CDAR(n)->u.sval.type == T_STRING)
 	  {
-	    name=CDAR(n)->u.sval.u.string->str;
+	    name=CDAR(n)->u.sval.u.string;
 	  }else{
-	    name="dynamically resolved function";
+	    alternate_name="dynamically resolved function";
 	  }
 	  break;
 
@@ -3791,23 +3792,23 @@ void fix_type_field(node *n)
 	case T_FUNCTION:
 	  if(CAR(n)->u.sval.subtype == FUNCTION_BUILTIN)
 	  {
-	    name=CAR(n)->u.sval.u.efun->name->str;
+	    name=CAR(n)->u.sval.u.efun->name;
 	  }else{
 	    name=ID_FROM_INT(CAR(n)->u.sval.u.object->prog,
-			     CAR(n)->u.sval.subtype)->name->str;
+			     CAR(n)->u.sval.subtype)->name;
 	  }
 	  break;
 
 	case T_ARRAY:
-	  name="array call";
+	  alternate_name="array call";
 	  break;
 
 	case T_PROGRAM:
-	  name="clone call";
+	  alternate_name="clone call";
 	  break;
 
 	default:
-	  name="`() (function call)";
+	  alternate_name="`() (function call)";
 	  break;
 	}
 	break;
@@ -3817,13 +3818,13 @@ void fix_type_field(node *n)
 	  int id_no = CAR(n)->u.integer.b;
 
 	  if (id_no == IDREF_MAGIC_THIS)
-	    name = "this";	/* Should perhaps qualify it. */
+	    alternate_name = "this";	/* Should perhaps qualify it. */
 
 	  else {
 	    int program_id = CAR(n)->u.integer.a;
 	    struct program_state *state = Pike_compiler;
 
-	    name="external symbol";
+	    alternate_name="external symbol";
 
 	    while (state && (state->new_program->id != program_id)) {
 	      state = state->previous;
@@ -3857,7 +3858,7 @@ void fix_type_field(node *n)
 	break;
 	  
       default:
-	name="unknown function";
+	alternate_name="unknown function";
       }
 
       if(max_args < args)
@@ -3868,14 +3869,25 @@ void fix_type_field(node *n)
 	  copy_pike_type(n->type, mixed_type_string);
 	  break;
 	}
-	my_yyerror("Too many arguments to %s.",name);
+	if (name) {
+	  my_yyerror("Too many arguments to %S.", name);
+	} else {
+	  my_yyerror("Too many arguments to %s.", alternate_name);
+	}
       }
       else if(max_correct_args == args)
       {
-	my_yyerror("Too few arguments to %s.",name);
-      }else{
-	my_yyerror("Bad argument %d to %s.",
+	if (name) {
+	  my_yyerror("Too few arguments to %S.", name);
+	} else {
+	  my_yyerror("Too few arguments to %s.", alternate_name);
+	}
+      } else if (name) {
+	my_yyerror("Bad argument %d to %S.",
 		   max_correct_args+1, name);
+      } else {
+	my_yyerror("Bad argument %d to %s.",
+		   max_correct_args+1, alternate_name);
       }
       
       yytype_error(NULL, f, s, 0);
diff --git a/src/pike_types.c b/src/pike_types.c
index b3ca34c125bf418b1be7eb532453a272d153ceef..dac3f9be460eced06d6b856366922ebbded7cd8e 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: pike_types.c,v 1.238 2004/10/30 11:38:27 mast Exp $
+|| $Id: pike_types.c,v 1.239 2004/11/05 16:21:23 grubba Exp $
 */
 
 #include "global.h"
@@ -4565,8 +4565,8 @@ void yyexplain_nonmatching_types(struct pike_type *type_a,
       yywarning("Expected: %s",s1->str);
       yywarning("Got     : %s",s2->str);
     }else{
-      my_yyerror("Expected: %s",s1->str);
-      my_yyerror("Got     : %s",s2->str);
+      my_yyerror("Expected: %S", s1);
+      my_yyerror("Got     : %S", s2);
     }
     free_string(s1);
     free_string(s2);
diff --git a/src/program.c b/src/program.c
index d74b10a44ec1cbb1bbf2bf3203af0e3a6847c549..68d1c4ab6cad3e638e04de12e0e3d35009e36ba1 100644
--- a/src/program.c
+++ b/src/program.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: program.c,v 1.574 2004/10/30 15:57:19 nilsson Exp $
+|| $Id: program.c,v 1.575 2004/11/05 16:21:23 grubba Exp $
 */
 
 #include "global.h"
@@ -1518,7 +1518,7 @@ struct node_s *resolve_identifier(struct pike_string *ident)
       else
 	if(Pike_compiler->compiler_pass==2) {
 	  if (throw_value.type == T_STRING) {
-	    my_yyerror("%O", throw_value);
+	    my_yyerror("%S", throw_value.u.string);
 	    free_svalue(&throw_value);
 	    throw_value.type = T_INT;
 	  }
@@ -1926,12 +1926,8 @@ void fixate_program(void)
     }
     if ((fun->func.offset == -1) && (funp->id_flags & ID_INLINE) &&
 	IDENTIFIER_IS_PIKE_FUNCTION(fun->identifier_flags)) {
-      if (fun->name->len < 900) {
-	my_yyerror("Missing definition for local function %S.",
-		   fun->name);
-      } else {
-	yyerror("Missing definition for local function.");
-      }
+      my_yyerror("Missing definition for local function %S.",
+		 fun->name);
     }
     add_to_identifier_index(i);
   }
@@ -1964,10 +1960,7 @@ void fixate_program(void)
 
 	if((e != i) && (e != -1))
 	{
-	  if(name->len < 1024)
-	    my_yyerror("Illegal to redefine final identifier %S", name);
-	  else
-	    my_yyerror("Illegal to redefine final identifier (name too large to print).");
+	  my_yyerror("Illegal to redefine final identifier %S", name);
 	}
       }
     }
@@ -4245,8 +4238,8 @@ int define_variable(struct pike_string *name,
 	if(!IDENTIFIER_IS_VARIABLE(ID_FROM_INT(Pike_compiler->new_program, n)->
 				   identifier_flags))
 	{
-	  my_yyerror("Illegal to redefine inherited variable "
-		     "with different type.");
+	  my_yyerror("Illegal to redefine inherited variable %S "
+		     "with different type.", name);
 	  return n;
 	}
 
@@ -4254,8 +4247,8 @@ int define_variable(struct pike_string *name,
 	     PIKE_T_MIXED) &&
 	    (ID_FROM_INT(Pike_compiler->new_program, n)->run_time_type !=
 	     compile_type_to_runtime_type(type))) {
-	  my_yyerror("Illegal to redefine inherited variable "
-		     "with different type.");
+	  my_yyerror("Illegal to redefine inherited variable %S "
+		     "with different type.", name);
 	  return n;
 	}
 
@@ -5929,9 +5922,13 @@ PMOD_EXPORT struct pike_string *low_get_function_line (struct object *o,
 
 void va_yyerror(const char *fmt, va_list args)
 {
-  char buf[8192];
-  Pike_vsnprintf (buf, sizeof (buf), fmt, args);
-  yyerror(buf);
+  struct string_builder s;
+  struct pike_string *tmp;
+  init_string_builder(&s, 0);
+  string_builder_vsprintf(&s, fmt, args);
+  tmp = finish_string_builder(&s);
+  low_yyerror(tmp);
+  free_string(tmp);
 }
 
 void my_yyerror(const char *fmt,...)
@@ -5981,7 +5978,7 @@ void handle_compile_exception (const char *yyerror_fmt, ...)
   if (SAFE_IS_ZERO(sp-1)) {
     struct pike_string *s = format_exception_for_error_msg (&thrown);
     if (s) {
-      my_yyerror("%S", s);
+      low_yyerror(s);
       free_string (s);
     }
   }
diff --git a/src/treeopt.in b/src/treeopt.in
index ae471f92b6c8f09469eef17907c71925c27de822..9958f62e75fe9523a8ec18c76fcc2d732f5addca 100644
--- a/src/treeopt.in
+++ b/src/treeopt.in
@@ -2,7 +2,7 @@
 // This file is part of Pike. For copyright information see COPYRIGHT.
 // Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 // for more information.
-// $Id: treeopt.in,v 1.74 2004/10/30 11:38:29 mast Exp $
+// $Id: treeopt.in,v 1.75 2004/11/05 16:21:23 grubba Exp $
 //
 // The tree optimizer
 //
@@ -1162,7 +1162,7 @@ F_FOR(0 = F_APPLY(1 = F_CONSTANT
 	node *n;
 	if ((!plus_name && !(plus_name = findstring("`+"))) ||
 	    !(n=find_module_identifier(plus_name, 0))) {
-	  my_yyerror("Internally used efun undefined: `+");
+	  yyerror("Internally used efun undefined: `+");
 	  tmp3 = mkintnode(0);
         } else {
 	  ADD_NODE_REF2(*arg2,
@@ -1181,7 +1181,7 @@ F_FOR(0 = F_APPLY(1 = F_CONSTANT
 	node *n;
 	if ((!minus_name && !(minus_name = findstring("`-"))) ||
 	    !(n=find_module_identifier(minus_name, 0))) {
-	  my_yyerror("Internally used efun undefined: `-");
+	  yyerror("Internally used efun undefined: `-");
 	  tmp3 = mkintnode(0);
         } else {
 	  ADD_NODE_REF2(*arg2,