From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from krisdoz.my.domain (kristaps@localhost [127.0.0.1]) by krisdoz.my.domain (8.14.3/8.14.3) with ESMTP id p16KabiD016072 for ; Sun, 6 Feb 2011 15:36:37 -0500 (EST) Received: (from kristaps@localhost) by krisdoz.my.domain (8.14.3/8.14.3/Submit) id p16KaaGN028107; Sun, 6 Feb 2011 15:36:36 -0500 (EST) Date: Sun, 6 Feb 2011 15:36:36 -0500 (EST) Message-Id: <201102062036.p16KaaGN028107@krisdoz.my.domain> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: kristaps@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: Add initial EQN support to mandoc. X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- Add initial EQN support to mandoc. This parses, then throws away, data between EQ and EN roff blocks. EQN is different from TBL in that data after .EQ is unilaterally considered an equation until an .EN. Thus, there's no need to jump through hoops in having table spans and so on. This is ONLY the parse code framework in libroff. EQN is not yet passed into the backends. Modified Files: -------------- mdocml: Makefile libroff.h main.c mandoc.h roff.c roff.h Added Files: ----------- mdocml: eqn.c Revision Data ------------- --- /dev/null +++ eqn.c @@ -0,0 +1,81 @@ +/* $Id: eqn.c,v 1.1 2011/02/06 20:36:36 kristaps 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 +#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: roff.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.h,v retrieving revision 1.22 retrieving revision 1.23 diff -Lroff.h -Lroff.h -u -p -r1.22 -r1.23 --- roff.h +++ roff.h @@ -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 */ }; Index: mandoc.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v retrieving revision 1.54 retrieving revision 1.55 diff -Lmandoc.h -Lmandoc.h -u -p -r1.54 -r1.55 --- mandoc.h +++ mandoc.h @@ -267,6 +267,11 @@ struct tbl_span { 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 retrieving revision 1.125 diff -Lroff.c -Lroff.c -u -p -r1.124 -r1.125 --- roff.c +++ roff.c @@ -64,6 +64,8 @@ enum rofft { ROFF_TS, ROFF_TE, ROFF_T_, + ROFF_EQ, + ROFF_EN, ROFF_cblock, ROFF_ccond, /* FIXME: remove this. */ ROFF_USERDEF, @@ -93,6 +95,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 { @@ -151,6 +156,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); @@ -189,6 +196,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 }, @@ -311,15 +320,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); @@ -477,6 +493,8 @@ roff_parseln(struct roff *r, int ln, cha * 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 @@ roff_parseln(struct roff *r, int ln, cha 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 @@ 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->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 @@ roff_T_(ROFF_ARGS) /* 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_userdef(ROFF_ARGS) ROFF_REPARSE : ROFF_APPEND); } - static char * roff_getname(struct roff *r, char **cpp, int ln, int pos) { @@ -1274,7 +1333,6 @@ roff_getname(struct roff *r, char **cpp, 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 @@ roff_setstr(struct roff *r, const char * *c = '\0'; } - static const char * roff_getstrn(const struct roff *r, const char *name, size_t len) { @@ -1357,7 +1414,6 @@ roff_getstrn(const struct roff *r, const return(n ? n->string : NULL); } - static void roff_freestr(struct roff *r) { @@ -1378,4 +1434,11 @@ 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); } Index: libroff.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libroff.h,v retrieving revision 1.17 retrieving revision 1.18 diff -Llibroff.h -Llibroff.h -u -p -r1.17 -r1.18 --- libroff.h +++ libroff.h @@ -43,6 +43,13 @@ struct tbl_node { 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_data(struct tbl_node *, int, c 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: Makefile =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/Makefile,v retrieving revision 1.309 retrieving revision 1.310 diff -LMakefile -LMakefile -u -p -r1.309 -r1.310 --- Makefile +++ Makefile @@ -31,11 +31,11 @@ CFLAGS += -g $(WFLAGS) $(VFLAGS) -DHA 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: main.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.c,v retrieving revision 1.142 retrieving revision 1.143 diff -Lmain.c -Lmain.c -u -p -r1.142 -r1.143 --- main.c +++ main.c @@ -863,6 +863,8 @@ rerun: 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, -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv