Index: usr.bin/col/col.c =================================================================== --- usr.bin/col/col.c +++ usr.bin/col/col.c @@ -109,7 +109,7 @@ static void usage(void); static CSET last_set; /* char_set of last char printed */ -static LINE *lines; +static LINE *lines; static int compress_spaces; /* if doing space -> tab conversion */ static int fine; /* if `fine' resolution (half lines) */ static int max_bufd_lines; /* max # of half lines to keep in memory */ @@ -340,8 +340,16 @@ } if (ferror(stdin)) err(1, NULL); - if (extra_lines) + if (extra_lines) { + /* + * Extra lines only exist if no lines have been flushed + * yet. This means that 'lines' must point to line zero + * after we flush the extra lines. + */ flush_lines(extra_lines); + l = lines; + this_line = 0; + } /* goto the last line that had a character on it */ for (; l->l_next; l = l->l_next) @@ -353,14 +361,22 @@ PUTC(SI); /* flush out the last few blank lines */ - if (max_line > this_line) - nblank_lines = max_line - this_line; - if (max_line & 1) - nblank_lines++; + if (max_line >= this_line) + nblank_lines = max_line - this_line + (max_line & 1); + if (nblank_lines == 0) + /* end with a newline even if the source doesn't */ + nblank_lines = 2; flush_blanks(); exit(0); } +/* + * Prints the first 'nflush' lines. Printed lines are freed. + * After this function returns, 'lines' points to the first + * of the remaining lines, and 'nblank_lines' will have the + * number of half line feeds between the final flushed line + * and the first remaining line. + */ static void flush_lines(int nflush) { @@ -372,11 +388,10 @@ if (l->l_line) { flush_blanks(); flush_line(l); + free(l->l_line); } - if (l->l_line || l->l_next) + if (l->l_next) nblank_lines++; - if (l->l_line) - (void)free(l->l_line); free_line(l); } if (lines) @@ -384,9 +399,8 @@ } /* - * Print a number of newline/half newlines. If fine flag is set, nblank_lines - * is the number of half line feeds, otherwise it is the number of whole line - * feeds. + * Print a number of newline/half newlines. + * nblank_lines is the number of half line feeds. */ static void flush_blanks(void) Index: usr.bin/col/tests/col_test.sh =================================================================== --- usr.bin/col/tests/col_test.sh +++ usr.bin/col/tests/col_test.sh @@ -1,5 +1,44 @@ # $FreeBSD$ +atf_test_case nl + +nl_head() +{ + atf_set "descr" "testing just newlines" +} +nl_body() +{ + atf_check \ + -o inline:"a\nb\n" \ + -e empty \ + -s exit:0 \ + col < $(atf_get_srcdir)/nl.in + + atf_check \ + -o inline:"a\nb\n" \ + -e empty \ + -s exit:0 \ + col -f < $(atf_get_srcdir)/nl.in + + atf_check \ + -o inline:"a\nb\n" \ + -e empty \ + -s exit:0 \ + col < $(atf_get_srcdir)/nl2.in + + atf_check \ + -o inline:"a\nb\n" \ + -e empty \ + -s exit:0 \ + col -f < $(atf_get_srcdir)/nl2.in + + atf_check \ + -o inline:"a\n\nb\n\n" \ + -e empty \ + -s exit:0 \ + col < $(atf_get_srcdir)/nl3.in +} + atf_test_case rlf rlf_head() @@ -25,9 +64,50 @@ -e empty \ -s exit:0 \ col -x < $(atf_get_srcdir)/rlf2.in + + atf_check \ + -o inline:" b\na\n" \ + -e empty \ + -s exit:0 \ + col < $(atf_get_srcdir)/rlf3.in +} + +atf_test_case hlf + +hlf_head() +{ + atf_set "descr" "testing half line feed" +} +hlf_body() +{ + atf_check \ + -o inline:"a f\naf\n" \ + -e empty \ + -s exit:0 \ + col < $(atf_get_srcdir)/hlf.in + + atf_check \ + -o inline:"a f9 f9 a\n" \ + -e empty \ + -s exit:0 \ + col -f < $(atf_get_srcdir)/hlf.in + + atf_check \ + -o inline:"a\n f\n" \ + -e empty \ + -s exit:0 \ + col < $(atf_get_srcdir)/hlf2.in + + atf_check \ + -o inline:"a9 f\n9" \ + -e empty \ + -s exit:0 \ + col -f < $(atf_get_srcdir)/hlf2.in } atf_init_test_cases() { + atf_add_test_case nl atf_add_test_case rlf + atf_add_test_case hlf } Index: usr.bin/col/tests/hlf.in =================================================================== --- /dev/null +++ usr.bin/col/tests/hlf.in @@ -0,0 +1,2 @@ +a +a8f8f Index: usr.bin/col/tests/hlf2.in =================================================================== --- /dev/null +++ usr.bin/col/tests/hlf2.in @@ -0,0 +1 @@ +a9f Index: usr.bin/col/tests/nl.in =================================================================== --- /dev/null +++ usr.bin/col/tests/nl.in @@ -0,0 +1,2 @@ +a +b Index: usr.bin/col/tests/nl2.in =================================================================== --- /dev/null +++ usr.bin/col/tests/nl2.in @@ -0,0 +1,2 @@ +a +b \ No newline at end of file Index: usr.bin/col/tests/nl3.in =================================================================== --- /dev/null +++ usr.bin/col/tests/nl3.in @@ -0,0 +1,4 @@ +a + +b + Index: usr.bin/col/tests/rlf3.in =================================================================== --- /dev/null +++ usr.bin/col/tests/rlf3.in @@ -0,0 +1 @@ +a b