From d3f19a8807625c3ef9817089048a7c32d50775c0 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Mon, 15 Dec 2008 01:54:58 +0000 Subject: Purged all old files in favour of new design. Selective reintegration. --- Makefile | 175 ++-------- compat.c | 1 + hash.c | 126 +++++++ html.c | 1085 ----------------------------------------------------------- html.h | 86 ----- index.7 | 156 --------- libmdocml.c | 261 -------------- libmdocml.h | 67 ---- literals.c | 615 --------------------------------- macro.c | 294 +++++++++++++--- mdoc.c | 734 ++++++++++++++++++++++++++++++++++++++++ mdoc.h | 289 ++++++++++++++++ mdocml.c | 463 ++++++++++++++++--------- mdocml.css | 58 ---- ml.c | 261 -------------- ml.h | 93 ----- mlg.c | 868 ----------------------------------------------- noop.c | 294 ---------------- private.h | 405 ++-------------------- tags.c | 188 ----------- tokens.c | 193 ----------- xml.c | 235 ------------- 22 files changed, 1773 insertions(+), 5174 deletions(-) create mode 100644 hash.c delete mode 100644 html.c delete mode 100644 html.h delete mode 100644 index.7 delete mode 100644 libmdocml.c delete mode 100644 libmdocml.h delete mode 100644 literals.c create mode 100644 mdoc.c create mode 100644 mdoc.h delete mode 100644 mdocml.css delete mode 100644 ml.c delete mode 100644 ml.h delete mode 100644 mlg.c delete mode 100644 noop.c delete mode 100644 tags.c delete mode 100644 tokens.c delete mode 100644 xml.c 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..a6a5e0ba --- /dev/null +++ b/hash.c @@ -0,0 +1,126 @@ +/* $Id: hash.c,v 1.1 2008/12/15 01:54:58 kristaps Exp $ */ +/* + * Copyright (c) 2008 Kristaps Dzonsons + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include "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 ec01135c..00000000 --- a/html.c +++ /dev/null @@ -1,1085 +0,0 @@ -/* $Id: html.c,v 1.27 2008/12/12 10:11:10 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#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 854e4ff6..00000000 --- a/html.h +++ /dev/null @@ -1,86 +0,0 @@ -/* $Id: html.h,v 1.4 2008/12/10 17:40:56 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef 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 c573771c..00000000 --- a/index.7 +++ /dev/null @@ -1,156 +0,0 @@ -.\" -.Dd $Mdocdate: December 10 2008 $ -.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 1a7f7c55..00000000 --- a/libmdocml.c +++ /dev/null @@ -1,261 +0,0 @@ -/* $Id: libmdocml.c,v 1.21 2008/12/10 14:42:46 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#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 55ce8edb..00000000 --- a/libmdocml.h +++ /dev/null @@ -1,67 +0,0 @@ -/* $Id: libmdocml.h,v 1.14 2008/12/10 14:42:46 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef LIBMDOCML_H -#define LIBMDOCML_H - -#include - -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 e6eba897..00000000 --- a/literals.c +++ /dev/null @@ -1,615 +0,0 @@ -/* $Id: literals.c,v 1.8 2008/12/10 12:05:33 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include - -#include "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 20d0d569..68a8cc92 100644 --- a/macro.c +++ b/macro.c @@ -1,4 +1,4 @@ -/* $Id: macro.c,v 1.1 2008/12/12 10:11:10 kristaps Exp $ */ +/* $Id: macro.c,v 1.2 2008/12/15 01:54:58 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -16,90 +16,294 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ +#include +#include #include +#include + +#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..381347dc --- /dev/null +++ b/mdoc.c @@ -0,0 +1,734 @@ +/* $Id: mdoc.c,v 1.1 2008/12/15 01:54:58 kristaps Exp $ */ +/* + * Copyright (c) 2008 Kristaps Dzonsons + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "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 = ""; + 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 = ""; + 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..baeb4484 --- /dev/null +++ b/mdoc.h @@ -0,0 +1,289 @@ +/* $Id: mdoc.h,v 1.1 2008/12/15 01:54:58 kristaps Exp $ */ +/* + * Copyright (c) 2008 Kristaps Dzonsons + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef 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 3198b4b6..f5440b8f 100644 --- a/mdocml.c +++ b/mdocml.c @@ -1,4 +1,4 @@ -/* $Id: mdocml.c,v 1.20 2008/12/10 14:42:46 kristaps Exp $ */ +/* $Id: mdocml.c,v 1.21 2008/12/15 01:54:58 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -16,39 +16,48 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -#include #include +#include #include -#include #include +#include #include #include #include #include #include -#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 = ""; + 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 efee8904..00000000 --- a/ml.c +++ /dev/null @@ -1,261 +0,0 @@ -/* $Id: ml.c,v 1.9 2008/12/10 00:58:15 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include - -#include "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 = " "; - ssz = 6; - break; - case (ROFFTok_Hyphen): - seq = "‐"; - ssz = 7; - break; - case (ROFFTok_Em): - seq = "—"; - ssz = 7; - break; - case (ROFFTok_En): - seq = "–"; - ssz = 7; - break; - case (ROFFTok_Ge): - seq = "≥"; - ssz = 7; - break; - case (ROFFTok_Le): - seq = "≤"; - ssz = 7; - break; - case (ROFFTok_Rquote): - seq = "”"; - ssz = 7; - break; - case (ROFFTok_Lquote): - seq = "“"; - ssz = 7; - break; - case (ROFFTok_Uparrow): - seq = "↑"; - ssz = 7; - break; - case (ROFFTok_Acute): - seq = "´"; - ssz = 6; - break; - case (ROFFTok_Grave): - seq = "`"; - ssz = 5; - break; - case (ROFFTok_Pi): - seq = "π"; - ssz = 6; - break; - case (ROFFTok_Ne): - seq = "≠"; - ssz = 7; - break; - case (ROFFTok_Lt): - seq = "<"; - ssz = 4; - break; - case (ROFFTok_Gt): - seq = ">"; - ssz = 4; - break; - case (ROFFTok_Plusmin): - seq = "±"; - ssz = 6; - break; - case (ROFFTok_Infty): - seq = "∞"; - ssz = 7; - break; - case (ROFFTok_Bar): - seq = "|"; - ssz = 6; - break; - case (ROFFTok_Nan): - seq = "Nan"; - ssz = 3; - break; - case (ROFFTok_Quote): - seq = """; - 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 = "&"; - ssz = 5; - break; - - /* Quotation ml-escape. */ - case ('"'): - seq = """; - ssz = 6; - break; - - /* Lt ml-escape. */ - case ('<'): - seq = "<"; - ssz = 4; - break; - - /* Gt ml-escape. */ - case ('>'): - seq = ">"; - 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 4d725f80..00000000 --- a/ml.h +++ /dev/null @@ -1,93 +0,0 @@ -/* $Id: ml.h,v 1.16 2008/12/10 17:31:57 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef 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 4054da86..00000000 --- a/mlg.c +++ /dev/null @@ -1,868 +0,0 @@ -/* $Id: mlg.c,v 1.29 2008/12/10 17:31:57 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "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, "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 f1a0f41f..00000000 --- a/noop.c +++ /dev/null @@ -1,294 +0,0 @@ -/* $Id: noop.c,v 1.3 2008/12/10 17:31:57 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include - -#include "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 05281758..41c9dcd2 100644 --- a/private.h +++ b/private.h @@ -1,4 +1,4 @@ -/* $Id: private.h,v 1.40 2008/12/10 14:42:46 kristaps Exp $ */ +/* $Id: private.h,v 1.41 2008/12/15 01:54:58 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -19,387 +19,52 @@ #ifndef PRIVATE_H #define PRIVATE_H -#include -#include +#include "mdoc.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 mdoc { + void *data; + struct mdoc_cb cb; + void *htab; + struct mdoc_node *last; + struct mdoc_node *first; }; -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. */ +struct mdoc_macro { + int (*fp)(struct mdoc *, int, int, int *, char *); + int flags; +#define MDOC_CALLABLE (1 << 0) +#define MDOC_EXPLICIT (1 << 1) }; -#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 struct mdoc_macro *const mdoc_macros; -extern const char *const *toknames; -extern const char *const *tokargnames; - -enum roffmsg { - ROFF_WARN, - ROFF_ERROR -}; - -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 -}; - -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 -}; - -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 d0f928b2..00000000 --- a/tags.c +++ /dev/null @@ -1,188 +0,0 @@ -/* $Id: tags.c,v 1.3 2008/12/10 17:40:56 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include - -#include "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[] = { - "", - }; - - -/* 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, "", 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, "", 3, res)); - default: - break; - } - - abort(); - /* NOTREACHED */ -} diff --git a/tokens.c b/tokens.c deleted file mode 100644 index 5c4ba320..00000000 --- a/tokens.c +++ /dev/null @@ -1,193 +0,0 @@ -/* $Id: tokens.c,v 1.4 2008/12/09 17:09:12 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include - -#include "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 98bed056..00000000 --- a/xml.c +++ /dev/null @@ -1,235 +0,0 @@ -/* $Id: xml.c,v 1.25 2008/12/10 17:31:58 kristaps Exp $ */ -/* - * Copyright (c) 2008 Kristaps Dzonsons - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include - -#include "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, "\n", NULL)) - return(0); - return(ml_puts(p->mbuf, "", 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, "", 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)); -} - -- cgit v1.2.3-56-ge451