diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2008-11-22 16:55:02 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2008-11-22 16:55:02 +0000 |
commit | f0b8bbc09a28f0ea611aa90debbad03ec445fef1 (patch) | |
tree | 82b0cc7479f1e3582f3480b844f222b34ebd6e28 | |
parent | 6df3d92658b4f43a3950f7a88baccded9b5e2cff (diff) | |
download | mandoc-f0b8bbc09a28f0ea611aa90debbad03ec445fef1.tar.gz |
Buffering and line-buffering working and tested.
-rw-r--r-- | mdocml.c | 114 |
1 files changed, 98 insertions, 16 deletions
@@ -42,16 +42,26 @@ struct md_buf { size_t line; }; +struct md_mbuf { + struct md_buf *buf; + size_t pos; +}; + static void usage(void); static int md_begin(const char *, const char *); static int md_begin_io(const char *, const char *); static int md_begin_bufs(struct md_file *, struct md_file *); static int md_run(struct md_buf *, struct md_buf *); -static int md_line(struct md_buf *, const struct md_buf *, +static int md_line(struct md_mbuf *, const struct md_buf *, const char *, size_t); static ssize_t md_buf_fill(struct md_buf *); +static int md_buf_flush(struct md_mbuf *); + +static int md_buf_putchar(struct md_mbuf *, char); +static int md_buf_puts(struct md_mbuf *, + const char *, size_t); int @@ -117,9 +127,7 @@ md_begin_io(const char *out, const char *in) assert(out); assert(in); - /* XXX: put an output file in TMPDIR and switch it out when the - * true file is ready to be written. - */ + /* TODO: accept "-" as both input and output. */ fin.name = in; @@ -130,7 +138,7 @@ md_begin_io(const char *out, const char *in) fout.name = out; - fout.fd = open(fout.name, O_WRONLY | O_CREAT | O_EXCL, 0644); + fout.fd = open(fout.name, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (-1 == fout.fd) { warn("%s", fout.name); if (-1 == close(fin.fd)) @@ -173,11 +181,13 @@ md_begin_bufs(struct md_file *out, struct md_file *in) inbuf.file = in; inbuf.line = 1; - inbuf.bufsz = MAX(stin.st_blksize, BUFSIZ); + /*inbuf.bufsz = MAX(stin.st_blksize, BUFSIZ);*/ + inbuf.bufsz = 256; outbuf.file = out; outbuf.line = 1; - outbuf.bufsz = MAX(stout.st_blksize, BUFSIZ); + /*outbuf.bufsz = MAX(stout.st_blksize, BUFSIZ);*/ + outbuf.bufsz = 256; if (NULL == (inbuf.buf = malloc(inbuf.bufsz))) { warn("malloc"); @@ -210,6 +220,9 @@ md_buf_fill(struct md_buf *in) if (-1 == (ssz = read(in->file->fd, in->buf, in->bufsz))) warn("%s", in->file->name); + else + (void)printf("%s: filled %zd bytes\n", + in->file->name, ssz); return(ssz); } @@ -218,6 +231,7 @@ md_buf_fill(struct md_buf *in) static int md_run(struct md_buf *out, struct md_buf *in) { + struct md_mbuf mbuf; ssize_t sz, i; char line[BUFSIZ]; size_t pos; @@ -225,6 +239,9 @@ md_run(struct md_buf *out, struct md_buf *in) assert(in); assert(out); + mbuf.buf = out; + mbuf.pos = 0; + /* LINTED */ for (pos = 0; ; ) { if (-1 == (sz = md_buf_fill(in))) @@ -234,7 +251,7 @@ md_run(struct md_buf *out, struct md_buf *in) for (i = 0; i < sz; i++) { if ('\n' == in->buf[i]) { - if (md_line(out, in, line, pos)) + if (md_line(&mbuf, in, line, pos)) return(1); in->line++; pos = 0; @@ -253,27 +270,92 @@ md_run(struct md_buf *out, struct md_buf *in) } } - if (0 != pos) - return(md_line(out, in, line, pos)); + if (0 != pos && md_line(&mbuf, in, line, pos)) + return(1); - return(0); + return(md_buf_flush(&mbuf) ? 0 : 1); +} + + +static int +md_buf_flush(struct md_mbuf *buf) +{ + ssize_t sz; + + assert(buf); + assert(buf->buf); + assert(buf->buf->file); + assert(buf->buf->buf); + assert(buf->buf->file->name); + + (void)printf("%s: flushing %zu bytes\n", + buf->buf->file->name, buf->pos); + + if (0 == buf->pos) + return(1); + + sz = write(buf->buf->file->fd, buf->buf->buf, buf->pos); + + if (-1 == sz) { + warn("%s", buf->buf->file->name); + return(0); + } else if ((size_t)sz != buf->pos) { + warnx("%s: short write", buf->buf->file->name); + return(0); + } + + buf->pos = 0; + return(1); } static int -md_line(struct md_buf *out, const struct md_buf *in, +md_buf_putchar(struct md_mbuf *buf, char c) +{ + return(md_buf_puts(buf, &c, 1)); +} + + +static int +md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz) +{ + size_t ssz; + + assert(p); + assert(buf); + assert(buf->buf); + + while (buf->pos + sz > buf->buf->bufsz) { + ssz = buf->buf->bufsz - buf->pos; + (void)memcpy(buf->buf->buf + buf->pos, p, ssz); + p += ssz; + sz -= ssz; + buf->pos += ssz; + + if ( ! md_buf_flush(buf)) + return(0); + } + + (void)memcpy(buf->buf->buf + buf->pos, p, sz); + buf->pos += sz; + return(1); +} + + +static int +md_line(struct md_mbuf *out, const struct md_buf *in, const char *buf, size_t sz) { - size_t i; assert(buf); assert(out); assert(in); - for (i = 0; i < sz; i++) - (void)putchar(buf[i]); + if ( ! md_buf_puts(out, buf, sz)) + return(1); + if ( ! md_buf_putchar(out, '\n')) + return(1); - (void)putchar('\n'); return(0); } |