summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2011-07-25 15:37:00 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2011-07-25 15:37:00 +0000
commit50079d4076610ce94c315c3ead86fa3dd19dc673 (patch)
treea0a462e3767cedd8ddb18951887372ecbe0ebe93
parent9e5a4ae8da2d23137cf7342e8fe27ed1172b98f5 (diff)
downloadmandoc-50079d4076610ce94c315c3ead86fa3dd19dc673.tar.gz
Implement the first steps of equation parsing from within libmdoc.
This consists of a shim around the text parser that calls out to libroff if equation components exist on the line. Right now this will do nothing, as the equation delimiter always returns nil.
-rw-r--r--Makefile5
-rw-r--r--eqn.c11
-rw-r--r--libmandoc.h4
-rw-r--r--libroff.h4
-rw-r--r--mdoc.c54
-rw-r--r--roff.c49
-rw-r--r--tbl.c6
7 files changed, 113 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index 47cacdf0..351dcc08 100644
--- a/Makefile
+++ b/Makefile
@@ -332,6 +332,11 @@ clean:
rm -f config.h config.log $(COMPAT_OBJS) $(COMPAT_LNS)
rm -f mdocml.tar.gz mdocml-win32.zip
rm -f index.html $(INDEX_OBJS)
+ rm -rf test-strlcpy.DSYM
+ rm -rf test-strlcat.DSYM
+ rm -rf test-strptime.DSYM
+ rm -rf test-mmap.DSYM
+ rm -rf test-getsubopt.DSYM
install: all
mkdir -p $(DESTDIR)$(BINDIR)
diff --git a/eqn.c b/eqn.c
index 63d53d20..2ff91b7a 100644
--- a/eqn.c
+++ b/eqn.c
@@ -294,8 +294,7 @@ eqn_read(struct eqn_node **epp, int ln,
*/
if (0 == strncmp(p, ".EN", 3)) {
- er = eqn_end(ep);
- *epp = NULL;
+ er = eqn_end(epp);
p += 3;
while (' ' == *p || '\t' == *p)
p++;
@@ -333,7 +332,7 @@ eqn_alloc(const char *name, int pos, int line, struct mparse *parse)
p = mandoc_calloc(1, sizeof(struct eqn_node));
- if ('\0' != *name) {
+ if (name && '\0' != *name) {
sz = strlen(name);
assert(sz);
do {
@@ -352,11 +351,15 @@ eqn_alloc(const char *name, int pos, int line, struct mparse *parse)
}
enum rofferr
-eqn_end(struct eqn_node *ep)
+eqn_end(struct eqn_node **epp)
{
+ struct eqn_node *ep;
struct eqn_box *root;
enum eqn_rest c;
+ ep = *epp;
+ *epp = NULL;
+
ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box));
root = ep->eqn.root;
diff --git a/libmandoc.h b/libmandoc.h
index 7a79257a..c7f0b41d 100644
--- a/libmandoc.h
+++ b/libmandoc.h
@@ -76,6 +76,10 @@ void roff_endparse(struct roff *);
int roff_regisset(const struct roff *, enum regs);
unsigned int roff_regget(const struct roff *, enum regs);
void roff_regunset(struct roff *, enum regs);
+char roff_eqndelim(const struct roff *);
+void roff_openeqn(struct roff *, const char *,
+ int, int, const char *);
+int roff_closeeqn(struct roff *);
const struct tbl_span *roff_span(const struct roff *);
const struct eqn *roff_eqn(const struct roff *);
diff --git a/libroff.h b/libroff.h
index f6317a96..8752b68c 100644
--- a/libroff.h
+++ b/libroff.h
@@ -72,9 +72,9 @@ int tbl_layout(struct tbl_node *, int, const char *);
int tbl_data(struct tbl_node *, int, const char *);
int tbl_cdata(struct tbl_node *, int, const char *);
const struct tbl_span *tbl_span(struct tbl_node *);
-void tbl_end(struct tbl_node *);
+void tbl_end(struct tbl_node **);
struct eqn_node *eqn_alloc(const char *, int, int, struct mparse *);
-enum rofferr eqn_end(struct eqn_node *);
+enum rofferr eqn_end(struct eqn_node **);
void eqn_free(struct eqn_node *);
enum rofferr eqn_read(struct eqn_node **, int,
const char *, int, int *);
diff --git a/mdoc.c b/mdoc.c
index 13a2f001..b67b6c87 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -97,6 +97,7 @@ static struct mdoc_node *node_alloc(struct mdoc *, int, int,
enum mdoct, enum mdoc_type);
static int node_append(struct mdoc *,
struct mdoc_node *);
+static int mdoc_preptext(struct mdoc *, int, char *, int);
static int mdoc_ptext(struct mdoc *, int, char *, int);
static int mdoc_pmacro(struct mdoc *, int, char *, int);
@@ -299,7 +300,7 @@ mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs)
return(mandoc_getcontrol(buf, &offs) ?
mdoc_pmacro(m, ln, buf, offs) :
- mdoc_ptext(m, ln, buf, offs));
+ mdoc_preptext(m, ln, buf, offs));
}
int
@@ -650,6 +651,57 @@ mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
mdoc_node_free(p);
}
+/*
+ * Pre-treat a text line.
+ * Text lines can consist of equations, which must be handled apart from
+ * the regular text.
+ * Thus, use this function to step through a line checking if it has any
+ * equations embedded in it.
+ * This must handle multiple equations AND equations that do not end at
+ * the end-of-line, i.e., will re-enter in the next roff parse.
+ */
+static int
+mdoc_preptext(struct mdoc *m, int line, char *buf, int offs)
+{
+ char *start, *end;
+ char delim;
+
+ while ('\0' != buf[offs]) {
+ /* Mark starting position if eqn is set. */
+ start = NULL;
+ if ('\0' != (delim = roff_eqndelim(m->roff)))
+ if (NULL != (start = strchr(buf + offs, delim)))
+ *start++ = '\0';
+
+ /* Parse text as normal. */
+ if ( ! mdoc_ptext(m, line, buf, offs))
+ return(0);
+
+ /* Continue only if an equation exists. */
+ if (NULL == start)
+ break;
+
+ /* Read past the end of the equation. */
+ offs += start - (buf + offs);
+ assert(start == &buf[offs]);
+ if (NULL != (end = strchr(buf + offs, delim))) {
+ *end++ = '\0';
+ while (' ' == *end)
+ end++;
+ }
+
+ /* Parse the equation itself. */
+ roff_openeqn(m->roff, NULL, line, offs, buf);
+
+ /* Process a finished equation? */
+ if (roff_closeeqn(m->roff))
+ if ( ! mdoc_addeqn(m, roff_eqn(m->roff)))
+ return(0);
+ offs += (end - (buf + offs));
+ }
+
+ return(1);
+}
/*
* Parse free-form text, that is, a line that does not begin with the
diff --git a/roff.c b/roff.c
index c6757a29..2ee06873 100644
--- a/roff.c
+++ b/roff.c
@@ -584,15 +584,13 @@ roff_endparse(struct roff *r)
if (r->eqn) {
mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
r->eqn->eqn.ln, r->eqn->eqn.pos, NULL);
- eqn_end(r->eqn);
- r->eqn = NULL;
+ eqn_end(&r->eqn);
}
if (r->tbl) {
mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse,
r->tbl->line, r->tbl->pos, NULL);
- tbl_end(r->tbl);
- r->tbl = NULL;
+ tbl_end(&r->tbl);
}
}
@@ -1182,9 +1180,8 @@ roff_TE(ROFF_ARGS)
if (NULL == r->tbl)
mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL);
else
- tbl_end(r->tbl);
+ tbl_end(&r->tbl);
- r->tbl = NULL;
return(ROFF_IGN);
}
@@ -1201,14 +1198,22 @@ roff_T_(ROFF_ARGS)
return(ROFF_IGN);
}
-/* ARGSUSED */
-static enum rofferr
-roff_EQ(ROFF_ARGS)
+int
+roff_closeeqn(struct roff *r)
{
- struct eqn_node *e;
+
+ return(r->eqn && ROFF_EQN == eqn_end(&r->eqn) ? 1 : 0);
+}
+
+void
+roff_openeqn(struct roff *r, const char *name, int line,
+ int offs, const char *buf)
+{
+ struct eqn_node *e;
+ int poff;
assert(NULL == r->eqn);
- e = eqn_alloc(*bufp + pos, ppos, ln, r->parse);
+ e = eqn_alloc(name, offs, line, r->parse);
if (r->last_eqn)
r->last_eqn->next = e;
@@ -1216,6 +1221,19 @@ roff_EQ(ROFF_ARGS)
r->first_eqn = r->last_eqn = e;
r->eqn = r->last_eqn = e;
+
+ if (buf) {
+ poff = 0;
+ eqn_read(&r->eqn, line, buf, offs, &poff);
+ }
+}
+
+/* ARGSUSED */
+static enum rofferr
+roff_EQ(ROFF_ARGS)
+{
+
+ roff_openeqn(r, *bufp + pos, ln, ppos, NULL);
return(ROFF_IGN);
}
@@ -1236,7 +1254,7 @@ roff_TS(ROFF_ARGS)
if (r->tbl) {
mandoc_msg(MANDOCERR_SCOPEBROKEN, r->parse, ln, ppos, NULL);
- tbl_end(r->tbl);
+ tbl_end(&r->tbl);
}
t = tbl_alloc(ppos, ln, r->parse);
@@ -1472,3 +1490,10 @@ roff_eqn(const struct roff *r)
return(r->last_eqn ? &r->last_eqn->eqn : NULL);
}
+
+char
+roff_eqndelim(const struct roff *r)
+{
+
+ return('\0');
+}
diff --git a/tbl.c b/tbl.c
index 10e11ca4..5af3ccf1 100644
--- a/tbl.c
+++ b/tbl.c
@@ -154,8 +154,12 @@ tbl_span(struct tbl_node *tbl)
}
void
-tbl_end(struct tbl_node *tbl)
+tbl_end(struct tbl_node **tblp)
{
+ struct tbl_node *tbl;
+
+ tbl = *tblp;
+ *tblp = NULL;
if (NULL == tbl->first_span || NULL == tbl->first_span->first)
mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse,