summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eqn.71
-rw-r--r--eqn.c95
-rw-r--r--man_html.c4
-rw-r--r--man_term.c2
-rw-r--r--mandoc.h15
-rw-r--r--mdoc_html.c4
-rw-r--r--mdoc_term.c2
-rw-r--r--tree.c68
8 files changed, 128 insertions, 63 deletions
diff --git a/eqn.7 b/eqn.7
index ee61b3b7..478f890f 100644
--- a/eqn.7
+++ b/eqn.7
@@ -73,6 +73,7 @@ Data in TEXT form is a non-empty sequence of non-space characters or a
non-empty quoted string.
Unless within a quoted string, white-space (and enclosing literal quote
pairs) is thrown away.
+Quoted strings are not scanned for replacement definitions.
.Pp
The following control statements are available:
.Bl -tag -width Ds
diff --git a/eqn.c b/eqn.c
index 681f9554..19b9b859 100644
--- a/eqn.c
+++ b/eqn.c
@@ -44,6 +44,7 @@ enum eqnpartt {
EQN__MAX
};
+static void eqn_box_free(struct eqn_box *);
static struct eqn_def *eqn_def_find(struct eqn_node *,
const char *, size_t);
static int eqn_do_define(struct eqn_node *);
@@ -51,7 +52,7 @@ static int eqn_do_ign2(struct eqn_node *);
static int eqn_do_undef(struct eqn_node *);
static const char *eqn_nexttok(struct eqn_node *, size_t *);
static const char *eqn_next(struct eqn_node *, char, size_t *);
-static int eqn_box(struct eqn_node *);
+static int eqn_box(struct eqn_node *, struct eqn_box *);
static const struct eqnpart eqnparts[EQN__MAX] = {
{ "define", 6, eqn_do_define }, /* EQN_DEFINE */
@@ -116,29 +117,33 @@ eqn_alloc(int pos, int line, struct mparse *parse)
enum rofferr
eqn_end(struct eqn_node *ep)
{
- int c;
+ struct eqn_box *root;
- /*
- * Validate the expression.
- * Use the grammar found in the literature.
- */
+ ep->eqn.root = root =
+ mandoc_calloc(1, sizeof(struct eqn_box));
+ root->type = EQN_ROOT;
if (0 == ep->sz)
return(ROFF_IGN);
- while (1 == (c = eqn_box(ep)))
- /* Keep parsing. */ ;
+ /*
+ * Validate the expression.
+ * Use the grammar found in the literature.
+ */
- return(c < 0 ? ROFF_IGN : ROFF_EQN);
+ return(eqn_box(ep, root) < 0 ? ROFF_IGN : ROFF_EQN);
}
static int
-eqn_box(struct eqn_node *ep)
+eqn_box(struct eqn_node *ep, struct eqn_box *last)
{
size_t sz;
const char *start;
- int i;
+ int i, nextc;
+ struct eqn_box *bp;
+ nextc = 1;
+again:
if (NULL == (start = eqn_nexttok(ep, &sz)))
return(0);
@@ -150,18 +155,24 @@ eqn_box(struct eqn_node *ep)
if ( ! (*eqnparts[i].fp)(ep))
return(-1);
- return(1);
+ goto again;
}
- ep->eqn.data = mandoc_realloc
- (ep->eqn.data, ep->eqn.sz + sz + 1);
+ bp = mandoc_calloc(1, sizeof(struct eqn_box));
+ bp->type = EQN_TEXT;
- if (0 == ep->eqn.sz)
- *ep->eqn.data = '\0';
+ if (nextc)
+ last->child = bp;
+ else
+ last->next = bp;
- ep->eqn.sz += sz;
- strlcat(ep->eqn.data, start, ep->eqn.sz + 1);
- return(1);
+ bp->text = mandoc_malloc(sz + 1);
+ *bp->text = '\0';
+ strlcat(bp->text, start, sz + 1);
+
+ last = bp;
+ nextc = 0;
+ goto again;
}
void
@@ -169,7 +180,7 @@ eqn_free(struct eqn_node *p)
{
int i;
- free(p->eqn.data);
+ eqn_box_free(p->eqn.root);
for (i = 0; i < (int)p->defsz; i++) {
free(p->defs[i].key);
@@ -181,6 +192,19 @@ eqn_free(struct eqn_node *p)
free(p);
}
+static void
+eqn_box_free(struct eqn_box *bp)
+{
+
+ if (bp->child)
+ eqn_box_free(bp->child);
+ if (bp->next)
+ eqn_box_free(bp->next);
+
+ free(bp->text);
+ free(bp);
+}
+
static const char *
eqn_nexttok(struct eqn_node *ep, size_t *sz)
{
@@ -199,6 +223,17 @@ eqn_next(struct eqn_node *ep, char quote, size_t *sz)
if (NULL == sz)
sz = &ssz;
+ lim = 0;
+ sv = ep->cur;
+again:
+ /* Prevent self-definitions. */
+
+ if (lim >= EQN_NEST_MAX) {
+ EQN_MSG(MANDOCERR_EQNNEST, ep);
+ return(NULL);
+ }
+
+ ep->cur = sv;
start = &ep->data[(int)ep->cur];
q = 0;
@@ -210,16 +245,6 @@ eqn_next(struct eqn_node *ep, char quote, size_t *sz)
q = 1;
}
- lim = 0;
-
- sv = ep->cur;
-again:
- if (lim >= EQN_NEST_MAX) {
- EQN_MSG(MANDOCERR_EQNNEST, ep);
- return(NULL);
- }
-
- ep->cur = sv;
start = &ep->data[(int)ep->cur];
next = q ? strchr(start, quote) : strchr(start, ' ');
@@ -238,6 +263,11 @@ again:
ep->cur += *sz;
}
+ /* Quotes aren't expanded for values. */
+
+ if (q)
+ return(start);
+
if (NULL != (def = eqn_def_find(ep, start, *sz))) {
diff = def->valsz - *sz;
@@ -322,9 +352,12 @@ eqn_do_define(struct eqn_node *ep)
}
def->valsz = sz;
- def->val = mandoc_realloc(ep->defs[i].val, sz + 1);
+ def->val = mandoc_realloc(def->val, sz + 1);
memcpy(def->val, start, sz);
def->val[(int)sz] = '\0';
+
+ /*fprintf(stderr, "Defining: [%s], [%s]\n",
+ def->key, def->val);*/
return(1);
}
diff --git a/man_html.c b/man_html.c
index 4305d926..f89b1c7a 100644
--- a/man_html.c
+++ b/man_html.c
@@ -230,8 +230,8 @@ print_man_node(MAN_ARGS)
return;
case (MAN_EQN):
PAIR_CLASS_INIT(&tag, "eqn");
- print_otag(h, TAG_SPAN, 1, &tag);
- print_text(h, n->eqn->data);
+ /*print_otag(h, TAG_SPAN, 1, &tag);
+ print_text(h, n->eqn->data);*/
break;
case (MAN_TBL):
/*
diff --git a/man_term.c b/man_term.c
index 9d39cc29..0029e8e7 100644
--- a/man_term.c
+++ b/man_term.c
@@ -905,7 +905,7 @@ print_man_node(DECL_ARGS)
p->flags |= TERMP_SENTENCE;
return;
case (MAN_EQN):
- term_word(p, n->eqn->data);
+ /*term_word(p, n->eqn->data);*/
return;
case (MAN_TBL):
/*
diff --git a/mandoc.h b/mandoc.h
index b16b1fc9..e6ee928a 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -277,9 +277,20 @@ struct tbl_span {
struct tbl_span *next;
};
+enum eqn_boxt {
+ EQN_ROOT,
+ EQN_TEXT
+};
+
+struct eqn_box {
+ enum eqn_boxt type;
+ struct eqn_box *child;
+ struct eqn_box *next;
+ char *text;
+};
+
struct eqn {
- size_t sz;
- char *data;
+ struct eqn_box *root;
int ln; /* invocation line */
int pos; /* invocation position */
};
diff --git a/mdoc_html.c b/mdoc_html.c
index bc9c52d0..de167d54 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -435,8 +435,8 @@ print_mdoc_node(MDOC_ARGS)
return;
case (MDOC_EQN):
PAIR_CLASS_INIT(&tag, "eqn");
- print_otag(h, TAG_SPAN, 1, &tag);
- print_text(h, n->eqn->data);
+ /*print_otag(h, TAG_SPAN, 1, &tag);
+ print_text(h, n->eqn->data);*/
break;
case (MDOC_TBL):
/*
diff --git a/mdoc_term.c b/mdoc_term.c
index 943cc8b0..39efd872 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -351,7 +351,7 @@ print_mdoc_node(DECL_ARGS)
p->flags |= TERMP_NOSPACE;
break;
case (MDOC_EQN):
- term_word(p, n->eqn->data);
+ /*term_word(p, n->eqn->data);*/
break;
case (MDOC_TBL):
term_tbl(p, n->span);
diff --git a/tree.c b/tree.c
index bf43242d..b4f14523 100644
--- a/tree.c
+++ b/tree.c
@@ -28,8 +28,9 @@
#include "man.h"
#include "main.h"
-static void print_mdoc(const struct mdoc_node *, int);
+static void print_box(const struct eqn_box *, int);
static void print_man(const struct man_node *, int);
+static void print_mdoc(const struct mdoc_node *, int);
static void print_span(const struct tbl_span *, int);
@@ -63,6 +64,7 @@ print_mdoc(const struct mdoc_node *n, int indent)
argv = NULL;
argc = sz = 0;
params = NULL;
+ t = p = NULL;
switch (n->type) {
case (MDOC_ROOT):
@@ -90,18 +92,14 @@ print_mdoc(const struct mdoc_node *n, int indent)
t = "text";
break;
case (MDOC_TBL):
- t = "tbl";
- break;
+ /* FALLTHROUGH */
case (MDOC_EQN):
- t = "eqn";
break;
default:
abort();
/* NOTREACHED */
}
- p = NULL;
-
switch (n->type) {
case (MDOC_TEXT):
p = n->string;
@@ -130,9 +128,8 @@ print_mdoc(const struct mdoc_node *n, int indent)
}
break;
case (MDOC_TBL):
- break;
+ /* FALLTHROUGH */
case (MDOC_EQN):
- p = n->eqn->data;
break;
case (MDOC_ROOT):
p = "root";
@@ -143,8 +140,11 @@ print_mdoc(const struct mdoc_node *n, int indent)
}
if (n->span) {
- assert(NULL == p);
+ assert(NULL == p && NULL == t);
print_span(n->span, indent);
+ } else if (n->eqn) {
+ assert(NULL == p && NULL == t);
+ print_box(n->eqn->root, indent);
} else {
for (i = 0; i < indent; i++)
putchar('\t');
@@ -164,11 +164,9 @@ print_mdoc(const struct mdoc_node *n, int indent)
for (i = 0; i < (int)sz; i++)
printf(" [%s]", params[i]);
- printf(" %d:%d", n->line, n->pos);
+ printf(" %d:%d\n", n->line, n->pos);
}
- putchar('\n');
-
if (n->child)
print_mdoc(n->child, indent + 1);
if (n->next)
@@ -182,6 +180,8 @@ print_man(const struct man_node *n, int indent)
const char *p, *t;
int i;
+ t = p = NULL;
+
switch (n->type) {
case (MAN_ROOT):
t = "root";
@@ -205,18 +205,14 @@ print_man(const struct man_node *n, int indent)
t = "block-tail";
break;
case (MAN_TBL):
- t = "tbl";
- break;
+ /* FALLTHROUGH */
case (MAN_EQN):
- t = "eqn";
break;
default:
abort();
/* NOTREACHED */
}
- p = NULL;
-
switch (n->type) {
case (MAN_TEXT):
p = n->string;
@@ -236,9 +232,8 @@ print_man(const struct man_node *n, int indent)
p = "root";
break;
case (MAN_TBL):
- break;
+ /* FALLTHROUGH */
case (MAN_EQN):
- p = n->eqn->data;
break;
default:
abort();
@@ -246,16 +241,17 @@ print_man(const struct man_node *n, int indent)
}
if (n->span) {
- assert(NULL == p);
+ assert(NULL == p && NULL == t);
print_span(n->span, indent);
+ } else if (n->eqn) {
+ assert(NULL == p && NULL == t);
+ print_box(n->eqn->root, indent);
} else {
for (i = 0; i < indent; i++)
putchar('\t');
- printf("%s (%s) %d:%d", p, t, n->line, n->pos);
+ printf("%s (%s) %d:%d\n", p, t, n->line, n->pos);
}
- putchar('\n');
-
if (n->child)
print_man(n->child, indent + 1);
if (n->next)
@@ -263,6 +259,30 @@ print_man(const struct man_node *n, int indent)
}
static void
+print_box(const struct eqn_box *ep, int indent)
+{
+ int i;
+
+ if (NULL == ep)
+ return;
+ for (i = 0; i < indent; i++)
+ putchar('\t');
+
+ switch (ep->type) {
+ case (EQN_ROOT):
+ puts("eqn-root");
+ print_box(ep->child, indent + 1);
+ return;
+ case (EQN_TEXT):
+ printf("eqn-text: [%s]\n", ep->text);
+ print_box(ep->next, indent);
+ return;
+ default:
+ break;
+ }
+}
+
+static void
print_span(const struct tbl_span *sp, int indent)
{
const struct tbl_dat *dp;
@@ -306,5 +326,5 @@ print_span(const struct tbl_span *sp, int indent)
putchar(' ');
}
- printf("(tbl) %d:1", sp->line);
+ printf("(tbl) %d:1\n", sp->line);
}