From e5e45ca1e35482d120a7ce776cf208369edcc459 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Sun, 10 Oct 2010 21:41:06 -0500 Subject: vcs-svn: teach line_buffer to handle multiple input files Collect the line_buffer state in a newly public line_buffer struct. Callers can use multiple line_buffers to manage input from multiple files at a time. svn-fe's delta applier will use this to stream a delta from svnrdump and the preimage it applies to from fast-import at the same time. The tests don't take advantage of the new features, but I think that's okay. It is easier to find lingering examples of nonreentrant code by searching for "static" in line_buffer.c. Signed-off-by: Jonathan Nieder --- test-line-buffer.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'test-line-buffer.c') diff --git a/test-line-buffer.c b/test-line-buffer.c index c11bf7f967..f9af892d28 100644 --- a/test-line-buffer.c +++ b/test-line-buffer.c @@ -22,25 +22,26 @@ static uint32_t strtouint32(const char *s) int main(int argc, char *argv[]) { + struct line_buffer buf = LINE_BUFFER_INIT; char *s; if (argc != 1) usage("test-line-buffer < input.txt"); - if (buffer_init(NULL)) + if (buffer_init(&buf, NULL)) die_errno("open error"); - while ((s = buffer_read_line())) { - s = buffer_read_string(strtouint32(s)); + while ((s = buffer_read_line(&buf))) { + s = buffer_read_string(&buf, strtouint32(s)); fputs(s, stdout); fputc('\n', stdout); - buffer_skip_bytes(1); - if (!(s = buffer_read_line())) + buffer_skip_bytes(&buf, 1); + if (!(s = buffer_read_line(&buf))) break; - buffer_copy_bytes(strtouint32(s) + 1); + buffer_copy_bytes(&buf, strtouint32(s) + 1); } - if (buffer_deinit()) + if (buffer_deinit(&buf)) die("input error"); if (ferror(stdout)) die("output error"); - buffer_reset(); + buffer_reset(&buf); return 0; } -- cgit v1.3 From 850c5ea44ce0b4aac3be7c4d14b38ec901e777d1 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Sun, 2 Jan 2011 18:50:16 -0600 Subject: vcs-svn: make test-line-buffer input format more flexible Imitate the input format of test-obj-pool to support arbitrary sequences of commands rather than alternating read/copy. This should make it easier to add tests that exercise other line_buffer functions. Signed-off-by: Jonathan Nieder --- t/t0080-vcs-svn.sh | 18 +++++++++--------- test-line-buffer.c | 56 +++++++++++++++++++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 29 deletions(-) (limited to 'test-line-buffer.c') diff --git a/t/t0080-vcs-svn.sh b/t/t0080-vcs-svn.sh index d3225ada68..8be97002ae 100755 --- a/t/t0080-vcs-svn.sh +++ b/t/t0080-vcs-svn.sh @@ -85,40 +85,40 @@ test_expect_success 'line buffer' ' printf "%s\n" "" foo >expected6 && test-line-buffer <<-\EOF >actual1 && - 5 + read 5 HELLO EOF test-line-buffer <<-\EOF >actual2 && - 0 + read 0 - 5 + copy 5 HELLO EOF q_to_nul <<-\EOF | - 1 + read 1 Q EOF test-line-buffer >actual3 && q_to_nul <<-\EOF | - 0 + read 0 - 1 + copy 1 Q EOF test-line-buffer >actual4 && test-line-buffer <<-\EOF >actual5 && - 5 + read 5 foo EOF test-line-buffer <<-\EOF >actual6 && - 0 + read 0 - 5 + copy 5 foo EOF diff --git a/test-line-buffer.c b/test-line-buffer.c index f9af892d28..383f35bba6 100644 --- a/test-line-buffer.c +++ b/test-line-buffer.c @@ -1,11 +1,5 @@ /* * test-line-buffer.c: code to exercise the svn importer's input helper - * - * Input format: - * number NL - * (number bytes) NL - * number NL - * ... */ #include "git-compat-util.h" @@ -20,28 +14,50 @@ static uint32_t strtouint32(const char *s) return (uint32_t) n; } +static void handle_command(const char *command, const char *arg, struct line_buffer *buf) +{ + switch (*command) { + case 'c': + if (!prefixcmp(command, "copy ")) { + buffer_copy_bytes(buf, strtouint32(arg) + 1); + return; + } + case 'r': + if (!prefixcmp(command, "read ")) { + const char *s = buffer_read_string(buf, strtouint32(arg)); + printf("%s\n", s); + buffer_skip_bytes(buf, 1); /* consume newline */ + return; + } + default: + die("unrecognized command: %s", command); + } +} + +static void handle_line(const char *line, struct line_buffer *stdin_buf) +{ + const char *arg = strchr(line, ' '); + if (!arg) + die("no argument in line: %s", line); + handle_command(line, arg + 1, stdin_buf); +} + int main(int argc, char *argv[]) { - struct line_buffer buf = LINE_BUFFER_INIT; + struct line_buffer stdin_buf = LINE_BUFFER_INIT; char *s; if (argc != 1) - usage("test-line-buffer < input.txt"); - if (buffer_init(&buf, NULL)) + usage("test-line-buffer < script"); + + if (buffer_init(&stdin_buf, NULL)) die_errno("open error"); - while ((s = buffer_read_line(&buf))) { - s = buffer_read_string(&buf, strtouint32(s)); - fputs(s, stdout); - fputc('\n', stdout); - buffer_skip_bytes(&buf, 1); - if (!(s = buffer_read_line(&buf))) - break; - buffer_copy_bytes(&buf, strtouint32(s) + 1); - } - if (buffer_deinit(&buf)) + while ((s = buffer_read_line(&stdin_buf))) + handle_line(s, &stdin_buf); + if (buffer_deinit(&stdin_buf)) die("input error"); if (ferror(stdout)) die("output error"); - buffer_reset(&buf); + buffer_reset(&stdin_buf); return 0; } -- cgit v1.3 From 7b990c90514b24097ee71edbc02cb3a497a9476b Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Sun, 2 Jan 2011 18:52:28 -0600 Subject: vcs-svn: tweak test-line-buffer to not assume line-oriented input Do not expect an implicit newline after each input record. Use a separate command to exercise buffer_skip_bytes. Signed-off-by: Jonathan Nieder --- t/t0081-line-buffer.sh | 27 +++++++++++++-------------- test-line-buffer.c | 10 +++++++--- 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'test-line-buffer.c') diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh index 13ac735b55..68d6163995 100755 --- a/t/t0081-line-buffer.sh +++ b/t/t0081-line-buffer.sh @@ -7,45 +7,44 @@ test_description="Test the svn importer's input handling routines. test_expect_success 'read greeting' ' echo HELLO >expect && test-line-buffer <<-\EOF >actual && - read 5 + read 6 HELLO EOF test_cmp expect actual ' test_expect_success '0-length read, send along greeting' ' - printf "%s\n" "" HELLO >expect && + echo HELLO >expect && test-line-buffer <<-\EOF >actual && read 0 - - copy 5 + copy 6 HELLO EOF test_cmp expect actual ' -test_expect_success 'buffer_read_string copes with trailing null byte' ' - echo >expect && +test_expect_success 'buffer_read_string copes with null byte' ' + >expect && q_to_nul <<-\EOF | test-line-buffer >actual && - read 1 + read 2 Q EOF test_cmp expect actual ' -test_expect_success '0-length read, copy null byte' ' - printf "%s\n" "" Q | q_to_nul >expect && +test_expect_success 'skip, copy null byte' ' + echo Q | q_to_nul >expect && q_to_nul <<-\EOF | test-line-buffer >actual && - read 0 - - copy 1 + skip 2 + Q + copy 2 Q EOF test_cmp expect actual ' test_expect_success 'long reads are truncated' ' - printf "%s\n" foo "" >expect && + echo foo >expect && test-line-buffer <<-\EOF >actual && read 5 foo @@ -56,7 +55,7 @@ test_expect_success 'long reads are truncated' ' test_expect_success 'long copies are truncated' ' printf "%s\n" "" foo >expect && test-line-buffer <<-\EOF >actual && - read 0 + read 1 copy 5 foo diff --git a/test-line-buffer.c b/test-line-buffer.c index 383f35bba6..da0bc6502c 100644 --- a/test-line-buffer.c +++ b/test-line-buffer.c @@ -19,14 +19,18 @@ static void handle_command(const char *command, const char *arg, struct line_buf switch (*command) { case 'c': if (!prefixcmp(command, "copy ")) { - buffer_copy_bytes(buf, strtouint32(arg) + 1); + buffer_copy_bytes(buf, strtouint32(arg)); return; } case 'r': if (!prefixcmp(command, "read ")) { const char *s = buffer_read_string(buf, strtouint32(arg)); - printf("%s\n", s); - buffer_skip_bytes(buf, 1); /* consume newline */ + fputs(s, stdout); + return; + } + case 's': + if (!prefixcmp(command, "skip ")) { + buffer_skip_bytes(buf, strtouint32(arg)); return; } default: -- cgit v1.3 From d280f68313eecb8b3838c70641a246382d5e5343 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Sun, 2 Jan 2011 19:07:16 -0600 Subject: t0081 (line-buffer): add buffering tests POSIX makes the behavior of read(2) from a pipe fairly clear: a read from an empty pipe will block until there is data available and any other read will not block, prefering to return a partial result. Likewise, fread(3) and fgets(3) are clearly specified to act as though implemented by calling fgetc(3) in a simple loop. But the buffering behavior of fgetc is less clear. Luckily, no sane platform is going to implement fgetc by calling the equivalent of read(2) more than once. fgetc has to be able to return without filling its buffer to preserve errno when errors are encountered anyway. So let's assume the simpler behavior (trust) but add some tests to catch insane platforms that violate that when they come (verify). First check that fread can handle a 0-length read from an empty fifo. Because open(O_RDONLY) blocks until the writing end is open, open the writing end of the fifo in advance in a subshell. Next try short inputs from a pipe that is not filled all the way. Lastly (two tests) try very large inputs from a pipe that will not fit in the relevant buffers. The first of these tests reads a little more than 8192 bytes, which is BUFSIZ (the size of stdio's buffers) on this Linux machine. The second reads a little over 64 KiB (the pipe capacity on Linux) and is not run unless requested by setting the GIT_REMOTE_SVN_TEST_BIG_FILES environment variable. Signed-off-by: Jonathan Nieder --- t/t0081-line-buffer.sh | 110 ++++++++++++++++++++++++++++++++++++++++++++++++- test-line-buffer.c | 22 ++++++++-- 2 files changed, 128 insertions(+), 4 deletions(-) (limited to 'test-line-buffer.c') diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh index 68d6163995..33a728ed98 100755 --- a/t/t0081-line-buffer.sh +++ b/t/t0081-line-buffer.sh @@ -1,10 +1,76 @@ #!/bin/sh test_description="Test the svn importer's input handling routines. + +These tests exercise the line_buffer library, but their real purpose +is to check the assumptions that library makes of the platform's input +routines. Processes engaged in bi-directional communication would +hang if fread or fgets is too greedy. + +While at it, check that input of newlines and null bytes are handled +correctly. " . ./test-lib.sh -test_expect_success 'read greeting' ' +test -n "$GIT_REMOTE_SVN_TEST_BIG_FILES" && test_set_prereq EXPENSIVE + +generate_tens_of_lines () { + tens=$1 && + line=$2 && + + i=0 && + while test $i -lt "$tens" + do + for j in a b c d e f g h i j + do + echo "$line" + done && + : $((i = $i + 1)) || + return + done +} + +long_read_test () { + : each line is 10 bytes, including newline && + line=abcdefghi && + echo "$line" >expect && + + if ! test_declared_prereq PIPE + then + echo >&4 "long_read_test: need to declare PIPE prerequisite" + return 127 + fi && + tens_of_lines=$(($1 / 100 + 1)) && + lines=$(($tens_of_lines * 10)) && + readsize=$((($lines - 1) * 10 + 3)) && + copysize=7 && + rm -f input && + mkfifo input && + { + { + generate_tens_of_lines $tens_of_lines "$line" && + sleep 100 + } >input & + } && + test-line-buffer input <<-EOF >output && + read $readsize + copy $copysize + EOF + kill $! && + test_line_count = $lines output && + tail -n 1 actual && + test_cmp expect actual +} + +test_expect_success 'setup: have pipes?' ' + rm -f frob && + if mkfifo frob + then + test_set_prereq PIPE + fi +' + +test_expect_success 'hello world' ' echo HELLO >expect && test-line-buffer <<-\EOF >actual && read 6 @@ -13,6 +79,21 @@ test_expect_success 'read greeting' ' test_cmp expect actual ' +test_expect_success PIPE '0-length read, no input available' ' + >expect && + rm -f input && + mkfifo input && + { + sleep 100 >input & + } && + test-line-buffer input <<-\EOF >actual && + read 0 + copy 0 + EOF + kill $! && + test_cmp expect actual +' + test_expect_success '0-length read, send along greeting' ' echo HELLO >expect && test-line-buffer <<-\EOF >actual && @@ -23,6 +104,33 @@ test_expect_success '0-length read, send along greeting' ' test_cmp expect actual ' +test_expect_success PIPE '1-byte read, no input available' ' + printf "%s" ab >expect && + rm -f input && + mkfifo input && + { + { + printf "%s" a && + printf "%s" b && + sleep 100 + } >input & + } && + test-line-buffer input <<-\EOF >actual && + read 1 + copy 1 + EOF + kill $! && + test_cmp expect actual +' + +test_expect_success PIPE 'long read (around 8192 bytes)' ' + long_read_test 8192 +' + +test_expect_success PIPE,EXPENSIVE 'longer read (around 65536 bytes)' ' + long_read_test 65536 +' + test_expect_success 'buffer_read_string copes with null byte' ' >expect && q_to_nul <<-\EOF | test-line-buffer >actual && diff --git a/test-line-buffer.c b/test-line-buffer.c index da0bc6502c..ec19b13ee2 100644 --- a/test-line-buffer.c +++ b/test-line-buffer.c @@ -49,15 +49,31 @@ static void handle_line(const char *line, struct line_buffer *stdin_buf) int main(int argc, char *argv[]) { struct line_buffer stdin_buf = LINE_BUFFER_INIT; + struct line_buffer file_buf = LINE_BUFFER_INIT; + struct line_buffer *input = &stdin_buf; + const char *filename; char *s; - if (argc != 1) - usage("test-line-buffer < script"); + if (argc == 1) + filename = NULL; + else if (argc == 2) + filename = argv[1]; + else + usage("test-line-buffer [file] < script"); if (buffer_init(&stdin_buf, NULL)) die_errno("open error"); + if (filename) { + if (buffer_init(&file_buf, filename)) + die_errno("error opening %s", filename); + input = &file_buf; + } + while ((s = buffer_read_line(&stdin_buf))) - handle_line(s, &stdin_buf); + handle_line(s, input); + + if (filename && buffer_deinit(&file_buf)) + die("error reading from %s", filename); if (buffer_deinit(&stdin_buf)) die("input error"); if (ferror(stdout)) -- cgit v1.3 From e832f43c1d26bf70611d98b62d95870a99292add Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Sun, 2 Jan 2011 21:05:46 -0600 Subject: vcs-svn: add binary-safe read function buffer_read_string works well for non line-oriented input except for one problem: it does not tell the caller how many bytes were actually written. This means that unless one is very careful about checking for errors (and eof) the calling program cannot tell the difference between the string "foo" followed by an early end of file and the string "foo\0bar\0baz". So introduce a variant that reports the length, too, a thinner wrapper around strbuf_fread. Its result is written to a strbuf so the caller does not need to keep track of the number of bytes read. Signed-off-by: Jonathan Nieder --- t/t0081-line-buffer.sh | 18 ++++++++++++++++++ test-line-buffer.c | 10 ++++++++++ vcs-svn/line_buffer.c | 6 ++++++ vcs-svn/line_buffer.h | 1 + 4 files changed, 35 insertions(+) (limited to 'test-line-buffer.c') diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh index 33a728ed98..a8eeb20645 100755 --- a/t/t0081-line-buffer.sh +++ b/t/t0081-line-buffer.sh @@ -151,6 +151,15 @@ test_expect_success 'skip, copy null byte' ' test_cmp expect actual ' +test_expect_success 'read null byte' ' + echo ">QhelloQ" | q_to_nul >expect && + q_to_nul <<-\EOF | test-line-buffer >actual && + binary 8 + QhelloQ + EOF + test_cmp expect actual +' + test_expect_success 'long reads are truncated' ' echo foo >expect && test-line-buffer <<-\EOF >actual && @@ -171,4 +180,13 @@ test_expect_success 'long copies are truncated' ' test_cmp expect actual ' +test_expect_success 'long binary reads are truncated' ' + echo ">foo" >expect && + test-line-buffer <<-\EOF >actual && + binary 5 + foo + EOF + test_cmp expect actual +' + test_done diff --git a/test-line-buffer.c b/test-line-buffer.c index ec19b13ee2..19bf2d4403 100644 --- a/test-line-buffer.c +++ b/test-line-buffer.c @@ -3,6 +3,7 @@ */ #include "git-compat-util.h" +#include "strbuf.h" #include "vcs-svn/line_buffer.h" static uint32_t strtouint32(const char *s) @@ -17,6 +18,15 @@ static uint32_t strtouint32(const char *s) static void handle_command(const char *command, const char *arg, struct line_buffer *buf) { switch (*command) { + case 'b': + if (!prefixcmp(command, "binary ")) { + struct strbuf sb = STRBUF_INIT; + strbuf_addch(&sb, '>'); + buffer_read_binary(buf, &sb, strtouint32(arg)); + fwrite(sb.buf, 1, sb.len, stdout); + strbuf_release(&sb); + return; + } case 'c': if (!prefixcmp(command, "copy ")) { buffer_copy_bytes(buf, strtouint32(arg)); diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c index 806932b321..661b007092 100644 --- a/vcs-svn/line_buffer.c +++ b/vcs-svn/line_buffer.c @@ -56,6 +56,12 @@ char *buffer_read_string(struct line_buffer *buf, uint32_t len) return ferror(buf->infile) ? NULL : buf->blob_buffer.buf; } +void buffer_read_binary(struct line_buffer *buf, + struct strbuf *sb, uint32_t size) +{ + strbuf_fread(sb, size, buf->infile); +} + void buffer_copy_bytes(struct line_buffer *buf, uint32_t len) { char byte_buffer[COPY_BUFFER_LEN]; diff --git a/vcs-svn/line_buffer.h b/vcs-svn/line_buffer.h index fb373903d2..0c2d3d955a 100644 --- a/vcs-svn/line_buffer.h +++ b/vcs-svn/line_buffer.h @@ -16,6 +16,7 @@ int buffer_init(struct line_buffer *buf, const char *filename); int buffer_deinit(struct line_buffer *buf); char *buffer_read_line(struct line_buffer *buf); char *buffer_read_string(struct line_buffer *buf, uint32_t len); +void buffer_read_binary(struct line_buffer *buf, struct strbuf *sb, uint32_t len); void buffer_copy_bytes(struct line_buffer *buf, uint32_t len); void buffer_skip_bytes(struct line_buffer *buf, uint32_t len); void buffer_reset(struct line_buffer *buf); -- cgit v1.3 From cb3f87cf1ba90373fdc240d65a4d65434099d9a3 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Sun, 2 Jan 2011 21:09:38 -0600 Subject: vcs-svn: allow input from file descriptor Based-on-patch-by: David Barr Signed-off-by: Jonathan Nieder --- t/t0081-line-buffer.sh | 9 +++++++++ test-line-buffer.c | 11 ++++++++--- vcs-svn/line_buffer.c | 8 ++++++++ vcs-svn/line_buffer.h | 1 + vcs-svn/line_buffer.txt | 9 +++++---- 5 files changed, 31 insertions(+), 7 deletions(-) (limited to 'test-line-buffer.c') diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh index a8eeb20645..550fad0823 100755 --- a/t/t0081-line-buffer.sh +++ b/t/t0081-line-buffer.sh @@ -131,6 +131,15 @@ test_expect_success PIPE,EXPENSIVE 'longer read (around 65536 bytes)' ' long_read_test 65536 ' +test_expect_success 'read from file descriptor' ' + rm -f input && + echo hello >expect && + echo hello >input && + echo copy 6 | + test-line-buffer "&4" 4actual && + test_cmp expect actual +' + test_expect_success 'buffer_read_string copes with null byte' ' >expect && q_to_nul <<-\EOF | test-line-buffer >actual && diff --git a/test-line-buffer.c b/test-line-buffer.c index 19bf2d4403..25b20b93fd 100644 --- a/test-line-buffer.c +++ b/test-line-buffer.c @@ -69,13 +69,18 @@ int main(int argc, char *argv[]) else if (argc == 2) filename = argv[1]; else - usage("test-line-buffer [file] < script"); + usage("test-line-buffer [file | &fd] < script"); if (buffer_init(&stdin_buf, NULL)) die_errno("open error"); if (filename) { - if (buffer_init(&file_buf, filename)) - die_errno("error opening %s", filename); + if (*filename == '&') { + if (buffer_fdinit(&file_buf, strtouint32(filename + 1))) + die_errno("error opening fd %s", filename + 1); + } else { + if (buffer_init(&file_buf, filename)) + die_errno("error opening %s", filename); + } input = &file_buf; } diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c index 37ec56e5be..e29a81a536 100644 --- a/vcs-svn/line_buffer.c +++ b/vcs-svn/line_buffer.c @@ -17,6 +17,14 @@ int buffer_init(struct line_buffer *buf, const char *filename) return 0; } +int buffer_fdinit(struct line_buffer *buf, int fd) +{ + buf->infile = fdopen(fd, "r"); + if (!buf->infile) + return -1; + return 0; +} + int buffer_deinit(struct line_buffer *buf) { int err; diff --git a/vcs-svn/line_buffer.h b/vcs-svn/line_buffer.h index 0a59c73e8b..630d83c31a 100644 --- a/vcs-svn/line_buffer.h +++ b/vcs-svn/line_buffer.h @@ -13,6 +13,7 @@ struct line_buffer { #define LINE_BUFFER_INIT {"", STRBUF_INIT, NULL} int buffer_init(struct line_buffer *buf, const char *filename); +int buffer_fdinit(struct line_buffer *buf, int fd); int buffer_deinit(struct line_buffer *buf); char *buffer_read_line(struct line_buffer *buf); char *buffer_read_string(struct line_buffer *buf, uint32_t len); diff --git a/vcs-svn/line_buffer.txt b/vcs-svn/line_buffer.txt index f8eaa4dd8c..4e8fb719c1 100644 --- a/vcs-svn/line_buffer.txt +++ b/vcs-svn/line_buffer.txt @@ -27,10 +27,11 @@ resources. Functions --------- -`buffer_init`:: - Open the named file for input. If filename is NULL, - start reading from stdin. On failure, returns -1 (with - errno indicating the nature of the failure). +`buffer_init`, `buffer_fdinit`:: + Open the named file or file descriptor for input. + buffer_init(buf, NULL) prepares to read from stdin. + On failure, returns -1 (with errno indicating the nature + of the failure). `buffer_deinit`:: Stop reading from the current file (closing it unless -- cgit v1.3 From 7e2fe3a9fc816391b322ad9b3f2adf9342631db6 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 24 Mar 2011 23:09:19 -0500 Subject: vcs-svn: remove buffer_read_string All previous users of buffer_read_string have already been converted to use the more intuitive buffer_read_binary, so remove the old API to avoid some confusion. Signed-off-by: Jonathan Nieder --- t/t0081-line-buffer.sh | 35 +++++++++++++---------------------- test-line-buffer.c | 6 ------ vcs-svn/line_buffer.c | 8 -------- vcs-svn/line_buffer.h | 4 +--- vcs-svn/line_buffer.txt | 12 +++--------- 5 files changed, 17 insertions(+), 48 deletions(-) (limited to 'test-line-buffer.c') diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh index 550fad0823..1dbe1c9b08 100755 --- a/t/t0081-line-buffer.sh +++ b/t/t0081-line-buffer.sh @@ -53,7 +53,7 @@ long_read_test () { } >input & } && test-line-buffer input <<-EOF >output && - read $readsize + binary $readsize copy $copysize EOF kill $! && @@ -71,23 +71,23 @@ test_expect_success 'setup: have pipes?' ' ' test_expect_success 'hello world' ' - echo HELLO >expect && + echo ">HELLO" >expect && test-line-buffer <<-\EOF >actual && - read 6 + binary 6 HELLO EOF test_cmp expect actual ' test_expect_success PIPE '0-length read, no input available' ' - >expect && + printf ">" >expect && rm -f input && mkfifo input && { sleep 100 >input & } && test-line-buffer input <<-\EOF >actual && - read 0 + binary 0 copy 0 EOF kill $! && @@ -95,9 +95,9 @@ test_expect_success PIPE '0-length read, no input available' ' ' test_expect_success '0-length read, send along greeting' ' - echo HELLO >expect && + echo ">HELLO" >expect && test-line-buffer <<-\EOF >actual && - read 0 + binary 0 copy 6 HELLO EOF @@ -105,7 +105,7 @@ test_expect_success '0-length read, send along greeting' ' ' test_expect_success PIPE '1-byte read, no input available' ' - printf "%s" ab >expect && + printf ">%s" ab >expect && rm -f input && mkfifo input && { @@ -116,7 +116,7 @@ test_expect_success PIPE '1-byte read, no input available' ' } >input & } && test-line-buffer input <<-\EOF >actual && - read 1 + binary 1 copy 1 EOF kill $! && @@ -140,15 +140,6 @@ test_expect_success 'read from file descriptor' ' test_cmp expect actual ' -test_expect_success 'buffer_read_string copes with null byte' ' - >expect && - q_to_nul <<-\EOF | test-line-buffer >actual && - read 2 - Q - EOF - test_cmp expect actual -' - test_expect_success 'skip, copy null byte' ' echo Q | q_to_nul >expect && q_to_nul <<-\EOF | test-line-buffer >actual && @@ -170,18 +161,18 @@ test_expect_success 'read null byte' ' ' test_expect_success 'long reads are truncated' ' - echo foo >expect && + echo ">foo" >expect && test-line-buffer <<-\EOF >actual && - read 5 + binary 5 foo EOF test_cmp expect actual ' test_expect_success 'long copies are truncated' ' - printf "%s\n" "" foo >expect && + printf "%s\n" ">" foo >expect && test-line-buffer <<-\EOF >actual && - read 1 + binary 1 copy 5 foo diff --git a/test-line-buffer.c b/test-line-buffer.c index 25b20b93fd..7ec9b13c9b 100644 --- a/test-line-buffer.c +++ b/test-line-buffer.c @@ -32,12 +32,6 @@ static void handle_command(const char *command, const char *arg, struct line_buf buffer_copy_bytes(buf, strtouint32(arg)); return; } - case 'r': - if (!prefixcmp(command, "read ")) { - const char *s = buffer_read_string(buf, strtouint32(arg)); - fputs(s, stdout); - return; - } case 's': if (!prefixcmp(command, "skip ")) { buffer_skip_bytes(buf, strtouint32(arg)); diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c index 33e733a04c..c39038723e 100644 --- a/vcs-svn/line_buffer.c +++ b/vcs-svn/line_buffer.c @@ -91,13 +91,6 @@ char *buffer_read_line(struct line_buffer *buf) return buf->line_buffer; } -char *buffer_read_string(struct line_buffer *buf, uint32_t len) -{ - strbuf_reset(&buf->blob_buffer); - strbuf_fread(&buf->blob_buffer, len, buf->infile); - return ferror(buf->infile) ? NULL : buf->blob_buffer.buf; -} - void buffer_read_binary(struct line_buffer *buf, struct strbuf *sb, uint32_t size) { @@ -134,5 +127,4 @@ off_t buffer_skip_bytes(struct line_buffer *buf, off_t nbytes) void buffer_reset(struct line_buffer *buf) { - strbuf_release(&buf->blob_buffer); } diff --git a/vcs-svn/line_buffer.h b/vcs-svn/line_buffer.h index f5c468afa4..d0b22dda76 100644 --- a/vcs-svn/line_buffer.h +++ b/vcs-svn/line_buffer.h @@ -7,10 +7,9 @@ struct line_buffer { char line_buffer[LINE_BUFFER_LEN]; - struct strbuf blob_buffer; FILE *infile; }; -#define LINE_BUFFER_INIT {"", STRBUF_INIT, NULL} +#define LINE_BUFFER_INIT { "", NULL } int buffer_init(struct line_buffer *buf, const char *filename); int buffer_fdinit(struct line_buffer *buf, int fd); @@ -23,7 +22,6 @@ long buffer_tmpfile_prepare_to_read(struct line_buffer *buf); int buffer_ferror(struct line_buffer *buf); char *buffer_read_line(struct line_buffer *buf); -char *buffer_read_string(struct line_buffer *buf, uint32_t len); int buffer_read_char(struct line_buffer *buf); void buffer_read_binary(struct line_buffer *buf, struct strbuf *sb, uint32_t len); /* Returns number of bytes read (not necessarily written). */ diff --git a/vcs-svn/line_buffer.txt b/vcs-svn/line_buffer.txt index 4ef0755cf5..8e139eb22d 100644 --- a/vcs-svn/line_buffer.txt +++ b/vcs-svn/line_buffer.txt @@ -16,8 +16,8 @@ The calling program: - initializes a `struct line_buffer` to LINE_BUFFER_INIT - specifies a file to read with `buffer_init` - - processes input with `buffer_read_line`, `buffer_read_string`, - `buffer_skip_bytes`, and `buffer_copy_bytes` + - processes input with `buffer_read_line`, `buffer_skip_bytes`, + and `buffer_copy_bytes` - closes the file with `buffer_deinit`, perhaps to start over and read another file. @@ -37,7 +37,7 @@ the calling program. A program the temporary file - declares writing is over with `buffer_tmpfile_prepare_to_read` - can re-read what was written with `buffer_read_line`, - `buffer_read_string`, and so on + `buffer_copy_bytes`, and so on - can reuse the temporary file by calling `buffer_tmpfile_rewind` again - removes the temporary file with `buffer_deinit`, perhaps to @@ -64,12 +64,6 @@ Functions Read a line and strip off the trailing newline. On failure or end of file, returns NULL. -`buffer_read_string`:: - Read `len` characters of input or up to the end of the - file, whichever comes first. Returns NULL on error. - Returns whatever characters were read (possibly "") - for end of file. - `buffer_copy_bytes`:: Read `len` bytes of input and dump them to the standard output stream. Returns early for error or end of file. -- cgit v1.3