summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--libmdocml.c210
-rw-r--r--libmdocml.h42
-rw-r--r--mdocml.c48
4 files changed, 237 insertions, 70 deletions
diff --git a/Makefile b/Makefile
index 47bbb565..af8856f0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,13 +2,13 @@ CFLAGS += -W -Wall -g
LINTFLAGS += -c -e -f -u
-CLEAN = mdocml mdocml.o mdocml.ln libmdocml.o libmdocml.ln mdocml.tgz
+CLEAN = mdocml mdocml.o mdocml.ln libmdocml.o libmdocml.ln mdocml.tgz llib-lmdocml.ln
INSTALL = Makefile libmdocml.h mdocml.c libmdocml.c mdocml.1
all: mdocml
-lint: mdocml.ln libmdocml.ln
+lint: llib-lmdocml.ln
dist: mdocml.tgz
@@ -24,6 +24,9 @@ mdocml.tgz: $(INSTALL)
( cd .dist/ && tar zcf ../mdocml.tgz mdocml/ )
rm -rf .dist/
+llib-lmdocml.ln: mdocml.ln libmdocml.ln
+ $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln
+
mdocml.ln: mdocml.c
mdocml.o: mdocml.c
diff --git a/libmdocml.c b/libmdocml.c
index 9e40da80..608c5266 100644
--- a/libmdocml.c
+++ b/libmdocml.c
@@ -28,12 +28,48 @@
#define BUFFER_LINE BUFSIZ
-typedef int (*md_line) (struct md_mbuf *, const struct md_rbuf *,
+struct md_rbuf {
+ int fd;
+ char *name;
+ char *buf;
+ size_t bufsz;
+ size_t line;
+};
+
+struct md_mbuf {
+ int fd;
+ char *name;
+ char *buf;
+ size_t bufsz;
+ size_t pos;
+};
+
+typedef int (*md_line) (const struct md_args *, struct md_mbuf *,
+ const struct md_rbuf *,
+ const char *, size_t);
+typedef int (*md_init) (const struct md_args *, struct md_mbuf *);
+typedef int (*md_exit) (const struct md_args *, struct md_mbuf *);
+
+static int md_line_dummy(const struct md_args *,
+ struct md_mbuf *,
+ const struct md_rbuf *,
const char *, size_t);
-static int md_line_dummy(struct md_mbuf *,
+static int md_line_html4_strict(const struct md_args *,
+ struct md_mbuf *,
const struct md_rbuf *,
const char *, size_t);
+static int md_init_html4_strict(const struct md_args *,
+ struct md_mbuf *);
+static int md_exit_html4_strict(const struct md_args *,
+ struct md_mbuf *);
+
+static int md_run_enter(const struct md_args *,
+ struct md_mbuf *, struct md_rbuf *);
+static int md_run_leave(const struct md_args *,
+ struct md_mbuf *,
+ struct md_rbuf *, int);
+
static ssize_t md_buf_fill(struct md_rbuf *);
static int md_buf_flush(struct md_mbuf *);
static int md_buf_putchar(struct md_mbuf *, char);
@@ -41,7 +77,7 @@ static int md_buf_puts(struct md_mbuf *,
const char *, size_t);
-ssize_t
+static ssize_t
md_buf_fill(struct md_rbuf *in)
{
ssize_t ssz;
@@ -58,7 +94,7 @@ md_buf_fill(struct md_rbuf *in)
}
-int
+static int
md_buf_flush(struct md_mbuf *buf)
{
ssize_t sz;
@@ -85,14 +121,14 @@ md_buf_flush(struct md_mbuf *buf)
}
-int
+static int
md_buf_putchar(struct md_mbuf *buf, char c)
{
return(md_buf_puts(buf, &c, 1));
}
-int
+static int
md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz)
{
size_t ssz;
@@ -121,73 +157,177 @@ md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz)
}
-int
-md_run(enum md_type type, struct md_mbuf *out, struct md_rbuf *in)
+static int
+md_run_leave(const struct md_args *args,
+ struct md_mbuf *mbuf, struct md_rbuf *rbuf, int c)
{
- ssize_t sz, i;
- char line[BUFFER_LINE];
- size_t pos;
- md_line func;
+ assert(args);
+ assert(mbuf);
+ assert(rbuf);
+
+ /* Run exiters. */
+ switch (args->type) {
+ case (MD_HTML4_STRICT):
+ if ( ! md_exit_html4_strict(args, mbuf))
+ return(-1);
+ break;
+ case (MD_DUMMY):
+ break;
+ default:
+ abort();
+ }
- assert(in);
- assert(out);
+ /* Make final flush of buffer. */
+ if ( ! md_buf_flush(mbuf))
+ return(-1);
+
+ return(c);
+}
- out->pos = 0;
- in->line = 1;
- assert(MD_DUMMY == type);
- func = md_line_dummy;
+static int
+md_run_enter(const struct md_args *args,
+ struct md_mbuf *mbuf, struct md_rbuf *rbuf)
+{
+ ssize_t sz, i;
+ char line[BUFFER_LINE];
+ size_t pos;
+ md_line fp;
+
+ assert(args);
+ assert(mbuf);
+ assert(rbuf);
+
+ /* Function ptrs to line-parsers. */
+ switch (args->type) {
+ case (MD_HTML4_STRICT):
+ fp = md_line_html4_strict;
+ break;
+ case (MD_DUMMY):
+ fp = md_line_dummy;
+ break;
+ default:
+ abort();
+ }
/* LINTED */
for (pos = 0; ; ) {
- if (-1 == (sz = md_buf_fill(in)))
- return(1);
+ if (-1 == (sz = md_buf_fill(rbuf)))
+ return(-1);
else if (0 == sz)
break;
for (i = 0; i < sz; i++) {
- if ('\n' == in->buf[i]) {
- if ((*func)(out, in, line, pos))
- return(1);
- in->line++;
+ if ('\n' == rbuf->buf[i]) {
+ if ( ! (*fp)(args, mbuf, rbuf, line, pos))
+ return(-1);
+ rbuf->line++;
pos = 0;
continue;
}
if (pos < BUFFER_LINE) {
/* LINTED */
- line[pos++] = in->buf[i];
+ line[pos++] = rbuf->buf[i];
continue;
}
warnx("%s: line %zu too long",
- in->name, in->line);
- return(1);
+ rbuf->name, rbuf->line);
+ return(-1);
}
}
- if (0 != pos && (*func)(out, in, line, pos))
- return(1);
+ if (0 != pos && ! (*fp)(args, mbuf, rbuf, line, pos))
+ return(-1);
- return(md_buf_flush(out) ? 0 : 1);
+ return(md_run_leave(args, mbuf, rbuf, 0));
+}
+
+
+int
+md_run(const struct md_args *args,
+ const struct md_buf *out, const struct md_buf *in)
+{
+ struct md_mbuf mbuf;
+ struct md_rbuf rbuf;
+
+ assert(args);
+ assert(in);
+ assert(out);
+
+ (void)memcpy(&mbuf, out, sizeof(struct md_buf));
+ (void)memcpy(&rbuf, in, sizeof(struct md_buf));
+
+ mbuf.pos = 0;
+ rbuf.line = 1;
+
+ /* Run initialisers. */
+ switch (args->type) {
+ case (MD_HTML4_STRICT):
+ if ( ! md_init_html4_strict(args, &mbuf))
+ return(-1);
+ break;
+ case (MD_DUMMY):
+ break;
+ default:
+ abort();
+ }
+
+ /* Go into mainline. */
+ return(md_run_enter(args, &mbuf, &rbuf));
}
static int
-md_line_dummy(struct md_mbuf *out, const struct md_rbuf *in,
- const char *buf, size_t sz)
+md_line_dummy(const struct md_args *args, struct md_mbuf *out,
+ const struct md_rbuf *in, const char *buf, size_t sz)
{
assert(buf);
assert(out);
assert(in);
+ assert(args);
if ( ! md_buf_puts(out, buf, sz))
- return(1);
+ return(0);
if ( ! md_buf_putchar(out, '\n'))
- return(1);
+ return(0);
- return(0);
+ return(1);
+}
+
+
+static int
+md_exit_html4_strict(const struct md_args *args, struct md_mbuf *p)
+{
+
+ assert(p);
+ assert(args);
+ return(1);
}
+static int
+md_init_html4_strict(const struct md_args *args, struct md_mbuf *p)
+{
+
+ assert(p);
+ assert(args);
+ return(1);
+}
+
+
+static int
+md_line_html4_strict(const struct md_args *args, struct md_mbuf *out,
+ const struct md_rbuf *in, const char *buf, size_t sz)
+{
+
+ assert(args);
+ assert(buf);
+ assert(out);
+ assert(in);
+ (void)sz;
+
+ return(1);
+}
diff --git a/libmdocml.h b/libmdocml.h
index 85843ce6..5d7e9727 100644
--- a/libmdocml.h
+++ b/libmdocml.h
@@ -21,29 +21,43 @@
#include <sys/types.h>
-struct md_rbuf {
- int fd;
- const char *name;
- char *buf;
- size_t bufsz;
- size_t line;
+struct md_params_dummy {
+ int dummy;
};
-struct md_mbuf {
- int fd;
- const char *name;
- char *buf;
- size_t bufsz;
- size_t pos;
+struct md_params_html4_strict {
+ int dummy;
+};
+
+union md_params {
+ struct md_params_dummy dummy;
+ struct md_params_html4_strict html4_strict;
};
enum md_type {
- MD_DUMMY
+ MD_DUMMY, /* Dummy type echoes input. */
+ MD_HTML4_STRICT /* HTML4.01-strict. */
+};
+
+struct md_args {
+ union md_params params;/* Parameters for parser. */
+ enum md_type type; /* Type of parser. */
+};
+
+struct md_buf {
+ int fd; /* Open file descriptor. */
+ char *name; /* Name of file/socket/whatever. */
+ char *buf; /* Buffer for storing data. */
+ size_t bufsz; /* Size of buf. */
};
__BEGIN_DECLS
-int md_run(enum md_type, struct md_mbuf *, struct md_rbuf *);
+/* Run the parser over prepared input and output buffers. Returns -1 on
+ * failure and 0 on success.
+ */
+int md_run(const struct md_args *,
+ const struct md_buf *, const struct md_buf *);
__END_DECLS
diff --git a/mdocml.c b/mdocml.c
index dbcb88d0..83daddbb 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -34,18 +34,21 @@
#define BUFFER_OUT_DEF BUFSIZ
static void usage(void);
-static int begin_io(const char *, const char *);
-static int leave_io(const struct md_mbuf *,
- const struct md_rbuf *, int);
-static int begin_bufs(struct md_mbuf *, struct md_rbuf *);
-static int leave_bufs(const struct md_mbuf *,
- const struct md_rbuf *, int);
+static int begin_io(const struct md_args *,
+ char *, char *);
+static int leave_io(const struct md_buf *,
+ const struct md_buf *, int);
+static int begin_bufs(const struct md_args *,
+ struct md_buf *, struct md_buf *);
+static int leave_bufs(const struct md_buf *,
+ const struct md_buf *, int);
int
main(int argc, char *argv[])
{
int c;
char *out, *in;
+ struct md_args args;
extern char *optarg;
extern int optind;
@@ -68,13 +71,15 @@ main(int argc, char *argv[])
if (1 == argc)
in = *argv++;
- return(begin_io(out ? out : "-", in ? in : "-"));
+ args.type = MD_DUMMY;
+
+ return(begin_io(&args, out ? out : "-", in ? in : "-"));
}
static int
-leave_io(const struct md_mbuf *out,
- const struct md_rbuf *in, int c)
+leave_io(const struct md_buf *out,
+ const struct md_buf *in, int c)
{
assert(out);
assert(in);
@@ -96,19 +101,20 @@ leave_io(const struct md_mbuf *out,
static int
-begin_io(const char *out, const char *in)
+begin_io(const struct md_args *args, char *out, char *in)
{
- struct md_rbuf fi;
- struct md_mbuf fo;
+ struct md_buf fi;
+ struct md_buf fo;
#define FI_FL O_RDONLY
#define FO_FL O_WRONLY|O_CREAT|O_TRUNC
+ assert(args);
assert(out);
assert(in);
- bzero(&fi, sizeof(struct md_rbuf));
- bzero(&fo, sizeof(struct md_mbuf));
+ bzero(&fi, sizeof(struct md_buf));
+ bzero(&fo, sizeof(struct md_buf));
fi.fd = STDIN_FILENO;
fo.fd = STDOUT_FILENO;
@@ -128,13 +134,13 @@ begin_io(const char *out, const char *in)
return(leave_io(&fo, &fi, 1));
}
- return(leave_io(&fo, &fi, begin_bufs(&fo, &fi)));
+ return(leave_io(&fo, &fi, begin_bufs(args, &fo, &fi)));
}
static int
-leave_bufs(const struct md_mbuf *out,
- const struct md_rbuf *in, int c)
+leave_bufs(const struct md_buf *out,
+ const struct md_buf *in, int c)
{
assert(out);
assert(in);
@@ -147,10 +153,13 @@ leave_bufs(const struct md_mbuf *out,
static int
-begin_bufs(struct md_mbuf *out, struct md_rbuf *in)
+begin_bufs(const struct md_args *args,
+ struct md_buf *out, struct md_buf *in)
{
struct stat stin, stout;
+ int c;
+ assert(args);
assert(in);
assert(out);
@@ -173,7 +182,8 @@ begin_bufs(struct md_mbuf *out, struct md_rbuf *in)
return(leave_bufs(out, in, 1));
}
- return(leave_bufs(out, in, md_run(MD_DUMMY, out, in)));
+ c = md_run(args, out, in);
+ return(leave_bufs(out, in, -1 == c ? 1 : 0));
}