aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-03-30 03:41:53 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-03-30 03:41:53 +0000
commit0c51832b6009b3e7198385254c5e5d4413bb668d (patch)
treefad367f2c25bd86bb55a82394bcf228ed5cb5050
parentb5b5ac32372c19b0776dceec67c9ed876b8616d3 (diff)
downloadbusybox-0c51832b6009b3e7198385254c5e5d4413bb668d.tar.gz
Experimental support for embeded newline. (im evil)
Fix segfault when using 'N' with an odd number of lines.
-rw-r--r--editors/Config.in9
-rw-r--r--editors/sed.c65
2 files changed, 64 insertions, 10 deletions
diff --git a/editors/Config.in b/editors/Config.in
index 4f2817598..c75267759 100644
--- a/editors/Config.in
+++ b/editors/Config.in
@@ -24,6 +24,15 @@ config CONFIG_SED
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
diff --git a/editors/sed.c b/editors/sed.c
index 1cbf974b6..292bc8662 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -430,7 +430,7 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
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 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
cmdstr++;
}
#endif
-
}
/* last part (mandatory) will be a command */
@@ -529,6 +528,18 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr)
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 @@ static void process_file(FILE *file)
* 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 @@ static void process_file(FILE *file)
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 @@ extern int sed_main(int argc, char **argv)
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 @@ extern int sed_main(int argc, char **argv)
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++;
}
}