summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile34
-rw-r--r--compat.c90
-rw-r--r--html.c (renamed from html4_strict.c)8
-rw-r--r--libmdocml.c15
-rw-r--r--libmdocml.h8
-rw-r--r--ml.c164
-rw-r--r--ml.h54
-rw-r--r--mlg.c496
-rw-r--r--private.h21
-rw-r--r--xml.c610
10 files changed, 762 insertions, 738 deletions
diff --git a/Makefile b/Makefile
index c2656cf3..a5ec3972 100644
--- a/Makefile
+++ b/Makefile
@@ -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 ml.ln
+LNS = mdocml.ln html.ln xml.ln libmdocml.ln roff.ln ml.ln mlg.ln compat.ln
LLNS = llib-lmdocml.ln
LIBS = libmdocml.a
-OBJS = mdocml.o html4_strict.o xml.o libmdocml.o roff.o ml.o
+OBJS = mdocml.o html.o xml.o libmdocml.o roff.o ml.o mlg.o compat.o
-SRCS = mdocml.c html4_strict.c xml.c libmdocml.c roff.c ml.c
+SRCS = mdocml.c html.c xml.c libmdocml.c roff.c ml.c mlg.c compat.c
HEADS = libmdocml.h private.h
@@ -52,23 +52,23 @@ 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 ml.ln
- $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln ml.ln
+llib-lmdocml.ln: mdocml.ln libmdocml.ln html.ln xml.ln roff.ln ml.ln mlg.ln compat.ln
+ $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html.ln xml.ln roff.ln ml.ln mlg.ln compat.ln
mdocml.ln: mdocml.c libmdocml.h
mdocml.o: mdocml.c libmdocml.h
-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
+libmdocml.a: libmdocml.o html.o xml.o roff.o ml.o mlg.o compat.o
+ $(AR) rs $@ libmdocml.o html.o xml.o roff.o ml.o mlg.o compat.o
-xml.ln: xml.c private.h libmdocml.h
+xml.ln: xml.c private.h libmdocml.h ml.h
-xml.o: xml.c private.h libmdocml.h
+xml.o: xml.c private.h libmdocml.h ml.h
-html4_strict.ln: html4_strict.c private.h libmdocml.h
+html.ln: html.c private.h libmdocml.h
-html4_strict.o: html4_strict.c private.h libmdocml.h
+html.o: html.c private.h libmdocml.h
roff.ln: roff.c private.h libmdocml.h
@@ -78,6 +78,14 @@ 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.ln: ml.c private.h libmdocml.h ml.h
-ml.o: ml.c private.h libmdocml.h
+ml.o: ml.c private.h libmdocml.h ml.h
+
+mlg.ln: mlg.c private.h libmdocml.h ml.h
+
+mlg.o: mlg.c private.h libmdocml.h ml.h
+
+compat.ln: compat.c
+
+compat.o: compat.c
diff --git a/compat.c b/compat.c
new file mode 100644
index 00000000..bb1972a3
--- /dev/null
+++ b/compat.c
@@ -0,0 +1,90 @@
+/* $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.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef __linux__
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left). At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+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 */
+}
+
+
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+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__*/
diff --git a/html4_strict.c b/html.c
index fcbc13d0..786b3097 100644
--- a/html4_strict.c
+++ b/html.c
@@ -1,4 +1,4 @@
-/* $Id: html4_strict.c,v 1.9 2008/11/29 14:14:21 kristaps Exp $ */
+/* $Id: html.c,v 1.1 2008/12/03 14:39:59 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -25,7 +25,7 @@
/* ARGSUSED */
int
-md_line_html4_strict(void *data, char *buf)
+md_line_html(void *data, char *buf)
{
return(1);
@@ -34,7 +34,7 @@ md_line_html4_strict(void *data, char *buf)
/* ARGSUSED */
int
-md_exit_html4_strict(void *data, int flush)
+md_exit_html(void *data, int flush)
{
return(1);
@@ -43,7 +43,7 @@ md_exit_html4_strict(void *data, int flush)
/* ARGSUSED */
void *
-md_init_html4_strict(const struct md_args *args,
+md_init_html(const struct md_args *args,
struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
{
diff --git a/libmdocml.c b/libmdocml.c
index 26ee15ae..f419c1f5 100644
--- a/libmdocml.c
+++ b/libmdocml.c
@@ -1,4 +1,4 @@
-/* $Id: libmdocml.c,v 1.17 2008/12/02 00:10:37 kristaps Exp $ */
+/* $Id: libmdocml.c,v 1.18 2008/12/03 14:39:59 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -139,8 +139,8 @@ md_run_leave(const struct md_args *args, struct md_mbuf *mbuf,
/* Run exiters. */
switch (args->type) {
- case (MD_HTML4_STRICT):
- if ( ! md_exit_html4_strict(data, -1 == c ? 0 : 1))
+ case (MD_HTML):
+ if ( ! md_exit_html(data, -1 == c ? 0 : 1))
c = -1;
break;
default:
@@ -172,8 +172,8 @@ md_run_enter(const struct md_args *args, struct md_mbuf *mbuf,
/* Function ptrs to line-parsers. */
switch (args->type) {
- case (MD_HTML4_STRICT):
- fp = md_line_html4_strict;
+ case (MD_HTML):
+ fp = md_line_html;
break;
default:
fp = md_line_xml;
@@ -242,9 +242,8 @@ md_run(const struct md_args *args,
/* Run initialisers. */
switch (args->type) {
- case (MD_HTML4_STRICT):
- data = md_init_html4_strict
- (args, &mbuf, &rbuf);
+ case (MD_HTML):
+ data = md_init_html(args, &mbuf, &rbuf);
break;
default:
data = md_init_xml(args, &mbuf, &rbuf);
diff --git a/libmdocml.h b/libmdocml.h
index 5a68c980..cbfda8e0 100644
--- a/libmdocml.h
+++ b/libmdocml.h
@@ -1,4 +1,4 @@
-/* $Id: libmdocml.h,v 1.10 2008/11/30 21:41:35 kristaps Exp $ */
+/* $Id: libmdocml.h,v 1.11 2008/12/03 14:39:59 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -25,18 +25,18 @@ struct md_params_xml {
int dummy;
};
-struct md_params_html4_strict {
+struct md_params_html {
int dummy;
};
union md_params {
struct md_params_xml xml;
- struct md_params_html4_strict html4_strict;
+ struct md_params_html html;
};
enum md_type {
MD_XML, /* XML. */
- MD_HTML4_STRICT /* HTML4.01-strict. */
+ MD_HTML /* HTML4.01-strict. */
};
struct md_args {
diff --git a/ml.c b/ml.c
index 8b52f6a5..917052ca 100644
--- a/ml.c
+++ b/ml.c
@@ -1,4 +1,4 @@
-/* $Id: ml.c,v 1.1 2008/12/02 18:26:57 kristaps Exp $ */
+/* $Id: ml.c,v 1.2 2008/12/03 14:39:59 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -21,164 +21,68 @@
#include "libmdocml.h"
#include "private.h"
+#include "ml.h"
+#ifdef __linux__
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
+#endif
-#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
+ml_nputstring(struct md_mbuf *p,
+ const char *buf, size_t sz, size_t *pos)
{
int i;
- ssize_t res, sz;
- res = 0;
-
- for (i = 0; i < (int)bufsz; i++) {
+ for (i = 0; i < (int)sz; i++) {
switch (buf[i]) {
case ('&'):
- if (-1 == (sz = ml_nputs(p, "&amp;", 5)))
- return(-1);
+ if ( ! ml_nputs(p, "&amp;", 5, pos))
+ return(0);
break;
case ('"'):
- if (-1 == (sz = ml_nputs(p, "&quot;", 6)))
- return(-1);
+ if ( ! ml_nputs(p, "&quot;", 6, pos))
+ return(0);
break;
case ('<'):
- if (-1 == (sz = ml_nputs(p, "&lt;", 4)))
- return(-1);
+ if ( ! ml_nputs(p, "&lt;", 4, pos))
+ return(0);
break;
case ('>'):
- if (-1 == (sz = ml_nputs(p, "&gt;", 4)))
- return(-1);
+ if ( ! ml_nputs(p, "&gt;", 4, pos))
+ return(0);
break;
default:
- if (-1 == (sz = ml_putchar(p, buf[i])))
- return(-1);
+ if ( ! ml_nputs(p, &buf[i], 1, pos))
+ return(0);
break;
}
- res += sz;
}
- return(res);
+ return(1);
}
-ssize_t
-ml_nputs(struct md_mbuf *p, const char *buf, size_t sz)
+int
+ml_nputs(struct md_mbuf *p, const char *buf, size_t sz, size_t *pos)
{
- return(0 == md_buf_puts(p, buf, sz) ? -1 : (ssize_t)sz);
+ if ( ! md_buf_puts(p, buf, sz))
+ return(0);
+
+ *pos += sz;
+ return(1);
}
-ssize_t
-ml_indent(struct md_mbuf *p, int indent)
+int
+ml_putchars(struct md_mbuf *p, char buf, size_t count, size_t *pos)
{
size_t i;
- ssize_t res, sz;
- res = sz 0;
+ for (i = 0; i < count; i++)
+ if ( ! ml_nputs(p, &buf, 1, pos))
+ return(0);
- /* LINTED */
- for (i = 0; i < MIN(indent, MAXINDENT); i++, res += sz)
- if (-1 == (sz = ml_nputs(p, " ", 4)))
- return(-1);
- return(res);
+ return(1);
}
diff --git a/ml.h b/ml.h
new file mode 100644
index 00000000..ac8a0369
--- /dev/null
+++ b/ml.h
@@ -0,0 +1,54 @@
+/* $Id: ml.h,v 1.1 2008/12/03 14:39:59 kristaps Exp $ */
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef ML_H
+#define ML_H
+
+struct md_mlg;
+
+enum md_ns {
+ MD_NS_BLOCK,
+ MD_NS_INLINE,
+ MD_NS_DEFAULT,
+};
+
+typedef ssize_t (*ml_endtag)(struct md_mbuf *,
+ const struct md_args *, enum md_ns, int);
+typedef ssize_t (*ml_begintag)(struct md_mbuf *,
+ const struct md_args *, enum md_ns, int,
+ const int *, const char **);
+
+
+__BEGIN_DECLS
+
+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_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 *,
+ ml_begintag, ml_endtag);
+int mlg_exit(struct md_mlg *, int);
+int mlg_line(struct md_mlg *, char *);
+
+__END_DECLS
+
+#endif /*!ML_H*/
diff --git a/mlg.c b/mlg.c
new file mode 100644
index 00000000..4302234a
--- /dev/null
+++ b/mlg.c
@@ -0,0 +1,496 @@
+/* $Id: mlg.c,v 1.1 2008/12/03 14:39:59 kristaps Exp $ */
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libmdocml.h"
+#include "private.h"
+#include "ml.h"
+
+/* TODO: literal tokens. */
+
+#define COLUMNS 72
+#define INDENT 4
+#define MAXINDENT 8
+
+enum md_tok {
+ MD_TEXT,
+ MD_INLINE_IN,
+ MD_INLINE_OUT,
+ MD_BLK_IN,
+ MD_BLK_OUT,
+};
+
+struct md_mlg {
+ const struct md_args *args;
+ const struct md_rbuf *rbuf;
+
+ struct md_mbuf *mbuf;
+ struct rofftree *tree;
+ size_t indent;
+ size_t pos;
+ enum md_tok last;
+ void *arg;
+ ml_begintag begintag;
+ ml_endtag endtag;
+ int flags;
+#define ML_OVERRIDE_ONE (1 << 0)
+#define ML_OVERRIDE_ALL (1 << 1)
+};
+
+
+static void mlg_roffmsg(void *arg, enum roffmsg,
+ const char *, const char *, char *);
+static int mlg_roffhead(void *);
+static int mlg_rofftail(void *);
+static int mlg_roffin(void *, int, int *, char **);
+static int mlg_roffdata(void *, int, char *);
+static int mlg_roffout(void *, int);
+static int mlg_roffblkin(void *, int, int *, char **);
+static int mlg_roffblkout(void *, int);
+static int mlg_roffspecial(void *, int, int *, char **, char **);
+static int mlg_begintag(struct md_mlg *, enum md_ns,
+ int, int *, 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_data(struct md_mlg *, int, char *);
+
+#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, char **argv)
+{
+ ssize_t res;
+
+ /* TODO: extra rules for block/inline. */
+
+ if ( ! ml_nputs(p->mbuf, "<", 1, &p->pos))
+ return(0);
+
+ res = (*p->begintag)(p->mbuf, p->args, ns, tok,
+ argc, (const char **)argv);
+ if (-1 == res)
+ return(0);
+
+ assert(res >= 0);
+ p->pos += (size_t)res;
+
+ /* TODO: extra rules for block/inline. */
+
+ return(ml_nputs(p->mbuf, ">", 1, &p->pos));
+}
+
+
+static int
+mlg_endtag(struct md_mlg *p, enum md_ns ns, int tok)
+{
+ ssize_t res;
+
+ /* TODO: extra rules for block/inline. */
+
+ if ( ! ml_nputs(p->mbuf, "</", 2, &p->pos))
+ return(0);
+
+ res = (*p->endtag)(p->mbuf, p->args, ns, tok);
+ if (-1 == res)
+ return(0);
+
+ assert(res >= 0);
+ p->pos += (size_t)res;
+
+ /* TODO: extra rules for block/inline. */
+
+ return(ml_nputs(p->mbuf, ">", 1, &p->pos));
+}
+
+
+static int
+mlg_indent(struct md_mlg *p)
+{
+ size_t count;
+
+ count = p->indent > MAXINDENT ? MAXINDENT : p->indent;
+ count *= INDENT;
+
+ assert(0 == p->pos);
+ return(ml_putchars(p->mbuf, ' ', count, &p->pos));
+}
+
+
+static int
+mlg_newline(struct md_mlg *p)
+{
+ size_t dummy;
+
+ if ( ! ml_nputs(p->mbuf, "\n", 1, &dummy))
+ return(0);
+ p->pos = 0;
+ return(1);
+}
+
+
+static void
+mlg_mode(struct md_mlg *p, enum md_tok ns)
+{
+ p->flags &= ~ML_OVERRIDE_ONE;
+ p->last = ns;
+}
+
+
+static int
+mlg_data(struct md_mlg *p, int space, char *buf)
+{
+ size_t sz;
+ char *bufp;
+
+ assert(p->mbuf);
+ assert(0 != p->indent);
+
+ if (ML_OVERRIDE_ONE & p->flags ||
+ ML_OVERRIDE_ALL & p->flags)
+ space = 0;
+
+ while (*buf) {
+ while (*buf && isspace(*buf))
+ buf++;
+
+ if (0 == *buf)
+ break;
+
+ bufp = buf;
+ while (*buf && ! isspace(*buf))
+ buf++;
+
+ if (0 != *buf)
+ *buf++ = 0;
+
+ sz = strlen(bufp);
+
+ if (0 == p->pos) {
+ if ( ! mlg_indent(p))
+ return(0);
+ if ( ! ml_nputstring(p->mbuf, bufp,
+ sz, &p->pos))
+ return(0);
+ if (p->indent * MAXINDENT + sz >= COLUMNS)
+ if ( ! mlg_newline(p))
+ return(0);
+ if ( ! (ML_OVERRIDE_ALL & p->flags))
+ space = 1;
+ continue;
+ }
+
+ 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->mbuf, " ", 1, &p->pos))
+ return(0);
+ }
+
+ if ( ! ml_nputstring(p->mbuf, bufp, sz, &p->pos))
+ return(0);
+
+ if ( ! (ML_OVERRIDE_ALL & p->flags))
+ space = 1;
+ }
+
+ return(1);
+}
+
+
+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);
+ free(p);
+ return(c);
+}
+
+
+struct md_mlg *
+mlg_alloc(const struct md_args *args,
+ const struct md_rbuf *rbuf,
+ struct md_mbuf *mbuf,
+ ml_begintag begintag, ml_endtag endtag)
+{
+ 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.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;
+ p->mbuf = mbuf;
+ p->rbuf = rbuf;
+ p->begintag = begintag;
+ p->endtag = endtag;
+
+ if (NULL == (p->tree = roff_alloc(&cb, p))) {
+ free(p);
+ return(NULL);
+ }
+
+ return(p);
+}
+
+
+static int
+mlg_roffhead(void *arg)
+{
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ mlg_mode(p, MD_BLK_IN);
+ if ( ! mlg_begintag(p, MD_NS_DEFAULT, -1, NULL, NULL))
+ return(0);
+
+ p->indent++;
+ return(mlg_newline(p));
+}
+
+
+static int
+mlg_rofftail(void *arg)
+{
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ if (0 != p->pos && ! mlg_newline(p))
+ return(0);
+
+ mlg_mode(p, MD_BLK_OUT);
+ if ( ! mlg_endtag(p, -1, MD_NS_DEFAULT))
+ return(0);
+
+ return(mlg_newline(p));
+}
+
+
+/* ARGSUSED */
+static int
+mlg_roffspecial(void *arg, int tok, int *argc, char **argv, char **more)
+{
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ switch (tok) {
+ case (ROFF_Ns):
+ p->flags |= ML_OVERRIDE_ONE;
+ break;
+ case (ROFF_Sm):
+ assert(*more);
+ if (0 == strcmp(*more, "on"))
+ p->flags |= ML_OVERRIDE_ALL;
+ else
+ p->flags &= ~ML_OVERRIDE_ALL;
+ break;
+ default:
+ break;
+ }
+
+ return(1);
+}
+
+
+static int
+mlg_roffblkin(void *arg, int tok, int *argc, char **argv)
+{
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ 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);
+
+ if ( ! mlg_begintag(p, MD_NS_BLOCK, tok, argc, argv))
+ return(0);
+ return(mlg_newline(p));
+}
+
+
+static int
+mlg_roffblkout(void *arg, int tok)
+{
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ 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);
+
+ mlg_mode(p, MD_BLK_OUT);
+ if ( ! mlg_endtag(p, MD_NS_BLOCK, tok))
+ return(0);
+ return(mlg_newline(p));
+}
+
+
+static int
+mlg_roffin(void *arg, int tok, int *argc, char **argv)
+{
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ /* FIXME: this part. */
+
+ 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->mbuf, " ", 1, &p->pos))
+ return(0);
+
+ if (0 == p->pos && ! mlg_indent(p))
+ return(0);
+
+ mlg_mode(p, MD_INLINE_IN);
+ return(mlg_begintag(p, MD_NS_INLINE, tok, argc, argv));
+}
+
+
+static int
+mlg_roffout(void *arg, int tok)
+{
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ if (0 == p->pos && ! mlg_indent(p))
+ return(0);
+
+ mlg_mode(p, MD_INLINE_OUT);
+ return(mlg_endtag(p, MD_NS_INLINE, tok));
+}
+
+
+static void
+mlg_roffmsg(void *arg, enum roffmsg lvl,
+ const char *buf, const char *pos, char *msg)
+{
+ char *level;
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ switch (lvl) {
+ case (ROFF_WARN):
+ if ( ! (MD_WARN_ALL & p->args->warnings))
+ return;
+ level = "warning";
+ break;
+ case (ROFF_ERROR):
+ level = "error";
+ break;
+ default:
+ abort();
+ }
+
+ if (pos)
+ (void)fprintf(stderr, "%s:%zu: %s: %s (column %zu)\n",
+ p->rbuf->name, p->rbuf->line, level,
+ msg, pos - buf);
+ else
+ (void)fprintf(stderr, "%s: %s: %s\n",
+ p->rbuf->name, level, msg);
+
+}
+
+
+static int
+mlg_roffdata(void *arg, int space, char *buf)
+{
+ struct md_mlg *p;
+
+ assert(arg);
+ p = (struct md_mlg *)arg;
+
+ if ( ! mlg_data(p, space, buf))
+ return(0);
+
+ mlg_mode(p, MD_TEXT);
+ return(1);
+}
+
diff --git a/private.h b/private.h
index 777d73f9..2f3d4cda 100644
--- a/private.h
+++ b/private.h
@@ -1,4 +1,4 @@
-/* $Id: private.h,v 1.23 2008/12/02 18:26:57 kristaps Exp $ */
+/* $Id: private.h,v 1.24 2008/12/03 14:39:59 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -19,7 +19,6 @@
#ifndef PRIVATE_H
#define PRIVATE_H
-/* Input buffer (input read into buffer, then filled when empty). */
struct md_rbuf {
int fd; /* Open descriptor. */
char *name; /* Name of file. */
@@ -28,7 +27,6 @@ struct md_rbuf {
size_t line; /* Current line number. */
};
-/* Output buffer (output buffered until full, then flushed). */
struct md_mbuf {
int fd; /* Open descriptor. */
char *name; /* Name of file. */
@@ -225,6 +223,8 @@ struct roffcb {
int (*roffspecial)(void *, int, int *, char **, char **);
};
+struct rofftree;
+
__BEGIN_DECLS
typedef void (*(*md_init)(const struct md_args *,
@@ -232,10 +232,10 @@ typedef void (*(*md_init)(const struct md_args *,
typedef int (*md_line)(void *, char *);
typedef int (*md_exit)(void *, int);
-void *md_init_html4_strict(const struct md_args *,
+void *md_init_html(const struct md_args *,
struct md_mbuf *, const struct md_rbuf *);
-int md_line_html4_strict(void *, char *);
-int md_exit_html4_strict(void *, int);
+int md_line_html(void *, char *);
+int md_exit_html(void *, int);
void *md_init_xml(const struct md_args *,
struct md_mbuf *, const struct md_rbuf *);
@@ -246,19 +246,10 @@ 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;
-
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*/
diff --git a/xml.c b/xml.c
index c28e4505..be33f86a 100644
--- a/xml.c
+++ b/xml.c
@@ -1,4 +1,4 @@
-/* $Id: xml.c,v 1.9 2008/12/02 18:26:57 kristaps Exp $ */
+/* $Id: xml.c,v 1.10 2008/12/03 14:39:59 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -16,295 +16,98 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/param.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <err.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libmdocml.h"
#include "private.h"
+#include "ml.h"
-#define COLUMNS 72
-
-enum md_ns {
- MD_NS_BLOCK,
- MD_NS_INLINE,
- MD_NS_DEFAULT
-};
-
-enum md_tok {
- MD_BLKIN, /* Controls spacing. */
- MD_BLKOUT,
- MD_IN,
- MD_OUT,
- MD_TEXT
-};
-
-struct md_xml {
- const struct md_args *args;
- const struct md_rbuf *rbuf;
-
- struct md_mbuf *mbuf;
- struct rofftree *tree;
- size_t indent;
- size_t pos;
- enum md_tok last;
- int flags;
-#define MD_LITERAL (1 << 0) /* TODO */
-#define MD_OVERRIDE_ONE (1 << 1)
-#define MD_OVERRIDE_ALL (1 << 2)
-};
-
-static void roffmsg(void *arg, enum roffmsg,
- const char *, const char *, char *);
-static int roffhead(void *);
-static int rofftail(void *);
-static int roffin(void *, int, int *, char **);
-static int roffdata(void *, int, char *);
-static int roffout(void *, int);
-static int roffblkin(void *, int, int *, char **);
-static int roffblkout(void *, int);
-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 xml_indent(struct md_xml *);
-static int mbuf_data(struct md_xml *, int, char *);
-static int xml_nputstring(struct md_xml *,
- const char *, size_t);
-static int xml_puts(struct md_xml *, const char *);
-static int xml_nputs(struct md_xml *,
- const char *, size_t);
-static int xml_begintag(struct md_xml *, const char *,
- enum md_ns, int *, char **);
-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)
-{
- p->flags &= ~MD_OVERRIDE_ONE;
- p->last = ns;
-}
+static ssize_t xml_endtag(struct md_mbuf *,
+ const struct md_args *,
+ enum md_ns, int);
+static ssize_t xml_begintag(struct md_mbuf *,
+ const struct md_args *,
+ enum md_ns, int,
+ const int *, const char **);
-static int
-xml_begintag(struct md_xml *p, const char *name, enum md_ns ns,
- int *argc, char **argv)
+static ssize_t
+xml_begintag(struct md_mbuf *mbuf, const struct md_args *args,
+ enum md_ns ns, int tok,
+ const int *argc, const char **argv)
{
- char buf[64];
- ssize_t sz;
size_t res;
+ res = 0;
+
switch (ns) {
case (MD_NS_BLOCK):
- res = strlcpy(buf, "block:", sizeof(buf));
- assert(res < sizeof(buf));
+ if ( ! ml_nputs(mbuf, "block:", 6, &res))
+ return(-1);
break;
case (MD_NS_INLINE):
- res = strlcpy(buf, "inline:", sizeof(buf));
- assert(res < sizeof(buf));
+ if ( ! ml_nputs(mbuf, "inline:", 7, &res))
+ return(-1);
break;
default:
- *buf = 0;
- break;
+ if ( ! ml_nputs(mbuf, "mbuf", 4, &res))
+ return(-1);
+ return((ssize_t)res);
}
- res = strlcat(buf, name, sizeof(buf));
- assert(res < sizeof(buf));
-
- if (-1 == (sz = ml_begintag(p->mbuf, buf, argc, argv)))
- return(0);
+ if ( ! ml_nputs(mbuf, toknames[tok],
+ strlen(toknames[tok]), &res))
+ return(-1);
- p->pos += sz;
- return(1);
+ return((ssize_t)res);
}
-static int
-xml_endtag(struct md_xml *p, const char *name, enum md_ns ns)
+static ssize_t
+xml_endtag(struct md_mbuf *mbuf, const struct md_args *args,
+ enum md_ns ns, int tok)
{
- char buf[64];
- ssize_t sz;
size_t res;
+ res = 0;
+
switch (ns) {
case (MD_NS_BLOCK):
- res = strlcpy(buf, "block:", sizeof(buf));
- assert(res < sizeof(buf));
+ if ( ! ml_nputs(mbuf, "block:", 6, &res))
+ return(-1);
break;
case (MD_NS_INLINE):
- res = strlcpy(buf, "inline:", sizeof(buf));
- assert(res < sizeof(buf));
+ if ( ! ml_nputs(mbuf, "inline:", 7, &res))
+ return(-1);
break;
default:
- *buf = 0;
- break;
+ if ( ! ml_nputs(mbuf, "mbuf", 4, &res))
+ return(-1);
+ return((ssize_t)res);
}
- res = strlcat(buf, name, sizeof(buf));
- assert(res < sizeof(buf));
-
- if (-1 == (sz = ml_endtag(p->mbuf, buf)))
- return(0);
-
- p->pos += sz;
- return(1);
-}
-
-
-static int
-xml_nputstring(struct md_xml *p, const char *buf, size_t sz)
-{
- ssize_t res;
-
- if (-1 == (res = ml_nputstring(p->mbuf, buf, sz)))
- return(0);
- p->pos += res;
- return(1);
-}
-
-
-static int
-xml_nputs(struct md_xml *p, const char *buf, size_t sz)
-{
- ssize_t res;
-
- if (-1 == (res = ml_nputs(p->mbuf, buf, sz)))
- return(0);
- p->pos += res;
- return(1);
-}
-
-
-static int
-xml_puts(struct md_xml *p, const char *buf)
-{
-
- return(xml_nputs(p, buf, strlen(buf)));
-}
-
-
-static int
-xml_indent(struct md_xml *p)
-{
- ssize_t res;
-
- if (-1 == (res = ml_indent(p->mbuf, p->indent)))
- return(0);
- p->pos += res;
- return(1);
-}
-
-
-static int
-mbuf_newline(struct md_xml *p)
-{
-
- if ( ! md_buf_putchar(p->mbuf, '\n'))
- return(0);
-
- p->pos = 0;
- return(1);
-}
-
-
-static int
-mbuf_data(struct md_xml *p, int space, char *buf)
-{
- size_t sz;
- char *bufp;
-
- assert(p->mbuf);
- assert(0 != p->indent);
-
- if (MD_OVERRIDE_ONE & p->flags || MD_OVERRIDE_ALL & p->flags)
- space = 0;
-
- if (MD_LITERAL & p->flags)
- return(xml_nputstring(p, buf, sizeof(buf)));
-
- while (*buf) {
- while (*buf && isspace(*buf))
- buf++;
-
- if (0 == *buf)
- break;
-
- bufp = buf;
- while (*buf && ! isspace(*buf))
- buf++;
-
- if (0 != *buf)
- *buf++ = 0;
-
- sz = strlen(bufp);
+ if ( ! ml_nputs(mbuf, toknames[tok],
+ strlen(toknames[tok]), &res))
+ return(-1);
- if (0 == p->pos) {
- if ( ! xml_indent(p))
- return(0);
- if ( ! xml_nputstring(p, bufp, sz))
- return(0);
- if (p->indent * MAXINDENT + sz >= COLUMNS)
- if ( ! mbuf_newline(p))
- return(0);
- if ( ! (MD_OVERRIDE_ALL & p->flags))
- space = 1;
- continue;
- }
-
- if (space && sz + p->pos >= COLUMNS) {
- if ( ! mbuf_newline(p))
- return(0);
- if ( ! xml_indent(p))
- return(0);
- } else if (space) {
- if ( ! xml_nputs(p, " ", 1))
- return(0);
- }
-
- if ( ! xml_nputstring(p, bufp, sz))
- return(0);
-
- if ( ! (MD_OVERRIDE_ALL & p->flags))
- space = 1;
- }
-
- return(1);
+ return((ssize_t)res);
}
int
-md_line_xml(void *arg, char *buf)
+md_line_xml(void *data, char *buf)
{
- struct md_xml *p;
- p = (struct md_xml *)arg;
- return(roff_engine(p->tree, buf));
+ return(mlg_line((struct md_mlg *)data, buf));
}
int
md_exit_xml(void *data, int flush)
{
- int c;
- struct md_xml *p;
-
- p = (struct md_xml *)data;
- c = roff_free(p->tree, flush);
- free(p);
- return(c);
+ return(mlg_exit((struct md_mlg *)data, flush));
}
@@ -312,328 +115,7 @@ void *
md_init_xml(const struct md_args *args,
struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
{
- struct roffcb cb;
- struct md_xml *p;
- cb.roffhead = roffhead;
- cb.rofftail = rofftail;
- cb.roffin = roffin;
- cb.roffout = roffout;
- cb.roffblkin = roffblkin;
- cb.roffblkout = roffblkout;
- cb.roffspecial = roffspecial;
- cb.roffmsg = roffmsg;
- cb.roffdata = roffdata;
-
- if (NULL == (p = calloc(1, sizeof(struct md_xml))))
- err(1, "malloc");
-
- p->args = args;
- p->mbuf = mbuf;
- p->rbuf = rbuf;
-
- assert(mbuf);
-
- if (NULL == (p->tree = roff_alloc(&cb, p))) {
- free(p);
- return(NULL);
- }
-
- return(p);
-}
-
-
-/* ARGSUSED */
-static int
-roffhead(void *arg)
-{
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
-
- if (-1 == xml_puts(p, "<?xml version=\"1.0\" "
- "encoding=\"UTF-8\"?>\n"))
- return(0);
- if (-1 == xml_puts(p, "<mdoc xmlns:block=\"block\" "
- "xmlns:special=\"special\" "
- "xmlns:inline=\"inline\">"))
- return(0);
-
- p->indent++;
- mbuf_mode(p, MD_BLKIN);
- return(mbuf_newline(p));
-}
-
-
-static int
-rofftail(void *arg)
-{
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
-
- if (0 != p->pos && ! mbuf_newline(p))
- return(0);
-
- mbuf_mode(p, MD_BLKOUT);
- if ( ! xml_endtag(p, "mdoc", MD_NS_DEFAULT))
- return(0);
- return(mbuf_newline(p));
+ return(mlg_alloc(args, rbuf, mbuf, xml_begintag, xml_endtag));
}
-
-/* ARGSUSED */
-static int
-roffspecial(void *arg, int tok, int *argc, char **argv, char **more)
-{
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
-
- /* FIXME: this is completely ad hoc. */
-
- switch (tok) {
- case (ROFF_Ns):
- p->flags |= MD_OVERRIDE_ONE;
- break;
- case (ROFF_Sm):
- assert(*more);
- if (0 == strcmp(*more, "on"))
- p->flags |= MD_OVERRIDE_ALL;
- else
- p->flags &= ~MD_OVERRIDE_ALL;
- break;
- default:
- break;
- }
-
- return(1);
-}
-
-
-static int
-roffblkin(void *arg, int tok, int *argc, char **argv)
-{
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
-
- if (0 != p->pos) {
- if ( ! mbuf_newline(p))
- return(0);
- if ( ! xml_indent(p))
- return(0);
- } else if ( ! xml_indent(p))
- return(0);
-
- /* FIXME: xml won't like standards args (e.g., p1003.1-90). */
-
- p->indent++;
- mbuf_mode(p, MD_BLKIN);
-
- if ( ! xml_begintag(p, toknames[tok], MD_NS_BLOCK,
- argc, argv))
- return(0);
- return(mbuf_newline(p));
-}
-
-
-static int
-roffblkout(void *arg, int tok)
-{
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
-
- p->indent--;
-
- if (0 != p->pos) {
- if ( ! mbuf_newline(p))
- return(0);
- if ( ! xml_indent(p))
- return(0);
- } else if ( ! xml_indent(p))
- return(0);
-
- mbuf_mode(p, MD_BLKOUT);
- if ( ! xml_endtag(p, toknames[tok], MD_NS_BLOCK))
- return(0);
- return(mbuf_newline(p));
-}
-
-
-static int
-roffin(void *arg, int tok, int *argc, char **argv)
-{
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
-
- if ( ! (MD_OVERRIDE_ONE & p->flags) &&
- ! (MD_OVERRIDE_ALL & p->flags) &&
- p->pos + 11 > COLUMNS)
- if ( ! mbuf_newline(p))
- return(0);
-
- if (0 != p->pos && (MD_TEXT == p->last || MD_OUT == p->last)
- && ! (MD_OVERRIDE_ONE & p->flags)
- && ! (MD_OVERRIDE_ALL & p->flags))
- if ( ! xml_nputs(p, " ", 1))
- return(0);
-
- if (0 == p->pos && ! xml_indent(p))
- return(0);
-
- mbuf_mode(p, MD_IN);
- return(xml_begintag(p, toknames[tok],
- MD_NS_INLINE, argc, argv));
-}
-
-
-static int
-roffout(void *arg, int tok)
-{
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
-
- if (0 == p->pos && ! xml_indent(p))
- return(0);
-
- mbuf_mode(p, MD_OUT);
- return(xml_endtag(p, toknames[tok], MD_NS_INLINE));
-}
-
-
-static void
-roffmsg(void *arg, enum roffmsg lvl,
- const char *buf, const char *pos, char *msg)
-{
- char *level;
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
-
- switch (lvl) {
- case (ROFF_WARN):
- if ( ! (MD_WARN_ALL & p->args->warnings))
- return;
- level = "warning";
- break;
- case (ROFF_ERROR):
- level = "error";
- break;
- default:
- abort();
- }
-
- if (pos)
- (void)fprintf(stderr, "%s:%zu: %s: %s (column %zu)\n",
- p->rbuf->name, p->rbuf->line, level,
- msg, pos - buf);
- else
- (void)fprintf(stderr, "%s: %s: %s\n",
- p->rbuf->name, level, msg);
-
-}
-
-
-static int
-roffdata(void *arg, int space, char *buf)
-{
- struct md_xml *p;
-
- assert(arg);
- p = (struct md_xml *)arg;
- if ( ! mbuf_data(p, space, buf))
- return(0);
-
- mbuf_mode(p, MD_TEXT);
- 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__*/