From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp-2.sys.kth.se (smtp-2.sys.kth.se [130.237.32.160]) by krisdoz.my.domain (8.14.3/8.14.3) with ESMTP id p13AQvr5027174 for ; Thu, 3 Feb 2011 05:26:57 -0500 (EST) Received: from mailscan-1.sys.kth.se (mailscan-1.sys.kth.se [130.237.32.91]) by smtp-2.sys.kth.se (Postfix) with ESMTP id 2DAE814F2E4; Thu, 3 Feb 2011 11:26:51 +0100 (CET) X-Virus-Scanned: by amavisd-new at kth.se Received: from smtp-2.sys.kth.se ([130.237.32.160]) by mailscan-1.sys.kth.se (mailscan-1.sys.kth.se [130.237.32.91]) (amavisd-new, port 10024) with LMTP id 9HHRAjsIrRGM; Thu, 3 Feb 2011 11:26:48 +0100 (CET) X-KTH-Auth: kristaps [85.8.61.49] X-KTH-mail-from: kristaps@bsd.lv Received: from h85-8-61-49.dynamic.se.alltele.net (h85-8-61-49.dynamic.se.alltele.net [85.8.61.49]) by smtp-2.sys.kth.se (Postfix) with ESMTP id E757D14F2DF; Thu, 3 Feb 2011 11:26:47 +0100 (CET) Message-ID: <4D4A82E6.9090402@bsd.lv> Date: Thu, 03 Feb 2011 11:26:46 +0100 From: Kristaps Dzonsons User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7 X-Mailinglist: mdocml-tech Reply-To: tech@mdocml.bsd.lv MIME-Version: 1.0 To: tech@mdocml.bsd.lv, Jason McIntyre Subject: [PATCH] Understand EQ/EN blocks. Content-Type: multipart/mixed; boundary="------------020606020003070107050506" This is a multi-part message in MIME format. --------------020606020003070107050506 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, Enclosed is a patch that sets us down the road of understanding EQ/EN blocks. It's quite simple. Like TBL, it intercepts equations in libroff (roff.c). It then passes back the EQN parse (eqn.c) into the main drive (main.c), which (not yet) will push these into libmdoc and libman. The difference between TBL and EQN is that EQN sucks in all stuff between .EQ and .EN, while TBL must interpret what happens in these blocks. For now, the bloat is one more file (the parser for EQN, which is for now just a few lines), some conditionals in the libroff parser to check for active equation parses, and handling of EQ/EN. The equations themselves are thrown away. This is only because I wanted to float a patch early with the libroff framework. It's trivial to put an addspan() style routine to both libmdoc and libman that at least print out the data. I'll do that with an Ok or two. Thoughts? By the way, we'll be able to fully support "delim", as libroff allows us to chop up its input lines and send them to the other backends, so foo $a + b$ bar assuming `$$' are the EQN delimiters, would be passed back as foo EQN:a + b bar Neat. Thanks, Kristaps --------------020606020003070107050506 Content-Type: text/plain; name="patch.eqn.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch.eqn.txt" ? XTextWidth.man ? awk.1 ? config.h ? config.log ? foo.1 ? foo.1.html ? foo.1.xhtml ? foo.3 ? foo.3.ps ? foo.html ? gcc.1 ? gm.1 ? gm.1.html ? mandoc ? mandoc.1.htm ? patch.eqn.txt ? patch.txt ? pcap-savefile.manfile.in ? roff.patch ? style.old.css Index: Makefile =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/Makefile,v retrieving revision 1.309 diff -u -r1.309 Makefile --- Makefile 7 Jan 2011 15:22:21 -0000 1.309 +++ Makefile 3 Feb 2011 10:14:03 -0000 @@ -31,11 +31,11 @@ LINTFLAGS += $(VFLAGS) -ROFFLNS = roff.ln tbl.ln tbl_opts.ln tbl_layout.ln tbl_data.ln +ROFFLNS = roff.ln tbl.ln tbl_opts.ln tbl_layout.ln tbl_data.ln eqn.ln -ROFFSRCS = roff.c tbl.c tbl_opts.c tbl_layout.c tbl_data.c +ROFFSRCS = roff.c tbl.c tbl_opts.c tbl_layout.c tbl_data.c eqn.c -ROFFOBJS = roff.o tbl.o tbl_opts.o tbl_layout.o tbl_data.o +ROFFOBJS = roff.o tbl.o tbl_opts.o tbl_layout.o tbl_data.o eqn.o MANDOCLNS = mandoc.ln Index: eqn.c =================================================================== RCS file: eqn.c diff -N eqn.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ eqn.c 3 Feb 2011 10:14:03 -0000 @@ -0,0 +1,78 @@ +/* $Id: tbl.c,v 1.22 2011/01/25 12:24:27 schwarze Exp $ */ +/* + * Copyright (c) 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "mandoc.h" +#include "roff.h" +#include "libmandoc.h" +#include "libroff.h" + +/* ARGSUSED */ +enum rofferr +eqn_read(struct eqn_node **epp, int ln, const char *p, int offs) +{ + size_t sz; + struct eqn_node *ep; + + if (0 == strcmp(p, ".EN")) { + *epp = NULL; + return(ROFF_EQN); + } + + ep = *epp; + + sz = strlen(&p[offs]); + ep->eqn.data = mandoc_realloc(ep->eqn.data, ep->eqn.sz + sz + 1); + if (0 == ep->eqn.sz) + *ep->eqn.data = '\0'; + + ep->eqn.sz += sz; + strlcat(ep->eqn.data, &p[offs], ep->eqn.sz + 1); + return(ROFF_IGN); +} + +struct eqn_node * +eqn_alloc(int pos, int line) +{ + struct eqn_node *p; + + p = mandoc_calloc(1, sizeof(struct eqn_node)); + p->line = line; + p->pos = pos; + return(p); +} + +void +eqn_end(struct eqn_node *e) +{ + + /* Nothing to do. */ +} + +void +eqn_free(struct eqn_node *p) +{ + + free(p->eqn.data); + free(p); +} Index: libroff.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libroff.h,v retrieving revision 1.17 diff -u -r1.17 libroff.h --- libroff.h 25 Jan 2011 12:24:27 -0000 1.17 +++ libroff.h 3 Feb 2011 10:14:03 -0000 @@ -43,6 +43,13 @@ struct tbl_node *next; }; +struct eqn_node { + int pos; /* invocation column */ + int line; /* invocation line */ + struct eqn eqn; + struct eqn_node *next; +}; + #define TBL_MSG(tblp, type, line, col) \ (*(tblp)->msg)((type), (tblp)->data, (line), (col), NULL) @@ -57,6 +64,10 @@ 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 Index: main.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.c,v retrieving revision 1.142 diff -u -r1.142 main.c --- main.c 2 Feb 2011 21:40:45 -0000 1.142 +++ main.c 3 Feb 2011 10:14:03 -0000 @@ -863,6 +863,8 @@ else mdoc_addspan(curp->mdoc, span); } + } else if (ROFF_EQN == rr) { + assert(curp->man || curp->mdoc); } else if (curp->man || curp->mdoc) { rc = curp->man ? man_parseln(curp->man, Index: mandoc.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v retrieving revision 1.54 diff -u -r1.54 mandoc.h --- mandoc.h 2 Feb 2011 21:40:45 -0000 1.54 +++ mandoc.h 3 Feb 2011 10:14:03 -0000 @@ -267,6 +267,11 @@ struct tbl_span *next; }; +struct eqn { + size_t sz; + char *data; +}; + /* * Available registers (set in libroff, accessed elsewhere). */ Index: roff.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v retrieving revision 1.124 diff -u -r1.124 roff.c --- roff.c 25 Jan 2011 01:12:02 -0000 1.124 +++ roff.c 3 Feb 2011 10:14:03 -0000 @@ -64,6 +64,8 @@ ROFF_TS, ROFF_TE, ROFF_T_, + ROFF_EQ, + ROFF_EN, ROFF_cblock, ROFF_ccond, /* FIXME: remove this. */ ROFF_USERDEF, @@ -93,6 +95,9 @@ 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 { @@ -151,6 +156,8 @@ 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); @@ -189,6 +196,8 @@ { "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 }, @@ -311,15 +320,22 @@ 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); @@ -477,6 +493,8 @@ * 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])) { @@ -485,18 +503,26 @@ 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) { @@ -532,6 +558,13 @@ (*r->msg)(MANDOCERR_SCOPEEXIT, r->data, r->last->line, r->last->col, NULL); + if (r->eqn) { + (*r->msg)(MANDOCERR_SCOPEEXIT, r->data, + r->eqn->line, r->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); @@ -1140,6 +1173,33 @@ /* 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) { struct tbl_node *t; @@ -1240,7 +1300,6 @@ ROFF_REPARSE : ROFF_APPEND); } - static char * roff_getname(struct roff *r, char **cpp, int ln, int pos) { @@ -1274,7 +1333,6 @@ return(name); } - /* * Store *string into the user-defined string called *name. * In multiline mode, append to an existing entry and append '\n'; @@ -1344,7 +1402,6 @@ *c = '\0'; } - static const char * roff_getstrn(const struct roff *r, const char *name, size_t len) { @@ -1357,7 +1414,6 @@ return(n ? n->string : NULL); } - static void roff_freestr(struct roff *r) { @@ -1378,4 +1434,11 @@ { 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); } Index: roff.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.h,v retrieving revision 1.22 diff -u -r1.22 roff.h --- roff.h 1 Jan 2011 16:18:39 -0000 1.22 +++ roff.h 3 Feb 2011 10:14:03 -0000 @@ -25,6 +25,7 @@ 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 */ }; --------------020606020003070107050506-- -- To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv