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 <jrnieder@gmail.com>
This commit is contained in:
Jonathan Nieder
2010-10-10 21:41:06 -05:00
parent d350822fa7
commit e5e45ca1e3
7 changed files with 50 additions and 46 deletions

View File

@ -8,20 +8,16 @@
#include "strbuf.h"
#define COPY_BUFFER_LEN 4096
static struct line_buffer buf_ = LINE_BUFFER_INIT;
static struct line_buffer *buf;
int buffer_init(const char *filename)
int buffer_init(struct line_buffer *buf, const char *filename)
{
buf = &buf_;
buf->infile = filename ? fopen(filename, "r") : stdin;
if (!buf->infile)
return -1;
return 0;
}
int buffer_deinit(void)
int buffer_deinit(struct line_buffer *buf)
{
int err;
if (buf->infile == stdin)
@ -32,7 +28,7 @@ int buffer_deinit(void)
}
/* Read a line without trailing newline. */
char *buffer_read_line(void)
char *buffer_read_line(struct line_buffer *buf)
{
char *end;
if (!fgets(buf->line_buffer, sizeof(buf->line_buffer), buf->infile))
@ -53,14 +49,14 @@ char *buffer_read_line(void)
return buf->line_buffer;
}
char *buffer_read_string(uint32_t len)
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_copy_bytes(uint32_t len)
void buffer_copy_bytes(struct line_buffer *buf, uint32_t len)
{
char byte_buffer[COPY_BUFFER_LEN];
uint32_t in;
@ -70,13 +66,13 @@ void buffer_copy_bytes(uint32_t len)
len -= in;
fwrite(byte_buffer, 1, in, stdout);
if (ferror(stdout)) {
buffer_skip_bytes(len);
buffer_skip_bytes(buf, len);
return;
}
}
}
void buffer_skip_bytes(uint32_t len)
void buffer_skip_bytes(struct line_buffer *buf, uint32_t len)
{
char byte_buffer[COPY_BUFFER_LEN];
uint32_t in;
@ -87,7 +83,7 @@ void buffer_skip_bytes(uint32_t len)
}
}
void buffer_reset(void)
void buffer_reset(struct line_buffer *buf)
{
strbuf_release(&buf->blob_buffer);
}