[gnu.utils.bug] more sed fixes

tarvaine@tukki.jyu.fi (Tapani Tarvainen) (10/17/89)

(1) '\n' didn't work in context addresses (yes, I have a real
    script that needs it).  This was easy to fix (effectively
    copied code from 's').

(2) Delimiters that normally mustn't be preceded by \ didn't
    work properly, e.g., 'sw\wordwouchw' would become 's/\word/ouch/'
    instead of 's/word/ouch/' as it should.  (This is rather
    unlikely to be of any consequence, but I fixed it anyway -
    it wasn't hard.)

(3) 'a' and 'r' command worked by copying the text to be appended to a
    buffer in memory - one runs out of memory easily that way, especially
    with 'r', and it wasted time, too.  I rewrote their handling so that
    when they're encountered during execution a pointer is added to a list
    which is then processed at the end.  Now you can read an arbitrarily
    big file with 'r' without difficulties.


Below is context diff from my previous version.  If you want diffs
from 1.06 distribution or the entire sed.c as it now stands (not
much longer than the diff by now) just send me mail.


*** sed.old	Mon Oct 16 20:56:24 1989
--- sed.c	Mon Oct 16 21:27:45 1989
***************
*** 1,7 ****
  
  /*  GNU SED, a batch stream editor.
      Copyright (C) 1989, Free Software Foundation, Inc.
! 	Last changed by Tapani Tarvainen 13 October 1989
  
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
--- 1,7 ----
  
  /*  GNU SED, a batch stream editor.
      Copyright (C) 1989, Free Software Foundation, Inc.
! 	Last changed by Tapani Tarvainen 16 October 1989
  
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
***************
*** 49,69 ****
  	- fixed a bug in append_pattern_space
  	  (moved n==0 test to beginning of loop)
  	- fixed 's/any//' so it won't do ck_malloc(0)
! 	- fixed 'r' reallocation of append buffer
! 	- changed 'a' reallocation: double append buffer when it overflows
! 	  instead of adding just enough for the new line
  	- fixed handling of comments at end of file
  	- changed error and usage messages slightly (print usage
  	  if no arguments, remove path from name in messages)
  	- moved some ANSI-routine replacements inside #ifndef __STDC__
  	  (introduced ck_strdup)
! 	- added ANSI-style prorotypes for everything (so this compiles
  	  OK even when sizeof(int) != sizeof(pointer) ...)
  	- added \x delimiter syntax for context addresses
  	  (e.g., '\-string-p' works like '/string/p')
  */
  
- 
  #ifdef MSDOS	/* MicroSoft C 5.1 defines this	*/
  #define __MSDOS__
  #endif
--- 49,69 ----
  	- fixed a bug in append_pattern_space
  	  (moved n==0 test to beginning of loop)
  	- fixed 's/any//' so it won't do ck_malloc(0)
! 	- rewrote 'a' and 'r' handling so that they no longer need
! 	  to store an extra copy of the string/file to be appended
!	- fixed \n behaviour in context addresses
!	- fixed \delimiter behaviour with odd delimiters
  	- fixed handling of comments at end of file
  	- changed error and usage messages slightly (print usage
  	  if no arguments, remove path from name in messages)
  	- moved some ANSI-routine replacements inside #ifndef __STDC__
  	  (introduced ck_strdup)
! 	- added ANSI-style prototypes for everything (so this compiles
  	  OK even when sizeof(int) != sizeof(pointer) ...)
  	- added \x delimiter syntax for context addresses
  	  (e.g., '\-string-p' works like '/string/p')
  */
  
  #ifdef MSDOS	/* MicroSoft C 5.1 defines this	*/
  #define __MSDOS__
  #endif
***************
*** 312,319 ****
  /* An input line that's been stored by later use by the program */
  struct line hold;
  
! /* A 'line' to append to the current line when it comes time to write it out */
! struct line append;
  
  
  /* When we're reading a script command from a string, 'prog_start' and 'prog_end' point
--- 312,320 ----
  /* An input line that's been stored by later use by the program */
  struct line hold;
  
! /* list of 'a' and 'r' commands to be executed at the end */
! struct sed_cmd **append_list;
! unsigned append_alloc, append_used;
  
  
  /* When we're reading a script command from a string, 'prog_start' and 'prog_end' point
***************
*** 424,432 ****
  	line.alloc=50;
  	line.text=ck_malloc(50);
  
! 	append.length=0;
! 	append.alloc=50;
! 	append.text=ck_malloc(50);
  
  	hold.length=0;
  	hold.alloc=50;
--- 425,433 ----
  	line.alloc=50;
  	line.text=ck_malloc(50);
  
! 	append_alloc = 10;
! 	append_list = ck_malloc(append_alloc * sizeof(struct sed_cmd *));
! 	append_used = 0;
  
  	hold.length=0;
  	hold.alloc=50;
***************
*** 681,687 ****
  				case EOF:
  					break;
  				default:
! 					add1_buffer(b,'\\');
  					add1_buffer(b,ch);
  					break;
  				}
--- 682,689 ----
  				case EOF:
  					break;
  				default:
! 					if (ch != slash)
! 						add1_buffer(b,'\\');
  					add1_buffer(b,ch);
  					break;
  				}
***************
*** 868,876 ****
  {
  	int	ch;
  	int	num;
  	char	*b;
  	VOID	*init_buffer();
- 	char	slash = '/';
  
  	ch=inchar();
  
--- 870,878 ----
  {
  	int	ch;
  	int	num;
+ 	int	slash;
  	char	*b;
  	VOID	*init_buffer();
  
  	ch=inchar();
  
***************
*** 884,898 ****
  		addr->addr_type=ADDR_NUM;
  		addr->addr_number = num;
  		return 1;
! 	} else if(ch=='/' || ch=='\\' && (slash = inchar()) != EOF) {
  		addr->addr_type=ADDR_REGEX;
  		b=init_buffer();
  		while((ch=inchar())!=EOF && ch!=slash) {
  			add1_buffer(b,ch);
  			if(ch=='\\') {
! 				ch=inchar();
! 				if(ch!=EOF)
  					add1_buffer(b,ch);
  			}
  		}
  		if(size_buffer(b)) {
--- 886,909 ----
  		addr->addr_type=ADDR_NUM;
  		addr->addr_number = num;
  		return 1;
! 	} else if(ch=='/' || ch=='\\' && (ch = inchar()) != EOF) {
! 		slash = ch;
  		addr->addr_type=ADDR_REGEX;
  		b=init_buffer();
  		while((ch=inchar())!=EOF && ch!=slash) {
  			add1_buffer(b,ch);
  			if(ch=='\\') {
! 				switch(ch=inchar()) {
! 				case 'n':
! 					add1_buffer(b,'\n');
! 					break;
! 				default:
! 					if (ch != slash)
! 						add1_buffer(b,'\\');
  					add1_buffer(b,ch);
+ 				case EOF:
+ 					break;
+ 				}
  			}
  		}
  		if(size_buffer(b)) {
***************
*** 1030,1038 ****
  		execute_program(the_program);
  		if(!no_default_output)
  			ck_fwrite(line.text,1,line.length,stdout);
! 		if(append.length) {
! 			ck_fwrite(append.text,1,append.length,stdout);
! 			append.length=0;
  		}
  		if(quit_cmd)
  			break;
--- 1041,1063 ----
  		execute_program(the_program);
  		if(!no_default_output)
  			ck_fwrite(line.text,1,line.length,stdout);
! 		if (append_used) {
! 			struct sed_cmd *cur_cmd;
! 			int n, i;
! 			char tmp_buf[1024];
! 			for (i = 0; i < append_used; i++) {
! 				cur_cmd = append_list[i];
! 				if (cur_cmd->cmd == 'a') {
! 					ck_fwrite(cur_cmd->x.cmd_txt.text,1,
! 					  cur_cmd->x.cmd_txt.text_len,stdout);
! 				} else { /* 'r' */
! 					rewind(cur_cmd->x.io_file);
! 					while((n=fread(tmp_buf,sizeof(char),1024,cur_cmd->x.io_file))>0)
! 						ck_fwrite(tmp_buf,1,n,stdout);
! 					if(ferror(cur_cmd->x.io_file))
! 						panic("Read error on input file to 'r' command\n");
! 				}
! 			}
  		}
  		if(quit_cmd)
  			break;
***************
*** 1095,1106 ****
  			break;
  
  		case 'a':
! 			while(append.alloc-append.length<cur_cmd->x.cmd_txt.text_len) {
! 				append.alloc *= 2;
! 				append.text=ck_realloc(append.text,append.alloc);
  			}
! 			bcopy(cur_cmd->x.cmd_txt.text,append.text+append.length,cur_cmd->x.cmd_txt.text_len);
! 			append.length+=cur_cmd->x.cmd_txt.text_len;
  			break;
  
  		case 'b':
--- 1120,1132 ----
  			break;
  
  		case 'a':
! 		case 'r':
! 			if (append_used == append_alloc) {
! 				append_alloc += 10;
! 				append_list = ck_realloc(append_list,
! 					append_alloc * sizeof(struct sed_cmd *));
  			}
! 			append_list[append_used++] = cur_cmd;
  			break;
  
  		case 'b':
***************
*** 1249,1271 ****
  		case 'q':
  quit:			quit_cmd++;
  			end_cycle++;
- 			break;
- 
- 		case 'r':
- 			{
- 				int n=0;
- 
- 				rewind(cur_cmd->x.io_file);
- 				do {
- 					append.length += n;
- 					if(append.length==append.alloc) {
- 						append.alloc *= 2;
- 						append.text = ck_realloc(append.text, append.alloc);
- 					}
- 				} while((n=fread(append.text+append.length,sizeof(char),append.alloc-append.length,cur_cmd->x.io_file))>0);
- 				if(ferror(cur_cmd->x.io_file))
- 					panic("Read error on input file to 'r' command\n");
- 			}
  			break;
  
  		case 's':
--- 1275,1280 ----
-- 
Tapani Tarvainen    (tarvaine@tukki.jyu.fi, tarvainen@finjyu.bitnet)

tarvaine@tukki.jyu.fi (Tapani Tarvainen) (10/17/89)

In article <1520@tukki.jyu.fi> tarvaine@tukki.jyu.fi I sent a patch for
sed.  The diff was incorrect, please junk it and use the one below instead.



*** sed.old	Mon Oct 16 20:56:24 1989
--- sed.c	Tue Oct 17 09:11:30 1989
***************
*** 1,7 ****
  
  /*  GNU SED, a batch stream editor.
      Copyright (C) 1989, Free Software Foundation, Inc.
! 	Last changed by Tapani Tarvainen 13 October 1989
  
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
--- 1,7 ----
  
  /*  GNU SED, a batch stream editor.
      Copyright (C) 1989, Free Software Foundation, Inc.
! 	Last changed by Tapani Tarvainen 17 October 1989
  
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
***************
*** 49,69 ****
  	- fixed a bug in append_pattern_space
  	  (moved n==0 test to beginning of loop)
  	- fixed 's/any//' so it won't do ck_malloc(0)
! 	- fixed 'r' reallocation of append buffer
! 	- changed 'a' reallocation: double append buffer when it overflows
! 	  instead of adding just enough for the new line
  	- fixed handling of comments at end of file
  	- changed error and usage messages slightly (print usage
  	  if no arguments, remove path from name in messages)
  	- moved some ANSI-routine replacements inside #ifndef __STDC__
  	  (introduced ck_strdup)
! 	- added ANSI-style prorotypes for everything (so this compiles
  	  OK even when sizeof(int) != sizeof(pointer) ...)
  	- added \x delimiter syntax for context addresses
  	  (e.g., '\-string-p' works like '/string/p')
  */
  
- 
  #ifdef MSDOS	/* MicroSoft C 5.1 defines this	*/
  #define __MSDOS__
  #endif
--- 49,67 ----
  	- fixed a bug in append_pattern_space
  	  (moved n==0 test to beginning of loop)
  	- fixed 's/any//' so it won't do ck_malloc(0)
! 	- rewrote 'a' and 'r' handling so that they no longer need
! 	  to store an extra copy of the string/file to be appended
  	- fixed handling of comments at end of file
  	- changed error and usage messages slightly (print usage
  	  if no arguments, remove path from name in messages)
  	- moved some ANSI-routine replacements inside #ifndef __STDC__
  	  (introduced ck_strdup)
! 	- added ANSI-style prototypes for everything (so this compiles
  	  OK even when sizeof(int) != sizeof(pointer) ...)
  	- added \x delimiter syntax for context addresses
  	  (e.g., '\-string-p' works like '/string/p')
  */
  
  #ifdef MSDOS	/* MicroSoft C 5.1 defines this	*/
  #define __MSDOS__
  #endif
***************
*** 312,319 ****
  /* An input line that's been stored by later use by the program */
  struct line hold;
  
! /* A 'line' to append to the current line when it comes time to write it out */
! struct line append;
  
  
  /* When we're reading a script command from a string, 'prog_start' and 'prog_end' point
--- 310,318 ----
  /* An input line that's been stored by later use by the program */
  struct line hold;
  
! /* list of 'a' and 'r' commands to be executed at the end */
! struct sed_cmd **append_list;
! unsigned append_alloc, append_used;
  
  
  /* When we're reading a script command from a string, 'prog_start' and 'prog_end' point
***************
*** 424,432 ****
  	line.alloc=50;
  	line.text=ck_malloc(50);
  
! 	append.length=0;
! 	append.alloc=50;
! 	append.text=ck_malloc(50);
  
  	hold.length=0;
  	hold.alloc=50;
--- 423,431 ----
  	line.alloc=50;
  	line.text=ck_malloc(50);
  
! 	append_alloc = 10;
! 	append_list = ck_malloc(append_alloc * sizeof(struct sed_cmd *));
! 	append_used = 0;
  
  	hold.length=0;
  	hold.alloc=50;
***************
*** 681,687 ****
  				case EOF:
  					break;
  				default:
! 					add1_buffer(b,'\\');
  					add1_buffer(b,ch);
  					break;
  				}
--- 680,687 ----
  				case EOF:
  					break;
  				default:
! 					if (ch != slash)
! 						add1_buffer(b,'\\');
  					add1_buffer(b,ch);
  					break;
  				}
***************
*** 868,876 ****
  {
  	int	ch;
  	int	num;
  	char	*b;
  	VOID	*init_buffer();
- 	char	slash = '/';
  
  	ch=inchar();
  
--- 868,876 ----
  {
  	int	ch;
  	int	num;
+ 	int	slash;
  	char	*b;
  	VOID	*init_buffer();
  
  	ch=inchar();
  
***************
*** 884,898 ****
  		addr->addr_type=ADDR_NUM;
  		addr->addr_number = num;
  		return 1;
! 	} else if(ch=='/' || ch=='\\' && (slash = inchar()) != EOF) {
  		addr->addr_type=ADDR_REGEX;
  		b=init_buffer();
  		while((ch=inchar())!=EOF && ch!=slash) {
  			add1_buffer(b,ch);
  			if(ch=='\\') {
! 				ch=inchar();
! 				if(ch!=EOF)
  					add1_buffer(b,ch);
  			}
  		}
  		if(size_buffer(b)) {
--- 884,907 ----
  		addr->addr_type=ADDR_NUM;
  		addr->addr_number = num;
  		return 1;
! 	} else if(ch=='/' || ch=='\\' && (ch = inchar()) != EOF) {
! 		slash = ch;
  		addr->addr_type=ADDR_REGEX;
  		b=init_buffer();
  		while((ch=inchar())!=EOF && ch!=slash) {
  			add1_buffer(b,ch);
  			if(ch=='\\') {
! 				switch(ch=inchar()) {
! 				case 'n':
! 					add1_buffer(b,'\n');
! 					break;
! 				default:
! 					if (ch != slash)
! 						add1_buffer(b,'\\');
  					add1_buffer(b,ch);
+ 				case EOF:
+ 					break;
+ 				}
  			}
  		}
  		if(size_buffer(b)) {
***************
*** 1030,1038 ****
  		execute_program(the_program);
  		if(!no_default_output)
  			ck_fwrite(line.text,1,line.length,stdout);
! 		if(append.length) {
! 			ck_fwrite(append.text,1,append.length,stdout);
! 			append.length=0;
  		}
  		if(quit_cmd)
  			break;
--- 1039,1062 ----
  		execute_program(the_program);
  		if(!no_default_output)
  			ck_fwrite(line.text,1,line.length,stdout);
! 		if (append_used) {
! 			struct sed_cmd *cur_cmd;
! 			int n, i;
! 			char tmp_buf[1024];
! 			for (i = 0; i < append_used; i++) {
! 				cur_cmd = append_list[i];
! 				if (cur_cmd->cmd == 'a') {
! 					ck_fwrite(cur_cmd->x.cmd_txt.text,1,
! 					  cur_cmd->x.cmd_txt.text_len,stdout);
! 				} else { /* 'r' */
! 					rewind(cur_cmd->x.io_file);
! 					while((n=fread(tmp_buf,sizeof(char),1024,cur_cmd->x.io_file))>0)
! 						ck_fwrite(tmp_buf,1,n,stdout);
! 					if(ferror(cur_cmd->x.io_file))
! 						panic("Read error on input file to 'r' command\n");
! 				}
! 			}
! 			append_used = 0;
  		}
  		if(quit_cmd)
  			break;
***************
*** 1095,1106 ****
  			break;
  
  		case 'a':
! 			while(append.alloc-append.length<cur_cmd->x.cmd_txt.text_len) {
! 				append.alloc *= 2;
! 				append.text=ck_realloc(append.text,append.alloc);
  			}
! 			bcopy(cur_cmd->x.cmd_txt.text,append.text+append.length,cur_cmd->x.cmd_txt.text_len);
! 			append.length+=cur_cmd->x.cmd_txt.text_len;
  			break;
  
  		case 'b':
--- 1119,1131 ----
  			break;
  
  		case 'a':
! 		case 'r':
! 			if (append_used == append_alloc) {
! 				append_alloc += 10;
! 				append_list = ck_realloc(append_list,
! 					append_alloc * sizeof(struct sed_cmd *));
  			}
! 			append_list[append_used++] = cur_cmd;
  			break;
  
  		case 'b':
***************
*** 1249,1271 ****
  		case 'q':
  quit:			quit_cmd++;
  			end_cycle++;
- 			break;
- 
- 		case 'r':
- 			{
- 				int n=0;
- 
- 				rewind(cur_cmd->x.io_file);
- 				do {
- 					append.length += n;
- 					if(append.length==append.alloc) {
- 						append.alloc *= 2;
- 						append.text = ck_realloc(append.text, append.alloc);
- 					}
- 				} while((n=fread(append.text+append.length,sizeof(char),append.alloc-append.length,cur_cmd->x.io_file))>0);
- 				if(ferror(cur_cmd->x.io_file))
- 					panic("Read error on input file to 'r' command\n");
- 			}
  			break;
  
  		case 's':
--- 1274,1279 ----
-- 
Tapani Tarvainen    (tarvaine@tukki.jyu.fi, tarvainen@finjyu.bitnet)

tarvaine@tukki.jyu.fi (Tapani Tarvainen) (10/17/89)

In article <1523@tukki.jyu.fi> tarvaine@tukki.jyu.fi I wrote:
>In article <1520@tukki.jyu.fi> tarvaine@tukki.jyu.fi I sent a patch for
>sed.  The diff was incorrect, please junk it and use the one below instead.

Oops ... it still wasn't correct (this is getting a bit embarrassing).
Let's hope I'll get it right this time.

Oh, this one has yet another change:  ? and + are now normal characters
in regexps, the operators are now \? and \+.  (Nobody commented my query
about whether this would be a good idea, so I'll stick to my own opinion.
If you don't like it, just delete the re_set_syntax() call - that's all
there is to it.)


*** sed.old	Mon Oct 16 20:56:24 1989
--- sed.c	Tue Oct 17 13:16:48 1989
***************
*** 1,7 ****
  
  /*  GNU SED, a batch stream editor.
      Copyright (C) 1989, Free Software Foundation, Inc.
! 	Last changed by Tapani Tarvainen 13 October 1989
  
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
--- 1,7 ----
  
  /*  GNU SED, a batch stream editor.
      Copyright (C) 1989, Free Software Foundation, Inc.
! 	Last changed by Tapani Tarvainen 17 October 1989
  
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
***************
*** 49,69 ****
  	- fixed a bug in append_pattern_space
  	  (moved n==0 test to beginning of loop)
  	- fixed 's/any//' so it won't do ck_malloc(0)
! 	- fixed 'r' reallocation of append buffer
! 	- changed 'a' reallocation: double append buffer when it overflows
! 	  instead of adding just enough for the new line
  	- fixed handling of comments at end of file
  	- changed error and usage messages slightly (print usage
  	  if no arguments, remove path from name in messages)
  	- moved some ANSI-routine replacements inside #ifndef __STDC__
  	  (introduced ck_strdup)
! 	- added ANSI-style prorotypes for everything (so this compiles
  	  OK even when sizeof(int) != sizeof(pointer) ...)
  	- added \x delimiter syntax for context addresses
  	  (e.g., '\-string-p' works like '/string/p')
  */
  
- 
  #ifdef MSDOS	/* MicroSoft C 5.1 defines this	*/
  #define __MSDOS__
  #endif
--- 49,69 ----
  	- fixed a bug in append_pattern_space
  	  (moved n==0 test to beginning of loop)
  	- fixed 's/any//' so it won't do ck_malloc(0)
! 	- rewrote 'a' and 'r' handling so that they no longer need
! 	  to store an extra copy of the string/file to be appended
! 	- changed regex syntax to use ? and + as normal characters
! 	  and \? and \+ as operators
  	- fixed handling of comments at end of file
  	- changed error and usage messages slightly (print usage
  	  if no arguments, remove path from name in messages)
  	- moved some ANSI-routine replacements inside #ifndef __STDC__
  	  (introduced ck_strdup)
! 	- added ANSI-style prototypes for everything (so this compiles
  	  OK even when sizeof(int) != sizeof(pointer) ...)
  	- added \x delimiter syntax for context addresses
  	  (e.g., '\-string-p' works like '/string/p')
  */
  
  #ifdef MSDOS	/* MicroSoft C 5.1 defines this	*/
  #define __MSDOS__
  #endif
***************
*** 312,319 ****
  /* An input line that's been stored by later use by the program */
  struct line hold;
  
! /* A 'line' to append to the current line when it comes time to write it out */
! struct line append;
  
  
  /* When we're reading a script command from a string, 'prog_start' and 'prog_end' point
--- 312,320 ----
  /* An input line that's been stored by later use by the program */
  struct line hold;
  
! /* list of 'a' and 'r' commands to be executed at the end */
! struct sed_cmd **append_list;
! unsigned append_alloc, append_used;
  
  
  /* When we're reading a script command from a string, 'prog_start' and 'prog_end' point
***************
*** 384,389 ****
--- 385,392 ----
  	}
  #endif
  
+ 	re_set_syntax(RE_BK_PLUS_QM);
+ 
  	while((opt=getopt(argc,argv,"ne:f:"))!=EOF) {
  		switch(opt) {
  		case 'n':
***************
*** 424,432 ****
  	line.alloc=50;
  	line.text=ck_malloc(50);
  
! 	append.length=0;
! 	append.alloc=50;
! 	append.text=ck_malloc(50);
  
  	hold.length=0;
  	hold.alloc=50;
--- 427,435 ----
  	line.alloc=50;
  	line.text=ck_malloc(50);
  
! 	append_alloc = 10;
! 	append_list = ck_malloc(append_alloc * sizeof(struct sed_cmd *));
! 	append_used = 0;
  
  	hold.length=0;
  	hold.alloc=50;
***************
*** 465,471 ****
  compile_file(str)
  char *str;
  {
- /*	FILE *file;	*/
  	int ch;
  
  	prog_start=prog_cur=prog_end=0;
--- 468,473 ----
***************
*** 681,687 ****
  				case EOF:
  					break;
  				default:
! 					add1_buffer(b,'\\');
  					add1_buffer(b,ch);
  					break;
  				}
--- 683,690 ----
  				case EOF:
  					break;
  				default:
! 					if (ch != slash)
! 						add1_buffer(b,'\\');
  					add1_buffer(b,ch);
  					break;
  				}
***************
*** 868,876 ****
  {
  	int	ch;
  	int	num;
  	char	*b;
  	VOID	*init_buffer();
- 	char	slash = '/';
  
  	ch=inchar();
  
--- 871,879 ----
  {
  	int	ch;
  	int	num;
+ 	int	slash;
  	char	*b;
  	VOID	*init_buffer();
  
  	ch=inchar();
  
***************
*** 884,899 ****
  		addr->addr_type=ADDR_NUM;
  		addr->addr_number = num;
  		return 1;
! 	} else if(ch=='/' || ch=='\\' && (slash = inchar()) != EOF) {
  		addr->addr_type=ADDR_REGEX;
  		b=init_buffer();
  		while((ch=inchar())!=EOF && ch!=slash) {
- 			add1_buffer(b,ch);
  			if(ch=='\\') {
! 				ch=inchar();
! 				if(ch!=EOF)
  					add1_buffer(b,ch);
! 			}
  		}
  		if(size_buffer(b)) {
  			last_regex=(struct re_pattern_buffer *)ck_malloc(sizeof(struct re_pattern_buffer));
--- 887,912 ----
  		addr->addr_type=ADDR_NUM;
  		addr->addr_number = num;
  		return 1;
! 	} else if(ch=='/' || ch=='\\' && (ch = inchar()) != EOF) {
! 		slash = ch;
  		addr->addr_type=ADDR_REGEX;
  		b=init_buffer();
  		while((ch=inchar())!=EOF && ch!=slash) {
  			if(ch=='\\') {
! 				switch(ch=inchar()) {
! 				case 'n':
! 					add1_buffer(b,'\n');
! 					break;
! 				default:
! 					if (ch != slash)
! 						add1_buffer(b,'\\');
  					add1_buffer(b,ch);
! 					break;
! 				case EOF:
! 					break;
! 				}
! 			} else
! 				add1_buffer(b,ch);
  		}
  		if(size_buffer(b)) {
  			last_regex=(struct re_pattern_buffer *)ck_malloc(sizeof(struct re_pattern_buffer));
***************
*** 1030,1038 ****
  		execute_program(the_program);
  		if(!no_default_output)
  			ck_fwrite(line.text,1,line.length,stdout);
! 		if(append.length) {
! 			ck_fwrite(append.text,1,append.length,stdout);
! 			append.length=0;
  		}
  		if(quit_cmd)
  			break;
--- 1043,1066 ----
  		execute_program(the_program);
  		if(!no_default_output)
  			ck_fwrite(line.text,1,line.length,stdout);
! 		if (append_used) {
! 			struct sed_cmd *cur_cmd;
! 			int n, i;
! 			char tmp_buf[1024];
! 			for (i = 0; i < append_used; i++) {
! 				cur_cmd = append_list[i];
! 				if (cur_cmd->cmd == 'a') {
! 					ck_fwrite(cur_cmd->x.cmd_txt.text,1,
! 					  cur_cmd->x.cmd_txt.text_len,stdout);
! 				} else { /* 'r' */
! 					rewind(cur_cmd->x.io_file);
! 					while((n=fread(tmp_buf,sizeof(char),1024,cur_cmd->x.io_file))>0)
! 						ck_fwrite(tmp_buf,1,n,stdout);
! 					if(ferror(cur_cmd->x.io_file))
! 						panic("Read error on input file to 'r' command\n");
! 				}
! 			}
! 			append_used = 0;
  		}
  		if(quit_cmd)
  			break;
***************
*** 1095,1106 ****
  			break;
  
  		case 'a':
! 			while(append.alloc-append.length<cur_cmd->x.cmd_txt.text_len) {
! 				append.alloc *= 2;
! 				append.text=ck_realloc(append.text,append.alloc);
  			}
! 			bcopy(cur_cmd->x.cmd_txt.text,append.text+append.length,cur_cmd->x.cmd_txt.text_len);
! 			append.length+=cur_cmd->x.cmd_txt.text_len;
  			break;
  
  		case 'b':
--- 1123,1135 ----
  			break;
  
  		case 'a':
! 		case 'r':
! 			if (append_used == append_alloc) {
! 				append_alloc += 10;
! 				append_list = ck_realloc(append_list,
! 					append_alloc * sizeof(struct sed_cmd *));
  			}
! 			append_list[append_used++] = cur_cmd;
  			break;
  
  		case 'b':
***************
*** 1249,1271 ****
  		case 'q':
  quit:			quit_cmd++;
  			end_cycle++;
- 			break;
- 
- 		case 'r':
- 			{
- 				int n=0;
- 
- 				rewind(cur_cmd->x.io_file);
- 				do {
- 					append.length += n;
- 					if(append.length==append.alloc) {
- 						append.alloc *= 2;
- 						append.text = ck_realloc(append.text, append.alloc);
- 					}
- 				} while((n=fread(append.text+append.length,sizeof(char),append.alloc-append.length,cur_cmd->x.io_file))>0);
- 				if(ferror(cur_cmd->x.io_file))
- 					panic("Read error on input file to 'r' command\n");
- 			}
  			break;
  
  		case 's':
--- 1278,1283 ----
-- 
Tapani Tarvainen    (tarvaine@tukki.jyu.fi, tarvainen@finjyu.bitnet)