From 2002d48e23de84408230d563b44e992dd74457eb Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Sun, 23 Nov 2008 16:53:18 +0000 Subject: Segmentation into html and dummy parsers. Initial recursive-descent parser in place for html/ml parser. Parsing of title tags more-or-less in place. --- Makefile | 39 ++++- dummy.c | 44 ++++++ html4_strict.c | 451 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ libmdocml.c | 203 ++++---------------------- private.h | 68 +++++++++ 5 files changed, 622 insertions(+), 183 deletions(-) create mode 100644 dummy.c create mode 100644 html4_strict.c create mode 100644 private.h diff --git a/Makefile b/Makefile index af8856f0..3d2c3e48 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,24 @@ CFLAGS += -W -Wall -g - LINTFLAGS += -c -e -f -u -CLEAN = mdocml mdocml.o mdocml.ln libmdocml.o libmdocml.ln mdocml.tgz llib-lmdocml.ln +LNS = mdocml.ln html4_strict.ln dummy.ln libmdocml.ln + +LLNS = llib-lmdocml.ln + +LIBS = libmdocml.a + +OBJS = mdocml.o html4_strict.o dummy.o libmdocml.o + +SRCS = mdocml.c html4_strict.c dummy.c libmdocml.c + +HEADS = libmdocml.h private.h + +MANS = mdocml.1 + +CLEAN = mdocml mdocml.tgz $(LLNS) $(LNS) $(OBJS) $(LIBS) + +INSTALL = Makefile $(HEADS) $(SRCS) $(MANS) -INSTALL = Makefile libmdocml.h mdocml.c libmdocml.c mdocml.1 all: mdocml @@ -12,8 +26,8 @@ lint: llib-lmdocml.ln dist: mdocml.tgz -mdocml: mdocml.o libmdocml.o - $(CC) $(CFLAGS) -o $@ mdocml.o libmdocml.o +mdocml: mdocml.o libmdocml.a + $(CC) $(CFLAGS) -o $@ mdocml.o libmdocml.a clean: rm -f $(CLEAN) @@ -24,8 +38,8 @@ 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 +llib-lmdocml.ln: mdocml.ln libmdocml.ln html4_strict.ln dummy.ln + $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html4_strict.ln dummy.ln mdocml.ln: mdocml.c @@ -33,8 +47,17 @@ mdocml.o: mdocml.c mdocml.c: libmdocml.h +libmdocml.a: libmdocml.o html4_strict.o dummy.o + $(AR) rs $@ libmdocml.o html4_strict.o dummy.o + +html4_strict.ln: html4_strict.c + +html4_strict.o: html4_strict.c + +html4_strict.c: private.h libmdocml.h + libmdocml.ln: libmdocml.c libmdocml.o: libmdocml.c -libmdocml.c: libmdocml.h +libmdocml.c: private.h libmdocml.h diff --git a/dummy.c b/dummy.c new file mode 100644 index 00000000..03c1e4bd --- /dev/null +++ b/dummy.c @@ -0,0 +1,44 @@ +/* $Id$ */ +/* + * Copyright (c) 2008 Kristaps Dzonsons + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include + +#include "libmdocml.h" +#include "private.h" + + +int +md_line_dummy(const struct md_args *args, + struct md_mbuf *out, const struct md_rbuf *in, + const char *buf, size_t sz, void *data) +{ + + assert(buf); + assert(out); + assert(in); + assert(args); + assert(NULL == data); + + if ( ! md_buf_puts(out, buf, sz)) + return(0); + if ( ! md_buf_putchar(out, '\n')) + return(0); + + return(1); +} diff --git a/html4_strict.c b/html4_strict.c new file mode 100644 index 00000000..6da9fd51 --- /dev/null +++ b/html4_strict.c @@ -0,0 +1,451 @@ +/* $Id$ */ +/* + * Copyright (c) 2008 Kristaps Dzonsons + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "libmdocml.h" +#include "private.h" + +enum roffd { + ROFF_ENTER = 0, + ROFF_EXIT +}; + +enum rofftype { + ROFF_NONE = 0, + ROFF_LAYOUT +}; + +struct rofftree; + +#define ROFFCALL_ARGS const struct md_args *arg, \ + struct md_mbuf *out, \ + const struct md_rbuf *in, \ + const char *buf, size_t sz, \ + size_t pos, enum roffd type, \ + struct rofftree *tree +typedef int (*roffcall)(ROFFCALL_ARGS); + +static int roff_Dd(ROFFCALL_ARGS); +static int roff_Dt(ROFFCALL_ARGS); +static int roff_Os(ROFFCALL_ARGS); +static int roff_Sh(ROFFCALL_ARGS); + +struct rofftok { + char id; +#define ROFF___ 0 +#define ROFF_Dd 1 +#define ROFF_Dt 2 +#define ROFF_Os 3 +#define ROFF_Sh 4 +#define ROFF_Max 5 + char name[2]; + roffcall cb; + enum rofftype type; + int flags; +#define ROFF_NESTED (1 << 0) +}; + +static const struct rofftok tokens[ROFF_Max] = { + { ROFF___, "\\\"", NULL, ROFF_NONE, 0 }, + { ROFF_Dd, "Dd", roff_Dd, ROFF_NONE, 0 }, + { ROFF_Dt, "Dt", roff_Dt, ROFF_NONE, 0 }, + { ROFF_Os, "Os", roff_Os, ROFF_LAYOUT, 0 }, + { ROFF_Sh, "Sh", roff_Sh, ROFF_LAYOUT, 0 }, +}; + +struct roffnode { + int tok; + struct roffnode *parent; + /* TODO: line number at acquisition. */ +}; + +struct rofftree { + struct roffnode *last; + + time_t date; + char title[256]; + char section[256]; + char volume[256]; + + int state; +#define ROFF_PRELUDE (1 << 0) +#define ROFF_PRELUDE_Os (1 << 1) +#define ROFF_PRELUDE_Dt (1 << 2) +#define ROFF_PRELUDE_Dd (1 << 3) +}; + +static int rofffind(const char *); +static int roffparse(const struct md_args *, + struct md_mbuf *, + const struct md_rbuf *, + const char *, size_t, + struct rofftree *); +static int textparse(struct md_mbuf *, + const struct md_rbuf *, + const char *, size_t, + const struct rofftree *); + + +int +md_exit_html4_strict(const struct md_args *args, struct md_mbuf *out, + const struct md_rbuf *in, void *data) +{ + struct rofftree *tree; + int error; + + assert(args); + assert(data); + tree = (struct rofftree *)data; + error = 0; + + while (tree->last) + if ( ! (*tokens[tree->last->tok].cb) + (args, error ? NULL : out, in, NULL, + 0, 0, ROFF_EXIT, tree)) + error = 1; + + free(tree); + return(error ? 0 : 1); +} + + +int +md_init_html4_strict(const struct md_args *args, struct md_mbuf *out, + const struct md_rbuf *in, void **data) +{ + struct rofftree *tree; + + assert(args); + assert(in); + assert(out); + assert(data); + + /* TODO: write HTML-DTD header. */ + + if (NULL == (tree = calloc(1, sizeof(struct rofftree)))) { + warn("malloc"); + return(0); + } + + *data = tree; + return(1); +} + + +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, void *data) +{ + struct rofftree *tree; + + assert(args); + assert(in); + assert(data); + + tree = (struct rofftree *)data; + + if (0 == sz) { + warnx("%s: blank line (line %zu)", in->name, in->line); + return(0); + } else if ('.' != *buf) + return(textparse(out, in, buf, sz, tree)); + + return(roffparse(args, out, in, buf, sz, tree)); +} + + +static int +textparse(struct md_mbuf *out, const struct md_rbuf *in, + const char *buf, size_t sz, + const struct rofftree *tree) +{ + + assert(tree); + assert(out); + assert(in); + assert(buf); + assert(sz > 0); + + if (NULL == tree->last) { + warnx("%s: unexpected text (line %zu)", + in->name, in->line); + return(0); + } else if (NULL == tree->last->parent) { + warnx("%s: disallowed text (line %zu)", + in->name, in->line); + return(0); + } + + if ( ! md_buf_puts(out, buf, sz)) + return(0); + return(md_buf_putstring(out, " ")); +} + + +static int +roffparse(const struct md_args *args, struct md_mbuf *out, + const struct md_rbuf *in, const char *buf, + size_t sz, struct rofftree *tree) +{ + int tokid, t; + size_t pos; + struct roffnode *node; + + assert(args); + assert(out); + assert(in); + assert(buf); + assert(sz > 0); + assert(tree); + + /* + * Extract the token identifier from the buffer. If there's no + * callback for the token (comment, etc.) then exit immediately. + * We don't do any error handling (yet), so if the token doesn't + * exist, die. + */ + + if (3 > sz) { + warnx("%s: malformed input (line %zu, col 1)", + in->name, in->line); + return(0); + } else if (ROFF_Max == (tokid = rofffind(buf + 1))) { + warnx("%s: unknown token `%c%c' (line %zu, col 1)", + in->name, *(buf + 1), + *(buf + 2), in->line); + return(0); + } else if (NULL == tokens[tokid].cb) + return(1); /* Skip token. */ + + pos = 3; + + /* + * If this is a non-nestable layout token and we're below a + * token of the same type, then recurse upward to the token, + * closing out the interim scopes. + * + * If there's a nested token on the chain, then raise an error + * as nested tokens have corresponding "ending" tokens and we're + * breaking their scope. + */ + + node = NULL; + + if (ROFF_LAYOUT == tokens[tokid].type && + ! (ROFF_NESTED & tokens[tokid].flags)) { + for (node = tree->last; node; node = node->parent) { + if (node->tok == tokid) + break; + + /* Don't break nested scope. */ + + if ( ! (ROFF_NESTED & tokens[node->tok].flags)) + continue; + warnx("%s: scope of %s broken by %s " + "(line %zu, col %zu)", + in->name, tokens[tokid].name, + tokens[node->tok].name, + in->line, pos); + return(0); + } + } + if (node) { + assert(ROFF_LAYOUT == tokens[tokid].type); + assert( ! (ROFF_NESTED & tokens[tokid].flags)); + assert(node->tok == tokid); + + /* Clear up to last scoped token. */ + + do { + t = tree->last->tok; + if ( ! (*tokens[tree->last->tok].cb) + (args, out, in, NULL, + 0, 0, ROFF_EXIT, tree)) + return(0); + } while (t != tokid); + } + + /* Proceed with actual token processing. */ + + return((*tokens[tokid].cb)(args, out, in, buf, sz, + pos, ROFF_ENTER, tree)); +} + + +static int +rofffind(const char *name) +{ + size_t i; + + assert(name); + /* FIXME: use a table, this is slow but ok for now. */ + for (i = 0; i < ROFF_Max; i++) + if (0 == strncmp(name, tokens[i].name, 2)) + return(i); + + return(ROFF_Max); +} + + +/* ARGUSED */ +static int +roff_Dd(ROFFCALL_ARGS) +{ + + assert(in); + assert(tree); + assert(arg); + assert(out); + assert(buf); + assert(sz > 0); + assert(pos > 0); + assert(type == ROFF_ENTER); + + if (tree->last) { + warnx("%s: superfluous prelude (line %zu, col %zu)", + in->name, in->line, pos); + return(0); + } + + if (0 != tree->state) { + warnx("%s: bad manual prelude (line %zu, col %zu)", + in->name, in->line, pos); + return(1); + } + + /* TODO: parse date from buffer. */ + + tree->date = time(NULL); + tree->state |= ROFF_PRELUDE_Dd; + return(1); +} + + +static int +roff_Dt(ROFFCALL_ARGS) +{ + + assert(in); + assert(tree); + assert(arg); + assert(out); + assert(buf); + assert(sz > 0); + assert(pos > 0); + assert(type == ROFF_ENTER); + + if (tree->last) { + warnx("%s: superfluous prelude (line %zu, col %zu)", + in->name, in->line, pos); + return(0); + } + + if ( ! (ROFF_PRELUDE_Dd & tree->state) || + (ROFF_PRELUDE_Os & tree->state) || + (ROFF_PRELUDE_Dt & tree->state)) { + warnx("%s: bad manual prelude (line %zu, col %zu)", + in->name, in->line, pos); + return(1); + } + + /* TODO: parse titles from buffer. */ + + tree->state |= ROFF_PRELUDE_Dt; + return(1); +} + + +static int +roff_Os(ROFFCALL_ARGS) +{ + struct roffnode *node; + + assert(arg); + assert(tree); + assert(in); + + if (ROFF_EXIT == type) { + assert(tree->last); + assert(tree->last->tok == ROFF_Os); + + /* TODO: flush out ML footer. */ + + node = tree->last; + tree->last = node->parent; + free(node); + + return(1); + } + + assert(out); + assert(buf); + assert(sz > 0); + assert(pos > 0); + + if (tree->last) { + warnx("%s: superfluous prelude (line %zu, col %zu)", + in->name, in->line, pos); + return(0); + } + + if ((ROFF_PRELUDE_Os & tree->state) || + ! (ROFF_PRELUDE_Dt & tree->state) || + ! (ROFF_PRELUDE_Dd & tree->state)) { + warnx("%s: bad manual prelude (line %zu, col %zu)", + in->name, in->line, pos); + return(1); + } + + node = malloc(sizeof(struct roffnode)); + if (NULL == node) { + warn("malloc"); + return(0); + } + node->tok = ROFF_Os; + node->parent = NULL; + + tree->state |= ROFF_PRELUDE_Os; + tree->last = node; + + return(1); +} + + +static int +roff_Sh(ROFFCALL_ARGS) +{ + + assert(arg); + /*assert(out);*/(void)out; + assert(in); + /*assert(buf);*/(void)buf; + (void)sz; + (void)pos; + (void)type; + assert(tree); + return(1); +} + diff --git a/libmdocml.c b/libmdocml.c index 86a58ec0..7317b6d9 100644 --- a/libmdocml.c +++ b/libmdocml.c @@ -25,58 +25,16 @@ #include #include "libmdocml.h" +#include "private.h" #define BUFFER_LINE BUFSIZ -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_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); -static int md_buf_putstring(struct md_mbuf *, - const char *); -static int md_buf_puts(struct md_mbuf *, - const char *, size_t); +static int md_run_enter(const struct md_args *, + struct md_mbuf *, struct md_rbuf *, void *); +static int md_run_leave(const struct md_args *, struct md_mbuf *, + struct md_rbuf *, int, void *); +static ssize_t md_buf_fill(struct md_rbuf *); +static int md_buf_flush(struct md_mbuf *); static ssize_t @@ -123,21 +81,21 @@ md_buf_flush(struct md_mbuf *buf) } -static int +int md_buf_putchar(struct md_mbuf *buf, char c) { return(md_buf_puts(buf, &c, 1)); } -static int +int md_buf_putstring(struct md_mbuf *buf, const char *p) { return(md_buf_puts(buf, p, strlen(p))); } -static int +int md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz) { size_t ssz; @@ -167,8 +125,8 @@ md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz) static int -md_run_leave(const struct md_args *args, - struct md_mbuf *mbuf, struct md_rbuf *rbuf, int c) +md_run_leave(const struct md_args *args, struct md_mbuf *mbuf, + struct md_rbuf *rbuf, int c, void *data) { assert(args); assert(mbuf); @@ -177,7 +135,7 @@ md_run_leave(const struct md_args *args, /* Run exiters. */ switch (args->type) { case (MD_HTML4_STRICT): - if ( ! md_exit_html4_strict(args, mbuf)) + if ( ! md_exit_html4_strict(args, mbuf, rbuf, data)) return(-1); break; case (MD_DUMMY): @@ -195,8 +153,8 @@ md_run_leave(const struct md_args *args, static int -md_run_enter(const struct md_args *args, - struct md_mbuf *mbuf, struct md_rbuf *rbuf) +md_run_enter(const struct md_args *args, struct md_mbuf *mbuf, + struct md_rbuf *rbuf, void *p) { ssize_t sz, i; char line[BUFFER_LINE]; @@ -222,14 +180,15 @@ md_run_enter(const struct md_args *args, /* LINTED */ for (pos = 0; ; ) { if (-1 == (sz = md_buf_fill(rbuf))) - return(-1); + return(md_run_leave(args, mbuf, rbuf, -1, p)); else if (0 == sz) break; for (i = 0; i < sz; i++) { if ('\n' == rbuf->buf[i]) { - if ( ! (*fp)(args, mbuf, rbuf, line, pos)) - return(-1); + if ( ! (*fp)(args, mbuf, rbuf, line, pos, p)) + return(md_run_leave(args, mbuf, rbuf, + -1, p)); rbuf->line++; pos = 0; continue; @@ -243,14 +202,14 @@ md_run_enter(const struct md_args *args, warnx("%s: line %zu too long", rbuf->name, rbuf->line); - return(-1); + return(md_run_leave(args, mbuf, rbuf, -1, p)); } } - if (0 != pos && ! (*fp)(args, mbuf, rbuf, line, pos)) - return(-1); + if (0 != pos && ! (*fp)(args, mbuf, rbuf, line, pos, p)) + return(md_run_leave(args, mbuf, rbuf, -1, p)); - return(md_run_leave(args, mbuf, rbuf, 0)); + return(md_run_leave(args, mbuf, rbuf, 0, p)); } @@ -260,6 +219,7 @@ md_run(const struct md_args *args, { struct md_mbuf mbuf; struct md_rbuf rbuf; + void *data; assert(args); assert(in); @@ -270,11 +230,13 @@ md_run(const struct md_args *args, mbuf.pos = 0; rbuf.line = 1; + data = NULL; /* Run initialisers. */ switch (args->type) { case (MD_HTML4_STRICT): - if ( ! md_init_html4_strict(args, &mbuf)) + if ( ! md_init_html4_strict + (args, &mbuf, &rbuf, &data)) return(-1); break; case (MD_DUMMY): @@ -284,114 +246,5 @@ md_run(const struct md_args *args, } /* Go into mainline. */ - return(md_run_enter(args, &mbuf, &rbuf)); -} - - -static int -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(0); - if ( ! md_buf_putchar(out, '\n')) - return(0); - - return(1); -} - - -static int -md_exit_html4_strict(const struct md_args *args, struct md_mbuf *out) -{ - char *tail; - - assert(out); - assert(args); - - tail = " \n" - " \n" - "\n"; - - if ( ! md_buf_putstring(out, tail)) - return(0); - - return(1); -} - - -static int -md_init_html4_strict(const struct md_args *args, struct md_mbuf *out) -{ - char *head; - - assert(out); - assert(args); - - head = "\n" - " \n" - " Manual Page\n" - " \n" - " \n" - "
\n";
-
-	if ( ! md_buf_putstring(out, head))
-		return(0);
-
-	return(1);
-}
-
-
-struct md_roff_macro {
-	char		 name[2];
-	int		 flags;
-#define	MD_PARSED	(1 << 0)
-#define	MD_CALLABLE	(1 << 1)
-#define	MD_TITLE	(1 << 2)
-};
-
-struct md_roff_macro[] = {
-	{ "Dd",		MD_TITLE 	},
-	{ "Dt",		MD_TITLE 	},
-	{ "Os",		MD_TITLE 	},
-	{ "Sh",		MD_PARSED 	},
-};
-
-
-static int
-md_roff(struct md_mbuf *out, const struct md_rbuf *in, 
-		const char *buf, size_t sz)
-{
-
-	assert(out);
-	assert(in);
-	assert(buf);
-	assert(sz >= 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(in);
-
-	if (0 == sz) {
-		warnx("%s: blank line (line %zu)", in->name, in->line);
-		return(0);
-	}
-
-	if ('.' == *buf) {
-		return(1);
-	}
-	
-	return(md_buf_puts(out, buf, sz));
+	return(md_run_enter(args, &mbuf, &rbuf, data));
 }
diff --git a/private.h b/private.h
new file mode 100644
index 00000000..934061c6
--- /dev/null
+++ b/private.h
@@ -0,0 +1,68 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef PRIVATE_H
+#define PRIVATE_H
+
+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;
+};
+
+__BEGIN_DECLS
+
+typedef	int	(*md_init)(const struct md_args *, struct md_mbuf *,
+			const struct md_rbuf *, void **);
+typedef	int	(*md_exit)(const struct md_args *, struct md_mbuf *, 
+			const struct md_rbuf *, void *);
+typedef	int	(*md_line)(const struct md_args *, 
+			struct md_mbuf *, const struct md_rbuf *, 
+			const char *, size_t, void *);
+
+int		  md_line_html4_strict(const struct md_args *,
+			struct md_mbuf *, const struct md_rbuf *,
+			const char *, size_t, void *);
+int		  md_init_html4_strict(const struct md_args *, 
+			struct md_mbuf *, const struct md_rbuf *,
+			void **);
+int		  md_exit_html4_strict(const struct md_args *,
+			struct md_mbuf *, const struct md_rbuf *, 
+			void *);
+
+int		  md_line_dummy(const struct md_args *,
+			struct md_mbuf *, const struct md_rbuf *, 
+			const char *, size_t, void *);
+
+int	 	  md_buf_puts(struct md_mbuf *, const char *, size_t);
+int	 	  md_buf_putchar(struct md_mbuf *, char);
+int	 	  md_buf_putstring(struct md_mbuf *, const char *);
+
+__END_DECLS
+
+#endif /*!PRIVATE_H*/
-- 
cgit