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-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.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
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
27config 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
27config CONFIG_VI 36config 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
431static char *add_cmd(sed_cmd_t *sed_cmd, char *cmdstr) 431static 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
530static void add_cmd_str(char *cmdstr) 529static 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 }