summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--html.c12
-rw-r--r--mlg.c223
-rw-r--r--private.h2
-rw-r--r--roff.c125
-rw-r--r--xml.c2
6 files changed, 226 insertions, 140 deletions
diff --git a/Makefile b/Makefile
index db7297b7..5d62ced9 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ FAIL = test.0 test.1 test.2 test.3 test.4 test.5 test.6 \
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.35 test.38 test.39 test.41
all: mdocml
diff --git a/html.c b/html.c
index de733ab6..9b5d1630 100644
--- a/html.c
+++ b/html.c
@@ -380,16 +380,25 @@ html_begintag(struct md_mbuf *mbuf, const struct md_args *args,
case (MD_NS_BLOCK):
if ( ! html_blocktagname(mbuf, args, tok))
return(0);
+ if (NULL == argc || NULL == argv)
+ return(1);
+ assert(argc && argv);
return(html_blocktagargs(mbuf, args,
tok, argc, argv));
case (MD_NS_BODY):
if ( ! html_blockbodytagname(mbuf, args, tok))
return(0);
+ if (NULL == argc || NULL == argv)
+ return(1);
+ assert(argc && argv);
return(html_blockbodytagargs(mbuf, args,
tok, argc, argv));
case (MD_NS_HEAD):
if ( ! html_blockheadtagname(mbuf, args, tok))
return(0);
+ if (NULL == argc || NULL == argv)
+ return(1);
+ assert(argc && argv);
return(html_blockheadtagargs(mbuf, args,
tok, argc, argv));
default:
@@ -398,6 +407,9 @@ html_begintag(struct md_mbuf *mbuf, const struct md_args *args,
if ( ! html_inlinetagname(mbuf, args, tok))
return(0);
+ if (NULL == argc || NULL == argv)
+ return(1);
+ assert(argc && argv);
return(html_inlinetagargs(mbuf, args, tok, argc, argv));
}
diff --git a/mlg.c b/mlg.c
index 53dbfa6e..71c3f825 100644
--- a/mlg.c
+++ b/mlg.c
@@ -73,8 +73,8 @@ static int mlg_roffdata(void *, int,
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_roffspecial(void *, int,
+ const char *, char **);
static int mlg_roffblkheadin(void *, int,
int *, char **);
static int mlg_roffblkheadout(void *, int);
@@ -82,8 +82,6 @@ static int mlg_roffblkbodyin(void *, int,
int *, char **);
static int mlg_roffblkbodyout(void *, int);
-static int mlg_beginblk(struct md_mlg *, enum md_ns, int,
- int *, char **);
static int mlg_endblk(struct md_mlg *, enum md_ns, int);
static int mlg_begintag(struct md_mlg *, enum md_ns,
int, int *, char **);
@@ -107,27 +105,6 @@ extern size_t strlcpy(char *, const char *, size_t);
static int
-mlg_beginblk(struct md_mlg *p, enum md_ns ns, int tok,
- int *argc, char **argv)
-{
- 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, ns, tok, argc, argv))
- return(0);
- return(mlg_newline(p));
-}
-
-
-static int
mlg_endblk(struct md_mlg *p, enum md_ns ns, int tok)
{
@@ -154,7 +131,37 @@ mlg_begintag(struct md_mlg *p, enum md_ns ns, int tok,
{
ssize_t res;
- /* TODO: extra rules for block/inline. */
+ 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->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->mbuf, "<", 1, &p->pos))
return(0);
@@ -167,9 +174,19 @@ mlg_begintag(struct md_mlg *p, enum md_ns ns, int tok,
assert(res >= 0);
p->pos += (size_t)res;
- /* TODO: extra rules for block/inline. */
+ if ( ! ml_nputs(p->mbuf, ">", 1, &p->pos))
+ return(0);
- return(ml_nputs(p->mbuf, ">", 1, &p->pos));
+ switch (ns) {
+ case (MD_NS_INLINE):
+ break;
+ default:
+ if ( ! mlg_newline(p))
+ return(0);
+ break;
+ }
+
+ return(1);
}
@@ -234,7 +251,6 @@ static int
mlg_data(struct md_mlg *p, int space, const char *start, char *buf)
{
size_t sz;
- char *bufp;
int c;
assert(p->mbuf);
@@ -244,72 +260,51 @@ mlg_data(struct md_mlg *p, int space, const char *start, char *buf)
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++;
+ sz = strlen(buf);
- if (0 != *buf)
- *buf++ = 0;
-
- sz = strlen(bufp);
-
- if (0 == p->pos) {
- if ( ! mlg_indent(p))
- return(0);
-
- c = ml_nputstring(p->mbuf, bufp, sz, &p->pos);
- if (0 == c) {
- mlg_err(p, start, bufp, "invalid "
- "character sequence");
- return(0);
- } else if (c > 1) {
- mlg_warn(p, start, bufp, "bogus "
- "character sequence");
- return(0);
- } else if (-1 == c)
- return(0);
-
- if (p->indent * INDENT + sz >= COLUMNS)
- if ( ! mlg_newline(p))
- return(0);
- if ( ! (ML_OVERRIDE_ALL & p->flags))
- space = 1;
- continue;
- }
+ if (0 == p->pos) {
+ if ( ! mlg_indent(p))
+ return(0);
- 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);
- }
+ c = ml_nputstring(p->mbuf, buf, sz, &p->pos);
- c = ml_nputstring(p->mbuf, bufp, sz, &p->pos);
if (0 == c) {
- mlg_err(p, start, bufp, "invalid "
- "character sequence");
+ mlg_err(p, start, buf, "bad char sequence");
return(0);
} else if (c > 1) {
- mlg_warn(p, start, bufp, "bogus "
- "character sequence");
+ mlg_warn(p, start, buf, "bogus char sequence");
return(0);
} else if (-1 == c)
return(0);
- if ( ! (ML_OVERRIDE_ALL & p->flags))
- space = 1;
+ if (p->indent * INDENT + 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->mbuf, " ", 1, &p->pos))
+ return(0);
}
+ c = ml_nputstring(p->mbuf, buf, sz, &p->pos);
+
+ if (0 == c) {
+ mlg_err(p, start, buf, "bad char sequence");
+ return(0);
+ } else if (c > 1) {
+ mlg_warn(p, start, buf, "bogus char sequence");
+ return(0);
+ } else if (-1 == c)
+ return(0);
+
return(1);
}
@@ -416,7 +411,7 @@ mlg_rofftail(void *arg)
/* ARGSUSED */
static int
-mlg_roffspecial(void *arg, int tok, int *argc, char **argv, char **more)
+mlg_roffspecial(void *arg, int tok, const char *start, char **more)
{
struct md_mlg *p;
@@ -424,6 +419,34 @@ mlg_roffspecial(void *arg, int tok, int *argc, char **argv, char **more)
p = (struct md_mlg *)arg;
switch (tok) {
+ case (ROFF_Xr):
+ if ( ! *more) {
+ mlg_err(p, start, start,
+ "missing required argument");
+ return(0);
+ }
+ if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, NULL))
+ return(0);
+ if ( ! ml_puts(p->mbuf, *more++, &p->pos))
+ return(0);
+ if (*more) {
+ if ( ! ml_nputs(p->mbuf, "(", 1, &p->pos))
+ return(0);
+ if ( ! mlg_data(p, 0, start, *more++))
+ return(0);
+ if ( ! ml_nputs(p->mbuf, ")", 1, &p->pos))
+ return(0);
+ }
+ if (*more) {
+ mlg_err(p, start, start, "too many arguments");
+ return(0);
+ }
+ if ( ! mlg_endtag(p, MD_NS_INLINE, tok))
+ return(0);
+ mlg_mode(p, MD_INLINE_OUT);
+ break;
+ case (ROFF_Fn):
+ break;
case (ROFF_Ns):
p->flags |= ML_OVERRIDE_ONE;
break;
@@ -446,7 +469,7 @@ static int
mlg_roffblkin(void *arg, int tok, int *argc, char **argv)
{
- return(mlg_beginblk((struct md_mlg *)arg,
+ return(mlg_begintag((struct md_mlg *)arg,
MD_NS_BLOCK, tok, argc, argv));
}
@@ -463,7 +486,7 @@ static int
mlg_roffblkbodyin(void *arg, int tok, int *argc, char **argv)
{
- return(mlg_beginblk((struct md_mlg *)arg,
+ return(mlg_begintag((struct md_mlg *)arg,
MD_NS_BODY, tok, argc, argv));
}
@@ -480,7 +503,7 @@ static int
mlg_roffblkheadin(void *arg, int tok, int *argc, char **argv)
{
- return(mlg_beginblk((struct md_mlg *)arg,
+ return(mlg_begintag((struct md_mlg *)arg,
MD_NS_HEAD, tok, argc, argv));
}
@@ -496,31 +519,9 @@ mlg_roffblkheadout(void *arg, int tok)
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));
+ return(mlg_begintag((struct md_mlg *)arg,
+ MD_NS_INLINE, tok, argc, argv));
}
diff --git a/private.h b/private.h
index 9c7f242f..b86cf619 100644
--- a/private.h
+++ b/private.h
@@ -261,7 +261,7 @@ struct roffcb {
int (*roffblkheadout)(void *, int);
int (*roffblkbodyin)(void *, int, int *, char **);
int (*roffblkbodyout)(void *, int);
- int (*roffspecial)(void *, int, int *, char **, char **);
+ int (*roffspecial)(void *, int, const char *, char **);
};
struct rofftree;
diff --git a/roff.c b/roff.c
index fbfd6d8f..3bf83bb4 100644
--- a/roff.c
+++ b/roff.c
@@ -67,18 +67,13 @@ struct rofftok {
const int *children; /* Limit to kids. */
int ctx; /* Blk-close node. */
enum rofftype type; /* Type of macro. */
- int flags;
+ int flags;
#define ROFF_PARSED (1 << 0) /* "Parsed". */
#define ROFF_CALLABLE (1 << 1) /* "Callable". */
#define ROFF_SHALLOW (1 << 2) /* Nesting block. */
#define ROFF_LSCOPE (1 << 3) /* Line scope. */
};
-struct roffarg {
- int flags;
-#define ROFF_VALUE (1 << 0) /* Has a value. */
-};
-
struct roffnode {
int tok; /* Token id. */
struct roffnode *parent; /* Parent (or NULL). */
@@ -111,6 +106,7 @@ static int roff_layout(ROFFCALL_ARGS);
static int roff_text(ROFFCALL_ARGS);
static int roff_noop(ROFFCALL_ARGS);
static int roff_depr(ROFFCALL_ARGS);
+static int roff_ordered(ROFFCALL_ARGS);
static struct roffnode *roffnode_new(int, struct rofftree *);
static void roffnode_free(struct rofftree *);
static void roff_warn(const struct rofftree *,
@@ -133,6 +129,7 @@ static int roffcall(struct rofftree *, int, char **);
static int roffparse(struct rofftree *, char *);
static int textparse(struct rofftree *, char *);
static int roffdata(struct rofftree *, int, char *);
+static int roffspecial(struct rofftree *, int, char **);
#ifdef __linux__
extern size_t strlcat(char *, const char *, size_t);
@@ -203,7 +200,7 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fa */ /* XXX needs arg */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Fd */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fl */
- { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Fn */ /* XXX needs arg */ /* FIXME */
+ {roff_ordered, NULL, NULL, NULL, 0, ROFF_TEXT, /*XXX*/ -1 }, /* Fn */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ft */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ic */ /* XXX needs arg */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* In */
@@ -217,7 +214,7 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ roff_text, roffarg_St, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* St */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Va */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Vt */ /* XXX needs arg */
- { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xr */ /* XXX needs arg */
+ {roff_ordered, NULL, NULL, NULL, 0, ROFF_TEXT, /*XXX*/ -1 }, /* Xr */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* %A */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE}, /* %B */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* %D */
@@ -249,7 +246,7 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Eo */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Fx */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ms */
- { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* No */
+ { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* No */
{ roff_Ns, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ns */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Nx */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ox */
@@ -271,8 +268,8 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Sy */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Tn */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ux */
- { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xc */
- { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xo */
+ { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xc */
+ { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Xo */
{ roff_layout, NULL, NULL, roffchild_Fo, 0, ROFF_LAYOUT, 0 }, /* Fo */
{ roff_noop, NULL, roffparent_Fc, NULL, ROFF_Fo, ROFF_LAYOUT, 0 }, /* Fc */
{ roff_layout, NULL, NULL, NULL, 0, ROFF_LAYOUT, 0 }, /* Oo */
@@ -285,6 +282,8 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ NULL, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Ud */
};
+#define ROFF_VALUE (1 << 0)
+
static const int tokenargs[ROFF_ARGMAX] = {
0, 0, 0, 0,
0, ROFF_VALUE, ROFF_VALUE, 0,
@@ -501,6 +500,13 @@ roffargs(const struct rofftree *tree,
p = buf;
+ /*
+ * This is an ugly little loop. It parses a line into
+ * space-delimited tokens. If a quote mark is encountered, a
+ * token is alloted the entire quoted text. If whitespace is
+ * escaped, it's included in the prior alloted token.
+ */
+
/* LINTED */
for (i = 0; *buf && i < ROFF_MAXLINEARG; i++) {
if ('\"' == *buf) {
@@ -516,8 +522,17 @@ roffargs(const struct rofftree *tree,
}
} else {
argv[i] = buf++;
- while (*buf && ! isspace(*buf))
- buf++;
+ while (*buf) {
+ if ( ! isspace(*buf)) {
+ buf++;
+ continue;
+ }
+ if (*(buf - 1) == '\\') {
+ buf++;
+ continue;
+ }
+ break;
+ }
if (0 == *buf)
continue;
}
@@ -525,7 +540,7 @@ roffargs(const struct rofftree *tree,
while (*buf && isspace(*buf))
buf++;
}
-
+
assert(i > 0);
if (ROFF_MAXLINEARG == i && *buf) {
roff_err(tree, p, "too many arguments for `%s'", toknames
@@ -861,6 +876,15 @@ roffnode_free(struct rofftree *tree)
static int
+roffspecial(struct rofftree *tree, int tok, char **ordp)
+{
+
+ return((*tree->cb.roffspecial)(tree->arg, tok,
+ tree->cur, ordp));
+}
+
+
+static int
roffcall(struct rofftree *tree, int tok, char **argv)
{
@@ -1124,13 +1148,10 @@ roff_Dt(ROFFCALL_ARGS)
static int
roff_Sm(ROFFCALL_ARGS)
{
- int argcp[1];
- char *argvp[1], *morep[1], *p;
+ char *morep[1], *p;
p = *argv++;
- argcp[0] = ROFF_ARGMAX;
- argvp[0] = NULL;
if (NULL == (morep[0] = *argv++)) {
roff_err(tree, p, "`Sm' expects an argument");
return(0);
@@ -1143,8 +1164,7 @@ roff_Sm(ROFFCALL_ARGS)
if (*argv)
roff_warn(tree, *argv, "`Sm' shouldn't have arguments");
- if ( ! (*tree->cb.roffspecial)(tree->arg,
- tok, argcp, argvp, morep))
+ if ( ! roffspecial(tree, tok, morep))
return(0);
while (*argv)
@@ -1160,16 +1180,12 @@ static int
roff_Ns(ROFFCALL_ARGS)
{
int j, c, first;
- int argcp[1];
- char *argvp[1], *morep[1];
+ char *morep[1];
first = (*argv++ == tree->cur);
+ morep[0] = NULL;
- argcp[0] = ROFF_ARGMAX;
- argvp[0] = morep[0] = NULL;
-
- if ( ! (*tree->cb.roffspecial)(tree->arg,
- tok, argcp, argvp, morep))
+ if ( ! roffspecial(tree, tok, morep))
return(0);
while (*argv) {
@@ -1362,6 +1378,61 @@ roff_layout(ROFFCALL_ARGS)
/* ARGSUSED */
static int
+roff_ordered(ROFFCALL_ARGS)
+{
+ int i, first, c;
+ char *ordp[ROFF_MAXLINEARG];
+
+ if (ROFF_PRELUDE & tree->state) {
+ roff_err(tree, *argv, "`%s' disallowed in prelude",
+ toknames[tok]);
+ return(0);
+ }
+
+ first = (*argv == tree->cur);
+ argv++;
+
+ if (NULL == *argv) {
+
+ /* FIXME: satisfies number of args? */
+
+ ordp[0] = NULL;
+ return(roffspecial(tree, tok, ordp));
+ }
+
+ i = 0;
+ while (*argv && i < ROFF_MAXLINEARG) {
+ if (ROFF_MAX != (c = rofffindcallable(*argv)))
+ return(roffcall(tree, c, argv));
+ if (roffispunct(*argv))
+ break;
+
+ ordp[i++] = *argv++;
+ }
+
+ ordp[i] = NULL;
+
+ /* FIXME: too many or too few args? */
+
+ if (i == ROFF_MAXLINEARG && *argv) {
+ roff_err(tree, *argv, "too many args", toknames[tok]);
+ return(0);
+ }
+
+ /* FIXME: error if there's stuff after the punctuation. */
+
+ if ( ! roffspecial(tree, tok, ordp))
+ return(0);
+
+ if ( ! first || NULL == *argv)
+ return(1);
+
+ return(roffpurgepunct(tree, argv));
+}
+
+
+/* ARGSUSED */
+static int
roff_text(ROFFCALL_ARGS)
{
int i, j, first, c, argcp[ROFF_MAXLINEARG];
diff --git a/xml.c b/xml.c
index 90ce6124..124c80ae 100644
--- a/xml.c
+++ b/xml.c
@@ -83,6 +83,8 @@ xml_begintag(struct md_mbuf *mbuf, const struct md_args *args,
{
size_t res;
+ /* FIXME: doesn't print arguments! */
+
res = 0;
switch (ns) {