aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-01-29 17:10:19 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-01-29 17:10:19 +0000
commitf8c312083a59153e627f3795581663bc1afe03fa (patch)
tree3ecbd8b554f6a4c82f9b03d29087914f3d8a9623
parent531a4b43c3f7e390833d17a713fd4f8bd80109db (diff)
downloadbusybox-w32-f8c312083a59153e627f3795581663bc1afe03fa.tar.gz
busybox-w32-f8c312083a59153e627f3795581663bc1afe03fa.tar.bz2
busybox-w32-f8c312083a59153e627f3795581663bc1afe03fa.zip
add to testsuite and fix yet another sed corner case
git-svn-id: svn://busybox.net/trunk/busybox@17639 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--editors/sed.c30
-rwxr-xr-xtestsuite/sed.tests3
2 files changed, 27 insertions, 6 deletions
diff --git a/editors/sed.c b/editors/sed.c
index bf40877e4..695e5e974 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -724,6 +724,7 @@ static void add_input_file(FILE *file)
724 */ 724 */
725enum { 725enum {
726 NO_EOL_CHAR = 1, 726 NO_EOL_CHAR = 1,
727 LAST_IS_NUL = 2,
727}; 728};
728static char *get_next_line(char *gets_char) 729static char *get_next_line(char *gets_char)
729{ 730{
@@ -737,17 +738,24 @@ static char *get_next_line(char *gets_char)
737 * doesn't end with either '\n' or '\0' */ 738 * doesn't end with either '\n' or '\0' */
738 gc = NO_EOL_CHAR; 739 gc = NO_EOL_CHAR;
739 while (bbg.current_input_file < bbg.input_file_count) { 740 while (bbg.current_input_file < bbg.input_file_count) {
741 FILE *fp = bbg.input_file_list[bbg.current_input_file];
740 /* Read line up to a newline or NUL byte, inclusive, 742 /* Read line up to a newline or NUL byte, inclusive,
741 * return malloc'ed char[]. length of the chunk read 743 * return malloc'ed char[]. length of the chunk read
742 * is stored in len. NULL if EOF/error */ 744 * is stored in len. NULL if EOF/error */
743 temp = bb_get_chunk_from_file( 745 temp = bb_get_chunk_from_file(fp, &len);
744 bbg.input_file_list[bbg.current_input_file], &len);
745 if (temp) { 746 if (temp) {
746 /* len > 0 here, it's ok to do temp[len-1] */ 747 /* len > 0 here, it's ok to do temp[len-1] */
747 char c = temp[len-1]; 748 char c = temp[len-1];
748 if (c == '\n' || c == '\0') { 749 if (c == '\n' || c == '\0') {
749 temp[len-1] = '\0'; 750 temp[len-1] = '\0';
750 gc = c; 751 gc = c;
752 if (c == '\0') {
753 int ch = fgetc(fp);
754 if (ch != EOF)
755 ungetc(ch, fp);
756 else
757 gc = LAST_IS_NUL;
758 }
751 } 759 }
752 /* else we put NO_EOL_CHAR into *gets_char */ 760 /* else we put NO_EOL_CHAR into *gets_char */
753 break; 761 break;
@@ -761,7 +769,8 @@ static char *get_next_line(char *gets_char)
761 * (note: *no* newline after "b bang"!) */ 769 * (note: *no* newline after "b bang"!) */
762 } 770 }
763 /* Close this file and advance to next one */ 771 /* Close this file and advance to next one */
764 fclose(bbg.input_file_list[bbg.current_input_file++]); 772 fclose(fp);
773 bbg.current_input_file++;
765 } 774 }
766 *gets_char = gc; 775 *gets_char = gc;
767 return temp; 776 return temp;
@@ -785,20 +794,29 @@ static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char l
785{ 794{
786 char lpc = *last_puts_char; 795 char lpc = *last_puts_char;
787 796
788 /* Is this a first line from new file 797 /* Need to insert a '\n' between two files because first file's
789 * and old file didn't end with '\n' or '\0'? */ 798 * last line wasn't terminated? */
790 if (lpc != '\n' && lpc != '\0') { 799 if (lpc != '\n' && lpc != '\0') {
791 fputc('\n', file); 800 fputc('\n', file);
792 lpc = '\n'; 801 lpc = '\n';
793 } 802 }
794 fputs(s, file); 803 fputs(s, file);
804
795 /* 'x' - just something which is not '\n', '\0' or NO_EOL_CHAR */ 805 /* 'x' - just something which is not '\n', '\0' or NO_EOL_CHAR */
796 if (s[0]) 806 if (s[0])
797 lpc = 'x'; 807 lpc = 'x';
798 if (last_gets_char != NO_EOL_CHAR) { /* had trailing '\n' or '\0'? */ 808
809 /* had trailing '\0' and it was last char of file? */
810 if (last_gets_char == LAST_IS_NUL) {
811 fputc('\0', file);
812 lpc = 'x'; /* */
813 } else
814 /* had trailing '\n' or '\0'? */
815 if (last_gets_char != NO_EOL_CHAR) {
799 fputc(last_gets_char, file); 816 fputc(last_gets_char, file);
800 lpc = last_gets_char; 817 lpc = last_gets_char;
801 } 818 }
819
802 if (ferror(file)) { 820 if (ferror(file)) {
803 xfunc_error_retval = 4; /* It's what gnu sed exits with... */ 821 xfunc_error_retval = 4; /* It's what gnu sed exits with... */
804 bb_error_msg_and_die(bb_msg_write_error); 822 bb_error_msg_and_die(bb_msg_write_error);
diff --git a/testsuite/sed.tests b/testsuite/sed.tests
index cc200703d..9576b6c4b 100755
--- a/testsuite/sed.tests
+++ b/testsuite/sed.tests
@@ -143,6 +143,9 @@ testing "sed subst+write" \
143 "sed -e 's/i/z/' -e 'woutputw' input -; echo -n X; cat outputw" \ 143 "sed -e 's/i/z/' -e 'woutputw' input -; echo -n X; cat outputw" \
144 "thzngy\nagaznXthzngy\nagazn" "thingy" "again" 144 "thzngy\nagaznXthzngy\nagazn" "thingy" "again"
145rm outputw 145rm outputw
146testing "sed trailing NUL" \
147 "sed 's/i/z/' input -" \
148 "a\0b\0\nc" "a\0b\0" "c"
146 149
147# Test end-of-file matching behavior 150# Test end-of-file matching behavior
148 151