From e8577c374a9f7230bd229f8ea333569dda0d6de1 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Sun, 20 Mar 2011 23:36:43 +0000 Subject: Import the foundation for eqn(7) support. Written by kristaps@. For now, i'm adding one line to each of the four frontends to just pass the input text through to the output, not yet interpreting any of then eqn keywords. --- usr.bin/mandoc/Makefile | 4 +- usr.bin/mandoc/libroff.h | 11 +++++- usr.bin/mandoc/main.c | 30 +++++++++------ usr.bin/mandoc/man.3 | 15 +++++++- usr.bin/mandoc/man.c | 18 ++++++++- usr.bin/mandoc/man.h | 7 +++- usr.bin/mandoc/man_html.c | 5 ++- usr.bin/mandoc/man_term.c | 5 ++- usr.bin/mandoc/man_validate.c | 6 ++- usr.bin/mandoc/mandoc.h | 9 ++++- usr.bin/mandoc/mdoc.3 | 15 +++++++- usr.bin/mandoc/mdoc.c | 26 ++++++++++++- usr.bin/mandoc/mdoc.h | 6 ++- usr.bin/mandoc/mdoc_html.c | 5 ++- usr.bin/mandoc/mdoc_term.c | 7 +++- usr.bin/mandoc/mdoc_validate.c | 6 ++- usr.bin/mandoc/roff.c | 83 +++++++++++++++++++++++++++++++++++++----- usr.bin/mandoc/roff.h | 6 ++- usr.bin/mandoc/tree.c | 14 ++++++- 19 files changed, 235 insertions(+), 43 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile index 872b55dabb5..1594aea025c 100644 --- a/usr.bin/mandoc/Makefile +++ b/usr.bin/mandoc/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.52 2011/01/09 14:30:48 schwarze Exp $ +# $OpenBSD: Makefile,v 1.53 2011/03/20 23:36:42 schwarze Exp $ .include @@ -10,7 +10,7 @@ CFLAGS+=-W -Wall -Wstrict-prototypes CFLAGS+=-Wno-unused-parameter .endif -SRCS= roff.c tbl.c tbl_opts.c tbl_layout.c tbl_data.c mandoc.c +SRCS= roff.c tbl.c tbl_opts.c tbl_layout.c tbl_data.c eqn.c mandoc.c SRCS+= mdoc_macro.c mdoc.c mdoc_hash.c mdoc_strings.c \ mdoc_argv.c mdoc_validate.c lib.c att.c \ arch.c vol.c msec.c st.c diff --git a/usr.bin/mandoc/libroff.h b/usr.bin/mandoc/libroff.h index 9dd994d8991..dcac7832f0a 100644 --- a/usr.bin/mandoc/libroff.h +++ b/usr.bin/mandoc/libroff.h @@ -1,4 +1,4 @@ -/* $Id: libroff.h,v 1.2 2011/01/25 12:24:26 schwarze Exp $ */ +/* $Id: libroff.h,v 1.3 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -43,6 +43,11 @@ struct tbl_node { struct tbl_node *next; }; +struct eqn_node { + struct eqn eqn; + struct eqn_node *next; +}; + #define TBL_MSG(tblp, type, line, col) \ (*(tblp)->msg)((type), (tblp)->data, (line), (col), NULL) @@ -57,6 +62,10 @@ 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 *); +struct eqn_node *eqn_alloc(int, int); +void eqn_end(struct eqn_node *); +void eqn_free(struct eqn_node *); +enum rofferr eqn_read(struct eqn_node **, int, const char *, int); __END_DECLS diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c index 7f1fdf08aa5..338ece9048e 100644 --- a/usr.bin/mandoc/main.c +++ b/usr.bin/mandoc/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.73 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: main.c,v 1.74 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -839,27 +839,35 @@ rerun: * currently open parse. Since we only get here if * there does exist data (see tbl_data.c), we're * guaranteed that something's been allocated. + * Do the same for ROFF_EQN. */ - if (ROFF_TBL == rr) { - assert(curp->man || curp->mdoc); + rc = -1; + + if (ROFF_TBL == rr) while (NULL != (span = roff_span(curp->roff))) { - if (curp->man) - man_addspan(curp->man, span); - else + rc = curp->man ? + man_addspan(curp->man, span) : mdoc_addspan(curp->mdoc, span); + if (0 == rc) + break; } - } else if (curp->man || curp->mdoc) { + else if (ROFF_EQN == rr) + rc = curp->mdoc ? + mdoc_addeqn(curp->mdoc, + roff_eqn(curp->roff)) : + man_addeqn(curp->man, + roff_eqn(curp->roff)); + else if (curp->man || curp->mdoc) rc = curp->man ? man_parseln(curp->man, curp->line, ln.buf, of) : mdoc_parseln(curp->mdoc, curp->line, ln.buf, of); - if ( ! rc) { - assert(MANDOCLEVEL_FATAL <= file_status); - break; - } + if (0 == rc) { + assert(MANDOCLEVEL_FATAL <= file_status); + break; } /* Temporary buffers typically are not full. */ diff --git a/usr.bin/mandoc/man.3 b/usr.bin/mandoc/man.3 index 8d8eaec9327..8f302259e57 100644 --- a/usr.bin/mandoc/man.3 +++ b/usr.bin/mandoc/man.3 @@ -1,4 +1,4 @@ -.\" $Id: man.3,v 1.21 2011/01/09 13:16:48 schwarze Exp $ +.\" $Id: man.3,v 1.22 2011/03/20 23:36:42 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" @@ -14,11 +14,13 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 9 2011 $ +.Dd $Mdocdate: March 20 2011 $ .Dt MAN 3 .Os .Sh NAME .Nm man , +.Nm man_addeqn , +.Nm man_addspan , .Nm man_alloc , .Nm man_endparse , .Nm man_free , @@ -32,6 +34,11 @@ .In man.h .Vt extern const char * const * man_macronames; .Ft int +.Fo man_addeqn +.Fa "struct man *man" +.Fa "const struct eqn *eqn" +.Fc +.Ft int .Fo man_addspan .Fa "struct man *man" .Fa "const struct tbl_span *span" @@ -106,6 +113,7 @@ for details. .El .Ss Functions If +.Fn man_addeqn , .Fn man_addspan , .Fn man_parseln , or @@ -116,6 +124,9 @@ or .Fn man_free will raise an assertion. .Bl -ohang +.It Fn man_addeqn +Add an equation to the parsing stream. +Returns 0 on failure, 1 on success. .It Fn man_addspan Add a table span to the parsing stream. Returns 0 on failure, 1 on success. diff --git a/usr.bin/mandoc/man.c b/usr.bin/mandoc/man.c index 9eba4001fee..29d879b1563 100644 --- a/usr.bin/mandoc/man.c +++ b/usr.bin/mandoc/man.c @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.56 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: man.c,v 1.57 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -342,6 +342,22 @@ man_node_delete(struct man *m, struct man_node *p) man_node_free(p); } +int +man_addeqn(struct man *m, const struct eqn *ep) +{ + struct man_node *n; + + assert( ! (MAN_HALT & m->flags)); + + n = man_node_alloc(m, ep->line, ep->pos, MAN_EQN, MAN_MAX); + n->eqn = ep; + + if ( ! man_node_append(m, n)) + return(0); + + m->next = MAN_NEXT_SIBLING; + return(man_descope(m, ep->line, ep->pos)); +} int man_addspan(struct man *m, const struct tbl_span *sp) diff --git a/usr.bin/mandoc/man.h b/usr.bin/mandoc/man.h index 0fdf892ea9b..ff0912ceb3c 100644 --- a/usr.bin/mandoc/man.h +++ b/usr.bin/mandoc/man.h @@ -1,4 +1,4 @@ -/* $Id: man.h,v 1.35 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: man.h,v 1.36 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -67,7 +67,8 @@ enum man_type { MAN_BLOCK, MAN_HEAD, MAN_BODY, - MAN_TBL + MAN_TBL, + MAN_EQN }; /* @@ -102,6 +103,7 @@ struct man_node { struct man_node *head; /* BLOCK node HEAD ptr */ struct man_node *body; /* BLOCK node BODY ptr */ const struct tbl_span *span; /* TBL */ + const struct eqn *eqn; /* EQN */ }; /* @@ -121,6 +123,7 @@ int man_parseln(struct man *, int, char *, int); int man_endparse(struct man *); int man_addspan(struct man *, const struct tbl_span *); +int man_addeqn(struct man *, const struct eqn *); const struct man_node *man_node(const struct man *); const struct man_meta *man_meta(const struct man *); diff --git a/usr.bin/mandoc/man_html.c b/usr.bin/mandoc/man_html.c index 41550ff5048..526835e6576 100644 --- a/usr.bin/mandoc/man_html.c +++ b/usr.bin/mandoc/man_html.c @@ -1,4 +1,4 @@ -/* $Id: man_html.c,v 1.35 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: man_html.c,v 1.36 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -200,6 +200,9 @@ print_man_node(MAN_ARGS) n->next->line > n->line)) print_otag(h, TAG_BR, 0, NULL); return; + case (MAN_EQN): + print_text(h, n->eqn->data); + return; case (MAN_TBL): /* * This will take care of initialising all of the table diff --git a/usr.bin/mandoc/man_term.c b/usr.bin/mandoc/man_term.c index 8e583015732..131580d4c9b 100644 --- a/usr.bin/mandoc/man_term.c +++ b/usr.bin/mandoc/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.65 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: man_term.c,v 1.66 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -892,6 +892,9 @@ print_man_node(DECL_ARGS) if (MAN_EOS & n->flags) p->flags |= TERMP_SENTENCE; return; + case (MAN_EQN): + term_word(p, n->eqn->data); + return; case (MAN_TBL): /* * Tables are preceded by a newline. Then process a diff --git a/usr.bin/mandoc/man_validate.c b/usr.bin/mandoc/man_validate.c index f6321084eb9..25d320add35 100644 --- a/usr.bin/mandoc/man_validate.c +++ b/usr.bin/mandoc/man_validate.c @@ -1,4 +1,4 @@ -/* $Id: man_validate.c,v 1.41 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: man_validate.c,v 1.42 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010 Ingo Schwarze @@ -118,6 +118,8 @@ man_valid_pre(struct man *m, struct man_node *n) /* FALLTHROUGH */ case (MAN_ROOT): /* FALLTHROUGH */ + case (MAN_EQN): + /* FALLTHROUGH */ case (MAN_TBL): return(1); default: @@ -147,6 +149,8 @@ man_valid_post(struct man *m) return(check_text(m, m->last)); case (MAN_ROOT): return(check_root(m, m->last)); + case (MAN_EQN): + /* FALLTHROUGH */ case (MAN_TBL): return(1); default: diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index 1c749031d66..2175e97ad8a 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.34 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.35 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * @@ -269,6 +269,13 @@ struct tbl_span { struct tbl_span *next; }; +struct eqn { + size_t sz; + char *data; + int line; /* invocation line */ + int pos; /* invocation position */ +}; + /* * Available registers (set in libroff, accessed elsewhere). */ diff --git a/usr.bin/mandoc/mdoc.3 b/usr.bin/mandoc/mdoc.3 index bb576d4bad4..24c32ccc380 100644 --- a/usr.bin/mandoc/mdoc.3 +++ b/usr.bin/mandoc/mdoc.3 @@ -1,4 +1,4 @@ -.\" $Id: mdoc.3,v 1.16 2011/01/09 13:16:48 schwarze Exp $ +.\" $Id: mdoc.3,v 1.17 2011/03/20 23:36:42 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2010 Ingo Schwarze @@ -15,11 +15,13 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 9 2011 $ +.Dd $Mdocdate: March 20 2011 $ .Dt MDOC 3 .Os .Sh NAME .Nm mdoc , +.Nm mdoc_addeqn , +.Nm mdoc_addspan , .Nm mdoc_alloc , .Nm mdoc_endparse , .Nm mdoc_free , @@ -34,6 +36,11 @@ .Vt extern const char * const * mdoc_macronames; .Vt extern const char * const * mdoc_argnames; .Ft int +.Fo mdoc_addeqn +.Fa "struct mdoc *mdoc" +.Fa "const struct eqn *eqn" +.Fc +.Ft int .Fo mdoc_addspan .Fa "struct mdoc *mdoc" .Fa "const struct tbl_span *span" @@ -97,6 +104,7 @@ for details. .El .Ss Functions If +.Fn mdoc_addeqn , .Fn mdoc_addspan , .Fn mdoc_parseln , or @@ -107,6 +115,9 @@ or .Fn mdoc_free will raise an assertion. .Bl -ohang +.It Fn mdoc_addeqn +Add an equation to the parsing stream. +Returns 0 on failure, 1 on success. .It Fn mdoc_addspan Add a table span to the parsing stream. Returns 0 on failure, 1 on success. diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c index 79dffc42cb9..24c09e765a3 100644 --- a/usr.bin/mandoc/mdoc.c +++ b/usr.bin/mandoc/mdoc.c @@ -1,4 +1,4 @@ -/* $Id: mdoc.c,v 1.80 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: mdoc.c,v 1.81 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010 Ingo Schwarze @@ -217,6 +217,30 @@ mdoc_endparse(struct mdoc *m) return(0); } +int +mdoc_addeqn(struct mdoc *m, const struct eqn *ep) +{ + struct mdoc_node *n; + + assert( ! (MDOC_HALT & m->flags)); + + /* No text before an initial macro. */ + + if (SEC_NONE == m->lastnamed) { + mdoc_pmsg(m, ep->line, ep->pos, MANDOCERR_NOTEXT); + return(1); + } + + n = node_alloc(m, ep->line, ep->pos, MDOC_MAX, MDOC_EQN); + n->eqn = ep; + + if ( ! node_append(m, n)) + return(0); + + m->next = MDOC_NEXT_SIBLING; + return(1); +} + int mdoc_addspan(struct mdoc *m, const struct tbl_span *sp) { diff --git a/usr.bin/mandoc/mdoc.h b/usr.bin/mandoc/mdoc.h index b442033e82e..1ac4ea25db8 100644 --- a/usr.bin/mandoc/mdoc.h +++ b/usr.bin/mandoc/mdoc.h @@ -1,4 +1,4 @@ -/* $Id: mdoc.h,v 1.44 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: mdoc.h,v 1.45 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -191,6 +191,7 @@ enum mdoc_type { MDOC_BODY, MDOC_BLOCK, MDOC_TBL, + MDOC_EQN, MDOC_ROOT }; @@ -401,6 +402,7 @@ struct mdoc_node { struct mdoc_node *tail; /* BLOCK */ char *string; /* TEXT */ const struct tbl_span *span; /* TBL */ + const struct eqn *eqn; /* EQN */ enum mdoc_endbody end; /* BODY */ }; @@ -430,6 +432,8 @@ const struct mdoc_meta *mdoc_meta(const struct mdoc *); int mdoc_endparse(struct mdoc *); int mdoc_addspan(struct mdoc *, const struct tbl_span *); +int mdoc_addeqn(struct mdoc *, + const struct eqn *); __END_DECLS diff --git a/usr.bin/mandoc/mdoc_html.c b/usr.bin/mandoc/mdoc_html.c index dbe71377153..ec1aa9aca9f 100644 --- a/usr.bin/mandoc/mdoc_html.c +++ b/usr.bin/mandoc/mdoc_html.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.53 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.54 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -428,6 +428,9 @@ print_mdoc_node(MDOC_ARGS) print_otag(h, TAG_BR, 0, NULL); print_text(h, n->string); return; + case (MDOC_EQN): + print_text(h, n->eqn->data); + return; case (MDOC_TBL): /* * This will take care of initialising all of the table diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c index 6a9da38df1e..d47781b87bb 100644 --- a/usr.bin/mandoc/mdoc_term.c +++ b/usr.bin/mandoc/mdoc_term.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.130 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.131 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010 Ingo Schwarze @@ -350,6 +350,9 @@ print_mdoc_node(DECL_ARGS) term_newln(p); term_word(p, n->string); break; + case (MDOC_EQN): + term_word(p, n->eqn->data); + break; case (MDOC_TBL): term_tbl(p, n->span); break; @@ -370,6 +373,8 @@ print_mdoc_node(DECL_ARGS) break; case (MDOC_TBL): break; + case (MDOC_EQN): + break; default: if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags) break; diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c index cabaef49858..68eea06ad09 100644 --- a/usr.bin/mandoc/mdoc_validate.c +++ b/usr.bin/mandoc/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.89 2011/03/07 01:35:33 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.90 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -334,6 +334,8 @@ mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n) /* FALLTHROUGH */ case (MDOC_TBL): /* FALLTHROUGH */ + case (MDOC_EQN): + /* FALLTHROUGH */ case (MDOC_ROOT): return(1); default: @@ -363,6 +365,8 @@ mdoc_valid_post(struct mdoc *mdoc) switch (mdoc->last->type) { case (MDOC_TEXT): /* FALLTHROUGH */ + case (MDOC_EQN): + /* FALLTHROUGH */ case (MDOC_TBL): return(1); case (MDOC_ROOT): diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index 1accc05a00f..f7a3fb9d026 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.31 2011/01/25 00:23:23 schwarze Exp $ */ +/* $Id: roff.c,v 1.32 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -60,6 +60,8 @@ enum rofft { ROFF_TS, ROFF_TE, ROFF_T_, + ROFF_EQ, + ROFF_EN, ROFF_cblock, ROFF_ccond, /* FIXME: remove this. */ ROFF_USERDEF, @@ -89,6 +91,9 @@ struct roff { struct tbl_node *first_tbl; /* first table parsed */ struct tbl_node *last_tbl; /* last table parsed */ struct tbl_node *tbl; /* current table being parsed */ + struct eqn_node *last_eqn; /* last equation parsed */ + struct eqn_node *first_eqn; /* first equation parsed */ + struct eqn_node *eqn; /* current equation being parsed */ }; struct roffnode { @@ -147,6 +152,8 @@ static void roff_setstr(struct roff *, static enum rofferr roff_so(ROFF_ARGS); static enum rofferr roff_TE(ROFF_ARGS); static enum rofferr roff_TS(ROFF_ARGS); +static enum rofferr roff_EQ(ROFF_ARGS); +static enum rofferr roff_EN(ROFF_ARGS); static enum rofferr roff_T_(ROFF_ARGS); static enum rofferr roff_userdef(ROFF_ARGS); @@ -185,6 +192,8 @@ static struct roffmac roffs[ROFF_MAX] = { { "TS", roff_TS, NULL, NULL, 0, NULL }, { "TE", roff_TE, NULL, NULL, 0, NULL }, { "T&", roff_T_, NULL, NULL, 0, NULL }, + { "EQ", roff_EQ, NULL, NULL, 0, NULL }, + { "EN", roff_EN, NULL, NULL, 0, NULL }, { ".", roff_cblock, NULL, NULL, 0, NULL }, { "\\}", roff_ccond, NULL, NULL, 0, NULL }, { NULL, roff_userdef, NULL, NULL, 0, NULL }, @@ -307,15 +316,22 @@ static void roff_free1(struct roff *r) { struct tbl_node *t; + struct eqn_node *e; - while (r->first_tbl) { - t = r->first_tbl; + while (NULL != (t = r->first_tbl)) { r->first_tbl = t->next; tbl_free(t); } r->first_tbl = r->last_tbl = r->tbl = NULL; + while (NULL != (e = r->first_eqn)) { + r->first_eqn = e->next; + eqn_free(e); + } + + r->first_eqn = r->last_eqn = r->eqn = NULL; + while (r->last) roffnode_pop(r); @@ -473,6 +489,8 @@ roff_parseln(struct roff *r, int ln, char **bufp, * First, if a scope is open and we're not a macro, pass the * text through the macro's filter. If a scope isn't open and * we're not a macro, just let it through. + * Finally, if there's an equation scope open, divert it into it + * no matter our state. */ if (r->last && ! ROFF_CTL((*bufp)[pos])) { @@ -481,18 +499,26 @@ roff_parseln(struct roff *r, int ln, char **bufp, e = (*roffs[t].text) (r, t, bufp, szp, ln, pos, pos, offs); assert(ROFF_IGN == e || ROFF_CONT == e); - if (ROFF_CONT == e && r->tbl) + if (ROFF_CONT != e) + return(e); + if (r->eqn) + return(eqn_read(&r->eqn, ln, *bufp, *offs)); + if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, *offs)); - return(e); + return(ROFF_CONT); } else if ( ! ROFF_CTL((*bufp)[pos])) { + if (r->eqn) + return(eqn_read(&r->eqn, ln, *bufp, *offs)); if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, *offs)); return(ROFF_CONT); - } + } else if (r->eqn) + return(eqn_read(&r->eqn, ln, *bufp, *offs)); /* * If a scope is open, go to the child handler for that macro, * as it may want to preprocess before doing anything with it. + * Don't do so if an equation is open. */ if (r->last) { @@ -528,6 +554,13 @@ roff_endparse(struct roff *r) (*r->msg)(MANDOCERR_SCOPEEXIT, r->data, r->last->line, r->last->col, NULL); + if (r->eqn) { + (*r->msg)(MANDOCERR_SCOPEEXIT, r->data, + r->eqn->eqn.line, r->eqn->eqn.pos, NULL); + eqn_end(r->eqn); + r->eqn = NULL; + } + if (r->tbl) { (*r->msg)(MANDOCERR_SCOPEEXIT, r->data, r->tbl->line, r->tbl->pos, NULL); @@ -1134,6 +1167,33 @@ roff_T_(ROFF_ARGS) return(ROFF_IGN); } +/* ARGSUSED */ +static enum rofferr +roff_EQ(ROFF_ARGS) +{ + struct eqn_node *e; + + assert(NULL == r->eqn); + e = eqn_alloc(ppos, ln); + + if (r->last_eqn) + r->last_eqn->next = e; + else + r->first_eqn = r->last_eqn = e; + + r->eqn = r->last_eqn = e; + return(ROFF_IGN); +} + +/* ARGSUSED */ +static enum rofferr +roff_EN(ROFF_ARGS) +{ + + (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL); + return(ROFF_IGN); +} + /* ARGSUSED */ static enum rofferr roff_TS(ROFF_ARGS) @@ -1236,7 +1296,6 @@ roff_userdef(ROFF_ARGS) ROFF_REPARSE : ROFF_APPEND); } - static char * roff_getname(struct roff *r, char **cpp, int ln, int pos) { @@ -1270,7 +1329,6 @@ roff_getname(struct roff *r, char **cpp, int ln, int pos) return(name); } - /* * Store *string into the user-defined string called *name. * In multiline mode, append to an existing entry and append '\n'; @@ -1340,7 +1398,6 @@ roff_setstr(struct roff *r, const char *name, const char *string, *c = '\0'; } - static const char * roff_getstrn(const struct roff *r, const char *name, size_t len) { @@ -1353,7 +1410,6 @@ roff_getstrn(const struct roff *r, const char *name, size_t len) return(n ? n->string : NULL); } - static void roff_freestr(struct roff *r) { @@ -1375,3 +1431,10 @@ roff_span(const struct roff *r) return(r->tbl ? tbl_span(r->tbl) : NULL); } + +const struct eqn * +roff_eqn(const struct roff *r) +{ + + return(r->last_eqn ? &r->last_eqn->eqn : NULL); +} diff --git a/usr.bin/mandoc/roff.h b/usr.bin/mandoc/roff.h index 1e533701a50..7b9197f4eab 100644 --- a/usr.bin/mandoc/roff.h +++ b/usr.bin/mandoc/roff.h @@ -1,6 +1,6 @@ -/* $Id: roff.h,v 1.7 2011/01/04 22:28:17 schwarze Exp $ */ +/* $Id: roff.h,v 1.8 2011/03/20 23:36:42 schwarze Exp $ */ /* - * Copyright (c) 2010 Kristaps Dzonsons + * Copyright (c) 2010, 2011 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -25,6 +25,7 @@ enum rofferr { ROFF_SO, /* include another file */ ROFF_IGN, /* ignore current line */ ROFF_TBL, /* a table row was successfully parsed */ + ROFF_EQN, /* an equation was successfully parsed */ ROFF_ERR /* badness: puke and stop */ }; @@ -39,6 +40,7 @@ enum rofferr roff_parseln(struct roff *, int, char **, size_t *, int, int *); void roff_endparse(struct roff *); const struct tbl_span *roff_span(const struct roff *); +const struct eqn *roff_eqn(const struct roff *); __END_DECLS diff --git a/usr.bin/mandoc/tree.c b/usr.bin/mandoc/tree.c index f66daad968e..3ad20fb2925 100644 --- a/usr.bin/mandoc/tree.c +++ b/usr.bin/mandoc/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.13 2011/02/10 00:06:30 schwarze Exp $ */ +/* $Id: tree.c,v 1.14 2011/03/20 23:36:42 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2011 Kristaps Dzonsons * @@ -88,6 +88,9 @@ print_mdoc(const struct mdoc_node *n, int indent) case (MDOC_TBL): t = "tbl"; break; + case (MDOC_EQN): + t = "eqn"; + break; default: abort(); /* NOTREACHED */ @@ -124,6 +127,9 @@ print_mdoc(const struct mdoc_node *n, int indent) break; case (MDOC_TBL): break; + case (MDOC_EQN): + p = n->eqn->data; + break; case (MDOC_ROOT): p = "root"; break; @@ -194,6 +200,9 @@ print_man(const struct man_node *n, int indent) case (MAN_TBL): t = "tbl"; break; + case (MAN_EQN): + t = "eqn"; + break; default: abort(); /* NOTREACHED */ @@ -219,6 +228,9 @@ print_man(const struct man_node *n, int indent) break; case (MAN_TBL): break; + case (MAN_EQN): + p = n->eqn->data; + break; default: abort(); /* NOTREACHED */ -- cgit v1.2.3