From: kristaps@mdocml.bsd.lv
To: source@mdocml.bsd.lv
Subject: mdocml: Add initial EQN support to mandoc.
Date: Sun, 6 Feb 2011 15:36:36 -0500 (EST) [thread overview]
Message-ID: <201102062036.p16KaaGN028107@krisdoz.my.domain> (raw)
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 <kristaps@bsd.lv>
+ *
+ * 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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#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
next reply other threads:[~2011-02-06 20:36 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-06 20:36 kristaps [this message]
2011-02-06 20:41 ` Kristaps Dzonsons
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201102062036.p16KaaGN028107@krisdoz.my.domain \
--to=kristaps@mdocml.bsd.lv \
--cc=source@mdocml.bsd.lv \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).