summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile175
-rw-r--r--compat.c1
-rw-r--r--hash.c126
-rw-r--r--html.c1085
-rw-r--r--html.h86
-rw-r--r--index.7156
-rw-r--r--libmdocml.c261
-rw-r--r--libmdocml.h67
-rw-r--r--literals.c615
-rw-r--r--macro.c292
-rw-r--r--mdoc.c734
-rw-r--r--mdoc.h289
-rw-r--r--mdocml.c461
-rw-r--r--mdocml.css58
-rw-r--r--ml.c261
-rw-r--r--ml.h93
-rw-r--r--mlg.c868
-rw-r--r--noop.c294
-rw-r--r--private.h405
-rw-r--r--tags.c188
-rw-r--r--tokens.c193
-rw-r--r--xml.c235
22 files changed, 1771 insertions, 5172 deletions
diff --git a/Makefile b/Makefile
index 4c8efc2d..45524cae 100644
--- a/Makefile
+++ b/Makefile
@@ -1,174 +1,57 @@
-VERSION = 1.0.3
+VERSION = 1.1.0
-# FIXME
-CFLAGS += -W -Wall -Wno-unused-parameter -g -DDEBUG
+CFLAGS += -W -Wall -Wno-unused-parameter -g
-LNS = mdocml.ln html.ln xml.ln libmdocml.ln roff.ln ml.ln mlg.ln \
- compat.ln tokens.ln literals.ln tags.ln noop.ln
+LNS = macro.ln mdoc.ln mdocml.ln hash.ln
-LLNS = llib-lmdocml.ln
+LLNS = llib-llibmdoc.ln llib-lmdocml.ln
-LIBS = libmdocml.a
+LIBS = libmdoc.a
-OBJS = mdocml.o html.o xml.o libmdocml.o roff.o ml.o mlg.o \
- compat.o tokens.o literals.o tags.o noop.o
+OBJS = macro.o mdoc.o mdocml.o hash.o
-SRCS = mdocml.c html.c xml.c libmdocml.c roff.c ml.c mlg.c \
- compat.c tokens.c literals.c tags.c noop.c
+SRCS = macro.c mdoc.c mdocml.c hash.c
-HEADS = libmdocml.h private.h ml.h roff.h html.h
+HEADS = mdoc.h
-MANS = mdocml.1 index.7
+BINS = mdocml
-HTML = index.html mdocml.html
+CLEAN = $(BINS) $(LNS) $(LLNS) $(LIBS) $(OBJS)
-XML = index.xml
+all: $(BINS)
-TEXT = index.txt
+lint: $(LLNS)
-CLEAN = mdocml $(LLNS) $(LNS) $(OBJS) $(LIBS) $(HTML) $(XML) $(TEXT) \
- mdocml-$(VERSION).tar.gz mdocml-port-$(VERSION).tar.gz
-
-INSTALL = Makefile $(HEADS) $(SRCS) $(MANS) mdocml.css
-
-FAIL = test.0 test.1 test.2 test.3 test.4 test.5 test.6 \
- test.15 test.20 test.22 test.24 test.26 test.27 test.30 \
- test.36 test.37 test.40 test.50 test.61 test.64 test.65 \
- test.66 test.69 test.70
-
-SUCCEED = test.7 test.8 test.9 test.10 test.11 test.12 test.13 \
- test.14 test.16 test.17 test.18 test.19 test.21 test.23 \
- test.25 test.28 test.29 test.31 test.32 test.33 test.34 \
- test.35 test.38 test.39 test.41 test.42 test.43 test.44 \
- test.45 test.46 test.47 test.48 test.49 test.51 test.52 \
- test.54 test.55 test.56 test.57 test.58 test.59 test.60 \
- test.62 test.63 test.67 test.68 test.71 test.72 test.73
-
-all: mdocml
-
-lint: llib-lmdocml.ln
-
-dist: mdocml-$(VERSION).tar.gz mdocml-port-$(VERSION).tar.gz
-
-www: all $(HTML) $(XML) $(TEXT)
-
-regress: mdocml
- @for f in $(FAIL); do \
- echo "./mdocml $$f" ; \
- ./mdocml -v $$f 1>/dev/null 2>/dev/null || continue ; \
- done
- @for f in $(SUCCEED); do \
- echo "./mdocml $$f" ; \
- ./mdocml -v $$f 1>/dev/null || exit 1 ; \
- done
-
-mdocml: mdocml.o libmdocml.a
- $(CC) $(CFLAGS) -o $@ mdocml.o libmdocml.a
+mdocml: mdocml.o libmdoc.a
+ $(CC) $(CFLAGS) -o $@ mdocml.o libmdoc.a
clean:
rm -f $(CLEAN)
-index.html: index.7 mdocml.css
- ./mdocml -fhtml -Wall -e -o $@ index.7
-
-index.xml: index.7 mdocml.css
- ./mdocml -fxml -Wall -o $@ index.7
-
-index.txt: index.7
- cp -f index.7 index.txt
-
-mdocml.html: mdocml.1 mdocml.css
- ./mdocml -Wall -fhtml -e -o $@ mdocml.1
-
-install:
- mkdir -p $(PREFIX)/bin/
- install -m 0755 mdocml $(PREFIX)/bin/
- mkdir -p $(PREFIX)/man/man1/
- install -m 0444 mdocml.1 $(PREFIX)/man/man1/
- mkdir -p $(PREFIX)/share/mdocml/
- install -m 0444 mdocml.css $(PREFIX)/share/mdocml/
-
-uninstall:
- rm -f $(PREFIX)/bin/mdocml
- rm -f $(PREFIX)/man/man1/mdocml.1
- rm -f $(PREFIX)/share/mdocml/mdocml.css
-
-install-www: www dist
- install -m 0644 mdocml-$(VERSION).tar.gz $(PREFIX)/
- install -m 0644 mdocml-$(VERSION).tar.gz $(PREFIX)/mdocml.tar.gz
- install -m 0644 mdocml-port-$(VERSION).tar.gz $(PREFIX)/
- install -m 0644 mdocml-port-$(VERSION).tar.gz $(PREFIX)/mdocml-port.tar.gz
- install -m 0644 $(HTML) $(XML) $(TEXT) $(PREFIX)/
-
-mdocml-$(VERSION).tar.gz: $(INSTALL)
- mkdir -p .dist/mdocml/mdocml-$(VERSION)/
- install -m 0644 $(INSTALL) .dist/mdocml/mdocml-$(VERSION)/
- ( cd .dist/mdocml/ && tar zcf ../../$@ mdocml-$(VERSION)/ )
- rm -rf .dist/
-
-mdocml-port-$(VERSION).tar.gz: $(INSTALL)
- mkdir -p .dist/mdocml/pkg
- sed -e "s!@VERSION@!$(VERSION)!" Makefile.port > .dist/mdocml/Makefile
- md5 mdocml-$(VERSION).tar.gz > .dist/mdocml/distinfo
- rmd160 mdocml-$(VERSION).tar.gz >> .dist/mdocml/distinfo
- sha1 mdocml-$(VERSION).tar.gz >> .dist/mdocml/distinfo
- install -m 0644 DESCR .dist/mdocml/pkg/DESCR
- echo @comment $$OpenBSD$$ > .dist/mdocml/pkg/PLIST
- echo bin/mdocml >> .dist/mdocml/pkg/PLIST
- echo share/mdocml/mdocml.css >> .dist/mdocml/pkg/PLIST
- echo @man man/man1/mdocml.1 >> .dist/mdocml/pkg/PLIST
- ( cd .dist/ && tar zcf ../$@ mdocml/ )
- rm -rf .dist/
-
-llib-lmdocml.ln: mdocml.ln libmdocml.ln html.ln xml.ln roff.ln ml.ln mlg.ln compat.ln tokens.ln literals.ln tags.ln noop.ln
- $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html.ln xml.ln roff.ln ml.ln mlg.ln compat.ln tokens.ln literals.ln tags.ln noop.ln
-
-mdocml.ln: mdocml.c libmdocml.h
-
-mdocml.o: mdocml.c libmdocml.h
-
-libmdocml.a: libmdocml.o html.o xml.o roff.o ml.o mlg.o compat.o tokens.o literals.o tags.o noop.o
- $(AR) rs $@ libmdocml.o html.o xml.o roff.o ml.o mlg.o compat.o tokens.o literals.o tags.o noop.o
-
-xml.ln: xml.c ml.h
-
-xml.o: xml.c ml.h
-
-html.ln: html.c private.h
-
-html.o: html.c private.h
-
-tags.ln: tags.c html.h
-
-tags.o: tags.c html.h
-
-roff.ln: roff.c private.h
-
-roff.o: roff.c private.h
-
-libmdocml.ln: libmdocml.c private.h
-
-libmdocml.o: libmdocml.c private.h
+llib-llibmdoc.ln: macro.ln mdoc.ln hash.ln
+ $(LINT) $(LINTFLAGS) -Cllibmdoc mdoc.ln macro.ln hash.ln
-ml.ln: ml.c ml.h
+llib-llmdocml.ln: mdocml.ln llib-llibmdoc.ln
+ $(LINT) $(LINTFLAGS) -Cllibmdoc mdocml.ln llib-llibmdoc.ln
-ml.o: ml.c ml.h
+macro.ln: macro.c private.h
-mlg.ln: mlg.c ml.h
+macro.o: macro.c private.h
-mlg.o: mlg.c ml.h
+hash.ln: hash.c private.h
-compat.ln: compat.c
+hash.o: hash.c private.h
-compat.o: compat.c
+mdoc.ln: mdoc.c private.h
-noop.ln: noop.c private.h
+mdoc.o: mdoc.c private.h
-noop.o: noop.c private.h
+mdocml.ln: mdocml.c mdoc.h
-html.h: ml.h
+mdocml.o: mdocml.c mdoc.h
-ml.h: private.h
+private.h: mdoc.h
-private.h: libmdocml.h
+libmdoc.a: macro.o mdoc.o hash.o
+ $(AR) rs $@ macro.o mdoc.o hash.o
diff --git a/compat.c b/compat.c
index bb1972a3..cec52d7b 100644
--- a/compat.c
+++ b/compat.c
@@ -87,4 +87,5 @@ strlcpy(char *dst, const char *src, size_t siz)
return(s - src - 1); /* count does not include NUL */
}
+
#endif /*__linux__*/
diff --git a/hash.c b/hash.c
new file mode 100644
index 00000000..1bdca064
--- /dev/null
+++ b/hash.c
@@ -0,0 +1,126 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * 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 <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "private.h"
+
+
+void
+mdoc_hash_free(void *htab)
+{
+
+ free(htab);
+}
+
+
+void *
+mdoc_hash_alloc(void)
+{
+ int i, major, minor, index;
+ const void **htab;
+
+ htab = calloc(27 * 26, sizeof(struct mdoc_macro *));
+ if (NULL == htab)
+ err(1, "calloc");
+
+ for (i = 1; i < MDOC_MAX; i++) {
+ major = mdoc_macronames[i][0];
+ assert((major >= 65 && major <= 90) ||
+ major == 37);
+
+ if (major == 37)
+ major = 0;
+ else
+ major -= 64;
+
+ minor = mdoc_macronames[i][1];
+ assert((minor >= 65 && minor <= 90) ||
+ (minor == 49) ||
+ (minor >= 97 && minor <= 122));
+
+ if (minor == 49)
+ minor = 0;
+ else if (minor <= 90)
+ minor -= 65;
+ else
+ minor -= 97;
+
+ assert(major >= 0 && major < 27);
+ assert(minor >= 0 && minor < 26);
+
+ index = (major * 27) + minor;
+
+ assert(NULL == htab[index]);
+ htab[index] = &mdoc_macros[i];
+ }
+
+ return((void *)htab);
+}
+
+
+int
+mdoc_hash_find(const void *arg, const char *tmp)
+{
+ int major, minor, index, slot;
+ const void **htab;
+
+ htab = (const void **)arg;
+
+ if (0 == tmp[0] || 0 == tmp[1])
+ return(MDOC_MAX);
+
+ if ( ! (tmp[0] == 37 || (tmp[0] >= 65 && tmp[0] <= 90)))
+ return(MDOC_MAX);
+
+ if ( ! ((tmp[1] >= 65 && tmp[1] <= 90) ||
+ (tmp[1] == 49) ||
+ (tmp[1] >= 97 && tmp[1] <= 122)))
+ return(MDOC_MAX);
+
+ if (tmp[0] == 37)
+ major = 0;
+ else
+ major = tmp[0] - 64;
+
+ if (tmp[1] == 49)
+ minor = 0;
+ else if (tmp[1] <= 90)
+ minor = tmp[1] - 65;
+ else
+ minor = tmp[1] - 97;
+
+ index = (major * 27) + minor;
+
+ if (NULL == htab[index])
+ return(MDOC_MAX);
+
+ slot = htab[index] - (void *)mdoc_macros;
+ assert(0 == slot % sizeof(struct mdoc_macro));
+ slot /= sizeof(struct mdoc_macro);
+
+ if (0 != strcmp(mdoc_macronames[slot], tmp))
+ return(MDOC_MAX);
+ return(slot);
+}
+
diff --git a/html.c b/html.c
deleted file mode 100644
index 6d34045f..00000000
--- a/html.c
+++ /dev/null
@@ -1,1085 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <sys/param.h>
-#include <sys/stat.h>
-
-#include <assert.h>
-#include <err.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "html.h"
-#include "ml.h"
-
-/* TODO: allow head/tail-less invocations (just "div" start). */
-
-struct htmlnode {
- int tok;
- enum md_ns ns;
- int argc[ROFF_MAXLINEARG];
- char *argv[ROFF_MAXLINEARG];
- struct htmlnode *parent;
-};
-
-struct htmlq {
- struct htmlnode *last;
-};
-
-
-static int html_loadcss(struct md_mbuf *,
- const char *);
-static int html_alloc(void **);
-static void html_free(void *);
-static ssize_t html_endtag(struct ml_args *,
- enum md_ns, int);
-static ssize_t html_beginstring(struct ml_args *,
- const char *, size_t);
-static ssize_t html_endstring(struct ml_args *,
- const char *, size_t);
-static ssize_t html_begintag(struct ml_args *,
- enum md_ns, int,
- const int *, const char **);
-static int html_begin(struct ml_args *,
- const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
-static int html_end(struct ml_args *,
- const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
-static int html_printargs(struct md_mbuf *, int,
- const char *, const int *,
- const char **, size_t *);
-static ssize_t html_beginhttp(struct md_mbuf *,
- const struct md_args *,
- const char *, size_t);
-static ssize_t html_endhttp(struct md_mbuf *,
- const struct md_args *,
- const char *, size_t);
-static int html_blocktagname(struct md_mbuf *,
- const struct md_args *, int,
- struct htmlq *, const int *,
- const char **, size_t *);
-static int html_blocktagargs(struct md_mbuf *,
- const struct md_args *, int,
- const int *, const char **, size_t *);
-static int html_headtagname(struct md_mbuf *,
- const struct md_args *, int,
- struct htmlq *, const int *,
- const char **, size_t *);
-static int html_headtagargs(struct md_mbuf *,
- const struct md_args *, int,
- const int *, const char **, size_t *);
-static int html_bodytagname(struct md_mbuf *,
- const struct md_args *,
- int, struct htmlq *, const int *,
- const char **, size_t *);
-static int html_bodytagargs(struct md_mbuf *,
- const struct md_args *, int,
- const int *, const char **, size_t *);
-static int html_inlinetagname(struct md_mbuf *,
- const struct md_args *, int, size_t *);
-static int html_inlinetagargs(struct md_mbuf *,
- const struct md_args *, int,
- const int *, const char **, size_t *);
-static int html_Bl_bodytagname(struct md_mbuf *,
- struct htmlq *, const int *,
- const char **, size_t *);
-static int html_It_blocktagname(struct md_mbuf *,
- struct htmlq *, const int *,
- const char **, size_t *);
-static int html_It_headtagname(struct md_mbuf *,
- struct htmlq *, const int *,
- const char **, size_t *);
-static int html_It_bodytagname(struct md_mbuf *,
- struct htmlq *, const int *,
- const char **, size_t *);
-static int html_tputln(struct md_mbuf *,
- enum ml_scope, int, enum html_tag);
-static int html_aputln(struct md_mbuf *, enum ml_scope,
- int, enum html_tag,
- int, const struct html_pair *);
-
-
-/* ARGSUSED */
-static int
-html_It_headtagname(struct md_mbuf *mbuf, struct htmlq *q,
- const int *argc, const char **argv, size_t *res)
-{
- struct htmlnode *n;
- int i;
- struct html_pair attr[2];
-
- for (n = q->last; n; n = n->parent)
- if (n->tok == ROFF_Bl)
- break;
-
- assert(n);
-
- /* LINTED */
- for (i = 0; ROFF_ARGMAX != n->argc[i] &&
- i < ROFF_MAXLINEARG; i++) {
- switch (n->argc[i]) {
- case (ROFF_Ohang):
- return(html_stput(mbuf, HTML_TAG_DIV, res));
- case (ROFF_Tag):
- attr[0].attr = HTML_ATTR_VALIGN;
- attr[0].val = "top";
- attr[1].attr = HTML_ATTR_NOWRAP;
- attr[1].val = "true";
- return(html_saput(mbuf, HTML_TAG_TD,
- res, 2, attr));
- case (ROFF_Column):
- attr[0].attr = HTML_ATTR_VALIGN;
- attr[0].val = "top";
- return(html_saput(mbuf, HTML_TAG_TD,
- res, 1, attr));
- default:
- break;
- }
- }
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-html_It_bodytagname(struct md_mbuf *mbuf, struct htmlq *q,
- const int *argc, const char **argv, size_t *res)
-{
- struct htmlnode *n;
- int i;
- struct html_pair attr[1];
-
- for (n = q->last; n; n = n->parent)
- if (n->tok == ROFF_Bl)
- break;
-
- assert(n);
-
- /* LINTED */
- for (i = 0; ROFF_ARGMAX != n->argc[i] &&
- i < ROFF_MAXLINEARG; i++) {
- switch (n->argc[i]) {
- case (ROFF_Enum):
- /* FALLTHROUGH */
- case (ROFF_Bullet):
- /* FALLTHROUGH */
- case (ROFF_Dash):
- /* FALLTHROUGH */
- case (ROFF_Hyphen):
- /* FALLTHROUGH */
- case (ROFF_Item):
- /* FALLTHROUGH */
- case (ROFF_Diag):
- /* FALLTHROUGH */
- case (ROFF_Hang):
- /* FALLTHROUGH */
- case (ROFF_Ohang):
- /* FALLTHROUGH */
- case (ROFF_Inset):
- return(html_stput(mbuf, HTML_TAG_DIV, res));
- case (ROFF_Tag):
- /* FALLTHROUGH */
- case (ROFF_Column):
- attr[0].attr = HTML_ATTR_VALIGN;
- attr[0].val = "top";
- return(html_saput(mbuf, HTML_TAG_TD,
- res, 1, attr));
- default:
- break;
- }
- }
-
- assert(i != ROFF_MAXLINEARG);
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-html_Bl_bodytagname(struct md_mbuf *mbuf, struct htmlq *q,
- const int *argc, const char **argv, size_t *res)
-{
- int i;
-
- for (i = 0; ROFF_ARGMAX != argc[i]
- && i < ROFF_MAXLINEARG; i++) {
- switch (argc[i]) {
- case (ROFF_Enum):
- return(html_stput(mbuf, HTML_TAG_OL, res));
- case (ROFF_Bullet):
- /* FALLTHROUGH */
- case (ROFF_Dash):
- /* FALLTHROUGH */
- case (ROFF_Hyphen):
- /* FALLTHROUGH */
- case (ROFF_Item):
- /* FALLTHROUGH */
- case (ROFF_Diag):
- /* FALLTHROUGH */
- case (ROFF_Hang):
- /* FALLTHROUGH */
- case (ROFF_Ohang):
- /* FALLTHROUGH */
- case (ROFF_Inset):
- return(html_stput(mbuf, HTML_TAG_UL, res));
- case (ROFF_Tag):
- /* FALLTHROUGH */
- case (ROFF_Column):
- return(html_stput(mbuf, HTML_TAG_TABLE, res));
- default:
- break;
- }
- }
-
- assert(i != ROFF_MAXLINEARG);
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-html_It_blocktagname(struct md_mbuf *mbuf, struct htmlq *q,
- const int *argc, const char **argv, size_t *res)
-{
- struct htmlnode *n;
- int i;
-
- for (n = q->last; n; n = n->parent)
- if (n->tok == ROFF_Bl)
- break;
-
- assert(n);
-
- /* LINTED */
- for (i = 0; ROFF_ARGMAX != n->argc[i] &&
- i < ROFF_MAXLINEARG; i++) {
- switch (n->argc[i]) {
- case (ROFF_Enum):
- /* FALLTHROUGH */
- case (ROFF_Bullet):
- /* FALLTHROUGH */
- case (ROFF_Dash):
- /* FALLTHROUGH */
- case (ROFF_Hyphen):
- /* FALLTHROUGH */
- case (ROFF_Item):
- /* FALLTHROUGH */
- case (ROFF_Diag):
- /* FALLTHROUGH */
- case (ROFF_Hang):
- /* FALLTHROUGH */
- case (ROFF_Ohang):
- /* FALLTHROUGH */
- case (ROFF_Inset):
- return(html_stput(mbuf, HTML_TAG_LI, res));
- case (ROFF_Tag):
- /* FALLTHROUGH */
- case (ROFF_Column):
- return(html_stput(mbuf, HTML_TAG_TR, res));
- default:
- break;
- }
- }
-
- assert(i != ROFF_MAXLINEARG);
- return(0);
-}
-
-
-static int
-html_loadcss(struct md_mbuf *mbuf, const char *css)
-{
- size_t res, bufsz;
- char *buf;
- struct stat st;
- int fd, c;
- ssize_t ssz;
-
- c = 0;
- res = 0;
- buf = NULL;
-
- if (-1 == (fd = open(css, O_RDONLY, 0))) {
- warn("%s", css);
- return(0);
- }
-
- if (-1 == fstat(fd, &st)) {
- warn("%s", css);
- goto out;
- }
-
- bufsz = MAX(st.st_blksize, BUFSIZ);
- if (NULL == (buf = malloc(bufsz))) {
- warn("malloc");
- goto out;
- }
-
- for (;;) {
- if (-1 == (ssz = read(fd, buf, bufsz))) {
- warn("%s", css);
- goto out;
- } else if (0 == ssz)
- break;
- if ( ! ml_nputs(mbuf, buf, (size_t)ssz, &res))
- goto out;
- }
-
- c = 1;
-
-out:
- if (-1 == close(fd)) {
- warn("%s", css);
- c = 0;
- }
-
- if (buf)
- free(buf);
-
- return(c);
-}
-
-
-static int
-html_tputln(struct md_mbuf *mbuf, enum ml_scope scope,
- int i, enum html_tag tag)
-{
-
- if ( ! ml_putchars(mbuf, ' ', INDENT(i) * INDENT_SZ, NULL))
- return(0);
- if ( ! html_tput(mbuf, scope, tag, NULL))
- return(0);
- return(ml_nputs(mbuf, "\n", 1, NULL));
-}
-
-
-static int
-html_aputln(struct md_mbuf *mbuf, enum ml_scope scope, int i,
- enum html_tag tag, int sz, const struct html_pair *p)
-{
-
- if ( ! ml_putchars(mbuf, ' ', INDENT(i) * INDENT_SZ, NULL))
- return(0);
- if ( ! html_aput(mbuf, scope, tag, NULL, sz, p))
- return(0);
- return(ml_nputs(mbuf, "\n", 1, NULL));
-}
-
-
-/* ARGSUSED */
-static int
-html_begin(struct ml_args *p, const struct tm *tm, const char *os,
- const char *name, enum roffmsec msec, enum roffvol vol)
-{
- enum roffvol bvol;
- struct html_pair attr[4];
- char ts[32], title[64];
- int i;
-
- (void)snprintf(ts, sizeof(ts), "%s(%s)",
- name, roff_msecname(msec));
-
- if (vol >= ROFF_ARCH_START) {
- switch (msec) {
- case(ROFF_MSEC_1):
- /* FALLTHROUGH */
- case(ROFF_MSEC_6):
- /* FALLTHROUGH */
- case(ROFF_MSEC_7):
- bvol = ROFF_VOL_URM;
- break;
- case(ROFF_MSEC_2):
- /* FALLTHROUGH */
- case(ROFF_MSEC_3):
- /* FALLTHROUGH */
- case(ROFF_MSEC_3p):
- /* FALLTHROUGH */
- case(ROFF_MSEC_4):
- /* FALLTHROUGH */
- case(ROFF_MSEC_5):
- bvol = ROFF_VOL_PRM;
- break;
- case(ROFF_MSEC_8):
- bvol = ROFF_VOL_PRM;
- break;
- case(ROFF_MSEC_9):
- bvol = ROFF_VOL_KM;
- break;
- case(ROFF_MSEC_UNASS):
- /* FALLTHROUGH */
- case(ROFF_MSEC_DRAFT):
- /* FALLTHROUGH */
- case(ROFF_MSEC_PAPER):
- bvol = ROFF_VOL_NONE;
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- (void)snprintf(title, sizeof(title), "%s (%s)",
- roff_volname(bvol), roff_volname(vol));
- } else
- (void)snprintf(title, sizeof(title), "%s", roff_volname(vol));
-
-
- i = 0;
-
- if ( ! html_typeput(p->mbuf, HTML_TYPE_4_01_STRICT, NULL))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_OPEN, i, HTML_TAG_HTML))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_OPEN, i++, HTML_TAG_HEAD))
- return(0);
-
- attr[0].attr = HTML_ATTR_HTTP_EQUIV;
- attr[0].val = "content-type";
- attr[1].attr = HTML_ATTR_CONTENT;
- attr[1].val = "text/html;charset=utf-8";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_META, 2, attr))
- return(0);
-
- attr[0].attr = HTML_ATTR_NAME;
- attr[0].val = "resource-type";
- attr[1].attr = HTML_ATTR_CONTENT;
- attr[1].val = "document";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_META, 2, attr))
- return(0);
-
- if ( ! html_tputln(p->mbuf, ML_OPEN, i, HTML_TAG_TITLE))
- return(0);
- if ( ! ml_putstring(p->mbuf, ts, NULL))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TITLE))
- return(0);
-
- if (HTML_CSS_EMBED & p->args->params.html.flags) {
- attr[0].attr = HTML_ATTR_TYPE;
- attr[0].val = "text/css";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i,
- HTML_TAG_STYLE, 1, attr))
- return(0);
- if ( ! html_commentput(p->mbuf, ML_OPEN, NULL))
- return(0);
-
- if ( ! html_loadcss(p->mbuf, p->args->params.html.css))
- return(0);
-
- if ( ! html_commentput(p->mbuf, ML_CLOSE, NULL))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_STYLE))
- return(0);
- } else {
- attr[0].attr = HTML_ATTR_REL;
- attr[0].val = "stylesheet";
- attr[1].attr = HTML_ATTR_TYPE;
- attr[1].val = "text/css";
- attr[2].attr = HTML_ATTR_HREF;
- attr[2].val = p->args->params.html.css;
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i,
- HTML_TAG_LINK, 3, attr))
- return(0);
- }
-
- if ( ! html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_HEAD))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_OPEN, i, HTML_TAG_BODY))
- return(0);
-
- attr[0].attr = HTML_ATTR_CLASS;
- attr[0].val = "mdoc";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_DIV, 1, attr))
- return(0);
-
- attr[0].attr = HTML_ATTR_WIDTH;
- attr[0].val = "100%";
- attr[1].attr = HTML_ATTR_CLASS;
- attr[1].val = "header-table";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i++, HTML_TAG_TABLE, 2, attr))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_OPEN, i++, HTML_TAG_TR))
- return(0);
-
- attr[0].attr = HTML_ATTR_ALIGN;
- attr[0].val = "left";
- attr[1].attr = HTML_ATTR_CLASS;
- attr[1].val = "header-section";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr))
- return(0);
- if ( ! ml_putstring(p->mbuf, ts, NULL))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD))
- return(0);
-
- attr[0].attr = HTML_ATTR_ALIGN;
- attr[0].val = "center";
- attr[1].attr = HTML_ATTR_CLASS;
- attr[1].val = "header-volume";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr))
- return(0);
- if ( ! ml_putstring(p->mbuf, title, NULL))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD))
- return(0);
-
- attr[0].attr = HTML_ATTR_ALIGN;
- attr[0].val = "right";
- attr[1].attr = HTML_ATTR_CLASS;
- attr[1].val = "header-section";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr))
- return(0);
- if ( ! ml_putstring(p->mbuf, ts, NULL))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD))
- return(0);
-
- if ( ! html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_TR))
- return(0);
- return(html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_TABLE));
-}
-
-
-/* ARGSUSED */
-static int
-html_end(struct ml_args *p, const struct tm *tm, const char *os,
- const char *name, enum roffmsec msec, enum roffvol vol)
-{
- struct html_pair attr[4];
- int i;
- char ts[64];
-
- if (0 == strftime(ts, sizeof(ts), "%B %d, %Y", tm)) {
- warn("strftime");
- return(0);
- }
-
- i = 0;
-
- attr[0].attr = HTML_ATTR_WIDTH;
- attr[0].val = "100%";
- attr[1].attr = HTML_ATTR_CLASS;
- attr[1].val = "header-footer";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i++, HTML_TAG_TABLE, 2, attr))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_OPEN, i++, HTML_TAG_TR))
- return(0);
-
- attr[0].attr = HTML_ATTR_ALIGN;
- attr[0].val = "left";
- attr[1].attr = HTML_ATTR_CLASS;
- attr[1].val = "footer-os";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr))
- return(0);
- if ( ! ml_putstring(p->mbuf, os, NULL))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD))
- return(0);
-
- attr[0].attr = HTML_ATTR_ALIGN;
- attr[0].val = "right";
- attr[1].attr = HTML_ATTR_CLASS;
- attr[1].val = "footer-date";
-
- if ( ! html_aputln(p->mbuf, ML_OPEN, i, HTML_TAG_TD, 2, attr))
- return(0);
- if ( ! ml_putstring(p->mbuf, ts, NULL))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, i, HTML_TAG_TD))
- return(0);
-
- if ( ! html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_TR))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, --i, HTML_TAG_TABLE))
- return(0);
-
- if ( ! html_tputln(p->mbuf, ML_CLOSE, 0, HTML_TAG_DIV))
- return(0);
- if ( ! html_tputln(p->mbuf, ML_CLOSE, 0, HTML_TAG_BODY))
- return(0);
- return(html_tputln(p->mbuf, ML_CLOSE, 0, HTML_TAG_HTML));
-}
-
-
-/* ARGSUSED */
-static int
-html_bodytagname(struct md_mbuf *mbuf,
- const struct md_args *args, int tok, struct htmlq *q,
- const int *argc, const char **argv, size_t *res)
-{
-
- switch (tok) {
- case (ROFF_Bl):
- return(html_Bl_bodytagname(mbuf, q, argc, argv, res));
- case (ROFF_Fo):
- return(html_stput(mbuf, HTML_TAG_SPAN, res));
- case (ROFF_It):
- return(html_It_bodytagname(mbuf, q, argc, argv, res));
- case (ROFF_Oo):
- return(html_stput(mbuf, HTML_TAG_SPAN, res));
- default:
- break;
- }
-
- return(html_stput(mbuf, HTML_TAG_DIV, res));
-}
-
-
-/* ARGSUSED */
-static int
-html_headtagname(struct md_mbuf *mbuf,
- const struct md_args *args, int tok, struct htmlq *q,
- const int *argc, const char **argv, size_t *res)
-{
-
- switch (tok) {
- case (ROFF_It):
- return(html_It_headtagname(mbuf, q, argc, argv, res));
- case (ROFF_Fo):
- /* FALLTHROUGH */
- case (ROFF_Oo):
- return(html_stput(mbuf, HTML_TAG_SPAN, res));
- case (ROFF_Sh):
- return(html_stput(mbuf, HTML_TAG_H1, res));
- case (ROFF_Ss):
- return(html_stput(mbuf, HTML_TAG_H2, res));
- default:
- break;
- }
-
- return(html_stput(mbuf, HTML_TAG_DIV, res));
-}
-
-
-/* ARGSUSED */
-static int
-html_blocktagname(struct md_mbuf *mbuf, const struct md_args *args,
- int tok, struct htmlq *q, const int *argc,
- const char **argv, size_t *res)
-{
-
- switch (tok) {
- case (ROFF_Fo):
- /* FALLTHROUGH */
- case (ROFF_Oo):
- return(html_stput(mbuf, HTML_TAG_SPAN, res));
- case (ROFF_It):
- return(html_It_blocktagname(mbuf, q, argc, argv, res));
- default:
- break;
- }
-
- return(html_stput(mbuf, HTML_TAG_DIV, res));
-}
-
-
-/* ARGSUSED */
-static int
-html_printargs(struct md_mbuf *mbuf, int tok, const char *ns,
- const int *argc, const char **argv, size_t *res)
-{
-
- /* FIXME: use API in ml.h. */
-
- if ( ! ml_puts(mbuf, " class=\"", res))
- return(0);
- if ( ! ml_puts(mbuf, ns, res))
- return(0);
- if ( ! ml_puts(mbuf, "-", res))
- return(0);
- if ( ! ml_puts(mbuf, toknames[tok], res))
- return(0);
- return(ml_puts(mbuf, "\"", res));
-}
-
-
-/* ARGSUSED */
-static int
-html_headtagargs(struct md_mbuf *mbuf,
- const struct md_args *args, int tok,
- const int *argc, const char **argv, size_t *res)
-{
-
- return(html_printargs(mbuf, tok, "head", argc, argv, res));
-}
-
-
-/* ARGSUSED */
-static int
-html_bodytagargs(struct md_mbuf *mbuf,
- const struct md_args *args, int tok,
- const int *argc, const char **argv, size_t *res)
-{
-
- return(html_printargs(mbuf, tok, "body", argc, argv, res));
-}
-
-
-/* ARGSUSED */
-static int
-html_blocktagargs(struct md_mbuf *mbuf,
- const struct md_args *args, int tok,
- const int *argc, const char **argv, size_t *res)
-{
-
- return(html_printargs(mbuf, tok, "block", argc, argv, res));
-}
-
-
-/* ARGSUSED */
-static int
-html_inlinetagargs(struct md_mbuf *mbuf,
- const struct md_args *args, int tok,
- const int *argc, const char **argv, size_t *res)
-{
-
- if ( ! html_printargs(mbuf, tok, "inline", argc, argv, res))
- return(0);
-
- switch (tok) {
- case (ROFF_Sh):
-
- /* FIXME: use API in ml.h. */
-
- assert(*argv);
- if ( ! ml_nputs(mbuf, " name=\"", 7, res))
- return(0);
- if ( ! ml_putstring(mbuf, *argv++, res))
- return(0);
- while (*argv) {
- if ( ! ml_putstring(mbuf, "_", res))
- return(0);
- if ( ! ml_putstring(mbuf, *argv++, res))
- return(0);
- }
- if ( ! ml_nputs(mbuf, "\"", 1, res))
- return(0);
- break;
-
- case (ROFF_Sx):
-
- /* FIXME: use API in ml.h. */
-
- assert(*argv);
- if ( ! ml_nputs(mbuf, " href=\"#", 8, res))
- return(0);
- if ( ! ml_putstring(mbuf, *argv++, res))
- return(0);
- while (*argv) {
- if ( ! ml_putstring(mbuf, "_", res))
- return(0);
- if ( ! ml_putstring(mbuf, *argv++, res))
- return(0);
- }
- if ( ! ml_nputs(mbuf, "\"", 1, res))
- return(0);
-
- break;
- default:
- break;
- }
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-html_inlinetagname(struct md_mbuf *mbuf,
- const struct md_args *args, int tok, size_t *res)
-{
-
- switch (tok) {
- case (ROFF_Dl):
- /* FALLTHROUGH */
- case (ROFF_D1):
- return(html_stput(mbuf, HTML_TAG_DIV, res));
- case (ROFF_Sh):
- return(html_stput(mbuf, HTML_TAG_A, res));
- case (ROFF_Pp):
- return(html_stput(mbuf, HTML_TAG_DIV, res));
- case (ROFF_Sx):
- return(html_stput(mbuf, HTML_TAG_A, res));
- default:
- break;
- }
-
- return(html_stput(mbuf, HTML_TAG_SPAN, res));
-}
-
-
-static ssize_t
-html_begintag(struct ml_args *p, enum md_ns ns,
- int tok, const int *argc, const char **argv)
-{
- size_t res;
- struct htmlq *q;
- struct htmlnode *node;
- int i;
-
- assert(ns != MD_NS_DEFAULT);
- res = 0;
-
- q = (struct htmlq *)p->data;
-
- if (NULL == (node = calloc(1, sizeof(struct htmlnode)))) {
- warn("calloc");
- return(-1);
- }
-
- node->parent = q->last;
- node->tok = tok;
- node->ns = ns;
-
- if (argc) {
- /* TODO: argv. */
-
- assert(argv);
- /* LINTED */
- for (i = 0; ROFF_ARGMAX != argc[i]
- && i < ROFF_MAXLINEARG; i++)
- node->argc[i] = argc[i];
- assert(i != ROFF_MAXLINEARG);
- }
-
-
- q->last = node;
-
- switch (ns) {
- case (MD_NS_BLOCK):
- if ( ! html_blocktagname(p->mbuf, p->args, tok,
- q, argc, argv, &res))
- return(-1);
- if ( ! html_blocktagargs(p->mbuf, p->args, tok,
- argc, argv, &res))
- return(-1);
- break;
- case (MD_NS_BODY):
- if ( ! html_bodytagname(p->mbuf, p->args, tok,
- q, argc, argv, &res))
- return(-1);
- if ( ! html_bodytagargs(p->mbuf, p->args, tok,
- argc, argv, &res))
- return(-1);
- break;
- case (MD_NS_HEAD):
- if ( ! html_headtagname(p->mbuf, p->args, tok, q,
- argc, argv, &res))
- return(-1);
- if ( ! html_headtagargs(p->mbuf, p->args, tok,
- argc, argv, &res))
- return(-1);
- break;
- default:
- if ( ! html_inlinetagname(p->mbuf, p->args, tok, &res))
- return(-1);
- if ( ! html_inlinetagargs(p->mbuf, p->args, tok,
- argc, argv, &res))
- return(-1);
- break;
- }
-
- return((ssize_t)res);
-}
-
-
-static ssize_t
-html_endtag(struct ml_args *p, enum md_ns ns, int tok)
-{
- size_t res;
- struct htmlq *q;
- struct htmlnode *node;
-
- assert(ns != MD_NS_DEFAULT);
- res = 0;
-
- q = (struct htmlq *)p->data;
- node = q->last;
-
- switch (ns) {
- case (MD_NS_BLOCK):
- if ( ! html_blocktagname(p->mbuf, p->args, tok,
- q, node->argc,
- (const char **)node->argv, &res))
- return(-1);
- break;
- case (MD_NS_BODY):
- if ( ! html_bodytagname(p->mbuf, p->args, tok,
- q, node->argc,
- (const char **)node->argv, &res))
- return(-1);
- break;
- case (MD_NS_HEAD):
- if ( ! html_headtagname(p->mbuf, p->args, tok,
- q, node->argc,
- (const char **)node->argv, &res))
- return(-1);
- break;
- default:
- if ( ! html_inlinetagname(p->mbuf, p->args, tok, &res))
- return(-1);
- break;
- }
-
- q->last = node->parent;
-
- free(node);
-
- return((ssize_t)res);
-}
-
-
-static int
-html_alloc(void **p)
-{
-
- if (NULL == (*p = calloc(1, sizeof(struct htmlq)))) {
- warn("calloc");
- return(0);
- }
- return(1);
-}
-
-
-static void
-html_free(void *p)
-{
- struct htmlq *q;
- struct htmlnode *n;
-
- assert(p);
- q = (struct htmlq *)p;
-
- /* LINTED */
- while ((n = q->last)) {
- q->last = n->parent;
- free(n);
- }
-
- free(q);
-}
-
-
-/* ARGSUSED */
-static ssize_t
-html_beginhttp(struct md_mbuf *mbuf,
- const struct md_args *args,
- const char *buf, size_t sz)
-{
- size_t res;
- struct html_pair pair;
-
- res = 0;
- pair.attr = HTML_ATTR_HREF;
- pair.val = (char *)buf;
-
- if ( ! html_aput(mbuf, ML_OPEN, HTML_TAG_A, &res, 1, &pair))
- return(-1);
- return((ssize_t)res);
-}
-
-
-/* ARGSUSED */
-static ssize_t
-html_endhttp(struct md_mbuf *mbuf,
- const struct md_args *args,
- const char *buf, size_t sz)
-{
- size_t res;
-
- res = 0;
- if ( ! html_tput(mbuf, ML_CLOSE, HTML_TAG_A, &res))
- return(-1);
- return((ssize_t)res);
-}
-
-
-/* ARGSUSED */
-static ssize_t
-html_beginstring(struct ml_args *p, const char *buf, size_t sz)
-{
-
- if (0 == strncmp(buf, "http://", 7))
- return(html_beginhttp(p->mbuf, p->args, buf, sz));
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static ssize_t
-html_endstring(struct ml_args *p, const char *buf, size_t sz)
-{
-
- if (0 == strncmp(buf, "http://", 7))
- return(html_endhttp(p->mbuf, p->args, buf, sz));
-
- return(0);
-}
-
-
-int
-md_line_html(void *data, char *buf)
-{
-
- return(mlg_line((struct md_mlg *)data, buf));
-}
-
-
-int
-md_exit_html(void *data, int flush)
-{
-
- return(mlg_exit((struct md_mlg *)data, flush));
-}
-
-
-void *
-md_init_html(const struct md_args *args,
- struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
-{
- struct ml_cbs cbs;
-
- cbs.ml_alloc = html_alloc;
- cbs.ml_free = html_free;
- cbs.ml_begintag = html_begintag;
- cbs.ml_endtag = html_endtag;
- cbs.ml_begin = html_begin;
- cbs.ml_end = html_end;
- cbs.ml_beginstring = html_beginstring;
- cbs.ml_endstring = html_endstring;
-
- return(mlg_alloc(args, rbuf, mbuf, &cbs));
-}
diff --git a/html.h b/html.h
deleted file mode 100644
index b73a3a4b..00000000
--- a/html.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 HTML_H
-#define HTML_H
-
-#include "ml.h"
-
-enum html_tag {
- HTML_TAG_SPAN = 0,
- HTML_TAG_HTML = 1,
- HTML_TAG_HEAD = 2,
- HTML_TAG_META = 3,
- HTML_TAG_TITLE = 4,
- HTML_TAG_STYLE = 5,
- HTML_TAG_LINK = 6,
- HTML_TAG_BODY = 7,
- HTML_TAG_DIV = 8,
- HTML_TAG_TABLE = 9,
- HTML_TAG_TD = 10,
- HTML_TAG_TR = 11,
- HTML_TAG_OL = 12,
- HTML_TAG_UL = 13,
- HTML_TAG_LI = 14,
- HTML_TAG_H1 = 15,
- HTML_TAG_H2 = 16,
- HTML_TAG_A = 17
-};
-
-enum html_attr {
- HTML_ATTR_CLASS = 0,
- HTML_ATTR_HTTP_EQUIV = 1,
- HTML_ATTR_CONTENT = 2,
- HTML_ATTR_NAME = 3,
- HTML_ATTR_TYPE = 4,
- HTML_ATTR_REL = 5,
- HTML_ATTR_HREF = 6,
- HTML_ATTR_WIDTH = 7,
- HTML_ATTR_ALIGN = 8,
- HTML_ATTR_VALIGN = 9,
- HTML_ATTR_NOWRAP = 10
-};
-
-enum html_type {
- HTML_TYPE_4_01_STRICT = 0
-};
-
-struct html_pair {
- enum html_attr attr;
- char *val;
-};
-
-__BEGIN_DECLS
-
-int html_typeput(struct md_mbuf *,
- enum html_type, size_t *);
-int html_commentput(struct md_mbuf *,
- enum ml_scope, size_t *);
-int html_tput(struct md_mbuf *,
- enum ml_scope, enum html_tag, size_t *);
-int html_aput(struct md_mbuf *, enum ml_scope,
- enum html_tag, size_t *,
- int, const struct html_pair *);
-int html_stput(struct md_mbuf *,
- enum html_tag, size_t *);
-int html_saput(struct md_mbuf *, enum html_tag,
- size_t *, int, const struct html_pair *);
-
-__END_DECLS
-
-#endif /*!HTML_H*/
diff --git a/index.7 b/index.7
deleted file mode 100644
index 6e3dc723..00000000
--- a/index.7
+++ /dev/null
@@ -1,156 +0,0 @@
-.\"
-.Dd $Mdocdate$
-.Dt index 7
-.Os LOCAL
-.\"
-.Sh NAME
-.Nm mdocml
-.Nd compile mdoc macros into mark-up language
-.\"
-.Sh DESCRIPTION
-The
-.Nm
-utility compiles
-.Xr mdoc 7
-macros, such as those inheriting from
-.Xr mdoc.samples 7 ,
-into XML or HTML documents. Unlike other similar utilities such as
-.Xr rman 1
-and
-.Xr man2html 1 ,
-.Nm
-is a full macro parser operating on source documents, specifically mdoc,
-validating input and compiling to HTML and XML output types.
-.Pp
-Downloads (source and ports) are available in the
-.Sx DOWNLOADS
-section.
-.Pp
-The
-.Nm
-utility is tested specifically on
-.Ox
-manual sources as compiled and invoked both on
-.Ox
-and Linux.
-.Nm
-is
-.Ud
-.\"
-.Ss Validation
-In order to operate sanely,
-.Nm
-fully validates its input. This includes, but is not limited to, the
-following checks:
-.Pp
-.Bl -enum -compact
-.It
-valid special characters (such as
-.Sq \en
-and
-.Sq \et ) ,
-.It
-sane macro scope (such as
-.Sq \&.Sh
-macros clobbering a pending
-.Sq \&.Bl
-scope),
-.It
-valid predefined characters (such as \\*(>= and \\*q),
-.It
-correctly-ordered prelude and sections,
-.It
-sane macro argument values (such as those for
-.Sq \&.Dt
-or
-.Sq \&.Sm ) ,
-.It
-valid manual sections and systems;
-.It
-and so on.
-.El
-.\"
-.Ss Filtering
-When a line of source has been parsed, it's passed to the output
-filters, which format and display data. The two available filters are
-HTML and XML.
-.Pp
-The HTML filter has the following features:
-.Pp
-.Bl -enum -compact
-.It
-HTML-4.01 strict compliance;
-.It
-proper rendering of values in UTF-8, such as
-.Dq quotes
-and \*(>= predefined values;
-.It
-URI-appearing http://bsd.lv/ strings are correctly enclosed in link tags;
-.It
-CSS-dictated style with meaningful non-CSS defaults;
-.It
-and so on.
-.El
-.Pp
-The XML filter creates a correct XML tree with
-.Dq block ,
-.Dq head ,
-.Dq body ,
-and
-.Dq inline
-namespaces corresponding to macro categories. Namespace identifiers
-correspond to their definitions. A sample is available at
-http://mdocml.bsd.lv/index.xml
-.Ns .
-.\"
-.Sh DOWNLOADS
-Download
-.Nm
-at http://mdocml.bsd.lv/mdocml.tar.gz
-.Ns .
-.\" - UPDATE ME WITH EVERY RELEASE. ----------------------------------
-The current version is 1.0.3, dated 10/12/2008.
-.\" ------------------------------------------------------------------
-.Pp
-An OpenBSD port is available at http://mdocml.bsd.lv/mdocml-port.tar.gz
-.Ns .
-.Pp
-Previous versions are archived as mdocml-x.y.z.tar.gz, with the appropriate
-versions filled in.
-.\"
-.Sh DOCUMENTS
-The manual for
-.Nm
-is available at http://mdocml.bsd.lv/mdocml.html
-.Ns .
-.\"
-.Sh EXAMPLES
-This page was produced as follows:
-.Pp
-.D1 % mdocml -fhtml -Wall -e -o index.html index.7
-.Pp
-The original mdoc source is at http://mdocml.bsd.lv/index.txt
-.Ns .
-.\"
-.Sh SEE ALSO
-.Bl -ohang
-.It Xr rman Ns : http://polyglotman.sourceforge.net/rman.html
-Accepts either formatted roff output or source and produces HTML output.
-.It Xr man2html Ns : http://www.nongnu.org/man2html/
-Accepts formatted
-.Xr nroff 1
-text and produces HTML output.
-.It Xr man.cgi Ns : http://www.freebsd.org/cgi/man.cgi/source
-.Fx
-and
-.Ox
-project CGI for producing HTML from nroff source.
-.It Xr roffit Ns : http://daniel.haxx.se/projects/roffit/
-HTML from roff manual source. Dead project?
-.El
-.\"
-.Sh AUTHORS
-The
-.Nm
-utility was written by
-.An Kristaps Dzonsons Aq kristaps@kth.se .
diff --git a/libmdocml.c b/libmdocml.c
deleted file mode 100644
index 33f5ffa7..00000000
--- a/libmdocml.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "private.h"
-
-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
-md_buf_fill(struct md_rbuf *in)
-{
- ssize_t ssz;
-
- assert(in);
- assert(in->buf);
- assert(in->bufsz > 0);
- assert(in->name);
-
- if (-1 == (ssz = read(in->fd, in->buf, in->bufsz)))
- warn("%s", in->name);
-
- return(ssz);
-}
-
-
-static int md_buf_flush(struct md_mbuf *buf)
-{
- ssize_t sz;
-
- assert(buf);
- assert(buf->buf);
- assert(buf->name);
-
- if (0 == buf->pos)
- return(1);
-
- sz = write(buf->fd, buf->buf, buf->pos);
-
- if (-1 == sz) {
- warn("%s", buf->name);
- return(0);
- } else if ((size_t)sz != buf->pos) {
- warnx("%s: short write", buf->name);
- return(0);
- }
-
- buf->pos = 0;
- return(1);
-}
-
-
-int
-md_buf_putchar(struct md_mbuf *buf, char c)
-{
-
- assert(buf);
- return(md_buf_puts(buf, &c, 1));
-}
-
-
-int
-md_buf_putstring(struct md_mbuf *buf, const char *p)
-{
-
- assert(buf);
- return(md_buf_puts(buf, p, strlen(p)));
-}
-
-
-int
-md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz)
-{
- size_t ssz;
-
- assert(p);
- assert(buf);
- assert(buf->buf);
-
- /* LINTED */
- while (buf->pos + sz > buf->bufsz) {
- ssz = buf->bufsz - buf->pos;
- (void)memcpy(/* LINTED */
- buf->buf + buf->pos, p, ssz);
- p += (long)ssz;
- sz -= ssz;
- buf->pos += ssz;
-
- if ( ! md_buf_flush(buf))
- return(0);
- }
-
- (void)memcpy(/* LINTED */
- buf->buf + buf->pos, p, sz);
- buf->pos += sz;
- return(1);
-}
-
-
-static int
-md_run_leave(const struct md_args *args, struct md_mbuf *mbuf,
- struct md_rbuf *rbuf, int c, void *data)
-{
- md_exit fp;
-
- assert(args);
- assert(mbuf);
- assert(rbuf);
-
- /* Run exiters. */
- switch (args->type) {
- case (MD_HTML):
- fp = md_exit_html;
- break;
- case (MD_XML):
- fp = md_exit_xml;
- break;
- default:
- fp = md_exit_noop;
- break;
- }
-
- if ( ! (*fp)(data, -1 == c ? 0 : 1))
- c = -1;
-
- /* Make final flush of buffer. */
- if (-1 != c && ! 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;
- size_t pos;
- char line[MD_LINE];
- md_line fp;
-
- assert(args);
- assert(mbuf);
- assert(rbuf);
-
- /* Function ptrs to line-parsers. */
- switch (args->type) {
- case (MD_HTML):
- fp = md_line_html;
- break;
- case (MD_XML):
- fp = md_line_xml;
- break;
- default:
- fp = md_line_noop;
- break;
- }
-
- pos = 0;
-
-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 < MD_LINE) {
- /* LINTED */
- rbuf->linebuf[pos++] = rbuf->buf[i];
- continue;
- }
- warnx("%s: line %zu too long",
- rbuf->name, rbuf->line);
- return(md_run_leave(args, mbuf, rbuf, -1, p));
- }
-
- rbuf->linebuf[(int)pos] = 0;
- (void)memcpy(line, rbuf->linebuf, sizeof(line));
- if ( ! (*fp)(p, line))
- return(md_run_leave(args, mbuf, rbuf, -1, p));
- rbuf->line++;
- pos = 0;
- }
-
- goto again;
- /* NOTREACHED */
-}
-
-
-int
-md_run(const struct md_args *args,
- const struct md_buf *out, const struct md_buf *in)
-{
- md_init fp;
- struct md_mbuf mbuf;
- struct md_rbuf rbuf;
- void *data;
-
- 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_HTML):
- fp = md_init_html;
- break;
- case (MD_XML):
- fp = md_init_xml;
- break;
- default:
- fp = md_init_noop;
- break;
- }
-
- data = (*fp)(args, &mbuf, &rbuf);
-
- /* Go into mainline. */
- return(md_run_enter(args, &mbuf, &rbuf, data));
-}
diff --git a/libmdocml.h b/libmdocml.h
deleted file mode 100644
index 93126e85..00000000
--- a/libmdocml.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 LIBMDOCML_H
-#define LIBMDOCML_H
-
-#include <sys/types.h>
-
-struct md_params_html {
- char *css;
- int flags;
-#define HTML_CSS_EMBED (1 << 0)
-};
-
-union md_params {
- struct md_params_html html;
-};
-
-enum md_type {
- MD_XML, /* XML. */
- MD_HTML, /* HTML4.01-strict. */
- MD_NOOP /* Validates only. */
-};
-
-struct md_args {
- union md_params params;/* Parameters for parser. */
- enum md_type type; /* Type of parser. */
-
- int warnings;
-#define MD_WARN_ALL (1 << 0)
-#define MD_WARN_ERROR (1 << 1)
- int verbosity;
-};
-
-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
-
-/* 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
-
-#endif /*!LIBMDOCML_H*/
diff --git a/literals.c b/literals.c
deleted file mode 100644
index 75c24e43..00000000
--- a/literals.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "private.h"
-
-#define ROFF_ATTname_V1 "v1"
-#define ROFF_ATTname_V2 "v2"
-#define ROFF_ATTname_V3 "v3"
-#define ROFF_ATTname_V6 "v6"
-#define ROFF_ATTname_V7 "v7"
-#define ROFF_ATTname_32V "32v"
-#define ROFF_ATTname_V_1 "V.1"
-#define ROFF_ATTname_V_4 "V.4"
-
-#define ROFFSecname_NAME "NAME"
-#define ROFFSecname_SYNOP "SYNOPSIS"
-#define ROFFSecname_DESC "DESCRIPTION"
-#define ROFFSecname_ENV "ENVIRONMENT"
-#define ROFFSecname_FILES "FILES"
-#define ROFFSecname_EX "EXAMPLES"
-#define ROFFSecname_DIAG "DIAGNOSTICS"
-#define ROFFSecname_ERRS "ERRORS"
-#define ROFFSecname_STAND "STANDARDS"
-#define ROFFSecname_HIST "HISTORY"
-#define ROFFSecname_AUTH "AUTHORS"
-#define ROFFSecname_CAVEATS "CAVEATS"
-#define ROFFSecname_BUGS "BUGS"
-#define ROFFSecname_RETVAL "RETURN VALUES"
-#define ROFFSecname_RETVAL1 "RETURN"
-#define ROFFSecname_RETVAL2 "VALUES"
-#define ROFFSecname_SEEALSO "SEE ALSO"
-#define ROFFSecname_SEEALSO1 "SEE"
-#define ROFFSecname_SEEALSO2 "ALSO"
-
-#define ROFF_MSECname_1 "1"
-#define ROFF_MSECname_2 "2"
-#define ROFF_MSECname_3 "3"
-#define ROFF_MSECname_3p "3p"
-#define ROFF_MSECname_4 "4"
-#define ROFF_MSECname_5 "5"
-#define ROFF_MSECname_6 "6"
-#define ROFF_MSECname_7 "7"
-#define ROFF_MSECname_8 "8"
-#define ROFF_MSECname_9 "9"
-#define ROFF_MSECname_UNASS "unass"
-#define ROFF_MSECname_DRAFT "draft"
-#define ROFF_MSECname_PAPER "paper"
-
-#define ROFF_VOLname_AMD "AMD"
-#define ROFF_VOLname_IND "IND"
-#define ROFF_VOLname_KM "KM"
-#define ROFF_VOLname_LOCAL "LOCAL"
-#define ROFF_VOLname_PRM "PRM"
-#define ROFF_VOLname_PS1 "PS1"
-#define ROFF_VOLname_SMM "SMM"
-#define ROFF_VOLname_URM "URM"
-#define ROFF_VOLname_USD "USD"
-#define ROFF_ARCHname_ALPHA "alpha"
-#define ROFF_ARCHname_AMD64 "amd64"
-#define ROFF_ARCHname_AMIGA "amiga"
-#define ROFF_ARCHname_ARC "arc"
-#define ROFF_ARCHname_ARMISH "armish"
-#define ROFF_ARCHname_AVIION "aviion"
-#define ROFF_ARCHname_HP300 "hp300"
-#define ROFF_ARCHname_HPPA "hppa"
-#define ROFF_ARCHname_HPPA64 "hppa64"
-#define ROFF_ARCHname_I386 "i386"
-#define ROFF_ARCHname_LANDISK "landisk"
-#define ROFF_ARCHname_LUNA88K "luna88k"
-#define ROFF_ARCHname_MAC68K "mac68k"
-#define ROFF_ARCHname_MACPPC "macppc"
-#define ROFF_ARCHname_MVME68K "mvme68k"
-#define ROFF_ARCHname_MVME88K "mvme88k"
-#define ROFF_ARCHname_MVMEPPC "mvmeppc"
-#define ROFF_ARCHname_PMAX "pmax"
-#define ROFF_ARCHname_SGI "sgi"
-#define ROFF_ARCHname_SPARC "sparc"
-#define ROFF_ARCHname_SPARC64 "sparc64"
-#define ROFF_ARCHname_SUN3 "sun3"
-#define ROFF_ARCHname_VAX "vax"
-#define ROFF_ARCHname_ZAURUS "zaurus"
-
-int
-roff_sec(const char **p)
-{
-
- assert(*p);
- if (NULL != *(p + 1)) {
- if (NULL != *(p + 2))
- return(ROFFSec_OTHER);
- if (0 == strcmp(*p, ROFFSecname_RETVAL1) &&
- 0 == strcmp(*(p + 1), ROFFSecname_RETVAL2))
- return(ROFFSec_RETVAL);
- if (0 == strcmp(*p, ROFFSecname_SEEALSO1) &&
- 0 == strcmp(*(p + 1), ROFFSecname_SEEALSO2))
- return(ROFFSec_SEEALSO);
- return(ROFFSec_OTHER);
- }
-
- if (0 == strcmp(*p, ROFFSecname_NAME))
- return(ROFFSec_NAME);
- else if (0 == strcmp(*p, ROFFSecname_SYNOP))
- return(ROFFSec_SYNOP);
- else if (0 == strcmp(*p, ROFFSecname_DESC))
- return(ROFFSec_DESC);
- else if (0 == strcmp(*p, ROFFSecname_ENV))
- return(ROFFSec_ENV);
- else if (0 == strcmp(*p, ROFFSecname_FILES))
- return(ROFFSec_FILES);
- else if (0 == strcmp(*p, ROFFSecname_EX))
- return(ROFFSec_EX);
- else if (0 == strcmp(*p, ROFFSecname_DIAG))
- return(ROFFSec_DIAG);
- else if (0 == strcmp(*p, ROFFSecname_ERRS))
- return(ROFFSec_ERRS);
- else if (0 == strcmp(*p, ROFFSecname_STAND))
- return(ROFFSec_STAND);
- else if (0 == strcmp(*p, ROFFSecname_HIST))
- return(ROFFSec_HIST);
- else if (0 == strcmp(*p, ROFFSecname_AUTH))
- return(ROFFSec_AUTH);
- else if (0 == strcmp(*p, ROFFSecname_CAVEATS))
- return(ROFFSec_CAVEATS);
- else if (0 == strcmp(*p, ROFFSecname_BUGS))
- return(ROFFSec_BUGS);
- else if (0 == strcmp(*p, ROFFSecname_RETVAL))
- return(ROFFSec_RETVAL);
- else if (0 == strcmp(*p, ROFFSecname_SEEALSO))
- return(ROFFSec_SEEALSO);
-
- return(ROFFSec_OTHER);
-}
-
-
-enum roffmsec
-roff_msec(const char *p)
-{
-
- assert(p);
- if (0 == strcmp(p, ROFF_MSECname_1))
- return(ROFF_MSEC_1);
- else if (0 == strcmp(p, ROFF_MSECname_2))
- return(ROFF_MSEC_2);
- else if (0 == strcmp(p, ROFF_MSECname_3))
- return(ROFF_MSEC_3);
- else if (0 == strcmp(p, ROFF_MSECname_3p))
- return(ROFF_MSEC_3p);
- else if (0 == strcmp(p, ROFF_MSECname_4))
- return(ROFF_MSEC_4);
- else if (0 == strcmp(p, ROFF_MSECname_5))
- return(ROFF_MSEC_5);
- else if (0 == strcmp(p, ROFF_MSECname_6))
- return(ROFF_MSEC_6);
- else if (0 == strcmp(p, ROFF_MSECname_7))
- return(ROFF_MSEC_7);
- else if (0 == strcmp(p, ROFF_MSECname_8))
- return(ROFF_MSEC_8);
- else if (0 == strcmp(p, ROFF_MSECname_9))
- return(ROFF_MSEC_9);
- else if (0 == strcmp(p, ROFF_MSECname_UNASS))
- return(ROFF_MSEC_UNASS);
- else if (0 == strcmp(p, ROFF_MSECname_DRAFT))
- return(ROFF_MSEC_DRAFT);
- else if (0 == strcmp(p, ROFF_MSECname_PAPER))
- return(ROFF_MSEC_PAPER);
-
- return(ROFF_MSEC_MAX);
-}
-
-
-char *
-roff_msecname(enum roffmsec sec)
-{
-
- switch (sec) {
- case(ROFF_MSEC_1):
- return(ROFF_MSECname_1);
- case(ROFF_MSEC_2):
- return(ROFF_MSECname_2);
- case(ROFF_MSEC_3):
- return(ROFF_MSECname_3);
- case(ROFF_MSEC_3p):
- return(ROFF_MSECname_3p);
- case(ROFF_MSEC_4):
- return(ROFF_MSECname_4);
- case(ROFF_MSEC_5):
- return(ROFF_MSECname_5);
- case(ROFF_MSEC_6):
- return(ROFF_MSECname_6);
- case(ROFF_MSEC_7):
- return(ROFF_MSECname_7);
- case(ROFF_MSEC_8):
- return(ROFF_MSECname_8);
- case(ROFF_MSEC_9):
- return(ROFF_MSECname_9);
- case(ROFF_MSEC_UNASS):
- return(ROFF_MSECname_UNASS);
- case(ROFF_MSEC_DRAFT):
- return(ROFF_MSECname_DRAFT);
- case(ROFF_MSEC_PAPER):
- return(ROFF_MSECname_PAPER);
- default:
- break;
- }
-
- abort();
- /* NOTREACHED */
-}
-
-
-char *
-roff_fmtstring(int tok)
-{
-
- switch (tok) {
- case (ROFF_Ex):
- return ("The %s utility exits 0 on success, and "
- ">0 if an error occurs.");
- case (ROFF_Rv):
- return ("The %s() function returns the value 0 if "
- "successful; otherwise the value -1 "
- "is returned and the global variable "
- "errno is set to indicate the error.");
- case (ROFF_In):
- return("#include \\*(Lt%s\\*(Gt");
- default:
- break;
- }
-
- abort();
- /* NOTREACHED */
-}
-
-
-char *
-roff_literal(int tok, const int *argc,
- const char **argv, const char **morep)
-{
-
- switch (tok) {
- case (ROFF_At):
- assert(NULL == *argv);
- assert(ROFF_ARGMAX == *argc);
- if (NULL == *morep)
- return("AT&T UNIX");
-
- switch (roff_att(*morep)) {
- case (ROFF_ATT_V1):
- return("Version 1 AT&T UNIX");
- case (ROFF_ATT_V2):
- return("Version 2 AT&T UNIX");
- case (ROFF_ATT_V3):
- return("Version 3 AT&T UNIX");
- case (ROFF_ATT_V6):
- return("Version 6 AT&T UNIX");
- case (ROFF_ATT_V7):
- return("Version 7 AT&T UNIX");
- case (ROFF_ATT_32V):
- return("Version 32v AT&T UNIX");
- case (ROFF_ATT_V_1):
- return("AT&T System V.1 UNIX");
- case (ROFF_ATT_V_4):
- return("AT&T System V.4 UNIX");
- default:
- break;
- }
-
- abort();
- /* NOTREACHED */
-
- case (ROFF_St):
- assert(ROFF_ARGMAX != *argc);
- assert(NULL == *argv);
- switch (*argc) {
- case(ROFF_p1003_1_88):
- return("IEEE Std 1003.1-1988 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1_90):
- return("IEEE Std 1003.1-1990 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1_96):
- return("ISO/IEC 9945-1:1996 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1_2001):
- return("IEEE Std 1003.1-2001 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1_2004):
- return("IEEE Std 1003.1-2004 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1):
- return("IEEE Std 1003.1 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1b):
- return("IEEE Std 1003.1b "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1b_93):
- return("IEEE Std 1003.1b-1993 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1c_95):
- return("IEEE Std 1003.1c-1995 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_1g_2000):
- return("IEEE Std 1003.1g-2000 "
- "(\\*(LqPOSIX\\*(Rq)");
- case(ROFF_p1003_2_92):
- return("IEEE Std 1003.2-1992 "
- "(\\*(LqPOSIX.2\\*(Rq)");
- case(ROFF_p1387_2_95):
- return("IEEE Std 1387.2-1995 "
- "(\\*(LqPOSIX.7.2\\*(Rq)");
- case(ROFF_p1003_2):
- return("IEEE Std 1003.2 "
- "(\\*(LqPOSIX.2\\*(Rq)");
- case(ROFF_p1387_2):
- return("IEEE Std 1387.2 "
- "(\\*(LqPOSIX.7.2\\*(Rq)");
- case(ROFF_isoC_90):
- return("ISO/IEC 9899:1990 "
- "(\\*(LqISO C90\\*(Rq)");
- case(ROFF_isoC_amd1):
- return("ISO/IEC 9899/AMD1:1995 "
- "(\\*(LqISO C90\\*(Rq)");
- case(ROFF_isoC_tcor1):
- return("ISO/IEC 9899/TCOR1:1994 "
- "(\\*(LqISO C90\\*(Rq)");
- case(ROFF_isoC_tcor2):
- return("ISO/IEC 9899/TCOR2:1995 "
- "(\\*(LqISO C90\\*(Rq)");
- case(ROFF_isoC_99):
- return("ISO/IEC 9899:1999 "
- "(\\*(LqISO C99\\*(Rq)");
- case(ROFF_ansiC):
- return("ANSI X3.159-1989 "
- "(\\*(LqANSI C\\*(Rq)");
- case(ROFF_ansiC_89):
- return("ANSI X3.159-1989 "
- "(\\*(LqANSI C\\*(Rq)");
- case(ROFF_ansiC_99):
- return("ANSI/ISO/IEC 9899-1999 "
- "(\\*(LqANSI C99\\*(Rq)");
- case(ROFF_ieee754):
- return("IEEE Std 754-1985");
- case(ROFF_iso8802_3):
- return("ISO 8802-3: 1989");
- case(ROFF_xpg3):
- return("X/Open Portability Guide Issue 3 "
- "(\\*(LqXPG3\\*(Rq)");
- case(ROFF_xpg4):
- return("X/Open Portability Guide Issue 4 "
- "(\\*(LqXPG4\\*(Rq)");
- case(ROFF_xpg4_2):
- return("X/Open Portability Guide Issue 4.2 "
- "(\\*(LqXPG4.2\\*(Rq)");
- case(ROFF_xpg4_3):
- return("X/Open Portability Guide Issue 4.3 "
- "(\\*(LqXPG4.3\\*(Rq)");
- case(ROFF_xbd5):
- return("X/Open System Interface Definitions "
- "Issue 5 (\\*(LqXBD5\\*(Rq)");
- case(ROFF_xcu5):
- return("X/Open Commands and Utilities Issue 5 "
- "(\\*(LqXCU5\\*(Rq)");
- case(ROFF_xsh5):
- return("X/Open System Interfaces and Headers "
- "Issue 5 (\\*(LqXSH5\\*(Rq)");
- case(ROFF_xns5):
- return("X/Open Networking Services Issue 5 "
- "(\\*(LqXNS5\\*(Rq)");
- case(ROFF_xns5_2d2_0):
- return("X/Open Networking Services "
- "Issue 5.2 Draft 2.0 "
- "(\\*(LqXNS5.2D2.0\\*(Rq)");
- case(ROFF_xcurses4_2):
- return("X/Open Curses Issue 4 Version 2 "
- "(\\*(LqXCURSES4.2\\*(Rq)");
- case(ROFF_susv2):
- return("Version 2 of the Single "
- "UNIX Specification");
- case(ROFF_susv3):
- return("Version 3 of the Single "
- "UNIX Specification");
- case(ROFF_svid4):
- return("System V Interface Definition, Fourth "
- "Edition (\\*(LqSVID4\\*(Rq)");
- default:
- break;
- }
- abort();
- /* NOTREACHED */
-
- case (ROFF_Bt):
- return("is currently in beta test.");
- case (ROFF_Ud):
- return("currently under development.");
- case (ROFF_Fx):
- return("FreeBSD");
- case (ROFF_Nx):
- return("NetBSD");
- case (ROFF_Ox):
- return("OpenBSD");
- case (ROFF_Ux):
- return("UNIX");
- case (ROFF_Bx):
- return("BSD");
- case (ROFF_Bsx):
- return("BSDI BSD/OS");
- default:
- break;
- }
-
- abort();
- /* NOTREACHED */
-}
-
-
-enum roffatt
-roff_att(const char *p)
-{
-
- assert(p);
- if (0 == strcmp(p, ROFF_ATTname_V1))
- return(ROFF_ATT_V1);
- else if (0 == strcmp(p, ROFF_ATTname_V2))
- return(ROFF_ATT_V2);
- else if (0 == strcmp(p, ROFF_ATTname_V3))
- return(ROFF_ATT_V3);
- else if (0 == strcmp(p, ROFF_ATTname_V6))
- return(ROFF_ATT_V6);
- else if (0 == strcmp(p, ROFF_ATTname_V7))
- return(ROFF_ATT_V7);
- else if (0 == strcmp(p, ROFF_ATTname_32V))
- return(ROFF_ATT_32V);
- else if (0 == strcmp(p, ROFF_ATTname_V_1))
- return(ROFF_ATT_V_1);
- else if (0 == strcmp(p, ROFF_ATTname_V_4))
- return(ROFF_ATT_V_4);
-
- return(ROFF_ATT_MAX);
-}
-
-
-enum roffvol
-roff_vol(const char *p)
-{
-
- if (0 == strcmp(p, ROFF_VOLname_AMD))
- return(ROFF_VOL_AMD);
- else if (0 == strcmp(p, ROFF_VOLname_IND))
- return(ROFF_VOL_IND);
- else if (0 == strcmp(p, ROFF_VOLname_KM))
- return(ROFF_VOL_KM);
- else if (0 == strcmp(p, ROFF_VOLname_LOCAL))
- return(ROFF_VOL_LOCAL);
- else if (0 == strcmp(p, ROFF_VOLname_PRM))
- return(ROFF_VOL_PRM);
- else if (0 == strcmp(p, ROFF_VOLname_PS1))
- return(ROFF_VOL_PS1);
- else if (0 == strcmp(p, ROFF_VOLname_SMM))
- return(ROFF_VOL_SMM);
- else if (0 == strcmp(p, ROFF_VOLname_URM))
- return(ROFF_VOL_URM);
- else if (0 == strcmp(p, ROFF_VOLname_USD))
- return(ROFF_VOL_USD);
- else if (0 == strcmp(p, ROFF_ARCHname_ALPHA))
- return(ROFF_ARCH_ALPHA);
- else if (0 == strcmp(p, ROFF_ARCHname_AMD64))
- return(ROFF_ARCH_AMD64);
- else if (0 == strcmp(p, ROFF_ARCHname_AMIGA))
- return(ROFF_ARCH_AMIGA);
- else if (0 == strcmp(p, ROFF_ARCHname_ARC))
- return(ROFF_ARCH_ARC);
- else if (0 == strcmp(p, ROFF_ARCHname_ARMISH))
- return(ROFF_ARCH_ARMISH);
- else if (0 == strcmp(p, ROFF_ARCHname_AVIION))
- return(ROFF_ARCH_AVIION);
- else if (0 == strcmp(p, ROFF_ARCHname_HP300))
- return(ROFF_ARCH_HP300);
- else if (0 == strcmp(p, ROFF_ARCHname_HPPA))
- return(ROFF_ARCH_HPPA);
- else if (0 == strcmp(p, ROFF_ARCHname_HPPA64))
- return(ROFF_ARCH_HPPA64);
- else if (0 == strcmp(p, ROFF_ARCHname_I386))
- return(ROFF_ARCH_I386);
- else if (0 == strcmp(p, ROFF_ARCHname_LANDISK))
- return(ROFF_ARCH_LANDISK);
- else if (0 == strcmp(p, ROFF_ARCHname_LUNA88K))
- return(ROFF_ARCH_LUNA88K);
- else if (0 == strcmp(p, ROFF_ARCHname_MAC68K))
- return(ROFF_ARCH_MAC68K);
- else if (0 == strcmp(p, ROFF_ARCHname_MACPPC))
- return(ROFF_ARCH_MACPPC);
- else if (0 == strcmp(p, ROFF_ARCHname_MVME68K))
- return(ROFF_ARCH_MVME68K);
- else if (0 == strcmp(p, ROFF_ARCHname_MVME88K))
- return(ROFF_ARCH_MVME88K);
- else if (0 == strcmp(p, ROFF_ARCHname_MVMEPPC))
- return(ROFF_ARCH_MVMEPPC);
- else if (0 == strcmp(p, ROFF_ARCHname_PMAX))
- return(ROFF_ARCH_PMAX);
- else if (0 == strcmp(p, ROFF_ARCHname_SGI))
- return(ROFF_ARCH_SGI);
- else if (0 == strcmp(p, ROFF_ARCHname_SPARC))
- return(ROFF_ARCH_SPARC);
- else if (0 == strcmp(p, ROFF_ARCHname_SPARC64))
- return(ROFF_ARCH_SPARC64);
- else if (0 == strcmp(p, ROFF_ARCHname_SUN3))
- return(ROFF_ARCH_SUN3);
- else if (0 == strcmp(p, ROFF_ARCHname_VAX))
- return(ROFF_ARCH_VAX);
- else if (0 == strcmp(p, ROFF_ARCHname_ZAURUS))
- return(ROFF_ARCH_ZAURUS);
-
- return(ROFF_VOL_MAX);
-}
-
-
-char *
-roff_volname(enum roffvol vol)
-{
-
- /* FIXME: is OpenBSD specific! */
-
- switch (vol) {
- case(ROFF_VOL_AMD):
- return("OpenBSD Ancestral Manual Documents");
- case(ROFF_VOL_IND):
- return("OpenBSD Manual Master Index");
- case(ROFF_VOL_KM):
- return("OpenBSD Kernel Manual");
- case(ROFF_VOL_LOCAL):
- return("OpenBSD Local Manual");
- case(ROFF_VOL_PRM):
- return("OpenBSD Programmer's Manual");
- case(ROFF_VOL_PS1):
- return("OpenBSD Programmer's Supplementary Documents");
- case(ROFF_VOL_SMM):
- return("OpenBSD System Manager's Manual");
- case(ROFF_VOL_URM):
- return("OpenBSD Reference Manual");
- case(ROFF_VOL_USD):
- return("OpenBSD User's Supplementary Documents");
- case(ROFF_ARCH_ALPHA):
- return("Alpha");
- case(ROFF_ARCH_AMD64):
- return("AMD64");
- case(ROFF_ARCH_AMIGA):
- return("Amiga");
- case(ROFF_ARCH_ARC):
- return("ARC");
- case(ROFF_ARCH_ARMISH):
- return("ARMISH");
- case(ROFF_ARCH_AVIION):
- return("AVIION");
- case(ROFF_ARCH_HP300):
- return("HP300");
- case(ROFF_ARCH_HPPA):
- return("HPPA");
- case(ROFF_ARCH_HPPA64):
- return("HPPA64");
- case(ROFF_ARCH_I386):
- return("i386");
- case(ROFF_ARCH_LANDISK):
- return("LANDISK");
- case(ROFF_ARCH_LUNA88K):
- return("Luna88K");
- case(ROFF_ARCH_MAC68K):
- return("Mac68K");
- case(ROFF_ARCH_MACPPC):
- return("MacPPC");
- case(ROFF_ARCH_MVME68K):
- return("MVME68K");
- case(ROFF_ARCH_MVME88K):
- return("MVME88K");
- case(ROFF_ARCH_MVMEPPC):
- return("MVMEPPC");
- case(ROFF_ARCH_PMAX):
- return("PMAX");
- case(ROFF_ARCH_SGI):
- return("SGI");
- case(ROFF_ARCH_SPARC):
- return("SPARC");
- case(ROFF_ARCH_SPARC64):
- return("SPARC64");
- case(ROFF_ARCH_SUN3):
- return("Sun3");
- case(ROFF_ARCH_VAX):
- return("Vax");
- case(ROFF_ARCH_ZAURUS):
- return("Zaurus");
- default:
- break;
- }
-
- abort();
- /* NOTREACHED */
-}
diff --git a/macro.c b/macro.c
index 722b2996..ba57be6a 100644
--- a/macro.c
+++ b/macro.c
@@ -16,90 +16,294 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+#include <assert.h>
+#include <ctype.h>
#include <stdlib.h>
+#include <stdio.h>
+
+#include "private.h"
+
+#define _C(p) ((const char **)p)
+
+static int isdelim(const char *);
+static int args_next(struct mdoc *, int, int *, char *, char **);
+static int append_text(struct mdoc *, int, int, int, char *[]);
+static int append_scoped(struct mdoc *, int, int, int, char *[]);
+
+
+static int
+isdelim(const char *p)
+{
+
+ if (0 == *p)
+ return(0);
+ if (0 != *(p + 1))
+ return(0);
+
+ switch (*p) {
+ case('{'):
+ /* FALLTHROUGH */
+ case('.'):
+ /* FALLTHROUGH */
+ case(','):
+ /* FALLTHROUGH */
+ case(';'):
+ /* FALLTHROUGH */
+ case(':'):
+ /* FALLTHROUGH */
+ case('?'):
+ /* FALLTHROUGH */
+ case('!'):
+ /* FALLTHROUGH */
+ case('('):
+ /* FALLTHROUGH */
+ case(')'):
+ /* FALLTHROUGH */
+ case('['):
+ /* FALLTHROUGH */
+ case(']'):
+ /* FALLTHROUGH */
+ case('}'):
+ return(1);
+ default:
+ break;
+ }
+
+ return(0);
+}
-#include "roff.h"
static int
-macro_args_next(struct rofftree *tree, int *pos, char *buf, char **v)
+args_next(struct mdoc *mdoc, int tok,
+ int *pos, char *buf, char **v)
{
- int i;
if (0 == buf[*pos])
return(0);
+ assert( ! isspace(buf[*pos]));
+
if ('\"' == buf[*pos]) {
- /* Syntax error: quotation marks not allowed. */
+ (void)mdoc_err(mdoc, tok, *pos, ERR_SYNTAX_QUOTE);
return(-1);
}
*v = &buf[*pos];
+ /* Scan ahead to end of token. */
+
while (buf[*pos] && ! isspace(buf[*pos]))
(*pos)++;
- if (buf[*pos + 1] && '\\' == buf[*pos]) {
- /* Syntax error: escaped whitespace not allowed. */
+ if (buf[*pos] && buf[*pos + 1] && '\\' == buf[*pos]) {
+ (void)mdoc_err(mdoc, tok, *pos, ERR_SYNTAX_WS);
return(-1);
}
- buf[i] = 0;
+ if (0 == buf[*pos])
+ return(1);
+
+ /* Scan ahead over trailing whitespace. */
+
+ buf[(*pos)++] = 0;
+ while (buf[*pos] && isspace(buf[*pos]))
+ (*pos)++;
+
+ if (0 == buf[*pos])
+ if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN))
+ return(-1);
+
return(1);
}
-/*
- * Parses the following:
- *
- * .Xx foo bar baz ; foo "bar baz" ; ;
- * ^---------- ^----------
- */
+
static int
-macro_fl(struct rofftree *tree, int tok, int *pos, char *buf)
+append_scoped(struct mdoc *mdoc, int tok, int pos, int sz, char *args[])
{
- int i, j, c, first;
- char *args[ROFF_MAXLINEARG];
- first = *pos == 0;
+ args[sz] = NULL;
+ mdoc_block_alloc(mdoc, pos, tok, 0, NULL);
+ mdoc_head_alloc(mdoc, pos, tok, sz, _C(args));
+ mdoc_body_alloc(mdoc, pos, tok);
+ return(1);
+}
- for (j = 0; ; ) {
- i = *pos;
- c = macro_args_next(tree, *i, buf, args[j]);
- if (-1 == c)
+
+static int
+append_text(struct mdoc *mdoc, int tok, int pos, int sz, char *args[])
+{
+
+ args[sz] = NULL;
+
+ switch (tok) {
+ /* ======= ADD MORE MACRO ARGUMENT-LIMITS BELOW. ======= */
+
+ case (MDOC_Ft):
+ /* FALLTHROUGH */
+ case (MDOC_Li):
+ /* FALLTHROUGH */
+ case (MDOC_Ms):
+ /* FALLTHROUGH */
+ case (MDOC_Pa):
+ /* FALLTHROUGH */
+ case (MDOC_Tn):
+ if (0 == sz && ! mdoc_warn(mdoc, tok, pos, WARN_ARGS_GE1))
return(0);
- if (0 == c)
- break;
+ mdoc_elem_alloc(mdoc, pos, tok, 0, NULL, sz, _C(args));
+ return(1);
- /* Break at the next command. */
+ case (MDOC_Ar):
+ /* FALLTHROUGH */
+ case (MDOC_Cm):
+ /* FALLTHROUGH */
+ case (MDOC_Fl):
+ mdoc_elem_alloc(mdoc, pos, tok, 0, NULL, sz, _C(args));
+ return(1);
- if (ROFF_MAX != (c = rofffindcallable(args[pos]))) {
- if ( ! macro(tree, tok, argc, argv, i, p))
- return(0);
- if ( ! parse(tree, c, pos, args))
+ case (MDOC_Ad):
+ /* FALLTHROUGH */
+ case (MDOC_Em):
+ /* FALLTHROUGH */
+ case (MDOC_Er):
+ /* FALLTHROUGH */
+ case (MDOC_Ev):
+ /* FALLTHROUGH */
+ case (MDOC_Fa):
+ /* FALLTHROUGH */
+ case (MDOC_Dv):
+ /* FALLTHROUGH */
+ case (MDOC_Ic):
+ /* FALLTHROUGH */
+ case (MDOC_Va):
+ /* FALLTHROUGH */
+ case (MDOC_Vt):
+ if (0 == sz)
+ return(mdoc_err(mdoc, tok, pos, ERR_ARGS_GE1));
+ mdoc_elem_alloc(mdoc, pos, tok, 0, NULL, sz, _C(args));
+ return(1);
+
+ /* ======= ADD MORE MACRO ARGUMENT-LIMITS ABOVE. ======= */
+ default:
+ break;
+ }
+
+ abort();
+ /* NOTREACHED */
+}
+
+
+int
+macro_text(struct mdoc *mdoc, int tok, int ppos, int *pos, char *buf)
+{
+ int lastarg, j, c, lasttok, lastpunct;
+ char *args[MDOC_LINEARG_MAX], *p;
+
+ lasttok = ppos;
+ lastpunct = 0;
+ j = 0;
+
+again:
+
+ lastarg = *pos;
+ c = args_next(mdoc, tok, pos, buf, &args[j]);
+
+ if (-1 == c)
+ return(0);
+ if (0 == c && ! lastpunct)
+ return(append_text(mdoc, tok, lasttok, j, args));
+ else if (0 == c)
+ return(1);
+
+ /* Command found. */
+
+ if (MDOC_MAX != (c = mdoc_find(mdoc, args[j]))) {
+ if ( ! lastpunct)
+ if ( ! append_text(mdoc, tok, lasttok, j, args))
return(0);
- break;
- }
+ return(mdoc_macro(mdoc, c, lastarg, pos, buf));
+ }
- /* Continue if we're just words. */
+ /* Word found. */
- if ( ! roffispunct(args[pos])) {
- i++;
- continue;
- }
+ if ( ! isdelim(args[j])) {
+ j++;
+ goto again;
+ }
+
+ /* Punctuation found. */
+
+ p = args[j]; /* Save argument (NULL-ified in append). */
+
+ if ( ! lastpunct)
+ if ( ! append_text(mdoc, tok, lasttok, j, args))
+ return(0);
+
+ args[j] = p;
- /* Break if there's only remaining punctuation. */
+ mdoc_word_alloc(mdoc, lastarg, args[j]);
+ lastpunct = 1;
+ j = 0;
- if (args[pos + 1] && roffispunct(args[pos + 1]))
+ goto again;
+
+ /* NOTREACHED */
+}
+
+
+int
+macro_scoped_implicit(struct mdoc *mdoc,
+ int tok, int ppos, int *pos, char *buf)
+{
+ int j, c, lastarg, t;
+ char *args[MDOC_LINEARG_MAX];
+ struct mdoc_node *n;
+
+ /*
+ * Look for an implicit parent.
+ */
+
+ assert( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags));
+
+ for (n = mdoc->last; n; n = n->parent) {
+ if (MDOC_BLOCK != n->type)
+ continue;
+ if (tok == (t = n->data.block.tok))
break;
+ if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
+ continue;
+ return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK));
+ }
- /* If there are remaining words, start anew. */
+ if (n) {
+ mdoc->last = n;
+ mdoc_msg(mdoc, ppos, "scope: rewound `%s'",
+ mdoc_macronames[tok]);
+ } else
+ mdoc_msg(mdoc, ppos, "scope: new `%s'",
+ mdoc_macronames[tok]);
- if ( ! macro(tree, tok, argc, argv, i, p))
- return(0);
+ j = 0;
+
+again:
+
+ lastarg = *pos;
+ c = args_next(mdoc, tok, pos, buf, &args[j]);
+
+ if (-1 == c)
+ return(0);
+ if (0 == c)
+ return(append_scoped(mdoc, tok, ppos, j, args));
- /* Spit out the punctuation. */
+ /* Command found. */
- if ( ! word(tree, tok, *args++))
+ if (MDOC_MAX != (c = mdoc_find(mdoc, args[j])))
+ if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_MACLIKE))
return(0);
- i++;
- }
+
+ /* Word found. */
+
+ j++;
+ goto again;
+
+ /* NOTREACHED */
}
diff --git a/mdoc.c b/mdoc.c
new file mode 100644
index 00000000..69f17e1a
--- /dev/null
+++ b/mdoc.c
@@ -0,0 +1,734 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * 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 <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "private.h"
+
+extern int macro_text(struct mdoc *, int, int, int *, char *);
+extern int macro_scoped_implicit(struct mdoc *,
+ int, int, int *, char *);
+
+const char *const __mdoc_macronames[MDOC_MAX] = {
+ "\\\"", "Dd", "Dt", "Os",
+ "Sh", "Ss", "Pp", "D1",
+ "Dl", "Bd", "Ed", "Bl",
+ "El", "It", "Ad", "An",
+ "Ar", "Cd", "Cm", "Dv",
+ "Er", "Ev", "Ex", "Fa",
+ "Fd", "Fl", "Fn", "Ft",
+ "Ic", "In", "Li", "Nd",
+ "Nm", "Op", "Ot", "Pa",
+ "Rv", "St", "Va", "Vt",
+ /* LINTED */
+ "Xr", "\%A", "\%B", "\%D",
+ /* LINTED */
+ "\%I", "\%J", "\%N", "\%O",
+ /* LINTED */
+ "\%P", "\%R", "\%T", "\%V",
+ "Ac", "Ao", "Aq", "At",
+ "Bc", "Bf", "Bo", "Bq",
+ "Bsx", "Bx", "Db", "Dc",
+ "Do", "Dq", "Ec", "Ef",
+ "Em", "Eo", "Fx", "Ms",
+ "No", "Ns", "Nx", "Ox",
+ "Pc", "Pf", "Po", "Pq",
+ "Qc", "Ql", "Qo", "Qq",
+ "Re", "Rs", "Sc", "So",
+ "Sq", "Sm", "Sx", "Sy",
+ "Tn", "Ux", "Xc", "Xo",
+ "Fo", "Fc", "Oo", "Oc",
+ "Bk", "Ek", "Bt", "Hf",
+ "Fr", "Ud",
+ };
+
+const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
+ "split", "nosplit", "ragged",
+ "unfilled", "literal", "file",
+ "offset", "bullet", "dash",
+ "hyphen", "item", "enum",
+ "tag", "diag", "hang",
+ "ohang", "inset", "column",
+ "width", "compact", "std",
+ "p1003.1-88", "p1003.1-90", "p1003.1-96",
+ "p1003.1-2001", "p1003.1-2004", "p1003.1",
+ "p1003.1b", "p1003.1b-93", "p1003.1c-95",
+ "p1003.1g-2000", "p1003.2-92", "p1387.2-95",
+ "p1003.2", "p1387.2", "isoC-90",
+ "isoC-amd1", "isoC-tcor1", "isoC-tcor2",
+ "isoC-99", "ansiC", "ansiC-89",
+ "ansiC-99", "ieee754", "iso8802-3",
+ "xpg3", "xpg4", "xpg4.2",
+ "xpg4.3", "xbd5", "xcu5",
+ "xsh5", "xns5", "xns5.2d2.0",
+ "xcurses4.2", "susv2", "susv3",
+ "svid4", "filled", "words",
+ };
+
+const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
+ { NULL, 0 }, /* \" */
+ { NULL, 0 }, /* Dd */
+ { NULL, 0 }, /* Dt */
+ { NULL, 0 }, /* Os */
+ { macro_scoped_implicit, 0 }, /* Sh */
+ { macro_scoped_implicit, 0 }, /* Ss */
+ { NULL, 0 }, /* Pp */
+ { NULL, 0 }, /* D1 */
+ { NULL, 0 }, /* Dl */
+ { NULL, 0 }, /* Bd */
+ { NULL, 0 }, /* Ed */
+ { NULL, 0 }, /* Bl */
+ { NULL, 0 }, /* El */
+ { NULL, 0 }, /* It */
+ { macro_text, MDOC_CALLABLE }, /* Ad */
+ { NULL, 0 }, /* An */
+ { macro_text, MDOC_CALLABLE }, /* Ar */
+ { NULL, 0 }, /* Cd */
+ { macro_text, MDOC_CALLABLE }, /* Cm */
+ { macro_text, MDOC_CALLABLE }, /* Dv */
+ { macro_text, MDOC_CALLABLE }, /* Er */
+ { macro_text, MDOC_CALLABLE }, /* Ev */
+ { NULL, 0 }, /* Ex */
+ { macro_text, MDOC_CALLABLE }, /* Fa */
+ { NULL, 0 }, /* Fd */
+ { macro_text, MDOC_CALLABLE }, /* Fl */
+ { NULL, 0 }, /* Fn */
+ { macro_text, 0 }, /* Ft */
+ { macro_text, MDOC_CALLABLE }, /* Ic */
+ { NULL, 0 }, /* In */
+ { macro_text, MDOC_CALLABLE }, /* Li */
+ { NULL, 0 }, /* Nd */
+ { NULL, 0 }, /* Nm */
+ { NULL, 0 }, /* Op */
+ { NULL, 0 }, /* Ot */
+ { macro_text, MDOC_CALLABLE }, /* Pa */
+ { NULL, 0 }, /* Rv */
+ { NULL, 0 }, /* St */
+ { macro_text, MDOC_CALLABLE }, /* Va */
+ { macro_text, MDOC_CALLABLE }, /* Vt */
+ { NULL, 0 }, /* Xr */
+ { NULL, 0 }, /* %A */
+ { NULL, 0 }, /* %B */
+ { NULL, 0 }, /* %D */
+ { NULL, 0 }, /* %I */
+ { NULL, 0 }, /* %J */
+ { NULL, 0 }, /* %N */
+ { NULL, 0 }, /* %O */
+ { NULL, 0 }, /* %P */
+ { NULL, 0 }, /* %R */
+ { NULL, 0 }, /* %T */
+ { NULL, 0 }, /* %V */
+ { NULL, 0 }, /* Ac */
+ { NULL, 0 }, /* Ao */
+ { NULL, 0 }, /* Aq */
+ { NULL, 0 }, /* At */
+ { NULL, 0 }, /* Bc */
+ { NULL, 0 }, /* Bf */
+ { NULL, 0 }, /* Bo */
+ { NULL, 0 }, /* Bq */
+ { NULL, 0 }, /* Bsx */
+ { NULL, 0 }, /* Bx */
+ { NULL, 0 }, /* Db */
+ { NULL, 0 }, /* Dc */
+ { NULL, 0 }, /* Do */
+ { NULL, 0 }, /* Dq */
+ { NULL, 0 }, /* Ec */
+ { NULL, 0 }, /* Ef */
+ { macro_text, MDOC_CALLABLE }, /* Em */
+ { NULL, 0 }, /* Eo */
+ { NULL, 0 }, /* Fx */
+ { macro_text, 0 }, /* Ms */
+ { NULL, 0 }, /* No */
+ { NULL, 0 }, /* Ns */
+ { NULL, 0 }, /* Nx */
+ { NULL, 0 }, /* Ox */
+ { NULL, 0 }, /* Pc */
+ { NULL, 0 }, /* Pf */
+ { NULL, 0 }, /* Po */
+ { NULL, 0 }, /* Pq */
+ { NULL, 0 }, /* Qc */
+ { NULL, 0 }, /* Ql */
+ { NULL, 0 }, /* Qo */
+ { NULL, 0 }, /* Qq */
+ { NULL, 0 }, /* Re */
+ { NULL, 0 }, /* Rs */
+ { NULL, 0 }, /* Sc */
+ { NULL, 0 }, /* So */
+ { NULL, 0 }, /* Sq */
+ { NULL, 0 }, /* Sm */
+ { NULL, 0 }, /* Sx */
+ { NULL, 0 }, /* Sy */
+ { macro_text, MDOC_CALLABLE }, /* Tn */
+ { NULL, 0 }, /* Ux */
+ { NULL, 0 }, /* Xc */
+ { NULL, 0 }, /* Xo */
+ { NULL, 0 }, /* Fo */
+ { NULL, 0 }, /* Fc */
+ { NULL, 0 }, /* Oo */
+ { NULL, 0 }, /* Oc */
+ { NULL, 0 }, /* Bk */
+ { NULL, 0 }, /* Ek */
+ { NULL, 0 }, /* Bt */
+ { NULL, 0 }, /* Hf */
+ { NULL, 0 }, /* Fr */
+ { NULL, 0 }, /* Ud */
+};
+
+const char * const *mdoc_macronames = __mdoc_macronames;
+const char * const *mdoc_argnames = __mdoc_argnames;
+const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
+
+
+static void *xcalloc(size_t, size_t);
+static char *xstrdup(const char *);
+
+static struct mdoc_arg *argdup(size_t, const struct mdoc_arg *);
+static void argfree(size_t, struct mdoc_arg *);
+static void argcpy(struct mdoc_arg *,
+ const struct mdoc_arg *);
+static char **paramdup(size_t, const char **);
+static void paramfree(size_t, char **);
+
+static void mdoc_node_freelist(struct mdoc_node *);
+static void mdoc_node_append(struct mdoc *, int,
+ struct mdoc_node *);
+static void mdoc_elem_free(struct mdoc_elem *);
+static void mdoc_text_free(struct mdoc_text *);
+
+
+const struct mdoc_node *
+mdoc_result(struct mdoc *mdoc)
+{
+
+ return(mdoc->first);
+}
+
+
+void
+mdoc_free(struct mdoc *mdoc)
+{
+
+ if (mdoc->first)
+ mdoc_node_freelist(mdoc->first);
+ if (mdoc->htab)
+ mdoc_hash_free(mdoc->htab);
+
+ free(mdoc);
+}
+
+
+struct mdoc *
+mdoc_alloc(void *data, const struct mdoc_cb *cb)
+{
+ struct mdoc *p;
+
+ p = xcalloc(1, sizeof(struct mdoc));
+
+ p->data = data;
+ (void)memcpy(&p->cb, cb, sizeof(struct mdoc_cb));
+
+ p->htab = mdoc_hash_alloc();
+ return(p);
+}
+
+
+static void *
+xcalloc(size_t num, size_t sz)
+{
+ void *p;
+
+ if (NULL == (p = calloc(num, sz)))
+ err(EXIT_FAILURE, "calloc");
+ return(p);
+}
+
+
+static char *
+xstrdup(const char *p)
+{
+ char *pp;
+
+ if (NULL == (pp = strdup(p)))
+ err(EXIT_FAILURE, "strdup");
+ return(pp);
+}
+
+
+int
+mdoc_parseln(struct mdoc *mdoc, char *buf)
+{
+ int c, i;
+ char tmp[5];
+
+ if ('.' != *buf) {
+ /* TODO. */
+ return(1);
+ }
+
+ if (buf[1] && '\\' == buf[1])
+ if (buf[2] && '\"' == buf[2])
+ return(1);
+
+ i = 1;
+ while (buf[i] && ! isspace(buf[i]) && i < (int)sizeof(tmp))
+ i++;
+
+ if (i == (int)sizeof(tmp))
+ return(mdoc_err(mdoc, -1, 1, ERR_MACRO_NOTSUP));
+ else if (i <= 2)
+ return(mdoc_err(mdoc, -1, 1, ERR_MACRO_NOTSUP));
+
+ i--;
+
+ (void)memcpy(tmp, buf + 1, i);
+ tmp[i++] = 0;
+
+ if (MDOC_MAX == (c = mdoc_find(mdoc, tmp)))
+ return(mdoc_err(mdoc, c, 1, ERR_MACRO_NOTSUP));
+
+ while (buf[i] && isspace(buf[i]))
+ i++;
+
+ if (NULL == (mdoc_macros[c].fp)) {
+ (void)mdoc_err(mdoc, c, 1, ERR_MACRO_NOTSUP);
+ return(0);
+ }
+
+ return((*mdoc_macros[c].fp)(mdoc, c, 1, &i, buf));
+}
+
+
+void
+mdoc_msg(struct mdoc *mdoc, int pos, const char *fmt, ...)
+{
+ va_list ap;
+ char buf[256];
+
+ if (NULL == mdoc->cb.mdoc_msg)
+ return;
+
+ va_start(ap, fmt);
+ (void)vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ (*mdoc->cb.mdoc_msg)(mdoc->data, pos, buf);
+}
+
+
+int
+mdoc_err(struct mdoc *mdoc, int tok, int pos, enum mdoc_err type)
+{
+
+ if (NULL == mdoc->cb.mdoc_err)
+ return(0);
+ return((*mdoc->cb.mdoc_err)(mdoc->data, tok, pos, type));
+}
+
+
+int
+mdoc_warn(struct mdoc *mdoc, int tok, int pos, enum mdoc_warn type)
+{
+
+ if (NULL == mdoc->cb.mdoc_warn)
+ return(0);
+ return((*mdoc->cb.mdoc_warn)(mdoc->data, tok, pos, type));
+}
+
+
+int
+mdoc_macro(struct mdoc *mdoc, int tok, int ppos, int *pos, char *buf)
+{
+
+ if (NULL == (mdoc_macros[tok].fp)) {
+ (void)mdoc_err(mdoc, tok, ppos, ERR_MACRO_NOTSUP);
+ return(0);
+ } else if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
+ (void)mdoc_err(mdoc, tok, ppos, ERR_MACRO_NOTCALL);
+ return(0);
+ }
+
+ return((*mdoc_macros[tok].fp)(mdoc, tok, ppos, pos, buf));
+}
+
+
+static void
+mdoc_node_append(struct mdoc *mdoc, int pos, struct mdoc_node *p)
+{
+ const char *nn, *on, *nt, *ot, *act;
+
+ switch (p->type) {
+ case (MDOC_TEXT):
+ nn = "<text>";
+ nt = "text";
+ break;
+ case (MDOC_BODY):
+ nn = mdoc_macronames[p->data.body.tok];
+ nt = "body";
+ break;
+ case (MDOC_ELEM):
+ nn = mdoc_macronames[p->data.elem.tok];
+ nt = "elem";
+ break;
+ case (MDOC_HEAD):
+ nn = mdoc_macronames[p->data.head.tok];
+ nt = "head";
+ break;
+ case (MDOC_BLOCK):
+ nn = mdoc_macronames[p->data.block.tok];
+ nt = "block";
+ break;
+ }
+
+ if (NULL == mdoc->first) {
+ assert(NULL == mdoc->last);
+ mdoc->first = p;
+ mdoc->last = p;
+ mdoc_msg(mdoc, pos, "parse: root %s `%s'", nt, nn);
+ return;
+ }
+
+ switch (mdoc->last->type) {
+ case (MDOC_TEXT):
+ on = "<text>";
+ ot = "text";
+ break;
+ case (MDOC_BODY):
+ on = mdoc_macronames[mdoc->last->data.body.tok];
+ ot = "body";
+ break;
+ case (MDOC_ELEM):
+ on = mdoc_macronames[mdoc->last->data.elem.tok];
+ ot = "elem";
+ break;
+ case (MDOC_HEAD):
+ on = mdoc_macronames[mdoc->last->data.head.tok];
+ ot = "head";
+ break;
+ case (MDOC_BLOCK):
+ on = mdoc_macronames[mdoc->last->data.block.tok];
+ ot = "block";
+ break;
+ }
+
+ switch (p->type) {
+ case (MDOC_BODY):
+ switch (mdoc->last->type) {
+ case (MDOC_BLOCK):
+ p->parent = mdoc->last;
+ mdoc->last->child = p;
+ act = "child";
+ break;
+ case (MDOC_HEAD):
+ p->parent = mdoc->last->parent;
+ mdoc->last->next = p;
+ act = "sibling";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+ break;
+ case (MDOC_HEAD):
+ assert(mdoc->last->type == MDOC_BLOCK);
+ p->parent = mdoc->last;
+ mdoc->last->child = p;
+ act = "child";
+ break;
+ default:
+ switch (mdoc->last->type) {
+ case (MDOC_BODY):
+ /* FALLTHROUGH */
+ case (MDOC_HEAD):
+ p->parent = mdoc->last->parent;
+ mdoc->last->child = p;
+ act = "child";
+ break;
+ default:
+ p->parent = mdoc->last->parent;
+ mdoc->last->next = p;
+ act = "sibling";
+ break;
+ }
+ break;
+ }
+
+ mdoc_msg(mdoc, pos, "parse: %s `%s' %s %s `%s'",
+ nt, nn, act, ot, on);
+ mdoc->last = p;
+}
+
+
+void
+mdoc_head_alloc(struct mdoc *mdoc, int pos, int tok,
+ size_t paramsz, const char **params)
+{
+ struct mdoc_node *p;
+
+ assert(mdoc->first);
+ assert(mdoc->last);
+ assert(mdoc->last->type == MDOC_BLOCK);
+ assert(mdoc->last->data.block.tok == tok);
+
+ p = xcalloc(1, sizeof(struct mdoc_node));
+ p->type = MDOC_HEAD;
+ p->data.head.tok = tok;
+ p->data.head.sz = paramsz;
+ p->data.head.args = paramdup(paramsz, params);
+
+ mdoc_node_append(mdoc, pos, p);
+}
+
+
+void
+mdoc_body_alloc(struct mdoc *mdoc, int pos, int tok)
+{
+ struct mdoc_node *p;
+
+ assert(mdoc->first);
+ assert(mdoc->last);
+ assert((mdoc->last->type == MDOC_BLOCK) ||
+ (mdoc->last->type == MDOC_HEAD));
+ if (mdoc->last->type == MDOC_BLOCK)
+ assert(mdoc->last->data.block.tok == tok);
+ else
+ assert(mdoc->last->data.head.tok == tok);
+
+ p = xcalloc(1, sizeof(struct mdoc_node));
+
+ p->type = MDOC_BODY;
+ p->data.body.tok = tok;
+
+ mdoc_node_append(mdoc, pos, p);
+}
+
+
+void
+mdoc_block_alloc(struct mdoc *mdoc, int pos, int tok,
+ size_t argsz, const struct mdoc_arg *args)
+{
+ struct mdoc_node *p;
+
+ p = xcalloc(1, sizeof(struct mdoc_node));
+
+ p->type = MDOC_BLOCK;
+ p->data.block.tok = tok;
+ p->data.block.argc = argsz;
+ p->data.block.argv = argdup(argsz, args);
+
+ mdoc_node_append(mdoc, pos, p);
+}
+
+
+void
+mdoc_elem_alloc(struct mdoc *mdoc, int pos, int tok,
+ size_t argsz, const struct mdoc_arg *args,
+ size_t paramsz, const char **params)
+{
+ struct mdoc_node *p;
+
+ p = xcalloc(1, sizeof(struct mdoc_node));
+ p->type = MDOC_ELEM;
+ p->data.elem.tok = tok;
+ p->data.elem.sz = paramsz;
+ p->data.elem.args = paramdup(paramsz, params);
+ p->data.elem.argc = argsz;
+ p->data.elem.argv = argdup(argsz, args);
+
+ mdoc_node_append(mdoc, pos, p);
+}
+
+
+void
+mdoc_word_alloc(struct mdoc *mdoc, int pos, const char *word)
+{
+ struct mdoc_node *p;
+
+ p = xcalloc(1, sizeof(struct mdoc_node));
+ p->type = MDOC_TEXT;
+ p->data.text.string = xstrdup(word);
+
+ mdoc_node_append(mdoc, pos, p);
+}
+
+
+static void
+argfree(size_t sz, struct mdoc_arg *p)
+{
+ size_t i, j;
+
+ if (0 == sz)
+ return;
+
+ assert(p);
+ for (i = 0; i < sz; i++)
+ if (p[i].sz > 0) {
+ assert(p[i].value);
+ for (j = 0; j < p[i].sz; j++)
+ free(p[i].value[j]);
+ }
+ free(p);
+}
+
+
+static void
+mdoc_elem_free(struct mdoc_elem *p)
+{
+
+ paramfree(p->sz, p->args);
+ argfree(p->argc, p->argv);
+}
+
+
+static void
+mdoc_block_free(struct mdoc_block *p)
+{
+
+ argfree(p->argc, p->argv);
+}
+
+
+static void
+mdoc_text_free(struct mdoc_text *p)
+{
+
+ if (p->string)
+ free(p->string);
+}
+
+
+static void
+mdoc_head_free(struct mdoc_head *p)
+{
+
+ paramfree(p->sz, p->args);
+}
+
+
+void
+mdoc_node_free(struct mdoc_node *p)
+{
+
+ switch (p->type) {
+ case (MDOC_TEXT):
+ mdoc_text_free(&p->data.text);
+ break;
+ case (MDOC_ELEM):
+ mdoc_elem_free(&p->data.elem);
+ break;
+ case (MDOC_BLOCK):
+ mdoc_block_free(&p->data.block);
+ break;
+ case (MDOC_HEAD):
+ mdoc_head_free(&p->data.head);
+ break;
+ default:
+ break;
+ }
+
+ free(p);
+}
+
+
+static void
+mdoc_node_freelist(struct mdoc_node *p)
+{
+
+ if (p->child)
+ mdoc_node_freelist(p->child);
+ if (p->next)
+ mdoc_node_freelist(p->next);
+
+ mdoc_node_free(p);
+}
+
+
+int
+mdoc_find(const struct mdoc *mdoc, const char *key)
+{
+
+ return(mdoc_hash_find(mdoc->htab, key));
+}
+
+
+static void
+argcpy(struct mdoc_arg *dst, const struct mdoc_arg *src)
+{
+ size_t i;
+
+ dst->arg = src->arg;
+ if (0 == (dst->sz = src->sz))
+ return;
+ dst->value = xcalloc(dst->sz, sizeof(char *));
+ for (i = 0; i < dst->sz; i++)
+ dst->value[i] = xstrdup(src->value[i]);
+}
+
+
+static struct mdoc_arg *
+argdup(size_t argsz, const struct mdoc_arg *args)
+{
+ struct mdoc_arg *pp;
+ size_t i;
+
+ if (0 == argsz)
+ return(NULL);
+
+ pp = xcalloc((size_t)argsz, sizeof(struct mdoc_arg));
+ for (i = 0; i < argsz; i++)
+ argcpy(&pp[i], &args[i]);
+
+ return(pp);
+}
+
+
+static void
+paramfree(size_t sz, char **p)
+{
+ size_t i;
+
+ if (0 == sz)
+ return;
+
+ assert(p);
+ for (i = 0; i < sz; i++)
+ free(p[i]);
+ free(p);
+}
+
+
+static char **
+paramdup(size_t sz, const char **p)
+{
+ char **pp;
+ size_t i;
+
+ if (0 == sz)
+ return(NULL);
+
+ pp = xcalloc(sz, sizeof(char *));
+ for (i = 0; i < sz; i++)
+ pp[i] = xstrdup(p[i]);
+
+ return(pp);
+}
diff --git a/mdoc.h b/mdoc.h
new file mode 100644
index 00000000..7dca294c
--- /dev/null
+++ b/mdoc.h
@@ -0,0 +1,289 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * 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 MDOC_H
+#define MDOC_H
+
+#define MDOC_LINEARG_MAX 9
+
+#define MDOC___ 0
+#define MDOC_Dd 1
+#define MDOC_Dt 2
+#define MDOC_Os 3
+#define MDOC_Sh 4
+#define MDOC_Ss 5
+#define MDOC_Pp 6
+#define MDOC_D1 7
+#define MDOC_Dl 8
+#define MDOC_Bd 9
+#define MDOC_Ed 10
+#define MDOC_Bl 11
+#define MDOC_El 12
+#define MDOC_It 13
+#define MDOC_Ad 14
+#define MDOC_An 15
+#define MDOC_Ar 16
+#define MDOC_Cd 17
+#define MDOC_Cm 18
+#define MDOC_Dv 19
+#define MDOC_Er 20
+#define MDOC_Ev 21
+#define MDOC_Ex 22
+#define MDOC_Fa 23
+#define MDOC_Fd 24
+#define MDOC_Fl 25
+#define MDOC_Fn 26
+#define MDOC_Ft 27
+#define MDOC_Ic 28
+#define MDOC_In 29
+#define MDOC_Li 30
+#define MDOC_Nd 31
+#define MDOC_Nm 32
+#define MDOC_Op 33
+#define MDOC_Ot 34
+#define MDOC_Pa 35
+#define MDOC_Rv 36
+#define MDOC_St 37
+#define MDOC_Va 38
+#define MDOC_Vt 39
+#define MDOC_Xr 40
+#define MDOC__A 41
+#define MDOC__B 42
+#define MDOC__D 43
+#define MDOC__I 44
+#define MDOC__J 45
+#define MDOC__N 46
+#define MDOC__O 47
+#define MDOC__P 48
+#define MDOC__R 49
+#define MDOC__T 50
+#define MDOC__V 51
+#define MDOC_Ac 52
+#define MDOC_Ao 53
+#define MDOC_Aq 54
+#define MDOC_At 55
+#define MDOC_Bc 56
+#define MDOC_Bf 57
+#define MDOC_Bo 58
+#define MDOC_Bq 59
+#define MDOC_Bsx 60
+#define MDOC_Bx 61
+#define MDOC_Db 62
+#define MDOC_Dc 63
+#define MDOC_Do 64
+#define MDOC_Dq 65
+#define MDOC_Ec 66
+#define MDOC_Ef 67
+#define MDOC_Em 68
+#define MDOC_Eo 69
+#define MDOC_Fx 70
+#define MDOC_Ms 71
+#define MDOC_No 72
+#define MDOC_Ns 73
+#define MDOC_Nx 74
+#define MDOC_Ox 75
+#define MDOC_Pc 76
+#define MDOC_Pf 77
+#define MDOC_Po 78
+#define MDOC_Pq 79
+#define MDOC_Qc 80
+#define MDOC_Ql 81
+#define MDOC_Qo 82
+#define MDOC_Qq 83
+#define MDOC_Re 84
+#define MDOC_Rs 85
+#define MDOC_Sc 86
+#define MDOC_So 87
+#define MDOC_Sq 88
+#define MDOC_Sm 89
+#define MDOC_Sx 90
+#define MDOC_Sy 91
+#define MDOC_Tn 92
+#define MDOC_Ux 93
+#define MDOC_Xc 94
+#define MDOC_Xo 95
+#define MDOC_Fo 96
+#define MDOC_Fc 97
+#define MDOC_Oo 98
+#define MDOC_Oc 99
+#define MDOC_Bk 100
+#define MDOC_Ek 101
+#define MDOC_Bt 102
+#define MDOC_Hf 103
+#define MDOC_Fr 104
+#define MDOC_Ud 105
+#define MDOC_MAX 106
+
+#define MDOC_Split 0
+#define MDOC_Nosplit 1
+#define MDOC_Ragged 2
+#define MDOC_Unfilled 3
+#define MDOC_Literal 4
+#define MDOC_File 5
+#define MDOC_Offset 6
+#define MDOC_Bullet 7
+#define MDOC_Dash 8
+#define MDOC_Hyphen 9
+#define MDOC_Item 10
+#define MDOC_Enum 11
+#define MDOC_Tag 12
+#define MDOC_Diag 13
+#define MDOC_Hang 14
+#define MDOC_Ohang 15
+#define MDOC_Inset 16
+#define MDOC_Column 17
+#define MDOC_Width 18
+#define MDOC_Compact 19
+#define MDOC_Std 20
+#define MDOC_p1003_1_88 21
+#define MDOC_p1003_1_90 22
+#define MDOC_p1003_1_96 23
+#define MDOC_p1003_1_2001 24
+#define MDOC_p1003_1_2004 25
+#define MDOC_p1003_1 26
+#define MDOC_p1003_1b 27
+#define MDOC_p1003_1b_93 28
+#define MDOC_p1003_1c_95 29
+#define MDOC_p1003_1g_2000 30
+#define MDOC_p1003_2_92 31
+#define MDOC_p1387_2_95 32
+#define MDOC_p1003_2 33
+#define MDOC_p1387_2 34
+#define MDOC_isoC_90 35
+#define MDOC_isoC_amd1 36
+#define MDOC_isoC_tcor1 37
+#define MDOC_isoC_tcor2 38
+#define MDOC_isoC_99 39
+#define MDOC_ansiC 40
+#define MDOC_ansiC_89 41
+#define MDOC_ansiC_99 42
+#define MDOC_ieee754 43
+#define MDOC_iso8802_3 44
+#define MDOC_xpg3 45
+#define MDOC_xpg4 46
+#define MDOC_xpg4_2 47
+#define MDOC_xpg4_3 48
+#define MDOC_xbd5 49
+#define MDOC_xcu5 50
+#define MDOC_xsh5 51
+#define MDOC_xns5 52
+#define MDOC_xns5_2d2_0 53
+#define MDOC_xcurses4_2 54
+#define MDOC_susv2 55
+#define MDOC_susv3 56
+#define MDOC_svid4 57
+#define MDOC_Filled 58
+#define MDOC_Words 59
+#define MDOC_ARG_MAX 60
+
+enum mdoc_err {
+ ERR_SYNTAX_QUOTE,
+ ERR_SYNTAX_WS,
+ ERR_MACRO_NOTSUP,
+ ERR_MACRO_NOTCALL,
+ ERR_SCOPE_BREAK,
+ ERR_ARGS_GE1
+};
+
+enum mdoc_warn {
+ WARN_SYNTAX_WS_EOLN,
+ WARN_SYNTAX_MACLIKE,
+ WARN_ARGS_GE1
+};
+
+struct mdoc_arg {
+ int arg;
+ size_t sz;
+ char **value;
+};
+
+enum mdoc_type {
+ MDOC_TEXT,
+ MDOC_ELEM,
+ MDOC_HEAD,
+ MDOC_BODY,
+ MDOC_BLOCK
+};
+
+struct mdoc_text {
+ char *string;
+};
+
+struct mdoc_block {
+ int tok;
+ size_t argc;
+ struct mdoc_arg *argv;
+};
+
+struct mdoc_head {
+ size_t sz;
+ char **args;
+ int tok;
+};
+
+struct mdoc_body {
+ int tok;
+};
+
+struct mdoc_elem {
+ size_t sz;
+ char **args;
+ int tok;
+ size_t argc;
+ struct mdoc_arg *argv;
+};
+
+union mdoc_data {
+ struct mdoc_text text;
+ struct mdoc_elem elem;
+ struct mdoc_body body;
+ struct mdoc_head head;
+ struct mdoc_block block;
+};
+
+struct mdoc_node {
+ struct mdoc_node *parent;
+ struct mdoc_node *child;
+ struct mdoc_node *next;
+ enum mdoc_type type;
+ union mdoc_data data;
+};
+
+struct mdoc_cb {
+ int (*mdoc_err)(void *, int, int, enum mdoc_err);
+ int (*mdoc_warn)(void *, int, int, enum mdoc_warn);
+ void (*mdoc_msg)(void *, int, const char *);
+};
+
+extern const char *const *mdoc_macronames;
+extern const char *const *mdoc_argnames;
+
+__BEGIN_DECLS
+
+struct mdoc;
+
+void mdoc_free(struct mdoc *);
+struct mdoc *mdoc_alloc(void *data, const struct mdoc_cb *);
+int mdoc_parseln(struct mdoc *, char *buf);
+
+const struct mdoc_node
+ *mdoc_result(struct mdoc *);
+
+__END_DECLS
+
+#endif /*!MDOC_H*/
diff --git a/mdocml.c b/mdocml.c
index 590d3119..a84a1572 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -16,39 +16,48 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include <assert.h>
-#include <err.h>
#include <fcntl.h>
+#include <err.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "libmdocml.h"
+#include "mdoc.h"
-#define BUFFER_IN_DEF BUFSIZ /* See begin_bufs. */
-#define BUFFER_OUT_DEF BUFSIZ /* See begin_bufs. */
+#define MD_LINE_SZ (256)
-#ifdef DEBUG
-#define CSS "mdocml.css"
-#else
-#define CSS "/usr/local/share/mdocml/mdocml.css"
-#endif
+struct md_parse {
+ int warn;
+#define MD_WARN_ALL (1 << 0)
+#define MD_WARN_ERR (1 << 1)
+ int dbg;
+ struct mdoc *mdoc;
+ char *buf;
+ u_long bufsz;
+ char *name;
+ int fd;
+ int lnn;
+ char *line;
+};
static void usage(void);
-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);
+static int parse_begin(struct md_parse *);
+static int parse_leave(struct md_parse *, int);
+static int io_begin(struct md_parse *);
+static int io_leave(struct md_parse *, int);
+static int buf_begin(struct md_parse *);
+static int buf_leave(struct md_parse *, int);
+
+static int msg_err(void *, int, int, enum mdoc_err);
+static int msg_warn(void *, int, int, enum mdoc_warn);
+static void msg_msg(void *, int, const char *);
#ifdef __linux__
extern int getsubopt(char **, char *const *, char **);
@@ -58,8 +67,8 @@ int
main(int argc, char *argv[])
{
int c;
- char *out, *in, *opts, *v;
- struct md_args args;
+ struct md_parse parser;
+ char *opts, *v;
#define ALL 0
#define ERROR 1
char *toks[] = { "all", "error", NULL };
@@ -67,49 +76,22 @@ main(int argc, char *argv[])
extern char *optarg;
extern int optind;
- out = in = NULL;
+ (void)memset(&parser, 0, sizeof(struct md_parse));
- (void)memset(&args, 0, sizeof(struct md_args));
-
- args.type = MD_NOOP;
-
- while (-1 != (c = getopt(argc, argv, "c:ef:o:vW:")))
+ while (-1 != (c = getopt(argc, argv, "vW:")))
switch (c) {
- case ('c'):
- if (args.type != MD_HTML)
- errx(1, "-c only valid for -fhtml");
- args.params.html.css = optarg;
- break;
- case ('e'):
- if (args.type != MD_HTML)
- errx(1, "-e only valid for -fhtml");
- args.params.html.flags |= HTML_CSS_EMBED;
- break;
- case ('f'):
- if (0 == strcmp(optarg, "html"))
- args.type = MD_HTML;
- else if (0 == strcmp(optarg, "xml"))
- args.type = MD_XML;
- else if (0 == strcmp(optarg, "noop"))
- args.type = MD_NOOP;
- else
- errx(1, "invalid filter type");
- break;
- case ('o'):
- out = optarg;
- break;
case ('v'):
- args.verbosity++;
+ parser.dbg++;
break;
case ('W'):
opts = optarg;
while (*opts)
switch (getsubopt(&opts, toks, &v)) {
case (ALL):
- args.warnings |= MD_WARN_ALL;
+ parser.warn |= MD_WARN_ALL;
break;
case (ERROR):
- args.warnings |= MD_WARN_ERROR;
+ parser.warn |= MD_WARN_ERR;
break;
default:
usage();
@@ -121,148 +103,324 @@ main(int argc, char *argv[])
return(1);
}
- if (MD_HTML == args.type)
- if (NULL == args.params.html.css)
- args.params.html.css = CSS;
-
argv += optind;
argc -= optind;
+ parser.name = "-";
if (1 == argc)
- in = *argv++;
+ parser.name = *argv++;
+
+ if ( ! io_begin(&parser))
+ return(EXIT_FAILURE);
- return(begin_io(&args, out ? out : "-", in ? in : "-"));
+ return(EXIT_SUCCESS);
}
-/*
- * Close out file descriptors opened in begin_io. If the descriptor
- * refers to stdin/stdout, then do nothing.
- */
static int
-leave_io(const struct md_buf *out,
- const struct md_buf *in, int c)
+io_leave(struct md_parse *p, int code)
{
- assert(out);
- assert(in);
- if (-1 != in->fd && -1 == close(in->fd)) {
- assert(in->name);
- warn("%s", in->name);
- c = 1;
- }
- if (-1 != out->fd && STDOUT_FILENO != out->fd &&
- -1 == close(out->fd)) {
- assert(out->name);
- warn("%s", out->name);
- c = 1;
+ if (-1 == p->fd || STDIN_FILENO == p->fd)
+ return(code);
+
+ if (-1 == close(p->fd)) {
+ warn("%s", p->name);
+ code = 0;
}
- if (1 == c && STDOUT_FILENO != out->fd)
- if (-1 == unlink(out->name))
- warn("%s", out->name);
+ return(code);
+}
+
+
+static int
+io_begin(struct md_parse *p)
+{
+
+ p->fd = STDIN_FILENO;
+ if (0 != strncmp(p->name, "-", 1))
+ if (-1 == (p->fd = open(p->name, O_RDONLY, 0))) {
+ warn("%s", p->name);
+ return(io_leave(p, 0));
+ }
- return(c);
+ return(io_leave(p, buf_begin(p)));
}
-/*
- * Open file descriptors or assign stdin/stdout, if dictated by the "-"
- * token instead of a filename.
- */
static int
-begin_io(const struct md_args *args, char *out, char *in)
+buf_leave(struct md_parse *p, int code)
{
- struct md_buf fi;
- struct md_buf fo;
-#define FI_FL O_RDONLY
-#define FO_FL O_WRONLY|O_CREAT|O_TRUNC
+ if (p->buf)
+ free(p->buf);
+ return(code);
+}
- assert(args);
- assert(out);
- assert(in);
- bzero(&fi, sizeof(struct md_buf));
- bzero(&fo, sizeof(struct md_buf));
+static int
+buf_begin(struct md_parse *p)
+{
+ struct stat st;
- fi.fd = STDIN_FILENO;
- fo.fd = STDOUT_FILENO;
+ if (-1 == fstat(p->fd, &st)) {
+ warn("%s", p->name);
+ return(1);
+ }
- fi.name = in;
- fo.name = out;
+ p->bufsz = MAX(st.st_blksize, BUFSIZ);
- if (0 != strncmp(fi.name, "-", 1))
- if (-1 == (fi.fd = open(fi.name, FI_FL, 0))) {
- warn("%s", fi.name);
- return(leave_io(&fo, &fi, 1));
- }
+ if (NULL == (p->buf = malloc(p->bufsz))) {
+ warn("malloc");
+ return(buf_leave(p, 0));
+ }
+
+ return(buf_leave(p, parse_begin(p)));
+}
+
+
+static void
+print_node(const struct mdoc_node *n, int indent)
+{
+ const char *p, *t;
+ int i;
+
+ switch (n->type) {
+ case (MDOC_TEXT):
+ assert(NULL == n->child);
+ p = "<text>";
+ t = "text";
+ break;
+ case (MDOC_BODY):
+ p = mdoc_macronames[n->data.body.tok];
+ t = "block-body";
+ break;
+ case (MDOC_HEAD):
+ p = mdoc_macronames[n->data.head.tok];
+ t = "block-head";
+ break;
+ case (MDOC_ELEM):
+ assert(NULL == n->child);
+ p = mdoc_macronames[n->data.elem.tok];
+ t = "element";
+ break;
+ case (MDOC_BLOCK):
+ p = mdoc_macronames[n->data.block.tok];
+ t = "block";
+ break;
+ }
+
+ for (i = 0; i < indent; i++)
+ (void)printf(" ");
+ (void)printf("%s (%s)\n", p, t);
+
+ if (n->child)
+ print_node(n->child, indent + 1);
+ if (n->next)
+ print_node(n->next, indent);
+}
+
+
+static int
+parse_leave(struct md_parse *p, int code)
+{
+ const struct mdoc_node *n;
- if (0 != strncmp(fo.name, "-", 1))
- if (-1 == (fo.fd = open(fo.name, FO_FL, 0644))) {
- warn("%s", fo.name);
- return(leave_io(&fo, &fi, 1));
+ if (p->mdoc) {
+ if ((n = mdoc_result(p->mdoc)))
+ print_node(n, 0);
+ mdoc_free(p->mdoc);
+ }
+ return(code);
+}
+
+
+static int
+parse_begin(struct md_parse *p)
+{
+ ssize_t sz, i;
+ size_t pos;
+ char line[256], sv[256];
+ struct mdoc_cb cb;
+
+ cb.mdoc_err = msg_err;
+ cb.mdoc_warn = msg_warn;
+ cb.mdoc_msg = msg_msg;
+
+ if (NULL == (p->mdoc = mdoc_alloc(p, &cb)))
+ return(parse_leave(p, 0));
+
+ p->lnn = 1;
+ p->line = sv;
+
+ for (pos = 0; ; ) {
+ if (-1 == (sz = read(p->fd, p->buf, p->bufsz))) {
+ warn("%s", p->name);
+ return(parse_leave(p, 0));
+ } else if (0 == sz)
+ break;
+
+ for (i = 0; i < sz; i++) {
+ if ('\n' != p->buf[i]) {
+ if (pos < sizeof(line)) {
+ /* LINTED */
+ sv[pos] = p->buf[i];
+ line[pos++] = p->buf[i];
+ continue;
+ }
+ warnx("%s: line %d too long",
+ p->name, p->lnn);
+ return(parse_leave(p, 0));
+ }
+
+ line[(int)pos] = sv[(int)pos] = 0;
+ if ( ! mdoc_parseln(p->mdoc, line))
+ return(parse_leave(p, 0));
+
+ p->lnn++;
+ pos = 0;
}
+ }
- return(leave_io(&fo, &fi, begin_bufs(args, &fo, &fi)));
+ return(parse_leave(p, 1));
}
-/*
- * Free buffers allocated in begin_bufs.
- */
static int
-leave_bufs(const struct md_buf *out,
- const struct md_buf *in, int c)
+msg_err(void *arg, int tok, int col, enum mdoc_err type)
+{
+ char *fmt, *lit;
+ struct md_parse *p;
+ int i;
+
+ p = (struct md_parse *)arg;
+
+ fmt = lit = NULL;
+
+ switch (type) {
+ case (ERR_SYNTAX_QUOTE):
+ lit = "syntax: unterminated quotation";
+ break;
+ case (ERR_SYNTAX_WS):
+ lit = "syntax: whitespace in argument";
+ break;
+ case (ERR_SCOPE_BREAK):
+ /* Which scope is broken? */
+ fmt = "macro `%s' breaks prior explicit scope";
+ break;
+ case (ERR_MACRO_NOTSUP):
+ fmt = "macro `%s' not supported";
+ break;
+ case (ERR_MACRO_NOTCALL):
+ fmt = "macro `%s' not callable";
+ break;
+ case (ERR_ARGS_GE1):
+ fmt = "macro `%s' expects one or more arguments";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ if (fmt) {
+ (void)fprintf(stderr, "%s:%d: error: ",
+ p->name, p->lnn);
+ (void)fprintf(stderr, fmt, mdoc_macronames[tok]);
+ } else
+ (void)fprintf(stderr, "%s:%d: error: %s",
+ p->name, p->lnn, lit);
+
+ if (p->dbg < 1) {
+ (void)fprintf(stderr, " (column %d)\n", col);
+ return(0);
+ }
+
+ (void)fprintf(stderr, "\nFrom: %s\n ", p->line);
+ for (i = 0; i < col; i++)
+ (void)fprintf(stderr, " ");
+ (void)fprintf(stderr, "^\n");
+
+ return(0);
+}
+
+
+static void
+msg_msg(void *arg, int col, const char *msg)
{
- assert(out);
- assert(in);
- if (out->buf)
- free(out->buf);
- if (in->buf)
- free(in->buf);
- return(c);
+ struct md_parse *p;
+ int i;
+
+ p = (struct md_parse *)arg;
+
+ if (p->dbg < 2)
+ return;
+
+ (void)printf("%s:%d: %s", p->name, p->lnn, msg);
+
+ if (p->dbg < 3) {
+ (void)printf(" (column %d)\n", col);
+ return;
+ }
+
+ (void)printf("\nFrom: %s\n ", p->line);
+ for (i = 0; i < col; i++)
+ (void)printf(" ");
+ (void)printf("^\n");
}
-/*
- * Allocate buffers to the maximum of either the input file's blocksize
- * or BUFFER_IN_DEF/BUFFER_OUT_DEF, which should be around BUFSIZE.
- */
static int
-begin_bufs(const struct md_args *args,
- struct md_buf *out, struct md_buf *in)
+msg_warn(void *arg, int tok, int col, enum mdoc_warn type)
{
- struct stat stin, stout;
- int c;
+ char *fmt, *lit;
+ struct md_parse *p;
+ int i;
+ extern char *__progname;
- assert(args);
- assert(in);
- assert(out);
+ p = (struct md_parse *)arg;
- if (-1 == fstat(in->fd, &stin)) {
- warn("%s", in->name);
- return(1);
- } else if (STDIN_FILENO != in->fd && 0 == stin.st_size) {
- warnx("%s: empty file", in->name);
+ if ( ! (p->warn & MD_WARN_ALL))
return(1);
- } else if (-1 == fstat(out->fd, &stout)) {
- warn("%s", out->name);
- return(1);
- }
- in->bufsz = MAX(stin.st_blksize, BUFFER_IN_DEF);
- out->bufsz = MAX(stout.st_blksize, BUFFER_OUT_DEF);
+ fmt = lit = NULL;
+
+ switch (type) {
+ case (WARN_SYNTAX_WS_EOLN):
+ lit = "syntax: whitespace at end-of-line";
+ break;
+ case (WARN_SYNTAX_MACLIKE):
+ lit = "syntax: macro-like argument";
+ break;
+ case (WARN_ARGS_GE1):
+ fmt = "macro `%s' suggests one or more arguments";
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
- if (NULL == (in->buf = malloc(in->bufsz))) {
- warn("malloc");
- return(leave_bufs(out, in, 1));
- } else if (NULL == (out->buf = malloc(out->bufsz))) {
- warn("malloc");
- return(leave_bufs(out, in, 1));
+ if (fmt) {
+ (void)fprintf(stderr, "%s:%d: warning: ",
+ p->name, p->lnn);
+ (void)fprintf(stderr, fmt, mdoc_macronames[tok]);
+ } else
+ (void)fprintf(stderr, "%s:%d: warning: %s",
+ p->name, p->lnn, lit);
+
+ if (p->dbg >= 1) {
+ (void)fprintf(stderr, "\nFrom: %s\n ", p->line);
+ for (i = 0; i < col; i++)
+ (void)fprintf(stderr, " ");
+ (void)fprintf(stderr, "^\n");
+ } else
+ (void)fprintf(stderr, " (column %d)\n", col);
+
+ if (p->warn & MD_WARN_ERR) {
+ (void)fprintf(stderr, "%s: considering warnings as "
+ "errors\n", __progname);
+ return(0);
}
- c = md_run(args, out, in);
- return(leave_bufs(out, in, -1 == c ? 1 : 0));
+ return(1);
}
@@ -271,8 +429,7 @@ usage(void)
{
extern char *__progname;
- (void)fprintf(stderr, "usage: %s [-v] [-Wwarn...] "
- "[-f filter] [-o outfile] [infile]\n",
+ (void)fprintf(stderr, "usage: %s [-v] [-Wwarn...] [infile]\n",
__progname);
}
diff --git a/mdocml.css b/mdocml.css
deleted file mode 100644
index 05f7906a..00000000
--- a/mdocml.css
+++ /dev/null
@@ -1,58 +0,0 @@
- body { margin: 10px;
- font-family: Tahoma, sans-serif;
- font-size: small; }
- h1 { font-size: small; }
- h2 { font-size: small; }
- div.mdoc { width: 600px; }
- div.block-Sh { margin-bottom: 20px; }
- div.head-Ss { font-weight: bold;
- margin-top: 10px;
- text-align: justify; }
- div.body-Sh { margin-left: 20px;
- margin-top: 10px;
- text-align: justify; }
- table.header-table { margin-bottom: 10px; }
- td.header-section { text-transform: uppercase; }
- span.inline-Nd:before { content: ' \2014 '; }
- span.inline-Fl:before { content: '-'; }
- span.inline-Fl { font-weight: bolder; }
- span.inline-Cm { font-weight: bolder; }
- span.inline-Cd { font-weight: bolder; }
- span.inline-Nm { font-weight: bolder; }
- span.inline-An { text-decoration: underline; }
- span.inline-Ar { text-decoration: underline; }
- span.inline-Pa { text-decoration: underline; }
- div.block-Bl { margin-top: 10px;
- margin-left: 20px; }
- div.inline-Pp { margin-bottom: 10px; }
- span.inline-Sy { font-weight: bolder; }
- span.inline-Tn { font-variant: small-caps; }
- div.inline-D1 { margin-left: 20px; }
- div.inline-Dl { margin-left: 20px; }
- span.head-Fo { font-weight: bolder; }
- span.body-Fo:before { content: '('; }
- span.body-Fo:after { content: ')'; }
- span.body-Oo:before { content: '['; }
- span.body-Oo:after { content: ']'; }
- span.inline-Va { text-decoration: underline; }
- span.inline-Vt { text-decoration: underline; }
- span.inline-Em { font-style: italic; }
- span.inline-Ft { text-decoration: underline; }
- span.inline-Fd { font-weight: bolder; }
- span.inline-Ic { font-weight: bolder; }
- span.inline-Op:before { content: '['; }
- span.inline-Op:after { content: ']'; }
- span.inline-Qq:before { content: '\"'; }
- span.inline-Qq:after { content: '\"'; }
- span.inline-Aq:before { content: '\3c'; }
- span.inline-Aq:after { content: '\3e'; }
- span.inline-Bq:before { content: '['; }
- span.inline-Bq:after { content: ']'; }
- span.inline-Dq:before { content: '\201c'; }
- span.inline-Dq:after { content: '\201d'; }
- span.inline-Pq:before { content: '('; }
- span.inline-Pq:after { content: ')'; }
- span.inline-Ql:before { content: '\2018'; }
- span.inline-Ql:after { content: '\2019'; }
- span.inline-Sq:before { content: '\2018'; }
- span.inline-Sq:after { content: '\2019'; }
diff --git a/ml.c b/ml.c
deleted file mode 100644
index f908fbe8..00000000
--- a/ml.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ml.h"
-
-#ifdef __linux__
-extern size_t strlcat(char *, const char *, size_t);
-extern size_t strlcpy(char *, const char *, size_t);
-#endif
-
-
-int
-ml_putstring(struct md_mbuf *p, const char *buf, size_t *pos)
-{
-
- return(ml_nputstring(p, buf, strlen(buf), pos));
-}
-
-
-int
-ml_nputstring(struct md_mbuf *p,
- const char *buf, size_t sz, size_t *pos)
-{
- int i, v;
- const char *seq;
- size_t ssz;
-
- for (i = 0; i < (int)sz; i++) {
- switch (buf[i]) {
-
- /* Escaped value. */
- case ('\\'):
- if (-1 == (v = rofftok_scan(buf, &i)))
- return(0);
-
- switch (v) {
- case (ROFFTok_Sp_A):
- seq = "\\a";
- ssz = 2;
- break;
- case (ROFFTok_Sp_B):
- seq = "\\b";
- ssz = 2;
- break;
- case (ROFFTok_Sp_F):
- seq = "\\f";
- ssz = 2;
- break;
- case (ROFFTok_Sp_N):
- seq = "\\n";
- ssz = 2;
- break;
- case (ROFFTok_Sp_R):
- seq = "\\r";
- ssz = 2;
- break;
- case (ROFFTok_Sp_T):
- seq = "\\t";
- ssz = 2;
- break;
- case (ROFFTok_Sp_V):
- seq = "\\v";
- ssz = 2;
- break;
- case (ROFFTok_Sp_0):
- seq = "\\0";
- ssz = 2;
- break;
- case (ROFFTok_Space):
- seq = "&nbsp;";
- ssz = 6;
- break;
- case (ROFFTok_Hyphen):
- seq = "&#8208;";
- ssz = 7;
- break;
- case (ROFFTok_Em):
- seq = "&#8212;";
- ssz = 7;
- break;
- case (ROFFTok_En):
- seq = "&#8211;";
- ssz = 7;
- break;
- case (ROFFTok_Ge):
- seq = "&#8805;";
- ssz = 7;
- break;
- case (ROFFTok_Le):
- seq = "&#8804;";
- ssz = 7;
- break;
- case (ROFFTok_Rquote):
- seq = "&#8221;";
- ssz = 7;
- break;
- case (ROFFTok_Lquote):
- seq = "&#8220;";
- ssz = 7;
- break;
- case (ROFFTok_Uparrow):
- seq = "&#8593;";
- ssz = 7;
- break;
- case (ROFFTok_Acute):
- seq = "&#180;";
- ssz = 6;
- break;
- case (ROFFTok_Grave):
- seq = "&#96;";
- ssz = 5;
- break;
- case (ROFFTok_Pi):
- seq = "&#960;";
- ssz = 6;
- break;
- case (ROFFTok_Ne):
- seq = "&#8800;";
- ssz = 7;
- break;
- case (ROFFTok_Lt):
- seq = "&lt;";
- ssz = 4;
- break;
- case (ROFFTok_Gt):
- seq = "&gt;";
- ssz = 4;
- break;
- case (ROFFTok_Plusmin):
- seq = "&#177;";
- ssz = 6;
- break;
- case (ROFFTok_Infty):
- seq = "&#8734;";
- ssz = 7;
- break;
- case (ROFFTok_Bar):
- seq = "&#124;";
- ssz = 6;
- break;
- case (ROFFTok_Nan):
- seq = "Nan";
- ssz = 3;
- break;
- case (ROFFTok_Quote):
- seq = "&quot;";
- ssz = 6;
- break;
- case (ROFFTok_Slash):
- seq = "\\";
- ssz = 1;
- break;
- case (ROFFTok_Null):
- seq = "";
- ssz = 0;
- break;
- default:
- return(0);
- }
- break;
-
- /* Ampersand ml-escape. */
- case ('&'):
- seq = "&amp;";
- ssz = 5;
- break;
-
- /* Quotation ml-escape. */
- case ('"'):
- seq = "&quot;";
- ssz = 6;
- break;
-
- /* Lt ml-escape. */
- case ('<'):
- seq = "&lt;";
- ssz = 4;
- break;
-
- /* Gt ml-escape. */
- case ('>'):
- seq = "&gt;";
- ssz = 4;
- break;
-
- default:
- seq = &buf[i];
- ssz = 1;
- break;
- }
-
- if (ssz > 0 && ! ml_nputs(p, seq, ssz, pos))
- return(-1);
- }
- return(1);
-}
-
-
-int
-ml_nputs(struct md_mbuf *p, const char *buf, size_t sz, size_t *pos)
-{
-
- if (0 == sz)
- return(1);
-
- if ( ! md_buf_puts(p, buf, sz))
- return(0);
-
- if (pos)
- *pos += sz;
- return(1);
-}
-
-
-int
-ml_puts(struct md_mbuf *p, const char *buf, size_t *pos)
-{
- size_t sz;
-
- if (0 == (sz = strlen(buf)))
- return(1);
-
- if ( ! md_buf_puts(p, buf, sz))
- return(0);
-
- if (pos)
- *pos += sz;
- return(1);
-}
-
-
-int
-ml_putchars(struct md_mbuf *p, char buf, size_t count, size_t *pos)
-{
- size_t i;
-
- for (i = 0; i < count; i++)
- if ( ! ml_nputs(p, &buf, 1, pos))
- return(0);
-
- return(1);
-}
diff --git a/ml.h b/ml.h
deleted file mode 100644
index 637a1d7a..00000000
--- a/ml.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 ML_H
-#define ML_H
-
-#include "private.h"
-
-#define COLUMNS 72
-#define INDENT_SZ 4
-#define INDENT(x) ((x) > MAXINDENT ? MAXINDENT : (x))
-#define MAXINDENT 10
-
-struct md_mlg;
-
-enum md_ns {
- MD_NS_BLOCK,
- MD_NS_HEAD,
- MD_NS_BODY,
- MD_NS_INLINE,
- MD_NS_DEFAULT
-};
-
-enum ml_scope {
- ML_OPEN,
- ML_CLOSE
-};
-
-struct ml_args {
- const struct md_args *args;
- const struct md_rbuf *rbuf;
- struct md_mbuf *mbuf;
- int section;
- void *data;
-};
-
-struct ml_cbs {
- int (*ml_begin)(struct ml_args *, const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
- int (*ml_end)(struct ml_args *, const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
- ssize_t (*ml_beginstring)(struct ml_args *,
- const char *, size_t);
- ssize_t (*ml_endstring)(struct ml_args *,
- const char *, size_t);
- ssize_t (*ml_endtag)(struct ml_args *, enum md_ns, int);
- ssize_t (*ml_begintag)(struct ml_args *, enum md_ns, int,
- const int *, const char **);
- int (*ml_alloc)(void **);
- void (*ml_free)(void *);
-};
-
-__BEGIN_DECLS
-
-int ml_putstring(struct md_mbuf *,
- const char *, size_t *);
-int ml_nputstring(struct md_mbuf *,
- const char *, size_t, size_t *);
-int ml_nputs(struct md_mbuf *,
- const char *, size_t, size_t *);
-int ml_puts(struct md_mbuf *, const char *, size_t *);
-int ml_putchars(struct md_mbuf *,
- char, size_t, size_t *);
-
-struct md_mlg *mlg_alloc(const struct md_args *,
- const struct md_rbuf *, struct md_mbuf *,
- const struct ml_cbs *);
-int mlg_exit(struct md_mlg *, int);
-int mlg_line(struct md_mlg *, char *);
-
-int ml_tagput(struct md_mbuf *,
- enum ml_scope, const char *, size_t *);
-
-__END_DECLS
-
-#endif /*!ML_H*/
diff --git a/mlg.c b/mlg.c
deleted file mode 100644
index b58136c6..00000000
--- a/mlg.c
+++ /dev/null
@@ -1,868 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <ctype.h>
-#include <err.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "ml.h"
-
-/* TODO: literal tokens. */
-
-enum md_tok {
- MD_TEXT,
- MD_INLINE_IN,
- MD_INLINE_OUT,
- MD_BLK_IN,
- MD_BLK_OUT
-};
-
-struct md_mlg {
- struct ml_args args;
- struct rofftree *tree;
- size_t indent;
- size_t pos;
- enum md_tok last;
- void *arg;
- struct ml_cbs cbs;
- int flags;
-#define ML_OVERRIDE_ONE (1 << 0)
-#define ML_OVERRIDE_ALL (1 << 1)
-};
-
-static int mlg_roffmsg(void *arg,
- enum roffmsg, const char *,
- const char *, const char *);
-static int mlg_roffhead(void *, const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
-static int mlg_rofftail(void *, const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
-static int mlg_roffin(void *, int,
- int *, const char **);
-static int mlg_roffdata(void *, int,
- const char *, const char *);
-static int mlg_roffout(void *, int);
-static int mlg_roffblkin(void *, int, int *,
- const char **);
-static int mlg_roffblkout(void *, int);
-static int mlg_roffspecial(void *, int,
- const char *, const int *,
- const char **, const char **);
-static int mlg_roffblkheadin(void *, int,
- int *, const char **);
-static int mlg_roffblkheadout(void *, int);
-static int mlg_roffblkbodyin(void *, int,
- int *, const char **);
-static int mlg_roffblkbodyout(void *, int);
-
-static int mlg_ref_special(struct md_mlg *, int,
- const char *, const char **);
-static int mlg_formatted_special(struct md_mlg *,
- int, const char *, const int *,
- const char **, const char **);
-static int mlg_literal_special(struct md_mlg *,
- int, const char *, const int *,
- const char **, const char **);
-static int mlg_function_special(struct md_mlg *,
- const char *, const char **);
-static int mlg_atom_special(struct md_mlg *, int,
- const char *, const char **);
-static int mlg_link_special(struct md_mlg *, int,
- const char *, const char **);
-static int mlg_anchor_special(struct md_mlg *,
- int, const char **);
-
-static int mlg_begintag(struct md_mlg *, enum md_ns,
- int, int *, const char **);
-static int mlg_endtag(struct md_mlg *, enum md_ns, int);
-static int mlg_indent(struct md_mlg *);
-static int mlg_newline(struct md_mlg *);
-static void mlg_mode(struct md_mlg *, enum md_tok);
-static int mlg_nstring(struct md_mlg *,
- const char *, const char *, size_t);
-static int mlg_string(struct md_mlg *,
- const char *, const char *);
-static int mlg_data(struct md_mlg *, int,
- const char *, const char *);
-static int mlg_err(struct md_mlg *, const char *,
- const char *, const char *, ...);
-static int mlg_msg(struct md_mlg *,
- enum roffmsg, const char *,
- const char *, const char *);
-static int mlg_vmsg(struct md_mlg *, enum roffmsg,
- const char *, const char *,
- const char *, va_list);
-
-#ifdef __linux__
-extern size_t strlcat(char *, const char *, size_t);
-extern size_t strlcpy(char *, const char *, size_t);
-#endif
-
-
-static int
-mlg_begintag(struct md_mlg *p, enum md_ns ns, int tok,
- int *argc, const char **argv)
-{
- ssize_t res;
-
- assert(MD_NS_DEFAULT != ns);
-
- switch (ns) {
- case (MD_NS_INLINE):
- if ( ! (ML_OVERRIDE_ONE & p->flags) &&
- ! (ML_OVERRIDE_ALL & p->flags) &&
- p->pos + 11 >= COLUMNS)
- if ( ! mlg_newline(p))
- return(0);
- if (0 != p->pos && (MD_TEXT == p->last ||
- MD_INLINE_OUT == p->last)
- && ! (ML_OVERRIDE_ONE & p->flags)
- && ! (ML_OVERRIDE_ALL & p->flags))
- if ( ! ml_nputs(p->args.mbuf, " ", 1, &p->pos))
- return(0);
- if (0 == p->pos && ! mlg_indent(p))
- return(0);
- mlg_mode(p, MD_INLINE_IN);
- break;
- default:
- if (0 != p->pos) {
- if ( ! mlg_newline(p))
- return(0);
- if ( ! mlg_indent(p))
- return(0);
- } else if ( ! mlg_indent(p))
- return(0);
- p->indent++;
- mlg_mode(p, MD_BLK_IN);
- break;
- }
-
- if ( ! ml_nputs(p->args.mbuf, "<", 1, &p->pos))
- return(0);
-
- res = (*p->cbs.ml_begintag)(&p->args, ns, tok, argc, argv);
- if (-1 == res)
- return(0);
-
- assert(res >= 0);
- p->pos += (size_t)res;
-
- if ( ! ml_nputs(p->args.mbuf, ">", 1, &p->pos))
- return(0);
-
- switch (ns) {
- case (MD_NS_INLINE):
- break;
- default:
- if ( ! mlg_newline(p))
- return(0);
- break;
- }
-
- return(1);
-}
-
-
-static int
-mlg_endtag(struct md_mlg *p, enum md_ns ns, int tok)
-{
- ssize_t res;
-
- assert(MD_NS_DEFAULT != ns);
-
- switch (ns) {
- case (MD_NS_INLINE):
- break;
- default:
- p->indent--;
- if (0 != p->pos) {
- if ( ! mlg_newline(p))
- return(0);
- if ( ! mlg_indent(p))
- return(0);
- } else if ( ! mlg_indent(p))
- return(0);
- break;
- }
-
- if ( ! ml_nputs(p->args.mbuf, "</", 2, &p->pos))
- return(0);
-
- res = (*p->cbs.ml_endtag)(&p->args, ns, tok);
- if (-1 == res)
- return(0);
-
- assert(res >= 0);
- p->pos += (size_t)res;
-
- if ( ! ml_nputs(p->args.mbuf, ">", 1, &p->pos))
- return(0);
-
- switch (ns) {
- case (MD_NS_INLINE):
- mlg_mode(p, MD_INLINE_OUT);
- break;
- default:
- mlg_mode(p, MD_BLK_OUT);
- break;
- }
-
- return(1);
-}
-
-
-static int
-mlg_indent(struct md_mlg *p)
-{
-
- assert(0 == p->pos);
- return(ml_putchars(p->args.mbuf, ' ', INDENT_SZ *
- INDENT(p->indent), &p->pos));
-}
-
-
-static int
-mlg_newline(struct md_mlg *p)
-{
-
- p->pos = 0;
- return(ml_nputs(p->args.mbuf, "\n", 1, NULL));
-}
-
-
-static void
-mlg_mode(struct md_mlg *p, enum md_tok ns)
-{
-
- p->flags &= ~ML_OVERRIDE_ONE;
- p->last = ns;
-}
-
-
-static int
-mlg_string(struct md_mlg *p, const char *start, const char *buf)
-{
-
- return(mlg_nstring(p, start, buf, strlen(buf)));
-}
-
-
-static int
-mlg_nstring(struct md_mlg *p, const char *start,
- const char *buf, size_t sz)
-{
- int c;
- ssize_t res;
-
- assert(p->args.mbuf);
- assert(0 != p->indent);
-
- res = (*p->cbs.ml_beginstring)(&p->args, buf, sz);
- if (-1 == res)
- return(0);
-
- if (0 == (c = ml_nputstring(p->args.mbuf, buf, sz, &p->pos)))
- return(mlg_err(p, start, buf, "bad string "
- "encoding: `%s'", buf));
- else if (-1 == c)
- return(0);
-
- res = (*p->cbs.ml_endstring)(&p->args, buf, sz);
- if (-1 == res)
- return(0);
-
- return(1);
-}
-
-
-static int
-mlg_data(struct md_mlg *p, int space,
- const char *start, const char *buf)
-{
- size_t sz;
-
- assert(p->args.mbuf);
- assert(0 != p->indent);
-
- if (ML_OVERRIDE_ONE & p->flags ||
- ML_OVERRIDE_ALL & p->flags)
- space = 0;
-
- sz = strlen(buf);
-
- if (0 == p->pos) {
- if ( ! mlg_indent(p))
- return(0);
- if ( ! mlg_nstring(p, start, buf, sz))
- return(0);
-
- if (INDENT(p->indent) * INDENT_SZ + sz >= COLUMNS)
- if ( ! mlg_newline(p))
- return(0);
-
- return(1);
- }
-
- if (space && sz + p->pos >= COLUMNS) {
- if ( ! mlg_newline(p))
- return(0);
- if ( ! mlg_indent(p))
- return(0);
- } else if (space) {
- if ( ! ml_nputs(p->args.mbuf, " ", 1, &p->pos))
- return(0);
- }
-
- return(mlg_nstring(p, start, buf, sz));
-}
-
-
-int
-mlg_line(struct md_mlg *p, char *buf)
-{
-
- return(roff_engine(p->tree, buf));
-}
-
-
-int
-mlg_exit(struct md_mlg *p, int flush)
-{
- int c;
-
- c = roff_free(p->tree, flush);
- (*p->cbs.ml_free)(p->args.data);
-
- free(p);
-
- return(c);
-}
-
-
-struct md_mlg *
-mlg_alloc(const struct md_args *args,
- const struct md_rbuf *rbuf,
- struct md_mbuf *mbuf,
- const struct ml_cbs *cbs)
-{
- struct roffcb cb;
- struct md_mlg *p;
-
- cb.roffhead = mlg_roffhead;
- cb.rofftail = mlg_rofftail;
- cb.roffin = mlg_roffin;
- cb.roffout = mlg_roffout;
- cb.roffblkin = mlg_roffblkin;
- cb.roffblkheadin = mlg_roffblkheadin;
- cb.roffblkheadout = mlg_roffblkheadout;
- cb.roffblkbodyin = mlg_roffblkbodyin;
- cb.roffblkbodyout = mlg_roffblkbodyout;
- cb.roffblkout = mlg_roffblkout;
- cb.roffspecial = mlg_roffspecial;
- cb.roffmsg = mlg_roffmsg;
- cb.roffdata = mlg_roffdata;
-
- if (NULL == (p = calloc(1, sizeof(struct md_mlg))))
- err(1, "calloc");
-
- p->args.args = args;
- p->args.mbuf = mbuf;
- p->args.rbuf = rbuf;
-
- (void)memcpy(&p->cbs, cbs, sizeof(struct ml_cbs));
-
- if (NULL == (p->tree = roff_alloc(&cb, p)))
- free(p);
- else if ( ! (*p->cbs.ml_alloc)(&p->args.data))
- free(p);
- else
- return(p);
-
- return(NULL);
-}
-
-
-static int
-mlg_roffhead(void *arg, const struct tm *tm, const char *os,
- const char *title, enum roffmsec sec, enum roffvol vol)
-{
- struct md_mlg *p;
-
- assert(arg);
- p = (struct md_mlg *)arg;
-
- mlg_mode(p, MD_BLK_IN);
-
- if ( ! (*p->cbs.ml_begin)(&p->args, tm, os, title, sec, vol))
- return(0);
-
- p->indent++;
- return(mlg_newline(p));
-}
-
-
-static int
-mlg_rofftail(void *arg, const struct tm *tm, const char *os,
- const char *title, enum roffmsec sec, enum roffvol vol)
-{
- struct md_mlg *p;
-
- assert(arg);
- p = (struct md_mlg *)arg;
-
- if (0 != p->pos)
- if ( ! mlg_newline(p))
- return(0);
-
- if ( ! (*p->cbs.ml_end)(&p->args, tm, os, title, sec, vol))
- return(0);
-
- mlg_mode(p, MD_BLK_OUT);
- return(mlg_newline(p));
-}
-
-
-static int
-mlg_literal_special(struct md_mlg *p, int tok, const char *start,
- const int *argc, const char **argv, const char **more)
-{
- char *lit;
-
- if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, more))
- return(0);
-
- lit = roff_literal(tok, argc, argv, more);
- assert(lit);
-
- if ( ! mlg_string(p, start, lit))
- return(0);
-
- while (*more) {
- if ( ! ml_nputs(p->args.mbuf, " ", 1, &p->pos))
- return(0);
- if ( ! mlg_string(p, start, *more++))
- return(0);
- }
-
- return(mlg_endtag(p, MD_NS_INLINE, tok));
-}
-
-
-static int
-mlg_ref_special(struct md_mlg *p, int tok,
- const char *start, const char **more)
-{
-
- if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, more))
- return(0);
-
- assert(*more);
- if ( ! ml_puts(p->args.mbuf, *more++, &p->pos))
- return(0);
-
- if (*more) {
- if ( ! ml_nputs(p->args.mbuf, "(", 1, &p->pos))
- return(0);
- if ( ! mlg_string(p, start, *more++))
- return(0);
- if ( ! ml_nputs(p->args.mbuf, ")", 1, &p->pos))
- return(0);
- }
-
- assert(NULL == *more);
- return(mlg_endtag(p, MD_NS_INLINE, tok));
-}
-
-
-/* ARGSUSED */
-static int
-mlg_formatted_special(struct md_mlg *p, int tok, const char *start,
- const int *argc, const char **argv, const char **more)
-{
- char buf[256], *lit;
-
- if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, more))
- return(0);
-
- lit = roff_fmtstring(tok);
-
- assert(lit);
- assert(*more);
- (void)snprintf(buf, sizeof(buf), lit, *more++);
- assert(NULL == *more);
-
- if ( ! mlg_string(p, start, buf))
- return(0);
-
- return(mlg_endtag(p, MD_NS_INLINE, tok));
-}
-
-
-static int
-mlg_atom_special(struct md_mlg *p, int tok,
- const char *start, const char **more)
-{
-
- if (ROFFSec_SYNOP == p->args.section) {
- if ( ! mlg_begintag(p, MD_NS_INLINE, ROFF_Pp, NULL, more))
- return(0);
- if ( ! mlg_endtag(p, MD_NS_INLINE, ROFF_Pp))
- return(0);
- }
-
- if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, more))
- return(0);
-
- assert(*more);
- if ( ! mlg_string(p, start, *more++))
- return(0);
-
- return(mlg_endtag(p, MD_NS_INLINE, tok));
-}
-
-
-static int
-mlg_function_special(struct md_mlg *p,
- const char *start, const char **more)
-{
-
- assert(*more);
-
- if ( ! mlg_begintag(p, MD_NS_INLINE, ROFF_Fn, NULL, more))
- return(0);
- if ( ! mlg_string(p, start, *more++))
- return(0);
- if ( ! mlg_endtag(p, MD_NS_INLINE, ROFF_Fn))
- return(0);
-
- if (NULL == *more)
- return(1);
-
- if ( ! ml_nputs(p->args.mbuf, "(", 1, &p->pos))
- return(0);
-
- p->flags |= ML_OVERRIDE_ONE;
-
- if ( ! mlg_begintag(p, MD_NS_INLINE, ROFF_Fa, NULL, more))
- return(0);
- if ( ! mlg_string(p, start, *more++))
- return(0);
- if ( ! mlg_endtag(p, MD_NS_INLINE, ROFF_Fa))
- return(0);
-
- while (*more) {
- if ( ! ml_nputs(p->args.mbuf, ", ", 2, &p->pos))
- return(0);
- if ( ! mlg_begintag(p, MD_NS_INLINE, ROFF_Fa, NULL, more))
- return(0);
- if ( ! mlg_string(p, start, *more++))
- return(0);
- if ( ! mlg_endtag(p, MD_NS_INLINE, ROFF_Fa))
- return(0);
- }
-
- return(ml_nputs(p->args.mbuf, ")", 1, &p->pos));
-}
-
-
-static int
-mlg_anchor_special(struct md_mlg *p, int tok, const char **more)
-{
- if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, more))
- return(0);
- return(mlg_endtag(p, MD_NS_INLINE, tok));
-}
-
-
-static int
-mlg_link_special(struct md_mlg *p, int tok,
- const char *start, const char **more)
-{
-
- if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, more))
- return(0);
- if ( ! mlg_string(p, start, *more++))
- return(0);
- while (*more) {
- if ( ! mlg_string(p, start, " "))
- return(0);
- if ( ! mlg_string(p, start, *more++))
- return(0);
- }
- return(mlg_endtag(p, MD_NS_INLINE, tok));
-}
-
-
-/* ARGSUSED */
-static int
-mlg_roffspecial(void *arg, int tok, const char *start,
- const int *argc, const char **argv, const char **more)
-{
- struct md_mlg *p;
-
- assert(arg);
- p = (struct md_mlg *)arg;
-
- switch (tok) {
- case (ROFF_Ns):
- p->flags |= ML_OVERRIDE_ONE;
- return(1);
-
- case (ROFF_Sm):
- assert(*more);
- if (0 == strcmp(*more, "on"))
- p->flags |= ML_OVERRIDE_ALL;
- else
- p->flags &= ~ML_OVERRIDE_ALL;
- return(1);
-
- case (ROFF_Fn):
- return(mlg_function_special(p, start, more));
-
- case (ROFF_Xr):
- return(mlg_ref_special(p, tok, start, more));
-
- case (ROFF_Sh):
- p->args.section = roff_sec(more);
- return(mlg_anchor_special(p, tok, more));
-
- case (ROFF_Sx):
- return(mlg_link_special(p, tok, start, more));
-
- case (ROFF_Nm):
- return(mlg_atom_special(p, tok, start, more));
-
- case (ROFF_In):
- /* NOTREACHED */
- case (ROFF_Ex):
- /* NOTREACHED */
- case (ROFF_Rv):
- return(mlg_formatted_special(p, tok, start,
- argc, argv, more));
-
- case (ROFF_At):
- /* FALLTHROUGH */
- case (ROFF_Bt):
- /* FALLTHROUGH */
- case (ROFF_Ud):
- /* FALLTHROUGH */
- case (ROFF_Ux):
- /* FALLTHROUGH */
- case (ROFF_Bx):
- /* FALLTHROUGH */
- case (ROFF_Bsx):
- /* FALLTHROUGH */
- case (ROFF_Fx):
- /* FALLTHROUGH */
- case (ROFF_Nx):
- /* FALLTHROUGH */
- case (ROFF_St):
- /* FALLTHROUGH */
- case (ROFF_Ox):
- return(mlg_literal_special(p, tok, start,
- argc, argv, more));
- default:
- break;
- }
-
- return(mlg_err(p, start, start, "`%s' not yet supported",
- toknames[tok]));
-}
-
-
-static int
-mlg_roffblkin(void *arg, int tok,
- int *argc, const char **argv)
-{
-
- return(mlg_begintag((struct md_mlg *)arg,
- MD_NS_BLOCK, tok, argc, argv));
-}
-
-
-static int
-mlg_roffblkout(void *arg, int tok)
-{
-
- return(mlg_endtag((struct md_mlg *)arg, MD_NS_BLOCK, tok));
-}
-
-
-static int
-mlg_roffblkbodyin(void *arg, int tok,
- int *argc, const char **argv)
-{
-
- return(mlg_begintag((struct md_mlg *)arg,
- MD_NS_BODY, tok, argc, argv));
-}
-
-
-static int
-mlg_roffblkbodyout(void *arg, int tok)
-{
-
- return(mlg_endtag((struct md_mlg *)arg, MD_NS_BODY, tok));
-}
-
-
-static int
-mlg_roffblkheadin(void *arg, int tok,
- int *argc, const char **argv)
-{
-
- return(mlg_begintag((struct md_mlg *)arg,
- MD_NS_HEAD, tok, argc, argv));
-}
-
-
-static int
-mlg_roffblkheadout(void *arg, int tok)
-{
-
- return(mlg_endtag((struct md_mlg *)arg, MD_NS_HEAD, tok));
-}
-
-
-static int
-mlg_roffin(void *arg, int tok, int *argc, const char **argv)
-{
-
- return(mlg_begintag((struct md_mlg *)arg,
- MD_NS_INLINE, tok, argc, argv));
-}
-
-
-static int
-mlg_roffout(void *arg, int tok)
-{
-
- return(mlg_endtag((struct md_mlg *)arg, MD_NS_INLINE, tok));
-}
-
-
-static int
-mlg_roffmsg(void *arg, enum roffmsg lvl, const char *buf,
- const char *pos, const char *msg)
-{
-
- return(mlg_msg((struct md_mlg *)arg, lvl, buf, pos, msg));
-}
-
-
-static int
-mlg_roffdata(void *arg, int space,
- const char *start, const char *buf)
-{
- struct md_mlg *p;
-
- assert(arg);
- p = (struct md_mlg *)arg;
-
- if ( ! mlg_data(p, space, start, buf))
- return(0);
-
- mlg_mode(p, MD_TEXT);
- return(1);
-}
-
-
-static int
-mlg_vmsg(struct md_mlg *p, enum roffmsg lvl, const char *start,
- const char *pos, const char *fmt, va_list ap)
-{
- char buf[128];
-
- (void)vsnprintf(buf, sizeof(buf), fmt, ap);
- return(mlg_msg(p, lvl, start, pos, buf));
-}
-
-
-static int
-mlg_err(struct md_mlg *p, const char *start,
- const char *pos, const char *fmt, ...)
-{
- va_list ap;
- int c;
-
- va_start(ap, fmt);
- c = mlg_vmsg(p, ROFF_ERROR, start, pos, fmt, ap);
- va_end(ap);
- return(c);
-}
-
-
-static int
-mlg_msg(struct md_mlg *p, enum roffmsg lvl,
- const char *buf, const char *pos, const char *msg)
-{
- char *level, b[256];
- size_t sz;
- int i;
-
- sz = sizeof(b);
-
- switch (lvl) {
- case (ROFF_WARN):
- level = "warning";
- if ( ! (MD_WARN_ALL & p->args.args->warnings))
- return(1);
- break;
- case (ROFF_ERROR):
- level = "error";
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- if (pos) {
- assert(pos >= buf);
- if (0 < p->args.args->verbosity) {
- (void)snprintf(b, sz, "%s:%zu: %s: %s\n",
- p->args.rbuf->name,
- p->args.rbuf->line,
- level, msg);
-
- (void)strlcat(b, "Error at: ", sz);
- (void)strlcat(b, p->args.rbuf->linebuf, sz);
- (void)strlcat(b, "\n ", sz);
-
- for (i = 0; i < pos - buf; i++)
- (void)strlcat(b, " ", sz);
-
- (void)strlcat(b, "^", sz);
- } else
- (void)snprintf(b, sz, "%s:%zu: %s: %s (%zu)",
- p->args.rbuf->name,
- p->args.rbuf->line,
- level, msg, pos - buf);
- } else
- (void)snprintf(b, sz, "%s: %s: %s",
- p->args.rbuf->name, level, msg);
-
- (void)fprintf(stderr, "%s\n", b);
- return(lvl == ROFF_WARN ? 1 : 0);
-}
-
diff --git a/noop.c b/noop.c
deleted file mode 100644
index 520bd797..00000000
--- a/noop.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <err.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "private.h"
-
-
-struct md_noop {
- const struct md_args *args;
- const struct md_rbuf *rbuf;
- struct rofftree *tree;
-};
-
-
-static int noop_roffmsg(void *arg,
- enum roffmsg, const char *,
- const char *, const char *);
-static int noop_roffhead(void *, const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
-static int noop_rofftail(void *, const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
-static int noop_roffin(void *, int,
- int *, const char **);
-static int noop_roffdata(void *, int,
- const char *, const char *);
-static int noop_roffout(void *, int);
-static int noop_roffblkin(void *, int, int *,
- const char **);
-static int noop_roffblkout(void *, int);
-static int noop_roffspecial(void *, int,
- const char *, const int *,
- const char **, const char **);
-static int noop_roffblkheadin(void *, int,
- int *, const char **);
-static int noop_roffblkheadout(void *, int);
-static int noop_roffblkbodyin(void *, int,
- int *, const char **);
-static int noop_roffblkbodyout(void *, int);
-
-#ifdef __linux__
-extern size_t strlcat(char *, const char *, size_t);
-extern size_t strlcpy(char *, const char *, size_t);
-#endif
-
-
-int
-md_exit_noop(void *data, int flush)
-{
- struct md_noop *noop;
- int c;
-
- noop = (struct md_noop *)data;
- c = roff_free(noop->tree, flush);
- free(noop);
- return(c);
-}
-
-
-int
-md_line_noop(void *data, char *buf)
-{
- struct md_noop *noop;
-
- noop = (struct md_noop *)data;
- return(roff_engine(noop->tree, buf));
-}
-
-
-/* ARGSUSED */
-void *
-md_init_noop(const struct md_args *args,
- struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
-{
- struct roffcb cb;
- struct md_noop *noop;
-
- if (NULL == (noop = calloc(1, sizeof(struct md_noop))))
- err(1, "calloc");
-
- noop->args = args;
- noop->rbuf = rbuf;
-
- cb.roffhead = noop_roffhead;
- cb.rofftail = noop_rofftail;
- cb.roffin = noop_roffin;
- cb.roffout = noop_roffout;
- cb.roffblkin = noop_roffblkin;
- cb.roffblkheadin = noop_roffblkheadin;
- cb.roffblkheadout = noop_roffblkheadout;
- cb.roffblkbodyin = noop_roffblkbodyin;
- cb.roffblkbodyout = noop_roffblkbodyout;
- cb.roffblkout = noop_roffblkout;
- cb.roffspecial = noop_roffspecial;
- cb.roffmsg = noop_roffmsg;
- cb.roffdata = noop_roffdata;
-
- if (NULL == (noop->tree = roff_alloc(&cb, noop))) {
- free(noop);
- return(NULL);
- }
- return(noop);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffhead(void *arg, const struct tm *tm, const char *os,
- const char *title, enum roffmsec sec, enum roffvol vol)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_rofftail(void *arg, const struct tm *tm, const char *os,
- const char *title, enum roffmsec sec, enum roffvol vol)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffspecial(void *arg, int tok, const char *start,
- const int *argc, const char **argv, const char **more)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffblkin(void *arg, int tok,
- int *argc, const char **argv)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffblkout(void *arg, int tok)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffblkbodyin(void *arg, int tok,
- int *argc, const char **argv)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffblkbodyout(void *arg, int tok)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffblkheadin(void *arg, int tok,
- int *argc, const char **argv)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffblkheadout(void *arg, int tok)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffin(void *arg, int tok, int *argc, const char **argv)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffout(void *arg, int tok)
-{
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-noop_roffdata(void *arg, int tok,
- const char *start, const char *buf)
-{
-
- return(1);
-}
-
-
-static int
-noop_roffmsg(void *arg, enum roffmsg lvl,
- const char *buf, const char *pos, const char *msg)
-{
- struct md_noop *p;
- char *level;
- char b[256];
- int i;
-
- p = (struct md_noop *)arg;
- assert(p);
-
- switch (lvl) {
- case (ROFF_WARN):
- level = "warning";
- if ( ! (MD_WARN_ALL & p->args->warnings))
- return(1);
- break;
- case (ROFF_ERROR):
- level = "error";
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- if (pos) {
- assert(pos >= buf);
- if (0 < p->args->verbosity) {
- (void)snprintf(b, sizeof(b),
- "%s:%zu: %s: %s\n",
- p->rbuf->name, p->rbuf->line,
- level, msg);
- (void)strlcat(b, "Error at: ", sizeof(b));
- (void)strlcat(b, p->rbuf->linebuf, sizeof(b));
-
- (void)strlcat(b, "\n ", sizeof(b));
- for (i = 0; i < pos - buf; i++)
- (void)strlcat(b, " ", sizeof(b));
- (void)strlcat(b, "^", sizeof(b));
-
- } else
- (void)snprintf(b, sizeof(b),
- "%s:%zu: %s: %s (%zu)",
- p->rbuf->name, p->rbuf->line,
- level, msg, pos - buf);
- } else
- (void)snprintf(b, sizeof(b), "%s: %s: %s",
- p->rbuf->name, level, msg);
-
- (void)fprintf(stderr, "%s\n", b);
- return(lvl == ROFF_WARN ? 1 : 0);
-}
-
diff --git a/private.h b/private.h
index 1cc511b0..772b1451 100644
--- a/private.h
+++ b/private.h
@@ -19,387 +19,52 @@
#ifndef PRIVATE_H
#define PRIVATE_H
-#include <stdio.h>
-#include <time.h>
-
-#include "libmdocml.h"
-
-struct md_rbuf {
- int fd; /* Open descriptor. */
- char *name; /* Name of file. */
- char *buf; /* Buffer. */
- size_t bufsz; /* Size of buffer. */
- size_t line; /* Current line number. */
-#define MD_LINE (BUFSIZ)
- char linebuf[MD_LINE];
-};
-
-struct md_mbuf {
- int fd; /* Open descriptor. */
- char *name; /* Name of file. */
- char *buf; /* Buffer. */
- size_t bufsz; /* Size of buffer. */
- size_t pos; /* Position in buffer. */
-};
-
-#define ROFFTok_Sp_A 0
-#define ROFFTok_Sp_B 1
-#define ROFFTok_Sp_F 2
-#define ROFFTok_Sp_N 3
-#define ROFFTok_Sp_R 4
-#define ROFFTok_Sp_T 5
-#define ROFFTok_Sp_V 6
-#define ROFFTok_Space 7
-#define ROFFTok_Null 8
-#define ROFFTok_Hyphen 9
-#define ROFFTok_Em 10
-#define ROFFTok_En 11
-#define ROFFTok_Ge 12
-#define ROFFTok_Le 13
-#define ROFFTok_Rquote 14
-#define ROFFTok_Lquote 15
-#define ROFFTok_Uparrow 16
-#define ROFFTok_Acute 17
-#define ROFFTok_Grave 18
-#define ROFFTok_Pi 19
-#define ROFFTok_Ne 20
-#define ROFFTok_Lt 21
-#define ROFFTok_Gt 22
-#define ROFFTok_Plusmin 23
-#define ROFFTok_Infty 24
-#define ROFFTok_Bar 25
-#define ROFFTok_Nan 26
-#define ROFFTok_Quote 27
-#define ROFFTok_Sp_0 28
-#define ROFFTok_Slash 29
-#define ROFFTok_MAX 30
-
-#define ROFF___ 0
-#define ROFF_Dd 1
-#define ROFF_Dt 2
-#define ROFF_Os 3
-#define ROFF_Sh 4
-#define ROFF_Ss 5
-#define ROFF_Pp 6
-#define ROFF_D1 7
-#define ROFF_Dl 8
-#define ROFF_Bd 9
-#define ROFF_Ed 10
-#define ROFF_Bl 11
-#define ROFF_El 12
-#define ROFF_It 13
-#define ROFF_Ad 14
-#define ROFF_An 15
-#define ROFF_Ar 16
-#define ROFF_Cd 17
-#define ROFF_Cm 18
-#define ROFF_Dv 19
-#define ROFF_Er 20
-#define ROFF_Ev 21
-#define ROFF_Ex 22
-#define ROFF_Fa 23
-#define ROFF_Fd 24
-#define ROFF_Fl 25
-#define ROFF_Fn 26
-#define ROFF_Ft 27
-#define ROFF_Ic 28
-#define ROFF_In 29
-#define ROFF_Li 30
-#define ROFF_Nd 31
-#define ROFF_Nm 32
-#define ROFF_Op 33
-#define ROFF_Ot 34
-#define ROFF_Pa 35
-#define ROFF_Rv 36
-#define ROFF_St 37
-#define ROFF_Va 38
-#define ROFF_Vt 39
-#define ROFF_Xr 40
-#define ROFF__A 41
-#define ROFF__B 42
-#define ROFF__D 43
-#define ROFF__I 44
-#define ROFF__J 45
-#define ROFF__N 46
-#define ROFF__O 47
-#define ROFF__P 48
-#define ROFF__R 49
-#define ROFF__T 50
-#define ROFF__V 51
-#define ROFF_Ac 52
-#define ROFF_Ao 53
-#define ROFF_Aq 54
-#define ROFF_At 55
-#define ROFF_Bc 56
-#define ROFF_Bf 57
-#define ROFF_Bo 58
-#define ROFF_Bq 59
-#define ROFF_Bsx 60
-#define ROFF_Bx 61
-#define ROFF_Db 62
-#define ROFF_Dc 63
-#define ROFF_Do 64
-#define ROFF_Dq 65
-#define ROFF_Ec 66
-#define ROFF_Ef 67
-#define ROFF_Em 68
-#define ROFF_Eo 69
-#define ROFF_Fx 70
-#define ROFF_Ms 71
-#define ROFF_No 72
-#define ROFF_Ns 73
-#define ROFF_Nx 74
-#define ROFF_Ox 75
-#define ROFF_Pc 76
-#define ROFF_Pf 77
-#define ROFF_Po 78
-#define ROFF_Pq 79
-#define ROFF_Qc 80
-#define ROFF_Ql 81
-#define ROFF_Qo 82
-#define ROFF_Qq 83
-#define ROFF_Re 84
-#define ROFF_Rs 85
-#define ROFF_Sc 86
-#define ROFF_So 87
-#define ROFF_Sq 88
-#define ROFF_Sm 89
-#define ROFF_Sx 90
-#define ROFF_Sy 91
-#define ROFF_Tn 92
-#define ROFF_Ux 93
-#define ROFF_Xc 94
-#define ROFF_Xo 95
-#define ROFF_Fo 96
-#define ROFF_Fc 97
-#define ROFF_Oo 98
-#define ROFF_Oc 99
-#define ROFF_Bk 100
-#define ROFF_Ek 101
-#define ROFF_Bt 102
-#define ROFF_Hf 103
-#define ROFF_Fr 104
-#define ROFF_Ud 105
-#define ROFF_MAX 106
-
-#define ROFF_Split 0
-#define ROFF_Nosplit 1
-#define ROFF_Ragged 2
-#define ROFF_Unfilled 3
-#define ROFF_Literal 4
-#define ROFF_File 5
-#define ROFF_Offset 6
-#define ROFF_Bullet 7
-#define ROFF_Dash 8
-#define ROFF_Hyphen 9
-#define ROFF_Item 10
-#define ROFF_Enum 11
-#define ROFF_Tag 12
-#define ROFF_Diag 13
-#define ROFF_Hang 14
-#define ROFF_Ohang 15
-#define ROFF_Inset 16
-#define ROFF_Column 17
-#define ROFF_Width 18
-#define ROFF_Compact 19
-#define ROFF_Std 20
-#define ROFF_p1003_1_88 21
-#define ROFF_p1003_1_90 22
-#define ROFF_p1003_1_96 23
-#define ROFF_p1003_1_2001 24
-#define ROFF_p1003_1_2004 25
-#define ROFF_p1003_1 26
-#define ROFF_p1003_1b 27
-#define ROFF_p1003_1b_93 28
-#define ROFF_p1003_1c_95 29
-#define ROFF_p1003_1g_2000 30
-#define ROFF_p1003_2_92 31
-#define ROFF_p1387_2_95 32
-#define ROFF_p1003_2 33
-#define ROFF_p1387_2 34
-#define ROFF_isoC_90 35
-#define ROFF_isoC_amd1 36
-#define ROFF_isoC_tcor1 37
-#define ROFF_isoC_tcor2 38
-#define ROFF_isoC_99 39
-#define ROFF_ansiC 40
-#define ROFF_ansiC_89 41
-#define ROFF_ansiC_99 42
-#define ROFF_ieee754 43
-#define ROFF_iso8802_3 44
-#define ROFF_xpg3 45
-#define ROFF_xpg4 46
-#define ROFF_xpg4_2 47
-#define ROFF_xpg4_3 48
-#define ROFF_xbd5 49
-#define ROFF_xcu5 50
-#define ROFF_xsh5 51
-#define ROFF_xns5 52
-#define ROFF_xns5_2d2_0 53
-#define ROFF_xcurses4_2 54
-#define ROFF_susv2 55
-#define ROFF_susv3 56
-#define ROFF_svid4 57
-#define ROFF_Filled 58
-#define ROFF_Words 59
-#define ROFF_ARGMAX 60
-
-#define ROFF_MAXLINEARG 32
-
-extern const char *const *toknames;
-extern const char *const *tokargnames;
-
-enum roffmsg {
- ROFF_WARN,
- ROFF_ERROR
+#include "mdoc.h"
+
+struct mdoc {
+ void *data;
+ struct mdoc_cb cb;
+ void *htab;
+ struct mdoc_node *last;
+ struct mdoc_node *first;
};
-enum roffmsec {
- ROFF_MSEC_1,
- ROFF_MSEC_2,
- ROFF_MSEC_3,
- ROFF_MSEC_3p,
- ROFF_MSEC_4,
- ROFF_MSEC_5,
- ROFF_MSEC_6,
- ROFF_MSEC_7,
- ROFF_MSEC_8,
- ROFF_MSEC_9,
- ROFF_MSEC_UNASS,
- ROFF_MSEC_DRAFT,
- ROFF_MSEC_PAPER,
- ROFF_MSEC_MAX
+struct mdoc_macro {
+ int (*fp)(struct mdoc *, int, int, int *, char *);
+ int flags;
+#define MDOC_CALLABLE (1 << 0)
+#define MDOC_EXPLICIT (1 << 1)
};
-enum roffatt {
- ROFF_ATT_V1,
- ROFF_ATT_V2,
- ROFF_ATT_V3,
- ROFF_ATT_V6,
- ROFF_ATT_V7,
- ROFF_ATT_32V,
- ROFF_ATT_V_1,
- ROFF_ATT_V_4,
- ROFF_ATT_MAX
-};
+extern const struct mdoc_macro *const mdoc_macros;
-enum roffvol {
- ROFF_VOL_NONE,
- ROFF_VOL_AMD,
- ROFF_VOL_IND,
- ROFF_VOL_KM,
- ROFF_VOL_LOCAL,
- ROFF_VOL_PRM,
- ROFF_VOL_PS1,
- ROFF_VOL_SMM,
- ROFF_VOL_URM,
- ROFF_VOL_USD,
-#define ROFF_ARCH_START ROFF_ARCH_ALPHA
- ROFF_ARCH_ALPHA,
- ROFF_ARCH_AMD64,
- ROFF_ARCH_AMIGA,
- ROFF_ARCH_ARC,
- ROFF_ARCH_ARMISH,
- ROFF_ARCH_AVIION,
- ROFF_ARCH_HP300,
- ROFF_ARCH_HPPA,
- ROFF_ARCH_HPPA64,
- ROFF_ARCH_I386,
- ROFF_ARCH_LANDISK,
- ROFF_ARCH_LUNA88K,
- ROFF_ARCH_MAC68K,
- ROFF_ARCH_MACPPC,
- ROFF_ARCH_MVME68K,
- ROFF_ARCH_MVME88K,
- ROFF_ARCH_MVMEPPC,
- ROFF_ARCH_PMAX,
- ROFF_ARCH_SGI,
- ROFF_ARCH_SPARC,
- ROFF_ARCH_SPARC64,
- ROFF_ARCH_SUN3,
- ROFF_ARCH_VAX,
- ROFF_ARCH_ZAURUS,
- ROFF_VOL_MAX
-};
+__BEGIN_DECLS
-#define ROFFSec_NMASK (0x07)
+int mdoc_err(struct mdoc *, int, int, enum mdoc_err);
+int mdoc_warn(struct mdoc *, int, int, enum mdoc_warn);
+void mdoc_msg(struct mdoc *, int, const char *, ...);
-#define ROFFSec_PR_Os (1 << 1)
-#define ROFFSec_PR_Dt (1 << 2)
-#define ROFFSec_PR_Dd (1 << 3)
-#define ROFFSec_NAME (1 << 4)
-#define ROFFSec_SYNOP (1 << 5)
-#define ROFFSec_DESC (1 << 6)
-#define ROFFSec_RETVAL (1 << 7)
-#define ROFFSec_ENV (1 << 8)
-#define ROFFSec_FILES (1 << 9)
-#define ROFFSec_EX (1 << 10)
-#define ROFFSec_DIAG (1 << 11)
-#define ROFFSec_ERRS (1 << 12)
-#define ROFFSec_SEEALSO (1 << 13)
-#define ROFFSec_STAND (1 << 14)
-#define ROFFSec_HIST (1 << 15)
-#define ROFFSec_AUTH (1 << 16)
-#define ROFFSec_CAVEATS (1 << 17)
-#define ROFFSec_BUGS (1 << 18)
-#define ROFFSec_OTHER (1 << 19)
+int mdoc_macro(struct mdoc *, int, int, int *, char *);
+int mdoc_find(const struct mdoc *, const char *);
-struct roffcb {
- int (*roffmsg)(void *, enum roffmsg,
- const char *, const char *, const char *);
- int (*roffhead)(void *, const struct tm *, const char *,
- const char *, enum roffmsec, enum roffvol);
- int (*rofftail)(void *, const struct tm *, const char *,
- const char *, enum roffmsec, enum roffvol);
- int (*roffdata)(void *, int, const char *, const char *);
- int (*roffin)(void *, int, int *, const char **);
- int (*roffout)(void *, int);
- int (*roffblkin)(void *, int, int *, const char **);
- int (*roffblkout)(void *, int);
- int (*roffblkheadin)(void *, int, int *, const char **);
- int (*roffblkheadout)(void *, int);
- int (*roffblkbodyin)(void *, int, int *, const char **);
- int (*roffblkbodyout)(void *, int);
- int (*roffspecial)(void *, int, const char *,
- const int *, const char **, const char **);
-};
+void mdoc_word_alloc(struct mdoc *, int, const char *);
+void mdoc_elem_alloc(struct mdoc *, int, int,
+ size_t, const struct mdoc_arg *,
+ size_t, const char **);
+void mdoc_block_alloc(struct mdoc *, int, int,
+ size_t, const struct mdoc_arg *);
+void mdoc_head_alloc(struct mdoc *,
+ int, int, size_t, const char **);
+void mdoc_body_alloc(struct mdoc *, int, int);
-struct rofftree;
+void mdoc_node_free(struct mdoc_node *);
-__BEGIN_DECLS
+void mdoc_sibling(struct mdoc *, int, struct mdoc_node **,
+ struct mdoc_node **, struct mdoc_node *);
-typedef void (*(*md_init)(const struct md_args *,
- struct md_mbuf *, const struct md_rbuf *));
-typedef int (*md_line)(void *, char *);
-typedef int (*md_exit)(void *, int);
-void *md_init_html(const struct md_args *,
- struct md_mbuf *, const struct md_rbuf *);
-int md_line_html(void *, char *);
-int md_exit_html(void *, int);
-void *md_init_noop(const struct md_args *,
- struct md_mbuf *, const struct md_rbuf *);
-int md_line_noop(void *, char *);
-int md_exit_noop(void *, int);
-void *md_init_xml(const struct md_args *,
- struct md_mbuf *, const struct md_rbuf *);
-int md_line_xml(void *, char *);
-int md_exit_xml(void *, int);
-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 *);
-struct rofftree *roff_alloc(const struct roffcb *, void *);
-int roff_engine(struct rofftree *, char *);
-int roff_free(struct rofftree *, int);
-int rofftok_scan(const char *, int *);
-char *roff_literal(int, const int *,
- const char **, const char **);
-char *roff_fmtstring(int);
-char *roff_msecname(enum roffmsec);
-enum roffmsec roff_msec(const char *);
-int roff_sec(const char **);
-enum roffatt roff_att(const char *);
-enum roffvol roff_vol(const char *);
-char *roff_volname(enum roffvol);
+void *mdoc_hash_alloc(void);
+int mdoc_hash_find(const void *, const char *);
+void mdoc_hash_free(void *);
__END_DECLS
diff --git a/tags.c b/tags.c
deleted file mode 100644
index cbc498a3..00000000
--- a/tags.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <stdarg.h>
-#include <stdlib.h>
-
-#include "html.h"
-
-static int html_tstart(struct md_mbuf *, enum ml_scope,
- enum html_tag, size_t *);
-static int html_tclose(struct md_mbuf *, size_t *);
-
-static const char * const tagnames[] = {
- "span", "html", "head", "meta",
- "title", "style", "link", "body",
- "div", "table", "td", "tr",
- "ol", "ul", "li", "h1",
- "h2", "a",
- };
-
-static const char * const attrnames[] = {
- "class", "http-equiv", "content", "name",
- "type", "rel", "href", "width",
- "align", "valign", "nowrap",
- };
-
-static const char * const typenames[] = {
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
- "\"http://www.w3.org/TR/html4/strict.dtd\">",
- };
-
-
-/* FIXME: move into ml.c. */
-static int
-html_tstart(struct md_mbuf *mbuf, enum ml_scope scope,
- enum html_tag tag, size_t *res)
-{
-
- switch (scope) {
- case (ML_OPEN):
- if ( ! ml_nputs(mbuf, "<", 1, res))
- return(0);
- break;
- case (ML_CLOSE):
- if ( ! ml_nputs(mbuf, "</", 2, res))
- return(0);
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- return(ml_puts(mbuf, tagnames[tag], res));
-}
-
-
-/* FIXME: move into ml.c. */
-static int
-html_tclose(struct md_mbuf *mbuf, size_t *res)
-{
-
- return(ml_nputs(mbuf, ">", 1, res));
-}
-
-
-
-int
-html_stput(struct md_mbuf *mbuf, enum html_tag tag, size_t *res)
-{
-
- return(ml_puts(mbuf, tagnames[tag], res));
-}
-
-
-int
-html_saput(struct md_mbuf *mbuf, enum html_tag tag,
- size_t *res, int sz, const struct html_pair *p)
-{
- int i;
-
- if ( ! ml_puts(mbuf, tagnames[tag], res))
- return(0);
-
- assert(sz >= 0);
- for (i = 0; i < sz; i++) {
-
- /* FIXME: move into ml.c. */
-
- if ( ! ml_nputs(mbuf, " ", 1, res))
- return(0);
- if ( ! ml_puts(mbuf, attrnames[p[i].attr], res))
- return(0);
- if ( ! ml_nputs(mbuf, "=\"", 2, res))
- return(0);
- if ( ! ml_putstring(mbuf, p[i].val, res))
- return(0);
- if ( ! ml_nputs(mbuf, "\"", 1, res))
- return(0);
- }
-
- return(1);
-}
-
-
-int
-html_tput(struct md_mbuf *mbuf, enum ml_scope scope,
- enum html_tag tag, size_t *res)
-{
-
- if ( ! html_tstart(mbuf, scope, tag, res))
- return(0);
- return(html_tclose(mbuf, res));
-}
-
-
-int
-html_aput(struct md_mbuf *mbuf, enum ml_scope scope,
- enum html_tag tag, size_t *res,
- int sz, const struct html_pair *p)
-{
- int i;
-
- if ( ! html_tstart(mbuf, scope, tag, res))
- return(0);
-
- assert(sz >= 0);
- for (i = 0; i < sz; i++) {
-
- /* FIXME: move into ml.c. */
-
- if ( ! ml_nputs(mbuf, " ", 1, res))
- return(0);
- if ( ! ml_puts(mbuf, attrnames[p[i].attr], res))
- return(0);
- if ( ! ml_nputs(mbuf, "=\"", 2, res))
- return(0);
- if ( ! ml_putstring(mbuf, p[i].val, res))
- return(0);
- if ( ! ml_nputs(mbuf, "\"", 1, res))
- return(0);
- }
-
- return(html_tclose(mbuf, res));
-}
-
-
-int
-html_typeput(struct md_mbuf *mbuf,
- enum html_type type, size_t *res)
-{
-
- return(ml_puts(mbuf, typenames[type], res));
-}
-
-
-int
-html_commentput(struct md_mbuf *mbuf,
- enum ml_scope scope, size_t *res)
-{
-
- switch (scope) {
- case (ML_OPEN):
- return(ml_nputs(mbuf, "<!--", 4, res));
- case (ML_CLOSE):
- return(ml_nputs(mbuf, "-->", 3, res));
- default:
- break;
- }
-
- abort();
- /* NOTREACHED */
-}
diff --git a/tokens.c b/tokens.c
deleted file mode 100644
index ce46d335..00000000
--- a/tokens.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "private.h"
-
-
-static int rofftok_dashes(const char *, int *);
-static int rofftok_special(const char *, int *);
-static int rofftok_predef(const char *, int *);
-static int rofftok_defined(const char *, int *);
-
-
-static int
-rofftok_defined(const char *buf, int *i)
-{
- const char *p;
-
- if (0 == buf[*i])
- return(-1);
- if (0 == buf[*i + 1])
- return(-1);
-
- (*i)++;
- p = &buf[(*i)++];
-
- if (0 == memcmp(p, ">=", 2))
- return(ROFFTok_Ge);
- else if (0 == memcmp(p, "<=", 2))
- return(ROFFTok_Le);
- else if (0 == memcmp(p, "Rq", 2))
- return(ROFFTok_Rquote);
- else if (0 == memcmp(p, "Lq", 2))
- return(ROFFTok_Lquote);
- else if (0 == memcmp(p, "ua", 2))
- return(ROFFTok_Uparrow);
- else if (0 == memcmp(p, "aa", 2))
- return(ROFFTok_Acute);
- else if (0 == memcmp(p, "ga", 2))
- return(ROFFTok_Grave);
- else if (0 == memcmp(p, "Pi", 2))
- return(ROFFTok_Pi);
- else if (0 == memcmp(p, "Ne", 2))
- return(ROFFTok_Ne);
- else if (0 == memcmp(p, "Le", 2))
- return(ROFFTok_Le);
- else if (0 == memcmp(p, "Ge", 2))
- return(ROFFTok_Ge);
- else if (0 == memcmp(p, "Lt", 2))
- return(ROFFTok_Lt);
- else if (0 == memcmp(p, "Gt", 2))
- return(ROFFTok_Gt);
- else if (0 == memcmp(p, "Pm", 2))
- return(ROFFTok_Plusmin);
- else if (0 == memcmp(p, "If", 2))
- return(ROFFTok_Infty);
- else if (0 == memcmp(p, "Na", 2))
- return(ROFFTok_Nan);
- else if (0 == memcmp(p, "Ba", 2))
- return(ROFFTok_Bar);
-
- return(-1);
-}
-
-
-static int
-rofftok_predef(const char *buf, int *i)
-{
- if (0 == buf[*i])
- return(-1);
- if ('(' == buf[*i])
- return(rofftok_defined(buf, i));
-
- switch (buf[*i]) {
- case ('q'):
- return(ROFFTok_Quote);
- default:
- break;
- }
-
- return(-1);
-}
-
-
-static int
-rofftok_dashes(const char *buf, int *i)
-{
-
- if (0 == buf[*i])
- return(-1);
- else if (buf[(*i)++] != 'e')
- return(-1);
- if (0 == buf[*i])
- return(-1);
-
- switch (buf[*i]) {
- case ('m'):
- return(ROFFTok_Em);
- case ('n'):
- return(ROFFTok_En);
- default:
- break;
- }
- return(-1);
-}
-
-
-static int
-rofftok_special(const char *buf, int *i)
-{
-
- if (0 == buf[*i])
- return(ROFFTok_Slash);
-
- switch (buf[*i]) {
- case ('a'):
- return(ROFFTok_Sp_A);
- case ('b'):
- return(ROFFTok_Sp_B);
- case ('f'):
- return(ROFFTok_Sp_F);
- case ('n'):
- return(ROFFTok_Sp_N);
- case ('r'):
- return(ROFFTok_Sp_R);
- case ('t'):
- return(ROFFTok_Sp_T);
- case ('v'):
- return(ROFFTok_Sp_V);
- case ('0'):
- return(ROFFTok_Sp_0);
- default:
- break;
- }
- return(-1);
-}
-
-
-int
-rofftok_scan(const char *buf, int *i)
-{
-
- assert(*buf);
- assert(buf[*i] == '\\');
-
- (*i)++;
-
- for ( ; buf[*i]; (*i)++) {
- switch (buf[*i]) {
- case ('e'):
- (*i)++;
- return(rofftok_special(buf, i));
- case ('('):
- (*i)++;
- return(rofftok_dashes(buf, i));
- case (' '):
- return(ROFFTok_Space);
- case ('&'):
- return(ROFFTok_Null);
- case ('-'):
- return(ROFFTok_Hyphen);
- case ('*'):
- (*i)++;
- return(rofftok_predef(buf, i));
- case ('\\'):
- return(ROFFTok_Slash);
- default:
- break;
- }
- }
-
- return(-1);
-}
-
-
diff --git a/xml.c b/xml.c
deleted file mode 100644
index c6fa18c8..00000000
--- a/xml.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/* $Id$ */
-/*
- * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
- *
- * 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 <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "private.h"
-#include "ml.h"
-
-
-static int xml_alloc(void **);
-static void xml_free(void *);
-static ssize_t xml_beginstring(struct ml_args *,
- const char *, size_t);
-static ssize_t xml_endstring(struct ml_args *,
- const char *, size_t);
-static int xml_begin(struct ml_args *, const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
-static int xml_end(struct ml_args *, const struct tm *,
- const char *, const char *,
- enum roffmsec, enum roffvol);
-static ssize_t xml_printtagname(struct ml_args *,
- enum md_ns, int);
-static ssize_t xml_printtagargs(struct ml_args *,
- const int *, const char **);
-static ssize_t xml_endtag(struct ml_args *, enum md_ns, int);
-static ssize_t xml_begintag(struct ml_args *, enum md_ns, int,
- const int *, const char **);
-
-
-static ssize_t
-xml_printtagargs(struct ml_args *p, const int *argc, const char **argv)
-{
- int i, c;
- size_t res;
-
- if (NULL == argc || NULL == argv)
- return(0);
- assert(argc && argv);
-
- /* LINTED */
- for (res = 0, i = 0; ROFF_ARGMAX != (c = argc[i]); i++) {
- if ( ! ml_nputs(p->mbuf, " ", 1, &res))
- return(-1);
-
- /* FIXME: should puke on some, no? */
-
- if ( ! ml_puts(p->mbuf, tokargnames[c], &res))
- return(-1);
- if ( ! ml_nputs(p->mbuf, "=\"", 2, &res))
- return(-1);
- if (argv[i]) {
- if ( ! ml_putstring(p->mbuf, argv[i], &res))
- return(-1);
- } else if ( ! ml_nputs(p->mbuf, "true", 4, &res))
- return(-1);
- if ( ! ml_nputs(p->mbuf, "\"", 1, &res))
- return(-1);
- }
-
- return((ssize_t)res);
-}
-
-
-static ssize_t
-xml_printtagname(struct ml_args *p, enum md_ns ns, int tok)
-{
- size_t res;
-
- res = 0;
- switch (ns) {
- case (MD_NS_BLOCK):
- if ( ! ml_nputs(p->mbuf, "block:", 6, &res))
- return(-1);
- break;
- case (MD_NS_INLINE):
- if ( ! ml_nputs(p->mbuf, "inline:", 7, &res))
- return(-1);
- break;
- case (MD_NS_BODY):
- if ( ! ml_nputs(p->mbuf, "body:", 5, &res))
- return(-1);
- break;
- case (MD_NS_HEAD):
- if ( ! ml_nputs(p->mbuf, "head:", 5, &res))
- return(-1);
- break;
- default:
- break;
- }
-
- if ( ! ml_puts(p->mbuf, toknames[tok], &res))
- return(-1);
- return((ssize_t)res);
-}
-
-
-/* ARGSUSED */
-static int
-xml_begin(struct ml_args *p, const struct tm *tm, const char *os,
- const char *title, enum roffmsec sec, enum roffvol vol)
-{
-
- if ( ! ml_puts(p->mbuf, "<?xml version=\"1.0\" "
- "encoding=\"UTF-8\"?>\n", NULL))
- return(0);
- return(ml_puts(p->mbuf, "<mdoc xmlns:block=\"block\" "
- "xmlns:body=\"body\" "
- "xmlns:head=\"head\" "
- "xmlns:inline=\"inline\">", NULL));
-}
-
-
-/* ARGSUSED */
-static int
-xml_end(struct ml_args *p, const struct tm *tm, const char *os,
- const char *title, enum roffmsec sec, enum roffvol vol)
-{
-
- return(ml_puts(p->mbuf, "</mdoc>", NULL));
-}
-
-
-/* ARGSUSED */
-static ssize_t
-xml_beginstring(struct ml_args *p, const char *buf, size_t sz)
-{
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static ssize_t
-xml_endstring(struct ml_args *p, const char *buf, size_t sz)
-{
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static ssize_t
-xml_begintag(struct ml_args *p, enum md_ns ns,
- int tok, const int *argc, const char **argv)
-{
- ssize_t res, sz;
-
- if (-1 == (res = xml_printtagname(p, ns, tok)))
- return(-1);
- if (-1 == (sz = xml_printtagargs(p, argc, argv)))
- return(-1);
- return(res + sz);
-}
-
-
-/* ARGSUSED */
-static ssize_t
-xml_endtag(struct ml_args *p, enum md_ns ns, int tok)
-{
-
- return(xml_printtagname(p, ns, tok));
-}
-
-
-/* ARGSUSED */
-int
-xml_alloc(void **p)
-{
-
- *p = NULL;
- return(1);
-}
-
-
-/* ARGSUSED */
-void
-xml_free(void *p)
-{
-
- /* Do nothing. */
-}
-
-
-int
-md_line_xml(void *data, char *buf)
-{
-
- return(mlg_line((struct md_mlg *)data, buf));
-}
-
-
-int
-md_exit_xml(void *data, int flush)
-{
-
- return(mlg_exit((struct md_mlg *)data, flush));
-}
-
-
-void *
-md_init_xml(const struct md_args *args,
- struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
-{
- struct ml_cbs cbs;
-
- cbs.ml_alloc = xml_alloc;
- cbs.ml_free = xml_free;
- cbs.ml_begintag = xml_begintag;
- cbs.ml_endtag = xml_endtag;
- cbs.ml_begin = xml_begin;
- cbs.ml_end = xml_end;
- cbs.ml_beginstring = xml_beginstring;
- cbs.ml_endstring = xml_endstring;
-
- return(mlg_alloc(args, rbuf, mbuf, &cbs));
-}
-