From 175c51d9a38aa43801777db95c54f0d7abf91092 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Thu, 21 Jul 2011 11:34:53 +0000 Subject: Flip eqn into using parsed nodes. I've temporarily disabled printing these in the front-ends except for -Ttree, which will display the parsed tree. While here, fix that quoted strings aren't scanned for replacement parts. --- eqn.7 | 3 +- eqn.c | 97 +++++++++++++++++++++++++++++++++++++++++-------------------- man_html.c | 6 ++-- man_term.c | 4 +-- mandoc.h | 17 +++++++++-- mdoc_html.c | 6 ++-- mdoc_term.c | 4 +-- tree.c | 70 ++++++++++++++++++++++++++++---------------- 8 files changed, 136 insertions(+), 71 deletions(-) diff --git a/eqn.7 b/eqn.7 index 3764276f..ca0fb622 100644 --- a/eqn.7 +++ b/eqn.7 @@ -1,4 +1,4 @@ -.\" $Id: eqn.7,v 1.5 2011/07/21 10:24:35 kristaps Exp $ +.\" $Id: eqn.7,v 1.6 2011/07/21 11:34:53 kristaps Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons .\" @@ -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 9f56a7c3..cb73a04f 100644 --- a/eqn.c +++ b/eqn.c @@ -1,4 +1,4 @@ -/* $Id: eqn.c,v 1.12 2011/07/21 10:24:35 kristaps Exp $ */ +/* $Id: eqn.c,v 1.13 2011/07/21 11:34:53 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -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 2dfb3e16..fa0b34b3 100644 --- a/man_html.c +++ b/man_html.c @@ -1,4 +1,4 @@ -/* $Id: man_html.c,v 1.78 2011/07/07 13:54:36 kristaps Exp $ */ +/* $Id: man_html.c,v 1.79 2011/07/21 11:34:53 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -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 4a77eb5f..cadb0b1c 100644 --- a/man_term.c +++ b/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.113 2011/07/03 22:57:32 kristaps Exp $ */ +/* $Id: man_term.c,v 1.114 2011/07/21 11:34:53 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -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 a832310a..7c46c763 100644 --- a/mandoc.h +++ b/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.82 2011/07/21 10:24:35 kristaps Exp $ */ +/* $Id: mandoc.h,v 1.83 2011/07/21 11:34:53 kristaps Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * @@ -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 33cebdac..00bf4425 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.172 2011/07/04 09:42:38 kristaps Exp $ */ +/* $Id: mdoc_html.c,v 1.173 2011/07/21 11:34:53 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -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 a1477546..99fd5b00 100644 --- a/mdoc_term.c +++ b/mdoc_term.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.231 2011/06/29 15:38:09 kristaps Exp $ */ +/* $Id: mdoc_term.c,v 1.232 2011/07/21 11:34:53 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010 Ingo Schwarze @@ -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 fecad80e..a446fb14 100644 --- a/tree.c +++ b/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.37 2011/03/23 12:33:01 kristaps Exp $ */ +/* $Id: tree.c,v 1.38 2011/07/21 11:34:53 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -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,22 +241,47 @@ 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) print_man(n->next, 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) { @@ -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); } -- cgit v1.2.3-56-ge451