diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-03-30 03:41:53 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-03-30 03:41:53 +0000 |
commit | 0c51832b6009b3e7198385254c5e5d4413bb668d (patch) | |
tree | fad367f2c25bd86bb55a82394bcf228ed5cb5050 | |
parent | b5b5ac32372c19b0776dceec67c9ed876b8616d3 (diff) | |
download | busybox-w32-0c51832b6009b3e7198385254c5e5d4413bb668d.tar.gz busybox-w32-0c51832b6009b3e7198385254c5e5d4413bb668d.tar.bz2 busybox-w32-0c51832b6009b3e7198385254c5e5d4413bb668d.zip |
Experimental support for embeded newline. (im evil)
Fix segfault when using 'N' with an odd number of lines.
-rw-r--r-- | editors/Config.in | 9 | ||||
-rw-r--r-- | editors/sed.c | 65 |
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 | |||
24 | help | 24 | help |
25 | Please submit a patch to add help text for this item. | 25 | Please submit a patch to add help text for this item. |
26 | 26 | ||
27 | config CONFIG_FEATURE_SED_EMBEDED_NEWLINE | ||
28 | bool " Embeded newline (EXPERIMENTAL)" | ||
29 | default n | ||
30 | depends on CONFIG_SED | ||
31 | help | ||
32 | This is a hack to allow matching of '\n' in regular expressions. | ||
33 | It works by translating '\n' to "\n" and back. | ||
34 | It may introduce unexpected results if you use "\n" in your text. | ||
35 | |||
27 | config CONFIG_VI | 36 | config CONFIG_VI |
28 | bool "vi" | 37 | bool "vi" |
29 | default n | 38 | 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) | |||
430 | 430 | ||
431 | static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr) | 431 | static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr) |
432 | { | 432 | { |
433 | 433 | ||
434 | /* Skip over leading whitespace and semicolons */ | 434 | /* Skip over leading whitespace and semicolons */ |
435 | cmdstr += strspn(cmdstr, semicolon_whitespace); | 435 | cmdstr += strspn(cmdstr, semicolon_whitespace); |
436 | 436 | ||
@@ -491,7 +491,6 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr) | |||
491 | cmdstr++; | 491 | cmdstr++; |
492 | } | 492 | } |
493 | #endif | 493 | #endif |
494 | |||
495 | } | 494 | } |
496 | 495 | ||
497 | /* last part (mandatory) will be a command */ | 496 | /* last part (mandatory) will be a command */ |
@@ -529,6 +528,18 @@ static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr) | |||
529 | 528 | ||
530 | static void add_cmd_str(char *cmdstr) | 529 | static void add_cmd_str(char *cmdstr) |
531 | { | 530 | { |
531 | #ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE | ||
532 | char *cmdstr_ptr = cmdstr; | ||
533 | |||
534 | /* HACK: convert "\n" to match tranlated '\n' string */ | ||
535 | while((cmdstr_ptr = strstr(cmdstr_ptr, "\\n")) != NULL) { | ||
536 | cmdstr = xrealloc(cmdstr, strlen(cmdstr) + 2); | ||
537 | cmdstr_ptr = strstr(cmdstr, "\\n"); | ||
538 | memmove(cmdstr_ptr + 1, cmdstr_ptr, strlen(cmdstr_ptr) + 1); | ||
539 | cmdstr_ptr[0] = '\\'; | ||
540 | cmdstr_ptr += 3; | ||
541 | } | ||
542 | #endif | ||
532 | do { | 543 | do { |
533 | sed_cmd_t *sed_cmd; | 544 | sed_cmd_t *sed_cmd; |
534 | sed_cmd = xcalloc(1, sizeof(sed_cmd_t)); | 545 | sed_cmd = xcalloc(1, sizeof(sed_cmd_t)); |
@@ -795,8 +806,35 @@ static void process_file(FILE *file) | |||
795 | * flag exists in the first place. | 806 | * flag exists in the first place. |
796 | */ | 807 | */ |
797 | 808 | ||
809 | #ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE | ||
810 | /* HACK: escape newlines twice so regex can match them */ | ||
811 | { | ||
812 | int offset = 0; | ||
813 | while(strchr(line + offset, '\n') != NULL) { | ||
814 | char *tmp; | ||
815 | line = xrealloc(line, strlen(line) + 2); | ||
816 | tmp = strchr(line + offset, '\n'); | ||
817 | memmove(tmp + 1, tmp, strlen(tmp) + 1); | ||
818 | tmp[0] = '\\'; | ||
819 | tmp[1] = 'n'; | ||
820 | offset = tmp - line + 2; | ||
821 | } | ||
822 | } | ||
823 | #endif | ||
798 | /* we print the line once, unless we were told to be quiet */ | 824 | /* we print the line once, unless we were told to be quiet */ |
799 | substituted = do_subst_command(sed_cmd, &line); | 825 | substituted = do_subst_command(sed_cmd, &line); |
826 | |||
827 | #ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE | ||
828 | /* undo HACK: escape newlines twice so regex can match them */ | ||
829 | { | ||
830 | char *tmp = line; | ||
831 | |||
832 | while((tmp = strstr(tmp, "\\n")) != NULL) { | ||
833 | memmove(tmp, tmp + 1, strlen(tmp + 1) + 1); | ||
834 | tmp[0] = '\n'; | ||
835 | } | ||
836 | } | ||
837 | #endif | ||
800 | altered |= substituted; | 838 | altered |= substituted; |
801 | if (!be_quiet && altered && ((sed_cmd->linear == NULL) || (sed_cmd->linear->cmd != 's'))) { | 839 | if (!be_quiet && altered && ((sed_cmd->linear == NULL) || (sed_cmd->linear->cmd != 's'))) { |
802 | force_print = 1; | 840 | force_print = 1; |
@@ -857,11 +895,13 @@ static void process_file(FILE *file) | |||
857 | linenum++; | 895 | linenum++; |
858 | break; | 896 | break; |
859 | case 'N': /* Append the next line to the current line */ | 897 | case 'N': /* Append the next line to the current line */ |
860 | line = realloc(line, strlen(line) + strlen(next_line) + 2); | 898 | if (next_line) { |
861 | strcat(line, "\n"); | 899 | line = realloc(line, strlen(line) + strlen(next_line) + 2); |
862 | strcat(line, next_line); | 900 | strcat(line, "\n"); |
863 | next_line = bb_get_chomped_line_from_file(file); | 901 | strcat(line, next_line); |
864 | linenum++; | 902 | next_line = bb_get_chomped_line_from_file(file); |
903 | linenum++; | ||
904 | } | ||
865 | break; | 905 | break; |
866 | case 'b': | 906 | case 'b': |
867 | sed_cmd = branch_to(sed_cmd->label); | 907 | sed_cmd = branch_to(sed_cmd->label); |
@@ -934,9 +974,12 @@ extern int sed_main(int argc, char **argv) | |||
934 | case 'n': | 974 | case 'n': |
935 | be_quiet++; | 975 | be_quiet++; |
936 | break; | 976 | break; |
937 | case 'e': | 977 | case 'e': { |
938 | add_cmd_str(optarg); | 978 | char *str_cmd = strdup(optarg); |
979 | add_cmd_str(str_cmd); | ||
980 | free(str_cmd); | ||
939 | break; | 981 | break; |
982 | } | ||
940 | case 'f': | 983 | case 'f': |
941 | load_cmd_file(optarg); | 984 | load_cmd_file(optarg); |
942 | break; | 985 | break; |
@@ -951,7 +994,9 @@ extern int sed_main(int argc, char **argv) | |||
951 | if (argv[optind] == NULL) | 994 | if (argv[optind] == NULL) |
952 | bb_show_usage(); | 995 | bb_show_usage(); |
953 | else { | 996 | else { |
954 | add_cmd_str(argv[optind]); | 997 | char *str_cmd = strdup(argv[optind]); |
998 | add_cmd_str(strdup(str_cmd)); | ||
999 | free(str_cmd); | ||
955 | optind++; | 1000 | optind++; |
956 | } | 1001 | } |
957 | } | 1002 | } |