From 049cc4aa4e4a294608c81ec192c2c6b046944a43 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Sun, 30 Nov 2008 21:41:35 +0000 Subject: Preliminary xml output filter (validate-renamed) done. --- Makefile | 18 +-- libmdocml.c | 7 +- libmdocml.h | 6 +- mdocml.1 | 49 ++++-- private.h | 8 +- roff.c | 4 +- validate.c | 470 -------------------------------------------------------- xml.c | 502 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 556 insertions(+), 508 deletions(-) delete mode 100644 validate.c create mode 100644 xml.c diff --git a/Makefile b/Makefile index 0dfdb46a..b138633b 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 validate.ln libmdocml.ln roff.ln +LNS = mdocml.ln html4_strict.ln xml.ln libmdocml.ln roff.ln LLNS = llib-lmdocml.ln LIBS = libmdocml.a -OBJS = mdocml.o html4_strict.o validate.o libmdocml.o roff.o +OBJS = mdocml.o html4_strict.o xml.o libmdocml.o roff.o -SRCS = mdocml.c html4_strict.c validate.c libmdocml.c roff.c +SRCS = mdocml.c html4_strict.c xml.c libmdocml.c roff.c HEADS = libmdocml.h private.h @@ -49,19 +49,19 @@ mdocml.tgz: $(INSTALL) ( cd .dist/ && tar zcf ../mdocml.tgz mdocml/ ) rm -rf .dist/ -llib-lmdocml.ln: mdocml.ln libmdocml.ln html4_strict.ln validate.ln roff.ln - $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html4_strict.ln validate.ln roff.ln +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 mdocml.ln: mdocml.c libmdocml.h mdocml.o: mdocml.c libmdocml.h -libmdocml.a: libmdocml.o html4_strict.o validate.o roff.o - $(AR) rs $@ libmdocml.o html4_strict.o validate.o roff.o +libmdocml.a: libmdocml.o html4_strict.o xml.o roff.o + $(AR) rs $@ libmdocml.o html4_strict.o xml.o roff.o -validate.ln: validate.c private.h libmdocml.h +xml.ln: xml.c private.h libmdocml.h -validate.o: validate.c private.h libmdocml.h +xml.o: xml.c private.h libmdocml.h html4_strict.ln: html4_strict.c private.h libmdocml.h diff --git a/libmdocml.c b/libmdocml.c index 11eff674..a10519bd 100644 --- a/libmdocml.c +++ b/libmdocml.c @@ -144,7 +144,7 @@ md_run_leave(const struct md_args *args, struct md_mbuf *mbuf, c = -1; break; default: - if ( ! md_exit_valid(data, -1 == c ? 0 : 1)) + if ( ! md_exit_xml(data, -1 == c ? 0 : 1)) c = -1; break; } @@ -176,7 +176,7 @@ md_run_enter(const struct md_args *args, struct md_mbuf *mbuf, fp = md_line_html4_strict; break; default: - fp = md_line_valid; + fp = md_line_xml; break; } @@ -247,8 +247,7 @@ md_run(const struct md_args *args, (args, &mbuf, &rbuf); break; default: - data = md_init_valid - (args, &mbuf, &rbuf); + data = md_init_xml(args, &mbuf, &rbuf); break; } diff --git a/libmdocml.h b/libmdocml.h index c2576146..74174e5f 100644 --- a/libmdocml.h +++ b/libmdocml.h @@ -21,7 +21,7 @@ #include -struct md_params_valid { +struct md_params_xml { int dummy; }; @@ -30,12 +30,12 @@ struct md_params_html4_strict { }; union md_params { - struct md_params_valid valid; + struct md_params_xml xml; struct md_params_html4_strict html4_strict; }; enum md_type { - MD_VALID, /* Validate input only. */ + MD_XML, /* XML. */ MD_HTML4_STRICT /* HTML4.01-strict. */ }; diff --git a/mdocml.1 b/mdocml.1 index c5f86d66..83a036d7 100644 --- a/mdocml.1 +++ b/mdocml.1 @@ -13,7 +13,7 @@ .\" .Sh SYNOPSIS .Nm mdocml -.Op Fl vW +.Op Fl W .Op Fl f Ar filter .Op Fl o Ar outfile .Op Ar infile @@ -27,32 +27,49 @@ formatted manual source and passes results into the output filter dictated by .Fl f Ar filter . The only current output filter is -.Ar validate , +.Ar xml , the default. The arguments are as follows: -.Bl -tag -width "\-o outfile," -.It Sq Fl o Ar outfile , +.Bl -tag -width "\-o outfile" +.It Fl f Ar filter +The output filter name, which defaults to +.Ar xml . +.It Fl o Ar outfile Place output in .Ar outfile , which may be .Qq \- -for standard output. The default is standard output. +for stdout. The default is stdout. +.It Fl W +Print compiler warnings to stderr. .It Ar infile Read input from .Ar infile , which may be .Qq \- -for standard input. The default is standard input. -.It Fl v -Print messages (output depends on filter). -.It Fl W -Print warnings (output depends on filter). +for stdin. The default is stdin. .El -.Ss Validate Filter -The validate filter, specified by -.Fl f Ar validate , -is the default filter. It produces no output, so specifying -.Fl o Ar outfile -results in an empty file. +.Ss XML Filter +The XML filter, specified by +.Fl f Ar xml , +is the default filter. It creates an XML document where element names are +their respective roff macro names. Each element name has an associated +namespace, which is one of +.Qq block , +.Qq inline , +or +.Qq special , +corresponding to the display mode of a node. +.Pp +Sample output follows: +.Bd -literal + + + + NAME example + example text + + +.Ed .\" The following requests should be uncommented and used where appropriate. .\" This next request is for sections 2, 3, and 9 function return values only. .\" .Sh RETURN VALUES diff --git a/private.h b/private.h index 95d8a41d..7811e843 100644 --- a/private.h +++ b/private.h @@ -213,7 +213,7 @@ struct roffcb { const char *, const char *, char *); int (*roffhead)(void *); int (*rofftail)(void *); - int (*roffin)(void *, int, int, int *, char **); + int (*roffin)(void *, int, int *, char **); int (*roffdata)(void *, int, char *); int (*roffout)(void *, int); int (*roffblkin)(void *, int, int *, char **); @@ -233,10 +233,10 @@ void *md_init_html4_strict(const struct md_args *, int md_line_html4_strict(void *, char *); int md_exit_html4_strict(void *, int); -void *md_init_valid(const struct md_args *, +void *md_init_xml(const struct md_args *, struct md_mbuf *, const struct md_rbuf *); -int md_line_valid(void *, char *); -int md_exit_valid(void *, int); +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); diff --git a/roff.c b/roff.c index a1f5f660..7d88c8a1 100644 --- a/roff.c +++ b/roff.c @@ -979,7 +979,7 @@ roff_layout(ROFFCALL_ARGS) if (NULL == *argv) return(1); - if ( ! (*tree->cb.roffin)(tree->arg, tok, 0, argcp, argvp)) + if ( ! (*tree->cb.roffin)(tree->arg, tok, argcp, argvp)) return(0); if ( ! (ROFF_PARSED & tokens[tok].flags)) { @@ -1075,7 +1075,7 @@ roff_text(ROFFCALL_ARGS) argcp[i] = ROFF_ARGMAX; argvp[i] = NULL; - if ( ! (*tree->cb.roffin)(tree->arg, tok, 1, argcp, argvp)) + if ( ! (*tree->cb.roffin)(tree->arg, tok, argcp, argvp)) return(0); if ( ! (ROFF_PARSED & tokens[tok].flags)) { diff --git a/validate.c b/validate.c deleted file mode 100644 index efd3bddf..00000000 --- a/validate.c +++ /dev/null @@ -1,470 +0,0 @@ -/* $Id$ */ -/* - * 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 "libmdocml.h" -#include "private.h" - -#define INDENT 4 -#define COLUMNS 72 - -#ifdef __linux__ /* FIXME */ -#define strlcat strncat -#endif - -enum md_tok { - MD_BLKIN, - MD_BLKOUT, - MD_IN, - MD_OUT, - MD_TEXT -}; - -struct md_valid { - 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) /* FIXME */ -}; - -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, 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); - -static int mbuf_newline(struct md_valid *); -static int mbuf_indent(struct md_valid *); -static int mbuf_data(struct md_valid *, int, char *); -static int mbuf_putstring(struct md_valid *, - const char *); -static int mbuf_nputstring(struct md_valid *, - const char *, size_t); - - -static int -mbuf_putstring(struct md_valid *p, const char *buf) -{ - - return(mbuf_nputstring(p, buf, strlen(buf))); -} - - -static int -mbuf_nputstring(struct md_valid *p, const char *buf, size_t sz) -{ - - p->pos += sz; - return(md_buf_puts(p->mbuf, buf, sz)); -} - - -static int -mbuf_indent(struct md_valid *p) -{ - size_t i; - - assert(p->pos == 0); - - /* LINTED */ - for (i = 0; i < MIN(p->indent, INDENT); i++) - if ( ! md_buf_putstring(p->mbuf, " ")) - return(0); - - p->pos += i * INDENT; - return(1); -} - - -static int -mbuf_newline(struct md_valid *p) -{ - - if ( ! md_buf_putchar(p->mbuf, '\n')) - return(0); - - p->pos = 0; - return(1); -} - - -static int -mbuf_data(struct md_valid *p, int space, char *buf) -{ - size_t sz; - char *bufp; - - assert(p->mbuf); - assert(0 != p->indent); - - /* - * FIXME: punctuation/no-space stuff shouldn't have a newline - * before it. - */ - - if (MD_LITERAL & p->flags) - return(mbuf_putstring(p, 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 (0 == p->pos) { - if ( ! mbuf_indent(p)) - return(0); - if ( ! mbuf_nputstring(p, bufp, sz)) - return(0); - if (p->indent * INDENT + sz >= COLUMNS) { - if ( ! mbuf_newline(p)) - return(0); - continue; - } - continue; - } - - if (sz + p->pos >= COLUMNS) { - if ( ! mbuf_newline(p)) - return(0); - if ( ! mbuf_indent(p)) - return(0); - } else if (space) - if ( ! mbuf_nputstring(p, " ", 1)) - return(0); - - if ( ! mbuf_nputstring(p, bufp, sz)) - return(0); - } - - return(1); -} - - -int -md_line_valid(void *arg, char *buf) -{ - struct md_valid *p; - - p = (struct md_valid *)arg; - return(roff_engine(p->tree, buf)); -} - - -int -md_exit_valid(void *data, int flush) -{ - int c; - struct md_valid *p; - - p = (struct md_valid *)data; - c = roff_free(p->tree, flush); - free(p); - - return(c); -} - - -void * -md_init_valid(const struct md_args *args, - struct md_mbuf *mbuf, const struct md_rbuf *rbuf) -{ - struct roffcb cb; - struct md_valid *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_valid)))) - 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_valid *p; - - assert(arg); - p = (struct md_valid *)arg; - - if ( ! mbuf_putstring(p, "\n")) - return(0); - if ( ! mbuf_nputstring(p, "", 6)) - return(0); - - p->indent++; - return(mbuf_newline(p)); -} - - -static int -rofftail(void *arg) -{ - struct md_valid *p; - - assert(arg); - p = (struct md_valid *)arg; - - if (0 != p->pos && ! mbuf_newline(p)) - return(0); - - if ( ! mbuf_nputstring(p, "", 7)) - return(0); - return(mbuf_newline(p)); -} - - -/* ARGSUSED */ -static int -roffspecial(void *arg, int tok) -{ - - return(1); -} - - -static int -roffblkin(void *arg, int tok, int *argc, char **argv) -{ - struct md_valid *p; - int i; - - assert(arg); - p = (struct md_valid *)arg; - - if (0 != p->pos) { - if ( ! mbuf_newline(p)) - return(0); - if ( ! mbuf_indent(p)) - return(0); - } else if ( ! mbuf_indent(p)) - return(0); - - if ( ! mbuf_nputstring(p, "<", 1)) - return(0); - if ( ! mbuf_putstring(p, toknames[tok])) - return(0); - - for (i = 0; ROFF_ARGMAX != argc[i]; i++) { - if ( ! mbuf_nputstring(p, " ", 1)) - return(0); - if ( ! mbuf_putstring(p, tokargnames[argc[i]])) - return(0); - if ( ! mbuf_nputstring(p, "=\"", 2)) - return(0); - if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true")) - return(0); - if ( ! mbuf_nputstring(p, "\"", 1)) - return(0); - } - - if ( ! mbuf_nputstring(p, ">", 1)) - return(0); - if ( ! mbuf_newline(p)) - return(0); - - p->indent++; - return(1); -} - - -static int -roffblkout(void *arg, int tok) -{ - struct md_valid *p; - - assert(arg); - p = (struct md_valid *)arg; - - p->indent--; - - if (0 != p->pos) { - if ( ! mbuf_newline(p)) - return(0); - if ( ! mbuf_indent(p)) - return(0); - } else if ( ! mbuf_indent(p)) - return(0); - - if ( ! mbuf_nputstring(p, "", 1)) - return(0); - if ( ! mbuf_newline(p)) - return(0); - - return(1); -} - - -static int -roffin(void *arg, int tok, int space, int *argc, char **argv) -{ - struct md_valid *p; - int i; - - assert(arg); - p = (struct md_valid *)arg; - - if (0 == p->pos && ! mbuf_indent(p)) - return(0); - - /* - * FIXME: put into a buffer before writing (check line length). - */ - - if (space && ! mbuf_nputstring(p, " ", 1)) - return(0); - if ( ! mbuf_nputstring(p, "<", 1)) - return(0); - if ( ! mbuf_putstring(p, toknames[tok])) - return(0); - - for (i = 0; ROFF_ARGMAX != argc[i]; i++) { - if ( ! mbuf_nputstring(p, " ", 1)) - return(0); - if ( ! mbuf_putstring(p, tokargnames[argc[i]])) - return(0); - if ( ! mbuf_nputstring(p, "=\"", 2)) - return(0); - if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true")) - return(0); - if ( ! mbuf_nputstring(p, "\"", 1)) - return(0); - } - - return(mbuf_nputstring(p, ">", 1)); -} - - -static int -roffout(void *arg, int tok) -{ - struct md_valid *p; - - assert(arg); - p = (struct md_valid *)arg; - - if (0 == p->pos && ! mbuf_indent(p)) - return(0); - - if ( ! mbuf_nputstring(p, "", 1)); -} - - -static void -roffmsg(void *arg, enum roffmsg lvl, - const char *buf, const char *pos, char *msg) -{ - char *level; - struct md_valid *p; - - assert(arg); - p = (struct md_valid *)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_valid *p; - - assert(arg); - p = (struct md_valid *)arg; - return(mbuf_data(p, space, buf)); -} diff --git a/xml.c b/xml.c new file mode 100644 index 00000000..d9916767 --- /dev/null +++ b/xml.c @@ -0,0 +1,502 @@ +/* $Id$ */ +/* + * 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 "libmdocml.h" +#include "private.h" + +#define INDENT 4 +#define COLUMNS 60 + +#ifdef __linux__ /* FIXME */ +#define strlcat strncat +#endif + +enum md_tok { + MD_BLKIN, + 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) /* FIXME */ +}; + +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); + +static int mbuf_newline(struct md_xml *); +static int mbuf_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 *, + const char *, size_t); + + +static int +mbuf_putstring(struct md_xml *p, const char *buf) +{ + + return(mbuf_nputstring(p, buf, strlen(buf))); +} + + +static int +mbuf_nputstring(struct md_xml *p, const char *buf, size_t sz) +{ + + p->pos += sz; + return(md_buf_puts(p->mbuf, buf, sz)); +} + + +static int +mbuf_indent(struct md_xml *p) +{ + size_t i; + + assert(p->pos == 0); + + /* LINTED */ + for (i = 0; i < MIN(p->indent, INDENT); i++) + if ( ! md_buf_putstring(p->mbuf, " ")) + return(0); + + p->pos += i * INDENT; + 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_LITERAL & p->flags) + return(mbuf_putstring(p, 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 (0 == p->pos) { + if ( ! mbuf_indent(p)) + return(0); + if ( ! mbuf_nputstring(p, bufp, sz)) + return(0); + if (p->indent * INDENT + sz >= COLUMNS) { + if ( ! mbuf_newline(p)) + return(0); + continue; + } + continue; + } + + if (space && sz + p->pos >= COLUMNS) { + if ( ! mbuf_newline(p)) + return(0); + if ( ! mbuf_indent(p)) + return(0); + } else if (space) { + if ( ! mbuf_nputstring(p, " ", 1)) + return(0); + } + + if ( ! mbuf_nputstring(p, bufp, sz)) + return(0); + + if ( ! space && p->pos >= COLUMNS) + if ( ! mbuf_newline(p)) + return(0); + } + + return(1); +} + + +int +md_line_xml(void *arg, char *buf) +{ + struct md_xml *p; + + p = (struct md_xml *)arg; + return(roff_engine(p->tree, 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); +} + + +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 ( ! mbuf_putstring(p, "\n")) + return(0); + if ( ! mbuf_nputstring(p, "", 12)) + return(0); + + p->indent++; + p->last = 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); + + if ( ! mbuf_nputstring(p, "", 13)) + return(0); + + p->last = MD_BLKOUT; + return(mbuf_newline(p)); +} + + +/* ARGSUSED */ +static int +roffspecial(void *arg, int tok) +{ + + /* FIXME */ + return(1); +} + + +static int +roffblkin(void *arg, int tok, int *argc, char **argv) +{ + struct md_xml *p; + int i; + + assert(arg); + p = (struct md_xml *)arg; + + if (0 != p->pos) { + if ( ! mbuf_newline(p)) + return(0); + if ( ! mbuf_indent(p)) + return(0); + } else if ( ! mbuf_indent(p)) + return(0); + + if ( ! mbuf_nputstring(p, "<", 1)) + return(0); + if ( ! mbuf_nputstring(p, "block:", 6)) + return(0); + if ( ! mbuf_putstring(p, toknames[tok])) + return(0); + + for (i = 0; ROFF_ARGMAX != argc[i]; i++) { + if ( ! mbuf_nputstring(p, " ", 1)) + return(0); + if ( ! mbuf_putstring(p, tokargnames[argc[i]])) + return(0); + if ( ! mbuf_nputstring(p, "=\"", 2)) + return(0); + if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true")) + return(0); + if ( ! mbuf_nputstring(p, "\"", 1)) + return(0); + } + + if ( ! mbuf_nputstring(p, ">", 1)) + return(0); + + p->last = MD_BLKIN; + p->indent++; + 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 ( ! mbuf_indent(p)) + return(0); + } else if ( ! mbuf_indent(p)) + return(0); + + if ( ! mbuf_nputstring(p, "", 1)) + return(0); + + p->last = MD_BLKOUT; + return(mbuf_newline(p)); +} + + +static int +roffin(void *arg, int tok, int *argc, char **argv) +{ + struct md_xml *p; + int i; + + assert(arg); + p = (struct md_xml *)arg; + + /* + * FIXME: put all of this in a buffer, then check the buffer + * length versus the column width for nicer output. This is a + * bit hacky. + */ + + if (p->pos + 11 > COLUMNS) + if ( ! mbuf_newline(p)) + return(0); + + if (0 != p->pos) { + switch (p->last) { + case (MD_TEXT): + /* FALLTHROUGH */ + case (MD_OUT): + if ( ! mbuf_nputstring(p, " ", 1)) + return(0); + break; + default: + break; + } + } else if ( ! mbuf_indent(p)) + return(0); + + p->last = MD_IN; + + if ( ! mbuf_nputstring(p, "<", 1)) + return(0); + if ( ! mbuf_nputstring(p, "inline:", 7)) + return(0); + if ( ! mbuf_putstring(p, toknames[tok])) + return(0); + + for (i = 0; ROFF_ARGMAX != argc[i]; i++) { + if ( ! mbuf_nputstring(p, " ", 1)) + return(0); + if ( ! mbuf_putstring(p, tokargnames[argc[i]])) + return(0); + if ( ! mbuf_nputstring(p, "=\"", 2)) + return(0); + if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true")) + return(0); + if ( ! mbuf_nputstring(p, "\"", 1)) + return(0); + } + return(mbuf_nputstring(p, ">", 1)); +} + + +static int +roffout(void *arg, int tok) +{ + struct md_xml *p; + + assert(arg); + p = (struct md_xml *)arg; + + if (0 == p->pos && ! mbuf_indent(p)) + return(0); + + p->last = MD_OUT; + + if ( ! mbuf_nputstring(p, "", 1)); +} + + +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); + + p->last = MD_TEXT; + return(1); +} -- cgit