From 50edc81d901bdd92da20a0e79123ff604fe42485 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Fri, 13 Jul 2001 13:26:40 +0200
Subject: [PATCH] get_{program_,}line() now returns a pike_string.
 store_linenumber() is now wide string safe. Added some more debug to
 store_linenumber(). Fixes [bug 1866].

Rev: src/builtin.cmod:1.59
Rev: src/builtin_functions.c:1.394
Rev: src/gc.c:1.169
Rev: src/interpret.c:1.219
Rev: src/interpreter.h:1.68
Rev: src/object.c:1.179
Rev: src/opcodes.c:1.113
Rev: src/program.c:1.353
Rev: src/program.h:1.138
---
 src/builtin.cmod        |  42 ++++-----
 src/builtin_functions.c |  24 +++---
 src/gc.c                |  19 ++--
 src/interpret.c         |  41 +++++----
 src/interpreter.h       |   8 +-
 src/object.c            |  12 +--
 src/opcodes.c           |   8 +-
 src/program.c           | 186 ++++++++++++++++++++++++++++++----------
 src/program.h           |  12 +--
 9 files changed, 228 insertions(+), 124 deletions(-)

diff --git a/src/builtin.cmod b/src/builtin.cmod
index ce7eed4b6f..456720e12c 100644
--- a/src/builtin.cmod
+++ b/src/builtin.cmod
@@ -1,5 +1,5 @@
 /* -*- c -*-
- * $Id: builtin.cmod,v 1.58 2001/07/11 17:57:23 mast Exp $
+ * $Id: builtin.cmod,v 1.59 2001/07/13 11:26:37 grubba Exp $
  */
 
 #include "global.h"
@@ -407,23 +407,19 @@ PIKEFUN string program_defined(program p)
 {
   if(p && p->num_linenumbers)
   {
-    char *tmp;
     INT32 line;
-    if((tmp=get_program_line(p, &line)))
-    {
-      struct pike_string *tmp2;
-      tmp2=make_shared_string(tmp);
-      pop_n_elems(args);
+    struct pike_string *tmp = get_program_line(p, &line);
 
-      push_string(tmp2);
-      if(line >= 1)
-      {
-	push_constant_text(":");
-	push_int(line);
-	f_add(3);
-      }
-      return;
+    pop_n_elems(args);
+
+    push_string(tmp);
+    if(line >= 1)
+    {
+      push_constant_text(":");
+      push_int(line);
+      f_add(3);
     }
+    return;
   }
 
   pop_n_elems(args);
@@ -802,8 +798,7 @@ PIKECLASS backtrace_frame
     push_text("backtrace_frame(");
     if (THIS->pc) {
       if (!THIS->filename) {
-	THIS->filename =
-	  make_shared_string(get_line(THIS->pc, THIS->prog, &THIS->lineno));
+	THIS->filename = get_line(THIS->pc, THIS->prog, &THIS->lineno);
       }
       THIS->pc = NULL;
     }
@@ -903,9 +898,7 @@ PIKECLASS backtrace_frame
       case 1:	/* Linenumber */
 	if (THIS->pc) {
 	  if (!THIS->filename) {
-	    THIS->filename =
-	      make_shared_string(get_line(THIS->pc, THIS->prog,
-					  &THIS->lineno));
+	    THIS->filename = get_line(THIS->pc, THIS->prog, &THIS->lineno);
 	  }
 	  THIS->pc = NULL;
 	}
@@ -979,9 +972,7 @@ PIKECLASS backtrace_frame
       /* First make sure we have line-number info. */
       if (THIS->pc) {
 	if (!THIS->filename) {
-	  THIS->filename =
-	  make_shared_string(get_line(THIS->pc, THIS->prog,
-				      &THIS->lineno));
+	  THIS->filename = get_line(THIS->pc, THIS->prog, &THIS->lineno);
 	}
 	THIS->pc = NULL;
       }
@@ -1721,10 +1712,7 @@ PIKECLASS single_string_replace
     copy_shared_string(THIS->to, to = to_->u.string);
 
     if (del->len) {
-      THIS->mojt = compile_memsearcher(MKPCHARP_STR(del),
-				       del->len,
-				       0x7fffffff,
-				       del);
+      THIS->mojt = simple_compile_memsearcher(del);
     }
   }
 
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 2ddf2298a1..f301c11f8c 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.393 2001/07/10 00:04:11 mast Exp $");
+RCSID("$Id: builtin_functions.c,v 1.394 2001/07/13 11:26:40 grubba Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -1018,8 +1018,6 @@ PMOD_EXPORT void f_backtrace(INT32 args)
   of=0;
   for(f=Pike_fp;f;f=(of=f)->next)
   {
-    char *program_name;
-
     debug_malloc_touch(f);
     frames--;
 
@@ -1055,11 +1053,12 @@ PMOD_EXPORT void f_backtrace(INT32 args)
 
       if(f->pc)
       {
-	program_name=get_line(f->pc, f->context.prog, & ITEM(i)[1].u.integer);
+	struct pike_string *program_name =
+	  get_line(f->pc, f->context.prog, & ITEM(i)[1].u.integer);
 	ITEM(i)[1].subtype=NUMBER_NUMBER;
 	ITEM(i)[1].type=T_INT;
 
-	ITEM(i)[0].u.string=make_shared_string(program_name);
+	ITEM(i)[0].u.string = program_name;
 #ifdef __CHECKER__
 	ITEM(i)[0].subtype=0;
 #endif
@@ -7222,22 +7221,21 @@ PMOD_EXPORT void f_function_defined(INT32 args)
   if(Pike_sp[-args].subtype != FUNCTION_BUILTIN &&
      Pike_sp[-args].u.object->prog)
   {
-    char *tmp;
-    INT32 line;
     struct identifier *id=ID_FROM_INT(Pike_sp[-args].u.object->prog,
 				      Pike_sp[-args].subtype);
     if(IDENTIFIER_IS_PIKE_FUNCTION( id->identifier_flags ) &&
       id->func.offset != -1)
     {
-      if((tmp=get_line(Pike_sp[-args].u.object->prog->program + id->func.offset,
-		       Pike_sp[-args].u.object->prog,
-		       &line)))
+      INT32 line = 0;
+      struct pike_string *tmp =
+	get_line(Pike_sp[-args].u.object->prog->program + id->func.offset,
+		 Pike_sp[-args].u.object->prog,
+		 &line);
+      if (tmp)
       {
-	struct pike_string *tmp2;
-	tmp2=make_shared_string(tmp);
 	pop_n_elems(args);
 	
-	push_string(tmp2);
+	push_string(tmp);
 	push_constant_text(":");
 	push_int(line);
 	f_add(3);
diff --git a/src/gc.c b/src/gc.c
index 1231203d17..d5c716def6 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -30,7 +30,7 @@ struct callback *gc_evaluator_callback=0;
 
 #include "block_alloc.h"
 
-RCSID("$Id: gc.c,v 1.168 2001/07/11 11:24:00 mast Exp $");
+RCSID("$Id: gc.c,v 1.169 2001/07/13 11:26:38 grubba Exp $");
 
 /* Run garbage collect approximately every time
  * 20 percent of all arrays, objects and programs is
@@ -785,7 +785,7 @@ void low_describe_something(void *a,
 
     case T_PROGRAM:
     {
-      char *tmp;
+      struct pike_string *tmp;
       INT32 line;
       int foo=0;
 
@@ -797,13 +797,17 @@ void low_describe_something(void *a,
       {
 	fprintf(stderr,"%*s**The program was written in C.\n",indent,"");
       }
-      tmp=get_program_line(p, &line);
-      if(strcmp(tmp, "-"))
+
+      tmp = get_program_line(p, &line);
+      if(strcmp(tmp->str, "-"))
       {
-	fprintf(stderr,"%*s**Location: %s:%ld\n",indent,"",tmp,(long)line);
+	fprintf(stderr,"%*s**Location: %s:%ld\n",
+		indent, "", tmp->str, (long)line);
+	free_string(tmp);
 	foo=1;
 	break;
       }
+      free_string(tmp);
 #if 0
       if(!foo && p->num_linenumbers>1 && EXTRACT_UCHAR(p->linenumbers)=='\177')
       {
@@ -2600,8 +2604,9 @@ int do_gc(void)
       fprintf(stderr, "|   Killing %p with %d refs", o, o->refs);
       if (o->prog) {
 	INT32 line;
-	char *file = get_program_line (o->prog, &line);
-	fprintf(stderr, ", prog %s:%d\n", file, line);
+	struct pike_string *file = get_program_line (o->prog, &line);
+	fprintf(stderr, ", prog %s:%d\n", file->str, line);
+	free_string(file);
       }
       else fputs(", is destructed\n", stderr);
     );
diff --git a/src/interpret.c b/src/interpret.c
index cf20f0dc50..40bfa6c798 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.218 2001/07/09 14:19:15 grubba Exp $");
+RCSID("$Id: interpret.c,v 1.219 2001/07/13 11:26:38 grubba Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -676,7 +676,7 @@ void dump_backlog(void)
 
     if(backlog[e].program)
     {
-      char *file;
+      struct pike_string *file;
       INT32 line;
 
 #ifdef _REENTRANT
@@ -687,24 +687,25 @@ void dump_backlog(void)
       }
 #endif
 
-      file=get_line(backlog[e].pc-1,backlog[e].program, &line);
+      file = get_line(backlog[e].pc-1,backlog[e].program, &line);
 #ifdef HAVE_COMPUTED_GOTO
       fprintf(stderr,"%s:%ld: %s",
-	      file,
+	      file->str,
 	      (long)line,
 	      get_opcode_name(backlog[e].instruction));
 #else /* !HAVE_COMPUTED_GOTO */
       if(backlog[e].instruction < 0 || backlog[e].instruction+F_OFFSET > F_MAX_OPCODE)
       {
 	fprintf(stderr,"%s:%ld: ILLEGAL INSTRUCTION %d\n",
-		file,
+		file->str,
 		(long)line,
 		backlog[e].instruction + F_OFFSET);
+	free_string(file);
 	continue;
       }
 
       fprintf(stderr,"%s:%ld: %s",
-	      file,
+	      file->str,
 	      (long)line,
 	      low_get_f_name(backlog[e].instruction + F_OFFSET, backlog[e].program));
       if(instrs[backlog[e].instruction].flags & I_HASARG2)
@@ -725,6 +726,7 @@ void dump_backlog(void)
 	      DO_NOT_WARN((long)backlog[e].stack),
 	      DO_NOT_WARN((long)backlog[e].mark_stack));
 #endif /* HAVE_COMPUTED_GOTO */
+      free_string(file);
     }
   }while(e!=backlogp);
 }
@@ -800,7 +802,8 @@ static void trace_return_value(void)
 
 static void do_trace_call(INT32 args)
 {
-  char *file,*s;
+  struct pike_string *filep = NULL;
+  char *file, *s;
   INT32 linep,e;
   my_strcat("(");
   for(e=0;e<args;e++)
@@ -820,13 +823,18 @@ static void do_trace_call(INT32 args)
   if(Pike_fp && Pike_fp->pc)
   {
     char *f;
-    file=get_line(Pike_fp->pc,Pike_fp->context.prog,&linep);
-    while((f=STRCHR(file,'/'))) file=f+1;
+    filep = get_line(Pike_fp->pc,Pike_fp->context.prog,&linep);
+    file = filep->str;
+    while((f=STRCHR(file,'/')))
+      file=f+1;
   }else{
     linep=0;
     file="-";
   }
   fprintf(stderr,"- %s:%4ld: %s\n",file,(long)linep,s);
+  if (filep) {
+    free_string(filep);
+  }
   free(s);
 }
 
@@ -1805,7 +1813,7 @@ void gdb_backtrace (
   for (of = 0; f; f = (of = f)->next)
     if (f->refs) {
       int args, i;
-      char *file = 0;
+      struct pike_string *file = NULL;
       INT32 line;
 
       if (f->context.prog) {
@@ -1814,9 +1822,10 @@ void gdb_backtrace (
 	else
 	  file = get_program_line (f->context.prog, &line);
       }
-      if (file)
-	fprintf (stderr, "%s:%d: ", file, line);
-      else
+      if (file) {
+	fprintf (stderr, "%s:%d: ", file->str, line);
+	free_string(file);
+      } else
 	fputs ("unknown program: ", stderr);
 
       if (f->current_object && f->current_object->prog) {
@@ -1934,7 +1943,8 @@ void gdb_backtrace (
 	    struct program *p = arg->u.object->prog;
 	    if (p && p->num_linenumbers) {
 	      file = get_program_line (p, &line);
-	      fprintf (stderr, "object(%s:%d)", file, line);
+	      fprintf (stderr, "object(%s:%d)", file->str, line);
+	      free_string(file);
 	    }
 	    else
 	      fputs ("object", stderr);
@@ -1945,7 +1955,8 @@ void gdb_backtrace (
 	    struct program *p = arg->u.program;
 	    if (p->num_linenumbers) {
 	      file = get_program_line (p, &line);
-	      fprintf (stderr, "program(%s:%d)", file, line);
+	      fprintf (stderr, "program(%s:%d)", file->str, line);
+	      free_string(file);
 	    }
 	    else
 	      fputs ("program", stderr);
diff --git a/src/interpreter.h b/src/interpreter.h
index cd2d6f4a87..dbab995106 100644
--- a/src/interpreter.h
+++ b/src/interpreter.h
@@ -129,10 +129,13 @@ static int eval_instruction(PIKE_OPCODE_T *pc)
     if(t_flag > 2)
     {
       char *file, *f;
+      struct pike_string *filep;
       INT32 linep;
 
-      file = get_line(pc-1,Pike_fp->context.prog,&linep);
-      while((f=STRCHR(file,'/'))) file=f+1;
+      filep = get_line(pc-1,Pike_fp->context.prog,&linep);
+      file = filep->str;
+      while((f=STRCHR(file,'/')))
+	file=f+1;
       fprintf(stderr,"- %s:%4ld:(%lx): %-25s %4ld %4ld\n",
 	      file,(long)linep,
 	      DO_NOT_WARN((long)(pc-Pike_fp->context.prog->program-1)),
@@ -143,6 +146,7 @@ static int eval_instruction(PIKE_OPCODE_T *pc)
 #endif /* HAVE_COMPUTED_GOTO */
 	      DO_NOT_WARN((long)(Pike_sp-Pike_interpreter.evaluator_stack)),
 	      DO_NOT_WARN((long)(Pike_mark_sp-Pike_interpreter.mark_stack)));
+      free_string(filep);
     }
 
 #ifdef HAVE_COMPUTED_GOTO
diff --git a/src/object.c b/src/object.c
index be5b00f16b..57af4442aa 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.178 2001/07/12 23:15:40 hubbe Exp $");
+RCSID("$Id: object.c,v 1.179 2001/07/13 11:26:39 grubba Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -112,11 +112,12 @@ PMOD_EXPORT struct object *low_clone(struct program *p)
 #ifdef DEBUG_MALLOC
   if(!debug_malloc_copy_names(o, p)) 
   {
-    char *tmp;
+    struct pike_string *tmp;
     INT32 line;
 
     tmp=get_program_line(p, &line);
-    debug_malloc_name(o, tmp, line);
+    debug_malloc_name(o, tmp->str, line);
+    free_string(tmp);
   }
   dmalloc_set_mmap_from_template(o,p);
 #endif
@@ -634,8 +635,9 @@ void destruct(struct object *o)
     fprintf(stderr, "|   Destructing %p with %d refs", o, o->refs);
     if (o->prog) {
       INT32 line;
-      char *file = get_program_line (o->prog, &line);
-      fprintf(stderr, ", prog %s:%d\n", file, line);
+      struct pike_string *file = get_program_line (o->prog, &line);
+      fprintf(stderr, ", prog %s:%d\n", file->str, line);
+      free_string(file);
     }
     else fputs(", is destructed\n", stderr);
   }
diff --git a/src/opcodes.c b/src/opcodes.c
index 25fe824ab6..50b9d7f350 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -27,7 +27,7 @@
 #include "bignum.h"
 #include "operators.h"
 
-RCSID("$Id: opcodes.c,v 1.112 2001/06/17 19:15:15 grubba Exp $");
+RCSID("$Id: opcodes.c,v 1.113 2001/07/13 11:26:40 grubba Exp $");
 
 void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 {
@@ -518,7 +518,9 @@ void o_cast(struct pike_type *type, INT32 run_time_type)
 	    if(Pike_fp->pc)
 	    {
 	      INT32 lineno;
-	      push_text(get_line(Pike_fp->pc, Pike_fp->context.prog, &lineno));
+	      push_string(get_line(Pike_fp->pc,
+				   Pike_fp->context.prog,
+				   &lineno));
 	    }else{
 	      push_int(0);
 	    }
@@ -545,7 +547,7 @@ void o_cast(struct pike_type *type, INT32 run_time_type)
 	  if(Pike_fp->pc)
 	  {
 	    INT32 lineno;
-	    push_text(get_line(Pike_fp->pc, Pike_fp->context.prog, &lineno));
+	    push_string(get_line(Pike_fp->pc, Pike_fp->context.prog, &lineno));
 	  }else{
 	    push_int(0);
 	  }
diff --git a/src/program.c b/src/program.c
index 870fdf1c3e..6eed93cc8a 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.352 2001/07/12 23:15:41 hubbe Exp $");
+RCSID("$Id: program.c,v 1.353 2001/07/13 11:26:39 grubba Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -1019,19 +1019,18 @@ int program_function_index_compare(const void *a,const void *b)
 }
 
 #ifdef PIKE_DEBUG
-char *find_program_name(struct program *p, INT32 *line)
+struct pike_string *find_program_name(struct program *p, INT32 *line)
 {
-#ifdef DEBUG_MALLOC
-  char *tmp;
-#endif
   ptrdiff_t pos;
   INT32 l;
   if(!line) line=&l;
 
 #ifdef DEBUG_MALLOC
-  tmp=dmalloc_find_name(p);
-  *line=0;
-  if(tmp) return tmp;
+  {
+    char *tmp=dmalloc_find_name(p);
+    *line=0;
+    if(tmp) return make_shared_string(tmp);
+  }
 #endif
 
   return get_program_line(p, line);
@@ -1093,7 +1092,7 @@ void fixate_program(void)
 #define DBSTR(X) ((X)?(X)->str:"")
     int e,v;
     INT32 line;
-    char *tmp;
+    struct pike_string *tmp;
     struct memory_map *m=0;;
     if(lex.current_file && 
        lex.current_file->str &&
@@ -1104,7 +1103,8 @@ void fixate_program(void)
     }
     else if( (tmp=find_program_name(Pike_compiler->new_program, &line)) )
     {
-      m=dmalloc_alloc_mmap( tmp, line);
+      m=dmalloc_alloc_mmap( tmp->str, line);
+      free_string(tmp);
     }else{
       m=dmalloc_alloc_mmap( "program id", Pike_compiler->new_program->id);
     }
@@ -1113,6 +1113,7 @@ void fixate_program(void)
     {
       struct inherit *i=Pike_compiler->new_program->inherits+e;
       char *tmp;
+      struct pike_string *tmp2 = NULL;
       char buffer[50];
 
       for(v=0;v<i->prog->num_variable_index;v++)
@@ -1132,10 +1133,12 @@ void fixate_program(void)
       {
 	tmp=i->name->str;
       }
-      else if(!(tmp=find_program_name(i->prog, &line)))
+      else if(!(tmp2 = find_program_name(i->prog, &line)))
       {
 	sprintf(buffer,"inherit[%d]",e);
 	tmp=buffer;
+      } else {
+	tmp = tmp2->str;
       }
       dmalloc_add_mmap_entry(m,
 			     tmp,
@@ -1143,7 +1146,9 @@ void fixate_program(void)
 			     i->prog->storage_needed - i->prog->inherits[0].storage_offset,
 			     1, /* count */
 			     0,0);
-
+      if (tmp2) {
+	free_string(tmp2);
+      }
     }
     dmalloc_set_mmap_template(Pike_compiler->new_program, m);
   }
@@ -1341,15 +1346,21 @@ void low_start_new_program(struct program *p,
 
     {
       INT32 line=0, off=0;
+      size_t len = 0;
+      INT32 shift = 0;
       char *file=0;
       char *cnt=Pike_compiler->new_program->linenumbers;
 
-      while(cnt < Pike_compiler->new_program->linenumbers + Pike_compiler->new_program->num_linenumbers)
+      while(cnt < Pike_compiler->new_program->linenumbers +
+	    Pike_compiler->new_program->num_linenumbers)
       {
 	if(*cnt == 127)
 	{
-	  file=cnt+1;
-	  cnt=file+strlen(file)+1;
+	  cnt++;
+	  len = get_small_number(&cnt);
+	  shift = *cnt;
+	  file = ++cnt;
+	  cnt += len<<shift;
 	}
 	off+=get_small_number(&cnt);
 	line+=get_small_number(&cnt);
@@ -1358,8 +1369,10 @@ void low_start_new_program(struct program *p,
       Pike_compiler->last_pc=off;
       if(file)
       {
+	struct pike_string *str = begin_wide_shared_string(len, shift);
 	if(Pike_compiler->last_file) free_string(Pike_compiler->last_file);
-	Pike_compiler->last_file=make_shared_string(file);
+	memcpy(str->str, file, len<<shift);
+	Pike_compiler->last_file = end_shared_string(str);
       }
     }
 
@@ -3896,7 +3909,7 @@ static void insert_small_number(INT32 a)
 #ifdef PIKE_DEBUG
   {
     unsigned char *tmp = Pike_compiler->new_program->linenumbers + start;
-    INT32 res = get_small_number(&tmp);
+    INT32 res = get_small_number((char **)&tmp);
     if (a != res) {
       tmp = Pike_compiler->new_program->linenumbers + start;
       fprintf(stderr, "0x%p: %02x %02x %02x %02x %02x\n",
@@ -3915,50 +3928,91 @@ void store_linenumber(INT32 current_line, struct pike_string *current_file)
   if(d_flag)
   {
     INT32 line=0, off=0;
+    size_t len = 0;
+    INT32 shift = 0;
     char *file=0;
     char *cnt=Pike_compiler->new_program->linenumbers;
 
-    while(cnt < Pike_compiler->new_program->linenumbers + Pike_compiler->new_program->num_linenumbers)
+    if (d_flag > 5) {
+      fprintf(stderr, "store_line_number(%d, \"%s\")\n",
+	      current_line, current_file->str);
+      fprintf(stderr, "  last_line:%d last_file:\"%s\"\n",
+	      Pike_compiler->last_line,
+	      Pike_compiler->last_file?Pike_compiler->last_file->str:"");
+    }
+
+    while(cnt < Pike_compiler->new_program->linenumbers +
+	  Pike_compiler->new_program->num_linenumbers)
     {
+      char *start = cnt;
       if(*cnt == 127)
       {
-	file=cnt+1;
-	cnt=file+strlen(file)+1;
+	cnt++;
+	len = get_small_number(&cnt);
+	shift = *cnt;
+	file = ++cnt;
+	cnt += len<<shift;
+	if (d_flag > 10) {
+	  fprintf(stderr, "Filename entry:\n"
+		  "  len: %d, shift: %d\n",
+		  len, shift);
+	}
       }
       off+=get_small_number(&cnt);
       line+=get_small_number(&cnt);
+      if (d_flag > 10) {
+	fprintf(stderr, "  off: %d, line: %d\n"
+		"  raw: ",
+		off, line);
+	for (;start < cnt; start++) {
+	  fprintf(stderr, "%02x ", *((unsigned char *)start));
+	}
+	fprintf(stderr, "\n");
+      }
     }
 
     if(Pike_compiler->last_line != line ||
        Pike_compiler->last_pc != off ||
-       (Pike_compiler->last_file && file && strcmp(Pike_compiler->last_file->str, file)))
+       (Pike_compiler->last_file && file &&
+	memcmp(Pike_compiler->last_file->str, file, len<<shift)))
     {
       fatal("Line numbering out of whack\n"
-	    "    (line: %d ?= %d)!\n"
-	    "    (  pc: %d ?= %d)!\n"
-	    "    (file: %s ?= %s)!\n",
+	    "    (line : %d ?= %d)!\n"
+	    "    (  pc : %d ?= %d)!\n"
+	    "    (shift: %d ?= %d)!\n"
+	    "    (len  : %d ?= %d)!\n"
+	    "    (file : %s ?= %s)!\n",
 	    Pike_compiler->last_line, line,
 	    Pike_compiler->last_pc, off,
+	    Pike_compiler->last_file?Pike_compiler->last_file->size_shift:0,
+	    shift,
+	    Pike_compiler->last_file?Pike_compiler->last_file->len:0, len,
 	    Pike_compiler->last_file?Pike_compiler->last_file->str:"N/A",
 	    file?file:"N/A");
     }
   }
 #endif
-  if(Pike_compiler->last_line!=current_line || Pike_compiler->last_file != current_file)
+  if(Pike_compiler->last_line != current_line ||
+     Pike_compiler->last_file != current_file)
   {
-    if(Pike_compiler->last_file != current_file)
+    if((Pike_compiler->last_file != current_file) ||
+       (DO_NOT_WARN((INT32)(PC - Pike_compiler->last_pc)) == 127))
     {
       char *tmp;
+      INT32 remain = DO_NOT_WARN((INT32)current_file->len)<<
+	current_file->size_shift;
+
       if(Pike_compiler->last_file) free_string(Pike_compiler->last_file);
       add_to_linenumbers(127);
-      for(tmp=current_file->str; *tmp; tmp++)
+      insert_small_number(DO_NOT_WARN((INT32)current_file->len));
+      add_to_linenumbers(current_file->size_shift);
+      for(tmp=current_file->str; remain-- > 0; tmp++)
 	add_to_linenumbers(*tmp);
-      add_to_linenumbers(0);
       copy_shared_string(Pike_compiler->last_file, current_file);
     }
     insert_small_number(DO_NOT_WARN((INT32)(PC-Pike_compiler->last_pc)));
     insert_small_number(current_line-Pike_compiler->last_line);
-    Pike_compiler->last_line=current_line;
+    Pike_compiler->last_line = current_line;
     Pike_compiler->last_pc = DO_NOT_WARN((INT32)PC);
   }
 }
@@ -3966,28 +4020,44 @@ void store_linenumber(INT32 current_line, struct pike_string *current_file)
 /* Returns the file where the program is defined. The line of the
  * class start is written to linep, or 0 if the program is the top
  * level of the file. */
-PMOD_EXPORT char *get_program_line(struct program *prog, INT32 *linep)
+PMOD_EXPORT struct pike_string *get_program_line(struct program *prog,
+						 INT32 *linep)
 {
-  char *file, *cnt;
+  char *cnt;
+  size_t len = 0;
+  INT32 shift = 0;
+  char *file = NULL;
 
   if(prog == Pike_compiler->new_program)
   {
+    struct pike_string *optimizer;
     linep[0]=0;
-    return "Optimizer";
+    MAKE_CONSTANT_SHARED_STRING(optimizer, "Optimizer");
+    return optimizer;
   }
 
   cnt = prog->linenumbers;
-  file = "-";
   if (cnt < prog->linenumbers + prog->num_linenumbers) {
     if (*cnt == 127) {
-      file = cnt + 1;
-      cnt = file + strlen(file) + 1;
+      cnt++;
+      len = get_small_number(&cnt);
+      shift = *cnt;
+      file = ++cnt;
+      cnt += len<<shift;
     }
-    get_small_number(&cnt);
+    get_small_number(&cnt);	/* Ignore the offset */
     *linep = get_small_number(&cnt);
   }
   else *linep = 0;
-  return file;
+  if (file) {
+    struct pike_string *str = begin_wide_shared_string(len, shift);
+    memcpy(str->str, file, len<<shift);
+    return end_shared_string(str);
+  } else {
+    struct pike_string *dash;
+    MAKE_CONSTANT_SHARED_STRING(dash, "-");
+    return dash;
+  }
 }
 
 /*
@@ -3996,43 +4066,57 @@ PMOD_EXPORT char *get_program_line(struct program *prog, INT32 *linep)
  * program, and line will be initialized to the line
  * in that file.
  */
-PMOD_EXPORT char *get_line(PIKE_OPCODE_T *pc,struct program *prog,INT32 *linep)
+PMOD_EXPORT struct pike_string *get_line(PIKE_OPCODE_T *pc,
+					 struct program *prog, INT32 *linep)
 {
-  static char *file, *cnt;
+  static char *file = NULL;
+  static char *cnt;
   static INT32 off,line,pid;
+  static size_t len;
+  static INT32 shift;
   ptrdiff_t offset;
 
   if (prog == 0) {
+    struct pike_string *unknown_program;
     *linep = 0;
-    return "Unknown program";
+    MAKE_CONSTANT_SHARED_STRING(unknown_program, "Unknown program");
+    return unknown_program;
   }
   offset = pc - prog->program;
 
   if(prog == Pike_compiler->new_program)
   {
+    struct pike_string *optimizer;
     linep[0]=0;
-    return "Optimizer";
+    MAKE_CONSTANT_SHARED_STRING(optimizer, "Optimizer");
+    return optimizer;
   }
 
   if(prog->id != pid || offset < off)
   {
     cnt=prog->linenumbers;
     off=line=0;
-    file="Line not found";
     pid=prog->id;
+    file = 0;
   }else{
     goto fromold;
   }
 
-  if ((offset > (ptrdiff_t)prog->num_program) || (offset < 0))
-    return file;
+  if ((offset > (ptrdiff_t)prog->num_program) || (offset < 0)) {
+    struct pike_string *res = begin_wide_shared_string(len, shift);
+    memcpy(res->str, file, len<<shift);
+    return end_shared_string(res);
+  }
 
   while(cnt < prog->linenumbers + prog->num_linenumbers)
   {
     if(*cnt == 127)
     {
-      file=cnt+1;
-      cnt=file+strlen(file)+1;
+      cnt++;
+      len = get_small_number(&cnt);
+      shift = *cnt;
+      file = ++cnt;
+      cnt += len<<shift;
     }
     off+=get_small_number(&cnt);
     if(off > offset) break;
@@ -4040,7 +4124,15 @@ PMOD_EXPORT char *get_line(PIKE_OPCODE_T *pc,struct program *prog,INT32 *linep)
     line+=get_small_number(&cnt);
   }
   linep[0]=line;
-  return file;
+  if (!file) {
+    struct pike_string *not_found;
+    MAKE_CONSTANT_SHARED_STRING(not_found, "Line not found");
+    return not_found;
+  } else {
+    struct pike_string *res = begin_wide_shared_string(len, shift);
+    memcpy(res->str, file, len<<shift);
+    return end_shared_string(res);
+  }
 }
 
 void my_yyerror(char *fmt,...)  ATTRIBUTE((format(printf,1,2)))
diff --git a/src/program.h b/src/program.h
index 21ad8d458a..8f94190df2 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.137 2001/07/12 23:15:41 hubbe Exp $
+ * $Id: program.h,v 1.138 2001/07/13 11:26:39 grubba Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -386,7 +386,7 @@ struct program *parent_compilation(int level);
 struct program *id_to_program(INT32 id);
 void optimize_program(struct program *p);
 int program_function_index_compare(const void *a,const void *b);
-char *find_program_name(struct program *p, INT32 *line);
+struct pike_string *find_program_name(struct program *p, INT32 *line);
 void fixate_program(void);
 struct program *low_allocate_program(void);
 void low_start_new_program(struct program *p,
@@ -511,9 +511,11 @@ void program_index_no_free(struct svalue *to, struct program *p,
 int get_small_number(char **q);
 void start_line_numbering(void);
 void store_linenumber(INT32 current_line, struct pike_string *current_file);
-PMOD_EXPORT char *get_program_line(struct program *prog,INT32 *linep);
-PMOD_EXPORT char *get_line(PIKE_OPCODE_T *pc, struct program *prog,
-			   INT32 *linep);
+PMOD_EXPORT struct pike_string *get_program_line(struct program *prog,
+						 INT32 *linep);
+PMOD_EXPORT struct pike_string *get_line(PIKE_OPCODE_T *pc,
+					 struct program *prog,
+					 INT32 *linep);
 void my_yyerror(char *fmt,...)  ATTRIBUTE((format(printf,1,2)));
 struct program *compile(struct pike_string *prog,
 			struct object *handler,
-- 
GitLab