Experimental support for embeded newline. (im evil)
Fix segfault when using 'N' with an odd number of lines.
This commit is contained in:
parent
b5b5ac3237
commit
0c51832b60
@ -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
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user