[BusyBox-cvs] busybox/editors sed.c,1.128,1.129

Glenn McGrath bug1 at busybox.net
Sat Apr 12 16:10:45 UTC 2003


Update of /var/cvs/busybox/editors
In directory winder:/tmp/cvs-serv31720

Modified Files:
	sed.c 
Log Message:
Fix logic error in grouped commands


Index: sed.c
===================================================================
RCS file: /var/cvs/busybox/editors/sed.c,v
retrieving revision 1.128
retrieving revision 1.129
diff -u -d -r1.128 -r1.129
--- sed.c	11 Apr 2003 17:10:23 -0000	1.128
+++ sed.c	12 Apr 2003 16:10:42 -0000	1.129
@@ -68,6 +68,13 @@
 	regex_t *beg_match;	/* sed -e '/match/cmd' */
 	regex_t *end_match;	/* sed -e '/match/,/end_match/cmd' */
 
+	int beg_line;		/* 'sed 1p'   0 == no begining line, apply commands to all lines */
+	int end_line;		/* 'sed 1,3p' 0 == no end line, use only beginning. -1 == $ */
+
+	/* inversion flag */
+	int invert;			/* the '!' after the address */
+//	int block_cmd;	/* This command is part of a group that has a command address */
+
 	/* SUBSTITUTION COMMAND SPECIFIC FIELDS */
 
 	/* sed -e 's/sub_match/replace/' */
@@ -80,9 +87,6 @@
 	/* FILE COMMAND (r) SPECIFIC FIELDS */
 	char *filename;
 
-	/* address storage */
-	int beg_line;		/* 'sed 1p'   0 == no begining line, apply commands to all lines */
-	int end_line;		/* 'sed 1,3p' 0 == no end line, use only beginning. -1 == $ */
 	/* SUBSTITUTION COMMAND SPECIFIC FIELDS */
 
 	unsigned int num_backrefs:4;	/* how many back references (\1..\9) */
@@ -98,9 +102,6 @@
 	/* the command */
 	char cmd;			/* p,d,s (add more at your leisure :-) */
 
-	/* inversion flag */
-	int invert;			/* the '!' after the address */
-
 	/* Branch commands */
 	char *label;
 
@@ -124,9 +125,7 @@
 /* linked list of sed commands */
 static sed_cmd_t sed_cmd_head;
 static sed_cmd_t *sed_cmd_tail = &sed_cmd_head;
-static sed_cmd_t *block_cmd;
 
-static int in_block = 0;
 const char *const semicolon_whitespace = "; \n\r\t\v\0";
 static regex_t *previous_regex_ptr = NULL;
 
@@ -484,7 +483,7 @@
 	/* if it wasnt a single-letter command that takes no arguments
 	 * then it must be an invalid command.
 	 */
-	else if (strchr("dghnNpPqx=", sed_cmd->cmd) == 0) {
+	else if (strchr("dghnNpPqx={}", sed_cmd->cmd) == 0) {
 		bb_error_msg_and_die("Unsupported command %c", sed_cmd->cmd);
 	}
 
@@ -512,13 +511,6 @@
 		return (strpbrk(cmdstr, "\n\r"));
 	}
 
-	/* Test for end of block */
-	if (*cmdstr == '}') {
-		in_block = 0;
-		cmdstr++;
-		return (cmdstr);
-	}
-
 	/* parse the command
 	 * format is: [addr][,addr]cmd
 	 *            |----||-----||-|
@@ -571,28 +563,9 @@
 	if (*cmdstr == '\0')
 		bb_error_msg_and_die("missing command");
 
-	/* This is the start of a block of commands */
-	if (*cmdstr == '{') {
-		if (in_block != 0) {
-			bb_error_msg_and_die("cant handle sub-blocks");
-		}
-		in_block = 1;
-		block_cmd = sed_cmd;
-
-		return (cmdstr + 1);
-	}
-
 	sed_cmd->cmd = *cmdstr;
 	cmdstr++;
 
-	if (in_block == 1) {
-		sed_cmd->beg_match = block_cmd->beg_match;
-		sed_cmd->end_match = block_cmd->end_match;
-		sed_cmd->beg_line = block_cmd->beg_line;
-		sed_cmd->end_line = block_cmd->end_line;
-		sed_cmd->invert = block_cmd->invert;
-	}
-
 	cmdstr = parse_cmd_str(sed_cmd, cmdstr);
 
 	/* Add the command to the command array */
@@ -828,12 +801,14 @@
 	if (pattern_space == NULL) {
 		return;
 	}
-
+ 
 	/* go through every line in the file */
 	do {
 		char *next_line;
 		sed_cmd_t *sed_cmd;
 		int substituted = 0;
+		/* This enables whole blocks of commands to be mask'ed out if the lead address doesnt match */
+		int block_mask = 1;
 
 		/* Read one line in advance so we can act on the last line, the '$' address */
 		next_line = bb_get_chomped_line_from_file(file);
@@ -855,7 +830,7 @@
 					&& sed_cmd->beg_match == NULL
 					&& sed_cmd->end_match == NULL) ||
 				/* this line number is the first address we're looking for */
-				(sed_cmd->beg_line && (sed_cmd->beg_line == linenum)) ||
+				(sed_cmd->beg_line > 0 && (sed_cmd->beg_line == linenum)) ||
 				/* this line matches our first address regex */
 				(sed_cmd->beg_match
 					&& (regexec(sed_cmd->beg_match, pattern_space, 0, NULL,
@@ -865,7 +840,12 @@
 					&& (next_line == NULL))
 				);
 
-			if (sed_cmd->invert ^ matched) {
+			if (sed_cmd->cmd == '{') {
+				block_mask = block_mask & matched;
+			}
+//			matched &= block_mask;
+
+			if (sed_cmd->invert ^ (matched & block_mask)) {
 				/* Update last used regex incase a blank substitute BRE is found */
 				if (sed_cmd->beg_match) {
 					previous_regex_ptr = sed_cmd->beg_match;
@@ -1060,11 +1040,10 @@
 					break;
 				case 'x':{
 					/* Swap hold and pattern space */
-					char *tmp;
-
-					tmp = pattern_space;
+					char *tmp = pattern_space;
 					pattern_space = hold_space;
 					hold_space = tmp;
+					break;
 				}
 				}
 			}
@@ -1081,7 +1060,7 @@
 					 * isn't the first time through) and.. */
 					|| ((still_in_range == 1)
 						/* this line number is the last address we're looking for or... */
-						&& ((sed_cmd->end_line
+						&& ((sed_cmd->end_line > 0
 								&& (sed_cmd->end_line == linenum))
 							/* this line matches our last address regex */
 							|| (sed_cmd->end_match
@@ -1093,6 +1072,10 @@
 					/* didn't hit the exit? then we're still in the middle of an address range */
 					still_in_range = 1;
 				}
+			}
+
+			if (sed_cmd->cmd == '}') {
+				block_mask = 1;
 			}
 
 			if (deleted)



More information about the busybox-cvs mailing list