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 p6HCDbQu013785 for ; Sun, 17 Jul 2011 08:13:37 -0400 (EDT) Received: (from kristaps@localhost) by krisdoz.my.domain (8.14.3/8.14.3/Submit) id p6HCDbvA026672; Sun, 17 Jul 2011 08:13:37 -0400 (EDT) Date: Sun, 17 Jul 2011 08:13:37 -0400 (EDT) Message-Id: <201107171213.p6HCDbvA026672@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 `define' support for eqn(7). X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- Add initial `define' support for eqn(7). This works by iterating over a simple list. It's a slow, auditable early implementation. Data is read (the reading function will be reused) then parsed, then the line re-run if remaining stuff exists. Note this function isn't the same as mandoc_getarg(), as eqn(7) uses a different system for reading quoted strings. This doesn't actually use the defines. Modified Files: -------------- mdocml: eqn.c libroff.h roff.c Revision Data ------------- Index: eqn.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/eqn.c,v retrieving revision 1.5 retrieving revision 1.6 diff -Leqn.c -Leqn.c -u -p -r1.5 -r1.6 --- eqn.c +++ eqn.c @@ -28,12 +28,18 @@ #include "libmandoc.h" #include "libroff.h" +static const char *eqn_nexttok(struct mparse *, int, int, + const char **, size_t *); + /* ARGSUSED */ enum rofferr -eqn_read(struct eqn_node **epp, int ln, const char *p, int offs) +eqn_read(struct eqn_node **epp, int ln, + const char *p, int pos, int *offs) { - size_t sz; - struct eqn_node *ep; + size_t sz; + struct eqn_node *ep; + const char *start, *end; + int i; if (0 == strcmp(p, ".EN")) { *epp = NULL; @@ -41,14 +47,69 @@ eqn_read(struct eqn_node **epp, int ln, } ep = *epp; + end = p + pos; + start = eqn_nexttok(ep->parse, ln, pos, &end, &sz); + + if (NULL == start) + return(ROFF_IGN); + + if (6 == sz && 0 == strncmp("define", start, 6)) { + /* + * TODO: warn if key is quoted: groff doesn't seem to + * like this (I don't know why). + */ + start = eqn_nexttok(ep->parse, ln, pos, &end, &sz); + for (i = 0; i < (int)ep->defsz; i++) { + if (ep->defs[i].keysz != sz) + continue; + if (0 == strncmp(ep->defs[i].key, start, sz)) + break; + } + + /* + * TODO: merge this code with roff_getstr(). + */ + + if (i == (int)ep->defsz) { + ep->defsz++; + ep->defs = mandoc_realloc + (ep->defs, ep->defsz * + sizeof(struct eqn_def)); + ep->defs[i].keysz = sz; + ep->defs[i].key = mandoc_malloc(sz + 1); + memcpy(ep->defs[i].key, start, sz); + ep->defs[i].key[(int)sz] = '\0'; + ep->defs[i].val = NULL; + ep->defs[i].valsz = 0; + } + + start = eqn_nexttok(ep->parse, ln, pos, &end, &sz); + + ep->defs[i].valsz = sz; + ep->defs[i].val = mandoc_realloc + (ep->defs[i].val, sz + 1); + memcpy(ep->defs[i].val, start, sz); + ep->defs[i].val[(int)sz] = '\0'; + + if ('\0' == *end) + return(ROFF_IGN); + + *offs = end - (p + pos); + assert(*offs > 0); + + return(ROFF_RERUN); + } else + end = p + pos; + + if (0 == (sz = strlen(end))) + return(ROFF_IGN); - 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); + strlcat(ep->eqn.data, end, ep->eqn.sz + 1); return(ROFF_IGN); } @@ -59,7 +120,6 @@ eqn_alloc(int pos, int line, struct mpar p = mandoc_calloc(1, sizeof(struct eqn_node)); p->parse = parse; - p->eqn.line = line; p->eqn.pos = pos; @@ -77,7 +137,52 @@ eqn_end(struct eqn_node *e) void eqn_free(struct eqn_node *p) { + int i; free(p->eqn.data); + + for (i = 0; i < (int)p->defsz; i++) { + free(p->defs[i].key); + free(p->defs[i].val); + } + + free(p->defs); free(p); +} + +static const char * +eqn_nexttok(struct mparse *mp, int ln, int pos, + const char **next, size_t *sz) +{ + const char *start; + int q; + + start = *next; + q = 0; + + if ('\0' == *start) + return(NULL); + + if ('"' == *start) { + start++; + q = 1; + } + + *next = q ? strchr(start, '"') : strchr(start, ' '); + + if (NULL != *next) { + *sz = (size_t)(*next - start); + if (q) + (*next)++; + while (' ' == **next) + (*next)++; + } else { + if (q) + mandoc_msg(MANDOCERR_BADQUOTE, + mp, ln, pos, NULL); + *next = strchr(start, '\0'); + *sz = (size_t)(*next - start); + } + + return(start); } Index: roff.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v retrieving revision 1.145 retrieving revision 1.146 diff -Lroff.c -Lroff.c -u -p -r1.145 -r1.146 --- roff.c +++ roff.c @@ -519,18 +519,18 @@ roff_parseln(struct roff *r, int ln, cha if (ROFF_CONT != e) return(e); if (r->eqn) - return(eqn_read(&r->eqn, ln, *bufp, pos)); + return(eqn_read(&r->eqn, ln, *bufp, pos, offs)); if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, pos)); return(ROFF_CONT); } else if ( ! ctl) { if (r->eqn) - return(eqn_read(&r->eqn, ln, *bufp, pos)); + return(eqn_read(&r->eqn, ln, *bufp, pos, offs)); if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, pos)); return(ROFF_CONT); } else if (r->eqn) - return(eqn_read(&r->eqn, ln, *bufp, ppos)); + return(eqn_read(&r->eqn, ln, *bufp, ppos, offs)); /* * If a scope is open, go to the child handler for that macro, Index: libroff.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libroff.h,v retrieving revision 1.21 retrieving revision 1.22 diff -Llibroff.h -Llibroff.h -u -p -r1.21 -r1.22 --- libroff.h +++ libroff.h @@ -42,10 +42,19 @@ struct tbl_node { struct tbl_node *next; }; +struct eqn_def { + char *key; + size_t keysz; + char *val; + size_t valsz; +}; + struct eqn_node { + struct eqn_def *defs; + size_t defsz; struct eqn eqn; - struct eqn_node *next; struct mparse *parse; + struct eqn_node *next; }; struct tbl_node *tbl_alloc(int, int, struct mparse *); @@ -62,7 +71,8 @@ void tbl_end(struct tbl_node *); struct eqn_node *eqn_alloc(int, int, struct mparse *); void eqn_end(struct eqn_node *); void eqn_free(struct eqn_node *); -enum rofferr eqn_read(struct eqn_node **, int, const char *, int); +enum rofferr eqn_read(struct eqn_node **, int, + const char *, int, int *); __END_DECLS -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv