diff options
Diffstat (limited to 'editors/sed.c')
-rw-r--r-- | editors/sed.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/editors/sed.c b/editors/sed.c index 374830f3f..f4a5f7b8a 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -252,7 +252,6 @@ static void cleanup_outname(void) | |||
252 | } | 252 | } |
253 | 253 | ||
254 | /* strcpy, replacing "\from" with 'to'. If to is NUL, replacing "\any" with 'any' */ | 254 | /* strcpy, replacing "\from" with 'to'. If to is NUL, replacing "\any" with 'any' */ |
255 | |||
256 | static unsigned parse_escapes(char *dest, const char *string, int len, char from, char to) | 255 | static unsigned parse_escapes(char *dest, const char *string, int len, char from, char to) |
257 | { | 256 | { |
258 | char *d = dest; | 257 | char *d = dest; |
@@ -282,7 +281,7 @@ static unsigned parse_escapes(char *dest, const char *string, int len, char from | |||
282 | return d - dest; | 281 | return d - dest; |
283 | } | 282 | } |
284 | 283 | ||
285 | static char *copy_parsing_escapes(const char *string, int len) | 284 | static char *copy_parsing_escapes(const char *string, int len, char delim) |
286 | { | 285 | { |
287 | const char *s; | 286 | const char *s; |
288 | char *dest = xmalloc(len + 1); | 287 | char *dest = xmalloc(len + 1); |
@@ -293,10 +292,15 @@ static char *copy_parsing_escapes(const char *string, int len) | |||
293 | len = parse_escapes(dest, string, len, s[1], s[0]); | 292 | len = parse_escapes(dest, string, len, s[1], s[0]); |
294 | string = dest; | 293 | string = dest; |
295 | } | 294 | } |
295 | if (delim) { | ||
296 | /* we additionally unescape any instances of escaped delimiter. | ||
297 | * For example, in 's+9\++X+' the pattern is "9+", not "9\+". | ||
298 | */ | ||
299 | len = parse_escapes(dest, string, len, delim, delim); | ||
300 | } | ||
296 | return dest; | 301 | return dest; |
297 | } | 302 | } |
298 | 303 | ||
299 | |||
300 | /* | 304 | /* |
301 | * index_of_next_unescaped_regexp_delim - walks left to right through a string | 305 | * index_of_next_unescaped_regexp_delim - walks left to right through a string |
302 | * beginning at a specified index and returns the index of the next regular | 306 | * beginning at a specified index and returns the index of the next regular |
@@ -353,12 +357,14 @@ static int parse_regex_delim(const char *cmdstr, char **match, char **replace) | |||
353 | 357 | ||
354 | /* save the match string */ | 358 | /* save the match string */ |
355 | idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr); | 359 | idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr); |
356 | *match = copy_parsing_escapes(cmdstr_ptr, idx); | 360 | *match = copy_parsing_escapes(cmdstr_ptr, idx, delimiter); |
357 | |||
358 | /* save the replacement string */ | 361 | /* save the replacement string */ |
359 | cmdstr_ptr += idx + 1; | 362 | cmdstr_ptr += idx + 1; |
360 | idx = index_of_next_unescaped_regexp_delim(- (int)delimiter, cmdstr_ptr); | 363 | idx = index_of_next_unescaped_regexp_delim(- (int)delimiter, cmdstr_ptr); |
361 | *replace = copy_parsing_escapes(cmdstr_ptr, idx); | 364 | //GNU sed 4.8: |
365 | // echo 789 | sed 's&8&\&&' - 7&9 ("\&" remained "\&") | ||
366 | // echo 789 | sed 's1\(8\)1\1\11' - 7119 ("\1\1" become "11") | ||
367 | *replace = copy_parsing_escapes(cmdstr_ptr, idx, delimiter != '&' ? delimiter : 0); | ||
362 | 368 | ||
363 | return ((cmdstr_ptr - cmdstr) + idx); | 369 | return ((cmdstr_ptr - cmdstr) + idx); |
364 | } | 370 | } |
@@ -386,7 +392,7 @@ static int get_address(const char *my_str, int *linenum, regex_t ** regex) | |||
386 | delimiter = *++pos; | 392 | delimiter = *++pos; |
387 | next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); | 393 | next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); |
388 | if (next != 0) { | 394 | if (next != 0) { |
389 | temp = copy_parsing_escapes(pos, next); | 395 | temp = copy_parsing_escapes(pos, next, 0); |
390 | G.previous_regex_ptr = *regex = xzalloc(sizeof(regex_t)); | 396 | G.previous_regex_ptr = *regex = xzalloc(sizeof(regex_t)); |
391 | xregcomp(*regex, temp, G.regex_type); | 397 | xregcomp(*regex, temp, G.regex_type); |
392 | free(temp); | 398 | free(temp); |
@@ -581,7 +587,7 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) | |||
581 | cmdstr++; | 587 | cmdstr++; |
582 | } | 588 | } |
583 | len = strlen(cmdstr); | 589 | len = strlen(cmdstr); |
584 | sed_cmd->string = copy_parsing_escapes(cmdstr, len); | 590 | sed_cmd->string = copy_parsing_escapes(cmdstr, len, 0); |
585 | cmdstr += len; | 591 | cmdstr += len; |
586 | /* "\anychar" -> "anychar" */ | 592 | /* "\anychar" -> "anychar" */ |
587 | parse_escapes(sed_cmd->string, sed_cmd->string, -1, '\0', '\0'); | 593 | parse_escapes(sed_cmd->string, sed_cmd->string, -1, '\0', '\0'); |