diff options
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | ml.c | 184 | ||||
-rw-r--r-- | private.h | 7 | ||||
-rw-r--r-- | roff.c | 4 | ||||
-rw-r--r-- | xml.c | 294 |
5 files changed, 372 insertions, 135 deletions
@@ -2,15 +2,15 @@ CFLAGS += -W -Wall -Wno-unused-parameter -g LINTFLAGS += -c -e -f -u -LNS = mdocml.ln html4_strict.ln xml.ln libmdocml.ln roff.ln +LNS = mdocml.ln html4_strict.ln xml.ln libmdocml.ln roff.ln ml.ln LLNS = llib-lmdocml.ln LIBS = libmdocml.a -OBJS = mdocml.o html4_strict.o xml.o libmdocml.o roff.o +OBJS = mdocml.o html4_strict.o xml.o libmdocml.o roff.o ml.o -SRCS = mdocml.c html4_strict.c xml.c libmdocml.c roff.c +SRCS = mdocml.c html4_strict.c xml.c libmdocml.c roff.c ml.c HEADS = libmdocml.h private.h @@ -52,15 +52,15 @@ mdocml.tgz: $(INSTALL) ( cd .dist/ && tar zcf ../mdocml.tgz mdocml/ ) rm -rf .dist/ -llib-lmdocml.ln: mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln - $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln +llib-lmdocml.ln: mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln ml.ln + $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln ml.ln mdocml.ln: mdocml.c libmdocml.h mdocml.o: mdocml.c libmdocml.h -libmdocml.a: libmdocml.o html4_strict.o xml.o roff.o - $(AR) rs $@ libmdocml.o html4_strict.o xml.o roff.o +libmdocml.a: libmdocml.o html4_strict.o xml.o roff.o ml.o + $(AR) rs $@ libmdocml.o html4_strict.o xml.o roff.o ml.o xml.ln: xml.c private.h libmdocml.h @@ -77,3 +77,7 @@ roff.o: roff.c private.h libmdocml.h libmdocml.ln: libmdocml.c private.h libmdocml.h libmdocml.o: libmdocml.c private.h libmdocml.h + +ml.ln: ml.c private.h libmdocml.h + +ml.o: ml.c private.h libmdocml.h @@ -0,0 +1,184 @@ +/* $Id$ */ +/* + * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include <stdlib.h> +#include <string.h> + +#include "libmdocml.h" +#include "private.h" + + +#define MAXINDENT 8 + +static ssize_t ml_puts(struct md_mbuf *, const char *); +static ssize_t ml_putchar(struct md_mbuf *, char); +static ssize_t ml_putstring(struct md_mbuf *, const char *); + + +static ssize_t +ml_puts(struct md_mbuf *p, const char *buf) +{ + + return(ml_nputs(p, buf, strlen(buf))); +} + + +static ssize_t +ml_putchar(struct md_mbuf *p, char buf) +{ + + return(ml_nputs(p, &buf, 1)); +} + + +static ssize_t +ml_putstring(struct md_mbuf *p, const char *buf) +{ + + return(ml_nputstring(p, buf, strlen(buf))); +} + + +ssize_t +ml_begintag(struct md_mbuf *p, const char *name, + int *argc, char **argv) +{ + int i; + ssize_t res, sz; + + res = 0; + + if (-1 == (sz = ml_nputs(p, "<", 1))) + return(-1); + res += sz; + + if (-1 == (sz = ml_puts(p, name))) + return(-1); + res += sz; + + for (i = 0; ROFF_ARGMAX != argc[i]; i++) { + if (-1 == (sz = ml_nputs(p, " ", 1))) + return(-1); + res += sz; + + if (-1 == (sz = ml_puts(p, tokargnames[argc[i]]))) + return(-1); + res += sz; + + if (-1 == (sz = ml_nputs(p, "=\"", 2))) + return(-1); + res += sz; + + if (-1 == (sz = ml_putstring(p, argv[i] ? + argv[i] : "true"))) + return(-1); + res += sz; + + if (-1 == (sz = ml_nputs(p, "\"", 1))) + return(-1); + res += sz; + } + + if (-1 == (sz = ml_nputs(p, ">", 1))) + return(-1); + + return(res + sz); +} + + +ssize_t +ml_endtag(struct md_mbuf *p, const char *tag) +{ + ssize_t res, sz; + + res = 0; + + if (-1 == (sz = ml_nputs(p, "</", 2))) + return(-1); + res += sz; + + if (-1 == (sz = ml_puts(p, tag))) + return(-1); + res += sz; + + if (-1 == (sz = ml_nputs(p, ">", 1))) + return(-1); + + return(res + sz); +} + + +ssize_t +ml_nputstring(struct md_mbuf *p, const char *buf, size_t bufsz) +{ + int i; + ssize_t res, sz; + + res = 0; + + for (i = 0; i < (int)bufsz; i++) { + switch (buf[i]) { + case ('&'): + if (-1 == (sz = ml_nputs(p, "&", 5))) + return(-1); + break; + case ('"'): + if (-1 == (sz = ml_nputs(p, """, 6))) + return(-1); + break; + case ('<'): + if (-1 == (sz = ml_nputs(p, "<", 4))) + return(-1); + break; + case ('>'): + if (-1 == (sz = ml_nputs(p, ">", 4))) + return(-1); + break; + default: + if (-1 == (sz = ml_putchar(p, buf[i]))) + return(-1); + break; + } + res += sz; + } + return(res); +} + + +ssize_t +ml_nputs(struct md_mbuf *p, const char *buf, size_t sz) +{ + + return(0 == md_buf_puts(p, buf, sz) ? -1 : (ssize_t)sz); +} + + +ssize_t +ml_indent(struct md_mbuf *p, int indent) +{ + size_t i; + ssize_t res, sz; + + res = sz 0; + + /* LINTED */ + for (i = 0; i < MIN(indent, MAXINDENT); i++, res += sz) + if (-1 == (sz = ml_nputs(p, " ", 4))) + return(-1); + return(res); +} @@ -252,6 +252,13 @@ struct rofftree *roff_alloc(const struct roffcb *, void *); int roff_engine(struct rofftree *, char *); int roff_free(struct rofftree *, int); +ssize_t ml_begintag(struct md_mbuf *, const char *, + int *, char **); +ssize_t ml_endtag(struct md_mbuf *, const char *); +ssize_t ml_nputstring(struct md_mbuf *, const char *, size_t); +ssize_t ml_nputs(struct md_mbuf *, const char *, size_t); +ssize_t ml_indent(struct md_mbuf *, int); + __END_DECLS #endif /*!PRIVATE_H*/ @@ -134,7 +134,7 @@ static int roffcall(struct rofftree *, int, char **); static int roffparse(struct rofftree *, char *); static int textparse(const struct rofftree *, char *); -#ifdef __linux__ +#ifdef __linux__ /* FIXME: remove */ static size_t strlcat(char *, const char *, size_t); static size_t strlcpy(char *, const char *, size_t); extern int vsnprintf(char *, size_t, @@ -1446,7 +1446,7 @@ roff_err(const struct rofftree *tree, const char *pos, char *fmt, ...) } -#ifdef __linux +#ifdef __linux /* FIXME: remove. */ /* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ /* @@ -28,7 +28,6 @@ #include "libmdocml.h" #include "private.h" -#define MAXINDENT 8 #define COLUMNS 72 enum md_ns { @@ -73,20 +72,23 @@ static int roffspecial(void *, int, int *, char **, char **); static void mbuf_mode(struct md_xml *, enum md_ns); static int mbuf_newline(struct md_xml *); -static int mbuf_indent(struct md_xml *); +static int xml_indent(struct md_xml *); static int mbuf_data(struct md_xml *, int, char *); -static int mbuf_putstring(struct md_xml *, - const char *); -static int mbuf_nputstring(struct md_xml *, +static int xml_nputstring(struct md_xml *, const char *, size_t); -static int mbuf_puts(struct md_xml *, const char *); -static int mbuf_nputs(struct md_xml *, +static int xml_puts(struct md_xml *, const char *); +static int xml_nputs(struct md_xml *, const char *, size_t); -static int mbuf_begintag(struct md_xml *, const char *, +static int xml_begintag(struct md_xml *, const char *, enum md_ns, int *, char **); -static int mbuf_endtag(struct md_xml *, +static int xml_endtag(struct md_xml *, const char *, enum md_ns); +#ifdef __linux__ /* FIXME: remove */ +static size_t strlcat(char *, const char *, size_t); +static size_t strlcpy(char *, const char *, size_t); +#endif + static void mbuf_mode(struct md_xml *p, enum md_ns ns) @@ -97,147 +99,110 @@ mbuf_mode(struct md_xml *p, enum md_ns ns) static int -mbuf_begintag(struct md_xml *p, const char *name, enum md_ns ns, +xml_begintag(struct md_xml *p, const char *name, enum md_ns ns, int *argc, char **argv) { - int i; - - if ( ! mbuf_nputs(p, "<", 1)) - return(0); + char buf[64]; + ssize_t sz; + size_t res; switch (ns) { - case (MD_NS_BLOCK): - if ( ! mbuf_nputs(p, "block:", 6)) - return(0); - break; - case (MD_NS_INLINE): - if ( ! mbuf_nputs(p, "inline:", 7)) - return(0); - break; - default: - break; + case (MD_NS_BLOCK): + res = strlcpy(buf, "block:", sizeof(buf)); + assert(res < sizeof(buf)); + break; + case (MD_NS_INLINE): + res = strlcpy(buf, "inline:", sizeof(buf)); + assert(res < sizeof(buf)); + break; + default: + *buf = 0; + break; } - if ( ! mbuf_puts(p, name)) + res = strlcat(buf, name, sizeof(buf)); + assert(res < sizeof(buf)); + + if (-1 == (sz = ml_begintag(p->mbuf, buf, argc, argv))) return(0); - for (i = 0; ROFF_ARGMAX != argc[i]; i++) { - if ( ! mbuf_nputs(p, " ", 1)) - return(0); - if ( ! mbuf_puts(p, tokargnames[argc[i]])) - return(0); - if ( ! mbuf_nputs(p, "=\"", 2)) - return(0); - if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true")) - return(0); - if ( ! mbuf_nputs(p, "\"", 1)) - return(0); - } - return(mbuf_nputs(p, ">", 1)); + p->pos += sz; + return(1); } static int -mbuf_endtag(struct md_xml *p, const char *tag, enum md_ns ns) +xml_endtag(struct md_xml *p, const char *name, enum md_ns ns) { - if ( ! mbuf_nputs(p, "</", 2)) - return(0); + char buf[64]; + ssize_t sz; + size_t res; switch (ns) { - case (MD_NS_BLOCK): - if ( ! mbuf_nputs(p, "block:", 6)) - return(0); - break; - case (MD_NS_INLINE): - if ( ! mbuf_nputs(p, "inline:", 7)) - return(0); - break; - default: - break; + case (MD_NS_BLOCK): + res = strlcpy(buf, "block:", sizeof(buf)); + assert(res < sizeof(buf)); + break; + case (MD_NS_INLINE): + res = strlcpy(buf, "inline:", sizeof(buf)); + assert(res < sizeof(buf)); + break; + default: + *buf = 0; + break; } - if ( ! mbuf_puts(p, tag)) - return(0); - return(mbuf_nputs(p, ">", 1)); -} - + res = strlcat(buf, name, sizeof(buf)); + assert(res < sizeof(buf)); -static int -mbuf_putstring(struct md_xml *p, const char *buf) -{ + if (-1 == (sz = ml_endtag(p->mbuf, buf))) + return(0); - return(mbuf_nputstring(p, buf, strlen(buf))); + p->pos += sz; + return(1); } static int -mbuf_nputstring(struct md_xml *p, const char *buf, size_t sz) +xml_nputstring(struct md_xml *p, const char *buf, size_t sz) { - int i; + ssize_t res; - for (i = 0; i < (int)sz; i++) { - switch (buf[i]) { - case ('&'): - if ( ! md_buf_puts(p->mbuf, "&", 5)) - return(0); - p->pos += 5; - break; - case ('"'): - if ( ! md_buf_puts(p->mbuf, """, 6)) - return(0); - p->pos += 6; - break; - case ('<'): - if ( ! md_buf_puts(p->mbuf, "<", 4)) - return(0); - p->pos += 4; - break; - case ('>'): - if ( ! md_buf_puts(p->mbuf, ">", 4)) - return(0); - p->pos += 4; - break; - default: - if ( ! md_buf_putchar(p->mbuf, buf[i])) - return(0); - p->pos++; - break; - } - } + if (-1 == (res = ml_nputstring(p->mbuf, buf, sz))) + return(0); + p->pos += res; return(1); } static int -mbuf_nputs(struct md_xml *p, const char *buf, size_t sz) +xml_nputs(struct md_xml *p, const char *buf, size_t sz) { + ssize_t res; - p->pos += sz; - return(md_buf_puts(p->mbuf, buf, sz)); + if (-1 == (res = ml_nputs(p->mbuf, buf, sz))) + return(0); + p->pos += res; + return(1); } static int -mbuf_puts(struct md_xml *p, const char *buf) +xml_puts(struct md_xml *p, const char *buf) { - return(mbuf_nputs(p, buf, strlen(buf))); + return(xml_nputs(p, buf, strlen(buf))); } static int -mbuf_indent(struct md_xml *p) +xml_indent(struct md_xml *p) { - size_t i; - - assert(p->pos == 0); - - /* LINTED */ - for (i = 0; i < MIN(p->indent, MAXINDENT); i++) - if ( ! md_buf_putstring(p->mbuf, " ")) - return(0); + ssize_t res; - p->pos += i * 4; + if (-1 == (res = ml_indent(p->mbuf, p->indent))) + return(0); + p->pos += res; return(1); } @@ -267,7 +232,7 @@ mbuf_data(struct md_xml *p, int space, char *buf) space = 0; if (MD_LITERAL & p->flags) - return(mbuf_putstring(p, buf)); + return(xml_nputstring(p, buf, sizeof(buf))); while (*buf) { while (*buf && isspace(*buf)) @@ -286,9 +251,9 @@ mbuf_data(struct md_xml *p, int space, char *buf) sz = strlen(bufp); if (0 == p->pos) { - if ( ! mbuf_indent(p)) + if ( ! xml_indent(p)) return(0); - if ( ! mbuf_nputstring(p, bufp, sz)) + if ( ! xml_nputstring(p, bufp, sz)) return(0); if (p->indent * MAXINDENT + sz >= COLUMNS) if ( ! mbuf_newline(p)) @@ -301,14 +266,14 @@ mbuf_data(struct md_xml *p, int space, char *buf) if (space && sz + p->pos >= COLUMNS) { if ( ! mbuf_newline(p)) return(0); - if ( ! mbuf_indent(p)) + if ( ! xml_indent(p)) return(0); } else if (space) { - if ( ! mbuf_nputs(p, " ", 1)) + if ( ! xml_nputs(p, " ", 1)) return(0); } - if ( ! mbuf_nputstring(p, bufp, sz)) + if ( ! xml_nputstring(p, bufp, sz)) return(0); if ( ! (MD_OVERRIDE_ALL & p->flags)) @@ -387,10 +352,10 @@ roffhead(void *arg) assert(arg); p = (struct md_xml *)arg; - if ( ! mbuf_puts(p, "<?xml version=\"1.0\" " + if (-1 == xml_puts(p, "<?xml version=\"1.0\" " "encoding=\"UTF-8\"?>\n")) return(0); - if ( ! mbuf_puts(p, "<mdoc xmlns:block=\"block\" " + if (-1 == xml_puts(p, "<mdoc xmlns:block=\"block\" " "xmlns:special=\"special\" " "xmlns:inline=\"inline\">")) return(0); @@ -413,7 +378,7 @@ rofftail(void *arg) return(0); mbuf_mode(p, MD_BLKOUT); - if ( ! mbuf_endtag(p, "mdoc", MD_NS_DEFAULT)) + if ( ! xml_endtag(p, "mdoc", MD_NS_DEFAULT)) return(0); return(mbuf_newline(p)); } @@ -460,9 +425,9 @@ roffblkin(void *arg, int tok, int *argc, char **argv) if (0 != p->pos) { if ( ! mbuf_newline(p)) return(0); - if ( ! mbuf_indent(p)) + if ( ! xml_indent(p)) return(0); - } else if ( ! mbuf_indent(p)) + } else if ( ! xml_indent(p)) return(0); /* FIXME: xml won't like standards args (e.g., p1003.1-90). */ @@ -470,7 +435,7 @@ roffblkin(void *arg, int tok, int *argc, char **argv) p->indent++; mbuf_mode(p, MD_BLKIN); - if ( ! mbuf_begintag(p, toknames[tok], MD_NS_BLOCK, + if ( ! xml_begintag(p, toknames[tok], MD_NS_BLOCK, argc, argv)) return(0); return(mbuf_newline(p)); @@ -490,13 +455,13 @@ roffblkout(void *arg, int tok) if (0 != p->pos) { if ( ! mbuf_newline(p)) return(0); - if ( ! mbuf_indent(p)) + if ( ! xml_indent(p)) return(0); - } else if ( ! mbuf_indent(p)) + } else if ( ! xml_indent(p)) return(0); mbuf_mode(p, MD_BLKOUT); - if ( ! mbuf_endtag(p, toknames[tok], MD_NS_BLOCK)) + if ( ! xml_endtag(p, toknames[tok], MD_NS_BLOCK)) return(0); return(mbuf_newline(p)); } @@ -519,14 +484,14 @@ roffin(void *arg, int tok, int *argc, char **argv) if (0 != p->pos && (MD_TEXT == p->last || MD_OUT == p->last) && ! (MD_OVERRIDE_ONE & p->flags) && ! (MD_OVERRIDE_ALL & p->flags)) - if ( ! mbuf_nputs(p, " ", 1)) + if ( ! xml_nputs(p, " ", 1)) return(0); - if (0 == p->pos && ! mbuf_indent(p)) + if (0 == p->pos && ! xml_indent(p)) return(0); mbuf_mode(p, MD_IN); - return(mbuf_begintag(p, toknames[tok], + return(xml_begintag(p, toknames[tok], MD_NS_INLINE, argc, argv)); } @@ -539,11 +504,11 @@ roffout(void *arg, int tok) assert(arg); p = (struct md_xml *)arg; - if (0 == p->pos && ! mbuf_indent(p)) + if (0 == p->pos && ! xml_indent(p)) return(0); mbuf_mode(p, MD_OUT); - return(mbuf_endtag(p, toknames[tok], MD_NS_INLINE)); + return(xml_endtag(p, toknames[tok], MD_NS_INLINE)); } @@ -595,3 +560,80 @@ roffdata(void *arg, int space, char *buf) return(1); } + +#ifdef __linux /* FIXME: remove. */ +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * 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. + */ +static size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past + * end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + + +static size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} +#endif /*__linux__*/ |