[BusyBox-cvs] busybox/editors sed.c,1.121,1.122

Glenn McGrath bug1 at busybox.net
Tue Apr 8 06:42:48 UTC 2003


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

Modified Files:
	sed.c 
Log Message:
Fixes block commands to correctly identify end of block, recognise the #n directive, fix substitue command when regex isnt specified


Index: sed.c
===================================================================
RCS file: /var/cvs/busybox/editors/sed.c,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -d -r1.121 -r1.122
--- sed.c	7 Apr 2003 16:04:14 -0000	1.121
+++ sed.c	8 Apr 2003 06:42:45 -0000	1.122
@@ -119,8 +119,11 @@
 /* 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;
 
 #ifdef CONFIG_FEATURE_CLEAN_UP
 static void destroy_cmd_strs(void)
@@ -245,6 +248,7 @@
 			bb_error_msg_and_die("unterminated match expression");
 		}
 		my_str[idx] = '\0';
+	
 		*regex = (regex_t *)xmalloc(sizeof(regex_t));
 		xregcomp(*regex, my_str+idx_start, REG_NEWLINE);
 		idx++; /* so it points to the next character after the last '/' */
@@ -305,8 +309,11 @@
 
 out:	
 	/* compile the match string into a regex */
-	sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
-	xregcomp(sed_cmd->sub_match, match, cflags);
+	if (*match != '\0') {
+		/* If match is empty, we use last regex used at runtime */
+		sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
+		xregcomp(sed_cmd->sub_match, match, cflags);
+	}
 	free(match);
 
 	return idx;
@@ -493,8 +500,19 @@
 
 	/* if this is a comment, jump past it and keep going */
 	if (*cmdstr == '#') {
+		/* "#n" is the same as using -n on the command line */
+		if (cmdstr[1] == 'n') {
+			be_quiet++;
+		}
 		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
@@ -548,32 +566,34 @@
 	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 (sed_cmd->cmd == '{') {
-		do {
-			sed_cmd_t *sed_cmd_new;
-			char *end_ptr = strpbrk(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;
+	}
 
-			*end_ptr = '\0';
-			sed_cmd_new = xcalloc(1, sizeof(sed_cmd_t));
-			sed_cmd_new->beg_match = sed_cmd->beg_match;
-			sed_cmd_new->end_match = sed_cmd->end_match;
-			sed_cmd_new->beg_line = sed_cmd->beg_line;
-			sed_cmd_new->end_line = sed_cmd->end_line;
-			sed_cmd_new->invert = sed_cmd->invert;
+	cmdstr = parse_cmd_str(sed_cmd, cmdstr);
 
-			add_cmd(sed_cmd_new, cmdstr);
-			cmdstr = end_ptr + 1;
-		} while (*cmdstr != '\0');
-	} else {
-		cmdstr = parse_cmd_str(sed_cmd, cmdstr);
+	/* Add the command to the command array */
+	sed_cmd_tail->linear = sed_cmd;
+	sed_cmd_tail = sed_cmd_tail->linear;
 
-		/* Add the command to the command array */
-		sed_cmd_tail->linear = sed_cmd;
-		sed_cmd_tail = sed_cmd_tail->linear;
-	}
 	return(cmdstr);
 }
 
@@ -700,17 +720,27 @@
 	}
 }
 
-static int do_subst_command(const sed_cmd_t *sed_cmd, char **line)
+static int do_subst_command(sed_cmd_t *sed_cmd, char **line)
 {
 	char *hackline = *line;
 	struct pipeline thepipe = { NULL, 0 , 0};
 	struct pipeline *const pipeline = &thepipe;
 	int altered = 0;
+	int result;
 	regmatch_t *regmatch = NULL;
+	regex_t *current_regex;
+
+	if (sed_cmd->sub_match == NULL) {
+		current_regex = previous_regex_ptr;
+	} else {
+		previous_regex_ptr = current_regex = sed_cmd->sub_match;
+	}
+	result = regexec(current_regex, hackline, 0, NULL, 0);
 
 	/* we only proceed if the substitution 'search' expression matches */
-	if (regexec(sed_cmd->sub_match, hackline, 0, NULL, 0) == REG_NOMATCH)
+	if (result == REG_NOMATCH) {
 		return 0;
+	}
 
 	/* whaddaya know, it matched. get the number of back references */
 	regmatch = xmalloc(sizeof(regmatch_t) * (sed_cmd->num_backrefs+1));
@@ -724,7 +754,7 @@
 
 	/* and now, as long as we've got a line to try matching and if we can match
 	 * the search string, we make substitutions */
-	while ((*hackline || !altered) && (regexec(sed_cmd->sub_match, hackline,
+	while ((*hackline || !altered) && (regexec(current_regex, hackline,
 					sed_cmd->num_backrefs+1, regmatch, 0) != REG_NOMATCH) ) {
 		int i;
 
@@ -818,6 +848,10 @@
 			   );
 
 			if (sed_cmd->invert ^ matched) {
+				/* Update last used regex incase a blank substitute BRE is found */
+				if (sed_cmd->beg_match) {
+					previous_regex_ptr = sed_cmd->beg_match;
+				}
 
 				/*
 				 * actual sedding
@@ -999,6 +1033,8 @@
 				if (
 					/* this is a single-address command or... */
 					(sed_cmd->end_line == 0 && sed_cmd->end_match == NULL) || (
+						/* If only one address */
+
 						/* we were in the middle of our address range (this
 						 * isn't the first time through) and.. */
 						(still_in_range == 1) && (



More information about the busybox-cvs mailing list