]> git.cameronkatri.com Git - mandoc.git/blobdiff - libmdocml.c
Split roff engine into roff.c.
[mandoc.git] / libmdocml.c
index 07513496abbcc804224fbafd70c1b4da2018cd26..42e795841084f0e2aad0a419a751dba3007d2f5f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: libmdocml.c,v 1.2 2008/11/22 18:34:06 kristaps Exp $ */
+/* $Id: libmdocml.c,v 1.9 2008/11/24 14:24:55 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 #include <unistd.h>
 
 #include "libmdocml.h"
+#include "private.h"
 
-#define        BUFFER_LINE      BUFSIZ
+#define        BUFFER_LINE      BUFSIZ /* Default line-buffer size. */
 
-typedef int (*md_line) (struct md_mbuf *, const struct md_rbuf *,
-                               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 int              md_line_dummy(struct md_mbuf *, 
-                               const struct md_rbuf *,
-                               const char *, size_t);
-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_puts(struct md_mbuf *, 
-                               const char *, size_t);
+static ssize_t  md_buf_fill(struct md_rbuf *);
+static int      md_buf_flush(struct md_mbuf *);
 
 
-ssize_t
+static ssize_t
 md_buf_fill(struct md_rbuf *in)
 {
        ssize_t          ssz;
@@ -58,7 +55,7 @@ md_buf_fill(struct md_rbuf *in)
 }
 
 
-int
+static int
 md_buf_flush(struct md_mbuf *buf)
 {
        ssize_t          sz;
@@ -92,6 +89,13 @@ md_buf_putchar(struct md_mbuf *buf, char c)
 }
 
 
+int
+md_buf_putstring(struct md_mbuf *buf, const char *p)
+{
+       return(md_buf_puts(buf, p, strlen(p)));
+}
+
+
 int
 md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz)
 {
@@ -121,73 +125,122 @@ 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, void *data)
+{
+       assert(args);
+       assert(mbuf);
+       assert(rbuf);
+
+       /* Run exiters. */
+       switch (args->type) {
+       case (MD_HTML4_STRICT):
+               if ( ! md_exit_html4_strict(data, -1 == c ? 0 : 1))
+                       c = -1;
+               break;
+       default:
+               if ( ! md_exit_dummy(data, -1 == c ? 0 : 1))
+                       c = -1;
+               break;
+       }
+
+       /* Make final flush of buffer. */
+       if ( ! md_buf_flush(mbuf))
+               return(-1);
+
+       return(c);
+}
+
+
+static int
+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];
        size_t           pos;
-       md_line          func;
-
-       assert(in);
-       assert(out); 
-
-       out->pos = 0;
-       in->line = 1;
+       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;
+       default:
+               fp = md_line_dummy;
+               break;
+       }
 
-       assert(MD_DUMMY == type);
-       func = md_line_dummy;
+       pos = 0;
 
-       /* LINTED */
-       for (pos = 0; ; ) {
-               if (-1 == (sz = md_buf_fill(in)))
-                       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++;
-                               pos = 0;
-                               continue;
-                       }
+again:
+       if (-1 == (sz = md_buf_fill(rbuf))) {
+               return(md_run_leave(args, mbuf, rbuf, -1, p));
+       } else if (0 == sz && 0 != pos) {
+               warnx("%s: no newline at end of file", rbuf->name);
+               return(md_run_leave(args, mbuf, rbuf, -1, p));
+       } else if (0 == sz)
+               return(md_run_leave(args, mbuf, rbuf, 0, p));
 
+       for (i = 0; i < sz; i++) {
+               if ('\n' != rbuf->buf[i]) {
                        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(md_run_leave(args, mbuf, rbuf, -1, p));
                }
-       }
 
-       if (0 != pos && (*func)(out, in, line, pos))
-               return(1);
+               line[pos] = 0;
+               if ( ! (*fp)(p, line, pos))
+                       return(md_run_leave(args, mbuf, rbuf, -1, p));
+               rbuf->line++;
+               pos = 0;
+       }
 
-       return(md_buf_flush(out) ? 0 : 1);
+       goto again;
+       /* NOTREACHED */
 }
 
 
-static int
-md_line_dummy(struct md_mbuf *out, const struct md_rbuf *in,
-               const char *buf, size_t sz)
+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;
+       void            *data;
 
-       assert(buf);
-       assert(out);
+       assert(args);
        assert(in);
+       assert(out); 
 
-       if ( ! md_buf_puts(out, buf, sz))
-               return(1);
-       if ( ! md_buf_putchar(out, '\n'))
-               return(1);
+       (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):
+               data = md_init_html4_strict
+                       (args, &mbuf, &rbuf);
+               break;
+       default:
+               data = md_init_dummy
+                       (args, &mbuf, &rbuf);
+               break;
+       }
 
-       return(0);
+       /* Go into mainline. */
+       return(md_run_enter(args, &mbuf, &rbuf, data));
 }
-
-