[BusyBox-cvs] busybox/editors Config.in,1.1,1.2 sed.c,1.115,1.116

Glenn McGrath bug1 at busybox.net
Sun Mar 30 03:41:56 UTC 2003


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

Modified Files:
	Config.in sed.c 
Log Message:
Experimental support for embeded newline. (im evil)
Fix segfault when using 'N' with an odd number of lines.


Index: Config.in
===================================================================
RCS file: /var/cvs/busybox/editors/Config.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Config.in	5 Dec 2002 08:40:35 -0000	1.1
+++ Config.in	30 Mar 2003 03:41:53 -0000	1.2
@@ -24,6 +24,15 @@
 	help
 	  Please submit a patch to add help text for this item.
 
+config CONFIG_FEATURE_SED_EMBEDED_NEWLINE
+	bool " Embeded newline (EXPERIMENTAL)"
+	default n
+	depends on CONFIG_SED
+	help
+	  This is a hack to allow matching of '\n' in regular expressions.
+	  It works by translating '\n' to "\n" and back.
+	  It may introduce unexpected results if you use "\n" in your text.
+
 config CONFIG_VI
 	bool "vi"
 	default n

Index: sed.c
===================================================================
RCS file: /var/cvs/busybox/editors/sed.c,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -d -r1.115 -r1.116
--- sed.c	28 Mar 2003 14:11:34 -0000	1.115
+++ sed.c	30 Mar 2003 03:41:53 -0000	1.116
@@ -430,7 +430,7 @@
 
 static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
 {
-	
+
 	/* Skip over leading whitespace and semicolons */
 	cmdstr += strspn(cmdstr, semicolon_whitespace);
 
@@ -491,7 +491,6 @@
 			cmdstr++;
 		}
 #endif
-
 	}
 
 	/* last part (mandatory) will be a command */
@@ -529,6 +528,18 @@
 
 static void add_cmd_str(char *cmdstr)
 {
+#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
+	char *cmdstr_ptr = cmdstr;
+
+	/* HACK: convert "\n" to match tranlated '\n' string */
+	while((cmdstr_ptr = strstr(cmdstr_ptr, "\\n")) != NULL) {
+		cmdstr = xrealloc(cmdstr, strlen(cmdstr) + 2);
+		cmdstr_ptr = strstr(cmdstr, "\\n");
+		memmove(cmdstr_ptr + 1, cmdstr_ptr, strlen(cmdstr_ptr) + 1);
+		cmdstr_ptr[0] = '\\';
+		cmdstr_ptr += 3;
+	}
+#endif
 	do {
 		sed_cmd_t *sed_cmd;
 		sed_cmd = xcalloc(1, sizeof(sed_cmd_t));
@@ -795,8 +806,35 @@
 						 *    flag exists in the first place.
 						 */
 
+#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
+						/* HACK: escape newlines twice so regex can match them */
+						{
+							int offset = 0;
+							while(strchr(line + offset, '\n') != NULL) {
+								char *tmp;
+								line = xrealloc(line, strlen(line) + 2);
+								tmp = strchr(line + offset, '\n');
+								memmove(tmp + 1, tmp, strlen(tmp) + 1);
+								tmp[0] = '\\';
+								tmp[1] = 'n';
+								offset = tmp - line + 2;
+							}
+						}
+#endif
 						/* we print the line once, unless we were told to be quiet */
 						substituted = do_subst_command(sed_cmd, &line);
+
+#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
+						/* undo HACK: escape newlines twice so regex can match them */
+						{
+							char *tmp = line;
+
+							while((tmp = strstr(tmp, "\\n")) != NULL) {
+								memmove(tmp, tmp + 1, strlen(tmp + 1) + 1);
+								tmp[0] = '\n';
+							}
+						}
+#endif
 						altered |= substituted;
 						if (!be_quiet && altered && ((sed_cmd->linear == NULL) || (sed_cmd->linear->cmd != 's'))) {
 							force_print = 1;
@@ -857,11 +895,13 @@
 						linenum++;
 						break;
 					case 'N':	/* Append the next line to the current line */
-						line = realloc(line, strlen(line) + strlen(next_line) + 2);
-						strcat(line, "\n");
-						strcat(line, next_line);
-						next_line = bb_get_chomped_line_from_file(file);
-						linenum++;
+						if (next_line) {
+							line = realloc(line, strlen(line) + strlen(next_line) + 2);
+							strcat(line, "\n");
+							strcat(line, next_line);
+							next_line = bb_get_chomped_line_from_file(file);
+							linenum++;
+						}
 						break;
 					case 'b':
 						sed_cmd = branch_to(sed_cmd->label);
@@ -934,9 +974,12 @@
 			case 'n':
 				be_quiet++;
 				break;
-			case 'e':
-				add_cmd_str(optarg);
+			case 'e': {
+				char *str_cmd = strdup(optarg);
+				add_cmd_str(str_cmd);
+				free(str_cmd);
 				break;
+			}
 			case 'f': 
 				load_cmd_file(optarg);
 				break;
@@ -951,7 +994,9 @@
 		if (argv[optind] == NULL)
 			bb_show_usage();
 		else {
-			add_cmd_str(argv[optind]);
+			char *str_cmd = strdup(argv[optind]);
+			add_cmd_str(strdup(str_cmd));
+			free(str_cmd);
 			optind++;
 		}
 	}




More information about the busybox-cvs mailing list