summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2008-12-02 00:10:37 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2008-12-02 00:10:37 +0000
commit0d055120de349c30f0ceb537d57f8694f67397da (patch)
tree6909226bceaa9d9affdfc9845b27a40c83ef76f3
parentfcccec27b02c05557ea3cad60051abb8ca5a2e62 (diff)
downloadmandoc-0d055120de349c30f0ceb537d57f8694f67397da.tar.gz
Improvements to the xml part.
-rw-r--r--Makefile2
-rw-r--r--libmdocml.c2
-rw-r--r--mdocml.16
-rw-r--r--mdocml.c3
-rw-r--r--roff.c143
-rw-r--r--xml.c170
6 files changed, 213 insertions, 113 deletions
diff --git a/Makefile b/Makefile
index fb85076f..e659dbc0 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,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.25 test.28 test.29 test.31 test.32 test.33 test.34
all: mdocml
diff --git a/libmdocml.c b/libmdocml.c
index a10519bd..7cf6c079 100644
--- a/libmdocml.c
+++ b/libmdocml.c
@@ -150,7 +150,7 @@ md_run_leave(const struct md_args *args, struct md_mbuf *mbuf,
}
/* Make final flush of buffer. */
- if ( ! md_buf_flush(mbuf))
+ if (-1 != c && ! md_buf_flush(mbuf))
return(-1);
return(c);
diff --git a/mdocml.1 b/mdocml.1
index 765b3a41..4bfd0cf3 100644
--- a/mdocml.1
+++ b/mdocml.1
@@ -84,7 +84,6 @@ structured ones:
The engine doesn't understand the
.Sq \&Xo ,
.Sq \&Xc ,
-.Sq \&Ns ,
.Sq \&No ,
.Sq \&Db ,
.Sq \&Sm ,
@@ -102,4 +101,9 @@ If terminating punctuation is found, then
remaining tokens are flushed after line scope is closed, not just the
last one.
.El
+.Pp
+The roff engine in
+.Nm
+produces text in-line; thus, output may already be partially written by
+the time an error is encountered.
.\" .Sh BUGS
diff --git a/mdocml.c b/mdocml.c
index 4f7eac9a..84ceec26 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -106,6 +106,9 @@ leave_io(const struct md_buf *out,
warn("%s", out->name);
c = 1;
}
+ if (1 == c && STDOUT_FILENO != out->fd)
+ if (-1 == unlink(out->name))
+ warn("%s", out->name);
return(c);
}
diff --git a/roff.c b/roff.c
index cb5983b5..9b513050 100644
--- a/roff.c
+++ b/roff.c
@@ -112,6 +112,7 @@ struct rofftree {
static int roff_Dd(ROFFCALL_ARGS);
static int roff_Dt(ROFFCALL_ARGS);
static int roff_Os(ROFFCALL_ARGS);
+static int roff_Ns(ROFFCALL_ARGS);
static int roff_layout(ROFFCALL_ARGS);
static int roff_text(ROFFCALL_ARGS);
@@ -126,6 +127,7 @@ static void roff_warn(const struct rofftree *,
static void roff_err(const struct rofftree *,
const char *, char *, ...);
+static int roffpurgepunct(struct rofftree *, char **);
static int roffscan(int, const int *);
static int rofffindtok(const char *);
static int rofffindarg(const char *);
@@ -253,7 +255,7 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ 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 }, /* Ns */
+ { 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 */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pc */
@@ -878,6 +880,29 @@ roffnextopt(const struct rofftree *tree, int tok,
static int
+roffpurgepunct(struct rofftree *tree, char **argv)
+{
+ int i;
+
+ i = 0;
+ while (argv[i])
+ i++;
+ assert(i > 0);
+ if ( ! roffispunct(argv[--i]))
+ return(1);
+ while (i >= 0 && roffispunct(argv[i]))
+ i--;
+ i++;
+
+ /* LINTED */
+ while (argv[i])
+ if ( ! (*tree->cb.roffdata)(tree->arg, 0, argv[i++]))
+ return(0);
+ return(1);
+}
+
+
+static int
roffparseopts(struct rofftree *tree, int tok,
char ***args, int *argc, char **argv)
{
@@ -1047,6 +1072,79 @@ roff_Dt(ROFFCALL_ARGS)
/* ARGSUSED */
static int
+roff_Ns(ROFFCALL_ARGS)
+{
+ int j, c, first;
+
+ first = (*argv == tree->cur);
+
+ argv++;
+
+ if (ROFF_MAX != (c = rofffindcallable(*argv))) {
+ if (NULL == tokens[c].cb) {
+ roff_err(tree, *argv, "unsupported macro `%s'",
+ toknames[c]);
+ return(0);
+ }
+ if ( ! (*tree->cb.roffspecial)(tree->arg, tok))
+ return(0);
+ if ( ! (*tokens[c].cb)(c, tree, argv, ROFF_ENTER))
+ return(0);
+ if ( ! first)
+ return(1);
+ return(roffpurgepunct(tree, argv));
+ }
+
+ if ( ! (*tree->cb.roffdata)(tree->arg, 0, *argv++))
+ return(0);
+
+ while (*argv) {
+ if (ROFF_MAX == (c = rofffindcallable(*argv))) {
+ if ( ! roffispunct(*argv)) {
+ if ( ! (*tree->cb.roffdata)
+ (tree->arg, 1, *argv++))
+ return(0);
+ continue;
+ }
+
+ /* FIXME: this is identical to that of
+ * roff_text. */
+
+ /* See if only punctuation remains. */
+
+ for (j = 0; argv[j]; j++)
+ if ( ! roffispunct(argv[j]))
+ break;
+
+ if (argv[j]) {
+ if ( ! (*tree->cb.roffdata)
+ (tree->arg, 0, *argv++))
+ return(0);
+ continue;
+ }
+
+ /* Only punctuation remains. */
+
+ break;
+ }
+ if (NULL == tokens[c].cb) {
+ roff_err(tree, *argv, "unsupported macro `%s'",
+ toknames[c]);
+ return(0);
+ }
+ if ( ! (*tokens[c].cb)(c, tree, argv, ROFF_ENTER))
+ return(0);
+ break;
+ }
+
+ if ( ! first)
+ return(1);
+ return(roffpurgepunct(tree, argv));
+}
+
+
+/* ARGSUSED */
+static int
roff_Os(ROFFCALL_ARGS)
{
char *p;
@@ -1188,23 +1286,8 @@ roff_layout(ROFFCALL_ARGS)
* a token isn't punctuation.
*/
- i = 0;
- while (argv[i])
- i++;
-
- assert(i > 0);
- if ( ! roffispunct(argv[--i]))
- return((*tree->cb.roffout)(tree->arg, tok));
-
- while (i >= 0 && roffispunct(argv[i]))
- i--;
-
- i++;
-
- /* LINTED */
- while (argv[i])
- if ( ! (*tree->cb.roffdata)(tree->arg, 0, argv[i++]))
- return(0);
+ if ( ! roffpurgepunct(tree, argv))
+ return(0);
return((*tree->cb.roffout)(tree->arg, tok));
}
@@ -1314,29 +1397,7 @@ roff_text(ROFFCALL_ARGS)
if ( ! first)
return(1);
- /*
- * We're the line-dominant macro. Check if there's remaining
- * punctuation. If there is, then flush it out before exiting.
- */
-
- i = 0;
- while (argv[i])
- i++;
-
- assert(i > 0);
- if ( ! roffispunct(argv[--i]))
- return(1);
-
- while (i >= 0 && roffispunct(argv[i]))
- i--;
- i++;
-
- /* LINTED */
- while (argv[i])
- if ( ! (*tree->cb.roffdata)(tree->arg, 0, argv[i++]))
- return(0);
-
- return(1);
+ return(roffpurgepunct(tree, argv));
}
diff --git a/xml.c b/xml.c
index 99f41f07..4445f9c2 100644
--- a/xml.c
+++ b/xml.c
@@ -29,12 +29,18 @@
#include "private.h"
#define MAXINDENT 8
-#define COLUMNS 60
+#define COLUMNS 72
#ifdef __linux__ /* FIXME */
#define strlcat strncat
#endif
+enum md_ns {
+ MD_NS_BLOCK,
+ MD_NS_INLINE,
+ MD_NS_DEFAULT
+};
+
enum md_tok {
MD_BLKIN,
MD_BLKOUT,
@@ -78,6 +84,76 @@ static int mbuf_nputstring(struct md_xml *,
static int mbuf_puts(struct md_xml *, const char *);
static int mbuf_nputs(struct md_xml *,
const char *, size_t);
+static int mbuf_begintag(struct md_xml *, const char *,
+ enum md_ns, int *, char **);
+static int mbuf_endtag(struct md_xml *,
+ const char *, enum md_ns);
+
+
+static int
+mbuf_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);
+
+ 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;
+ }
+
+ if ( ! mbuf_puts(p, name))
+ 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));
+}
+
+
+static int
+mbuf_endtag(struct md_xml *p, const char *tag, enum md_ns ns)
+{
+ if ( ! mbuf_nputs(p, "</", 2))
+ return(0);
+
+ 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;
+ }
+
+ if ( ! mbuf_puts(p, tag))
+ return(0);
+ return(mbuf_nputs(p, ">", 1));
+}
static int
@@ -105,6 +181,16 @@ mbuf_nputstring(struct md_xml *p, const char *buf, size_t sz)
return(0);
p->pos += 6;
break;
+ case ('<'):
+ if ( ! md_buf_puts(p->mbuf, "&lt;", 4))
+ return(0);
+ p->pos += 4;
+ break;
+ case ('>'):
+ if ( ! md_buf_puts(p->mbuf, "&gt;", 4))
+ return(0);
+ p->pos += 4;
+ break;
default:
if ( ! md_buf_putchar(p->mbuf, buf[i]))
return(0);
@@ -318,15 +404,14 @@ rofftail(void *arg)
if (0 != p->pos && ! mbuf_newline(p))
return(0);
- if ( ! mbuf_puts(p, "</mdoc>"))
+ p->last = MD_BLKOUT;
+ if ( ! mbuf_endtag(p, "mdoc", MD_NS_DEFAULT))
return(0);
- p->last = MD_BLKOUT;
return(mbuf_newline(p));
}
-/* ARGSUSED */
static int
roffspecial(void *arg, int tok)
{
@@ -335,6 +420,8 @@ roffspecial(void *arg, int tok)
assert(arg);
p = (struct md_xml *)arg;
+ /* FIXME: this is completely ad hoc. */
+
switch (tok) {
case (ROFF_Ns):
p->last = MD_OVERRIDE;
@@ -351,7 +438,6 @@ static int
roffblkin(void *arg, int tok, int *argc, char **argv)
{
struct md_xml *p;
- int i;
assert(arg);
p = (struct md_xml *)arg;
@@ -364,33 +450,14 @@ roffblkin(void *arg, int tok, int *argc, char **argv)
} else if ( ! mbuf_indent(p))
return(0);
- if ( ! mbuf_nputs(p, "<", 1))
- return(0);
- if ( ! mbuf_nputs(p, "block:", 6))
- return(0);
- if ( ! mbuf_puts(p, toknames[tok]))
- return(0);
-
/* FIXME: xml won't like standards args (e.g., p1003.1-90). */
- 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);
- }
-
- if ( ! mbuf_nputs(p, ">", 1))
- return(0);
-
p->last = MD_BLKIN;
p->indent++;
+
+ if ( ! mbuf_begintag(p, toknames[tok], MD_NS_BLOCK,
+ argc, argv))
+ return(0);
return(mbuf_newline(p));
}
@@ -413,16 +480,10 @@ roffblkout(void *arg, int tok)
} else if ( ! mbuf_indent(p))
return(0);
- if ( ! mbuf_nputs(p, "</", 2))
- return(0);
- if ( ! mbuf_nputs(p, "block:", 6))
- return(0);
- if ( ! mbuf_puts(p, toknames[tok]))
- return(0);
- if ( ! mbuf_nputs(p, ">", 1))
- return(0);
-
p->last = MD_BLKOUT;
+
+ if ( ! mbuf_endtag(p, toknames[tok], MD_NS_BLOCK))
+ return(0);
return(mbuf_newline(p));
}
@@ -431,7 +492,6 @@ static int
roffin(void *arg, int tok, int *argc, char **argv)
{
struct md_xml *p;
- int i;
assert(arg);
p = (struct md_xml *)arg;
@@ -461,27 +521,8 @@ roffin(void *arg, int tok, int *argc, char **argv)
return(0);
p->last = MD_IN;
-
- if ( ! mbuf_nputs(p, "<", 1))
- return(0);
- if ( ! mbuf_nputs(p, "inline:", 7))
- return(0);
- if ( ! mbuf_puts(p, toknames[tok]))
- 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));
+ return(mbuf_begintag(p, toknames[tok],
+ MD_NS_INLINE, argc, argv));
}
@@ -493,20 +534,11 @@ roffout(void *arg, int tok)
assert(arg);
p = (struct md_xml *)arg;
- /* Continue with a regular out token. */
-
if (0 == p->pos && ! mbuf_indent(p))
return(0);
p->last = MD_OUT;
-
- if ( ! mbuf_nputs(p, "</", 2))
- return(0);
- if ( ! mbuf_nputs(p, "inline:", 7))
- return(0);
- if ( ! mbuf_puts(p, toknames[tok]))
- return(0);
- return(mbuf_nputs(p, ">", 1));
+ return(mbuf_endtag(p, toknames[tok], MD_NS_INLINE));
}