summaryrefslogtreecommitdiffstatshomepage
path: root/mdocml.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2008-11-22 16:55:02 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2008-11-22 16:55:02 +0000
commitab55bc6a44ba97e5ead915c63da6ee1be12f44f0 (patch)
tree8d98b1c364c53ebe2fe000fcabfc69959440e994 /mdocml.c
parent5e3f93f3205c713280c92d185b154e3849e58da0 (diff)
downloadmandoc-ab55bc6a44ba97e5ead915c63da6ee1be12f44f0.tar.gz
mandoc-ab55bc6a44ba97e5ead915c63da6ee1be12f44f0.tar.zst
mandoc-ab55bc6a44ba97e5ead915c63da6ee1be12f44f0.zip
Buffering and line-buffering working and tested.
Diffstat (limited to 'mdocml.c')
-rw-r--r--mdocml.c116
1 files changed, 99 insertions, 17 deletions
diff --git a/mdocml.c b/mdocml.c
index 48bedcb9..dc771431 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -1,4 +1,4 @@
-/* $Id: mdocml.c,v 1.1 2008/11/22 14:53:29 kristaps Exp $ */
+/* $Id: mdocml.c,v 1.2 2008/11/22 16:55:02 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -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);
}