aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--Makefile.depend3
-rw-r--r--cgi.c8
-rw-r--r--demandoc.c7
-rw-r--r--libmdoc.h8
-rw-r--r--main.c3
-rw-r--r--mandocdb.c3
-rw-r--r--mdoc.c31
-rw-r--r--mdoc.h8
-rw-r--r--mdoc_macro.c20
-rw-r--r--mdoc_state.c269
-rw-r--r--mdoc_validate.c195
-rw-r--r--roff.c13
-rw-r--r--roff_int.h3
14 files changed, 393 insertions, 182 deletions
diff --git a/Makefile b/Makefile
index c6bcefeb..9dd345c4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.469 2015/10/13 22:59:54 schwarze Exp $
+# $Id: Makefile,v 1.470 2015/10/20 02:01:31 schwarze Exp $
#
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
# Copyright (c) 2011, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -88,6 +88,7 @@ SRCS = att.c \
mdoc_html.c \
mdoc_macro.c \
mdoc_man.c \
+ mdoc_state.c \
mdoc_term.c \
mdoc_validate.c \
msec.c \
@@ -183,6 +184,7 @@ LIBMDOC_OBJS = att.o \
mdoc_argv.o \
mdoc_hash.o \
mdoc_macro.o \
+ mdoc_state.o \
mdoc_validate.o \
st.o
diff --git a/Makefile.depend b/Makefile.depend
index 85d7d673..4cb1df3e 100644
--- a/Makefile.depend
+++ b/Makefile.depend
@@ -1,5 +1,5 @@
att.o: att.c config.h roff.h mdoc.h libmdoc.h
-cgi.o: cgi.c config.h mandoc_aux.h mandoc.h roff.h main.h manconf.h mansearch.h cgi.h
+cgi.o: cgi.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h main.h manconf.h mansearch.h cgi.h
chars.o: chars.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h libmandoc.h
compat_err.o: compat_err.c config.h
compat_fgetln.o: compat_fgetln.c config.h
@@ -44,6 +44,7 @@ mdoc_hash.o: mdoc_hash.c config.h roff.h mdoc.h libmdoc.h
mdoc_html.o: mdoc_html.c config.h mandoc_aux.h roff.h mdoc.h out.h html.h main.h
mdoc_macro.o: mdoc_macro.c config.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
mdoc_man.o: mdoc_man.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h out.h main.h
+mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h
mdoc_term.o: mdoc_term.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h out.h term.h tag.h main.h
mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
diff --git a/cgi.c b/cgi.c
index 2148c7cf..7f78aa7b 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-/* $Id: cgi.c,v 1.110 2015/10/13 22:59:54 schwarze Exp $ */
+/* $Id: cgi.c,v 1.111 2015/10/20 02:01:31 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@usta.de>
@@ -33,6 +33,7 @@
#include "mandoc_aux.h"
#include "mandoc.h"
#include "roff.h"
+#include "mdoc.h"
#include "main.h"
#include "manconf.h"
#include "mansearch.h"
@@ -856,9 +857,10 @@ format(const struct req *req, const char *file)
vp = html_alloc(&conf);
- if (man->macroset == MACROSET_MDOC)
+ if (man->macroset == MACROSET_MDOC) {
+ mdoc_validate(man);
html_mdoc(vp, man);
- else
+ } else
html_man(vp, man);
html_free(vp);
diff --git a/demandoc.c b/demandoc.c
index deaa7909..63a4ad7f 100644
--- a/demandoc.c
+++ b/demandoc.c
@@ -1,4 +1,4 @@
-/* $Id: demandoc.c,v 1.22 2015/10/13 22:59:54 schwarze Exp $ */
+/* $Id: demandoc.c,v 1.23 2015/10/20 02:01:31 schwarze Exp $ */
/*
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -119,9 +119,10 @@ pmandoc(struct mparse *mp, int fd, const char *fn, int list)
if (man == NULL)
return;
- if (man->macroset == MACROSET_MDOC)
+ if (man->macroset == MACROSET_MDOC) {
+ mdoc_validate(man);
pmdoc(man->first->child, &line, &col, list);
- else
+ } else
pman(man->first->child, &line, &col, list);
if ( ! list)
diff --git a/libmdoc.h b/libmdoc.h
index e06ae6e6..5240fd0c 100644
--- a/libmdoc.h
+++ b/libmdoc.h
@@ -1,4 +1,4 @@
-/* $Id: libmdoc.h,v 1.106 2015/10/17 00:21:07 schwarze Exp $ */
+/* $Id: libmdoc.h,v 1.107 2015/10/20 02:01:31 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -73,11 +73,15 @@ void mdoc_tail_alloc(struct roff_man *, int, int, int);
struct roff_node *mdoc_endbody_alloc(struct roff_man *, int, int, int,
struct roff_node *, enum mdoc_endbody);
void mdoc_node_relink(struct roff_man *, struct roff_node *);
+void mdoc_node_validate(struct roff_man *);
+void mdoc_state(struct roff_man *, struct roff_node *);
+void mdoc_state_reset(struct roff_man *);
int mdoc_hash_find(const char *);
+const char *mdoc_a2arch(const char *);
const char *mdoc_a2att(const char *);
const char *mdoc_a2lib(const char *);
+enum roff_sec mdoc_a2sec(const char *);
const char *mdoc_a2st(const char *);
-const char *mdoc_a2arch(const char *);
void mdoc_argv(struct roff_man *, int, int,
struct mdoc_arg **, int *, char *);
enum margserr mdoc_args(struct roff_man *, int,
diff --git a/main.c b/main.c
index f21279da..39c8946e 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.250 2015/10/19 19:51:22 schwarze Exp $ */
+/* $Id: main.c,v 1.251 2015/10/20 02:01:31 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -696,6 +696,7 @@ parse(struct curparse *curp, int fd, const char *file)
if (man == NULL)
return;
if (man->macroset == MACROSET_MDOC) {
+ mdoc_validate(man);
switch (curp->outtype) {
case OUTT_HTML:
html_mdoc(curp->outdata, man);
diff --git a/mandocdb.c b/mandocdb.c
index ff4df09a..cbafc615 100644
--- a/mandocdb.c
+++ b/mandocdb.c
@@ -1,4 +1,4 @@
-/* $Id: mandocdb.c,v 1.203 2015/10/13 22:59:54 schwarze Exp $ */
+/* $Id: mandocdb.c,v 1.204 2015/10/20 02:01:31 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -1166,6 +1166,7 @@ mpages_merge(struct mparse *mp)
}
goto nextpage;
} else if (man != NULL && man->macroset == MACROSET_MDOC) {
+ mdoc_validate(man);
mpage->form = FORM_SRC;
mpage->sec = man->meta.msec;
mpage->sec = mandoc_strdup(
diff --git a/mdoc.c b/mdoc.c
index a6509722..12f126f5 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc.c,v 1.254 2015/10/12 00:08:15 schwarze Exp $ */
+/* $Id: mdoc.c,v 1.255 2015/10/20 02:01:31 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -121,24 +121,6 @@ mdoc_macro(MACRO_PROT_ARGS)
{
assert(tok > TOKEN_NONE && tok < MDOC_MAX);
- if (mdoc->flags & MDOC_PBODY) {
- if (tok == MDOC_Dt) {
- mandoc_vmsg(MANDOCERR_DT_LATE,
- mdoc->parse, line, ppos,
- "Dt %s", buf + *pos);
- return;
- }
- } else if ( ! (mdoc_macros[tok].flags & MDOC_PROLOGUE)) {
- if (mdoc->meta.title == NULL) {
- mandoc_vmsg(MANDOCERR_DT_NOTITLE,
- mdoc->parse, line, ppos, "%s %s",
- mdoc_macronames[tok], buf + *pos);
- mdoc->meta.title = mandoc_strdup("UNTITLED");
- }
- if (NULL == mdoc->meta.vol)
- mdoc->meta.vol = mandoc_strdup("LOCAL");
- mdoc->flags |= MDOC_PBODY;
- }
(*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf);
}
@@ -319,8 +301,8 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
* behaviour that we want to work around it.
*/
roff_elem_alloc(mdoc, line, offs, MDOC_sp);
+ mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
mdoc->next = ROFF_NEXT_SIBLING;
- mdoc_valid_post(mdoc);
return 1;
}
@@ -495,3 +477,12 @@ mdoc_isdelim(const char *p)
return DELIM_NONE;
}
+
+void
+mdoc_validate(struct roff_man *mdoc)
+{
+
+ mdoc->last = mdoc->first;
+ mdoc_node_validate(mdoc);
+ mdoc_state_reset(mdoc);
+}
diff --git a/mdoc.h b/mdoc.h
index 30f60fab..f793cc23 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -1,4 +1,4 @@
-/* $Id: mdoc.h,v 1.142 2015/04/23 16:17:44 schwarze Exp $ */
+/* $Id: mdoc.h,v 1.143 2015/10/20 02:01:31 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -279,3 +279,9 @@ extern const char *const *mdoc_macronames;
/* Names of macro args. Index is enum mdocargt. */
extern const char *const *mdoc_argnames;
+
+__BEGIN_DECLS
+
+void mdoc_validate(struct roff_man *);
+
+__END_DECLS
diff --git a/mdoc_macro.c b/mdoc_macro.c
index 63335cc7..ca959589 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.205 2015/10/17 00:21:07 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.206 2015/10/20 02:01:32 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -228,6 +228,7 @@ mdoc_endparse(struct roff_man *mdoc)
/* Rewind to the first. */
rew_last(mdoc, mdoc->first);
+ mdoc_state_reset(mdoc);
}
/*
@@ -262,25 +263,18 @@ lookup(struct roff_man *mdoc, int from, int line, int ppos, const char *p)
static void
rew_last(struct roff_man *mdoc, const struct roff_node *to)
{
- struct roff_node *np;
if (to->flags & MDOC_VALID)
return;
while (mdoc->last != to) {
- /*
- * Save the parent here, because we may delete the
- * mdoc->last node in the post-validation phase and reset
- * it to mdoc->last->parent, causing a step in the closing
- * out to be lost.
- */
- np = mdoc->last->parent;
- mdoc_valid_post(mdoc);
- mdoc->last = np;
- assert(mdoc->last);
+ mdoc_state(mdoc, mdoc->last);
+ mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
+ mdoc->last = mdoc->last->parent;
}
+ mdoc_state(mdoc, mdoc->last);
+ mdoc->last->flags |= MDOC_VALID | MDOC_ENDED;
mdoc->next = ROFF_NEXT_SIBLING;
- mdoc_valid_post(mdoc);
}
/*
diff --git a/mdoc_state.c b/mdoc_state.c
new file mode 100644
index 00000000..061092ce
--- /dev/null
+++ b/mdoc_state.c
@@ -0,0 +1,269 @@
+/* $Id: mdoc_state.c,v 1.1 2015/10/20 02:01:32 schwarze Exp $ */
+/*
+ * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * 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.
+ */
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "mandoc.h"
+#include "roff.h"
+#include "mdoc.h"
+#include "libmandoc.h"
+#include "libmdoc.h"
+
+#define STATE_ARGS struct roff_man *mdoc, struct roff_node *n
+
+typedef void (*state_handler)(STATE_ARGS);
+
+static void state_bd(STATE_ARGS);
+static void state_dl(STATE_ARGS);
+static void state_sh(STATE_ARGS);
+static void state_sm(STATE_ARGS);
+
+static const state_handler state_handlers[MDOC_MAX] = {
+ NULL, /* Ap */
+ NULL, /* Dd */
+ NULL, /* Dt */
+ NULL, /* Os */
+ state_sh, /* Sh */
+ NULL, /* Ss */
+ NULL, /* Pp */
+ NULL, /* D1 */
+ state_dl, /* Dl */
+ state_bd, /* Bd */
+ NULL, /* Ed */
+ NULL, /* Bl */
+ NULL, /* El */
+ NULL, /* It */
+ NULL, /* Ad */
+ NULL, /* An */
+ NULL, /* Ar */
+ NULL, /* Cd */
+ NULL, /* Cm */
+ NULL, /* Dv */
+ NULL, /* Er */
+ NULL, /* Ev */
+ NULL, /* Ex */
+ NULL, /* Fa */
+ NULL, /* Fd */
+ NULL, /* Fl */
+ NULL, /* Fn */
+ NULL, /* Ft */
+ NULL, /* Ic */
+ NULL, /* In */
+ NULL, /* Li */
+ NULL, /* Nd */
+ NULL, /* Nm */
+ NULL, /* Op */
+ NULL, /* Ot */
+ NULL, /* Pa */
+ NULL, /* Rv */
+ NULL, /* St */
+ NULL, /* Va */
+ NULL, /* Vt */
+ NULL, /* Xr */
+ NULL, /* %A */
+ NULL, /* %B */
+ NULL, /* %D */
+ NULL, /* %I */
+ NULL, /* %J */
+ NULL, /* %N */
+ NULL, /* %O */
+ NULL, /* %P */
+ NULL, /* %R */
+ NULL, /* %T */
+ NULL, /* %V */
+ NULL, /* Ac */
+ NULL, /* Ao */
+ NULL, /* Aq */
+ NULL, /* At */
+ NULL, /* Bc */
+ NULL, /* Bf */
+ NULL, /* Bo */
+ NULL, /* Bq */
+ NULL, /* Bsx */
+ NULL, /* Bx */
+ NULL, /* Db */
+ NULL, /* Dc */
+ NULL, /* Do */
+ NULL, /* Dq */
+ NULL, /* Ec */
+ NULL, /* Ef */
+ NULL, /* Em */
+ NULL, /* Eo */
+ NULL, /* Fx */
+ NULL, /* Ms */
+ NULL, /* No */
+ NULL, /* Ns */
+ NULL, /* Nx */
+ NULL, /* Ox */
+ NULL, /* Pc */
+ NULL, /* Pf */
+ NULL, /* Po */
+ NULL, /* Pq */
+ NULL, /* Qc */
+ NULL, /* Ql */
+ NULL, /* Qo */
+ NULL, /* Qq */
+ NULL, /* Re */
+ NULL, /* Rs */
+ NULL, /* Sc */
+ NULL, /* So */
+ NULL, /* Sq */
+ state_sm, /* Sm */
+ NULL, /* Sx */
+ NULL, /* Sy */
+ NULL, /* Tn */
+ NULL, /* Ux */
+ NULL, /* Xc */
+ NULL, /* Xo */
+ NULL, /* Fo */
+ NULL, /* Fc */
+ NULL, /* Oo */
+ NULL, /* Oc */
+ NULL, /* Bk */
+ NULL, /* Ek */
+ NULL, /* Bt */
+ NULL, /* Hf */
+ NULL, /* Fr */
+ NULL, /* Ud */
+ NULL, /* Lb */
+ NULL, /* Lp */
+ NULL, /* Lk */
+ NULL, /* Mt */
+ NULL, /* Brq */
+ NULL, /* Bro */
+ NULL, /* Brc */
+ NULL, /* %C */
+ NULL, /* Es */
+ NULL, /* En */
+ NULL, /* Dx */
+ NULL, /* %Q */
+ NULL, /* br */
+ NULL, /* sp */
+ NULL, /* %U */
+ NULL, /* Ta */
+ NULL, /* ll */
+};
+
+
+void
+mdoc_state(struct roff_man *mdoc, struct roff_node *n)
+{
+ state_handler handler;
+
+ if (n->tok == TOKEN_NONE)
+ return;
+
+ if ( ! (mdoc_macros[n->tok].flags & MDOC_PROLOGUE))
+ mdoc->flags |= MDOC_PBODY;
+
+ handler = state_handlers[n->tok];
+ if (*handler)
+ (*handler)(mdoc, n);
+}
+
+void
+mdoc_state_reset(struct roff_man *mdoc)
+{
+
+ roff_setreg(mdoc->roff, "nS", 0, '=');
+ mdoc->flags = 0;
+}
+
+static void
+state_bd(STATE_ARGS)
+{
+ enum mdocargt arg;
+
+ if (n->type != ROFFT_HEAD &&
+ (n->type != ROFFT_BODY || n->end != ENDBODY_NOT))
+ return;
+
+ arg = n->parent->args->argv[0].arg;
+ if (arg != MDOC_Literal && arg != MDOC_Unfilled)
+ return;
+
+ state_dl(mdoc, n);
+}
+
+static void
+state_dl(STATE_ARGS)
+{
+
+ switch (n->type) {
+ case ROFFT_HEAD:
+ mdoc->flags |= MDOC_LITERAL;
+ break;
+ case ROFFT_BODY:
+ mdoc->flags &= ~MDOC_LITERAL;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+state_sh(STATE_ARGS)
+{
+ struct roff_node *nch;
+ char *secname;
+
+ if (n->type != ROFFT_HEAD)
+ return;
+
+ if ( ! (n->flags & MDOC_VALID)) {
+ secname = NULL;
+ deroff(&secname, n);
+
+ /*
+ * Set the section attribute for the BLOCK, HEAD,
+ * and HEAD children; the latter can only be TEXT
+ * nodes, so no recursion is needed. For other
+ * nodes, including the .Sh BODY, this is done
+ * when allocating the node data structures, but
+ * for .Sh BLOCK and HEAD, the section is still
+ * unknown at that time.
+ */
+
+ n->sec = n->parent->sec = secname == NULL ?
+ SEC_CUSTOM : mdoc_a2sec(secname);
+ for (nch = n->child; nch != NULL; nch = nch->next)
+ nch->sec = n->sec;
+ free(secname);
+ }
+
+ if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
+ roff_setreg(mdoc->roff, "nS", 1, '=');
+ mdoc->flags |= MDOC_SYNOPSIS;
+ } else {
+ roff_setreg(mdoc->roff, "nS", 0, '=');
+ mdoc->flags &= ~MDOC_SYNOPSIS;
+ }
+}
+
+static void
+state_sm(STATE_ARGS)
+{
+
+ if (n->child == NULL)
+ mdoc->flags ^= MDOC_SMOFF;
+ else if ( ! strcmp(n->child->string, "on"))
+ mdoc->flags &= ~MDOC_SMOFF;
+ else if ( ! strcmp(n->child->string, "off"))
+ mdoc->flags |= MDOC_SMOFF;
+}
diff --git a/mdoc_validate.c b/mdoc_validate.c
index 1b3de60b..384c5345 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_validate.c,v 1.297 2015/10/19 20:04:10 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.298 2015/10/20 02:01:32 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -63,7 +63,6 @@ static void check_argv(struct roff_man *,
struct roff_node *, struct mdoc_argv *);
static void check_args(struct roff_man *, struct roff_node *);
static int child_an(const struct roff_node *);
-static enum roff_sec a2sec(const char *);
static size_t macro2len(int);
static void rewrite_macro2len(char **);
@@ -111,25 +110,21 @@ static void post_st(POST_ARGS);
static void pre_an(PRE_ARGS);
static void pre_bd(PRE_ARGS);
static void pre_bl(PRE_ARGS);
-static void pre_dd(PRE_ARGS);
static void pre_display(PRE_ARGS);
-static void pre_dt(PRE_ARGS);
-static void pre_literal(PRE_ARGS);
static void pre_obsolete(PRE_ARGS);
-static void pre_os(PRE_ARGS);
static void pre_par(PRE_ARGS);
static void pre_std(PRE_ARGS);
static const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, NULL }, /* Ap */
- { pre_dd, post_dd }, /* Dd */
- { pre_dt, post_dt }, /* Dt */
- { pre_os, post_os }, /* Os */
+ { NULL, post_dd }, /* Dd */
+ { NULL, post_dt }, /* Dt */
+ { NULL, post_os }, /* Os */
{ NULL, post_sh }, /* Sh */
{ NULL, post_ignpar }, /* Ss */
{ pre_par, post_par }, /* Pp */
{ pre_display, post_d1 }, /* D1 */
- { pre_literal, post_literal }, /* Dl */
+ { pre_display, post_literal }, /* Dl */
{ pre_bd, post_literal }, /* Bd */
{ NULL, NULL }, /* Ed */
{ pre_bl, post_bl }, /* Bl */
@@ -317,16 +312,23 @@ mdoc_valid_pre(struct roff_man *mdoc, struct roff_node *n)
}
void
-mdoc_valid_post(struct roff_man *mdoc)
+mdoc_node_validate(struct roff_man *mdoc)
{
struct roff_node *n;
v_post p;
n = mdoc->last;
- if (n->flags & MDOC_VALID)
- return;
- n->flags |= MDOC_VALID | MDOC_ENDED;
+ mdoc->last = mdoc->last->child;
+ while (mdoc->last != NULL) {
+ mdoc_node_validate(mdoc);
+ if (mdoc->last == n)
+ mdoc->last = mdoc->last->child;
+ else
+ mdoc->last = mdoc->last->next;
+ }
+ mdoc->last = n;
+ mdoc->next = ROFF_NEXT_SIBLING;
switch (n->type) {
case ROFFT_TEXT:
case ROFFT_EQN:
@@ -353,6 +355,8 @@ mdoc_valid_post(struct roff_man *mdoc)
p = mdoc_valids[n->tok].post;
if (*p)
(*p)(mdoc);
+ if (mdoc->last == n)
+ mdoc_state(mdoc, n);
break;
}
}
@@ -594,7 +598,7 @@ pre_bd(PRE_ARGS)
int i;
enum mdoc_disp dt;
- pre_literal(mdoc, n);
+ pre_display(mdoc, n);
if (n->type != ROFFT_BLOCK)
return;
@@ -714,48 +718,6 @@ pre_obsolete(PRE_ARGS)
}
static void
-pre_dt(PRE_ARGS)
-{
-
- if (mdoc->meta.title != NULL)
- mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
- n->line, n->pos, "Dt");
- else if (mdoc->meta.os != NULL)
- mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
- n->line, n->pos, "Dt after Os");
-}
-
-static void
-pre_os(PRE_ARGS)
-{
-
- if (mdoc->meta.os != NULL)
- mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
- n->line, n->pos, "Os");
- else if (mdoc->flags & MDOC_PBODY)
- mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse,
- n->line, n->pos, "Os");
-}
-
-static void
-pre_dd(PRE_ARGS)
-{
-
- if (mdoc->meta.date != NULL)
- mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
- n->line, n->pos, "Dd");
- else if (mdoc->flags & MDOC_PBODY)
- mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse,
- n->line, n->pos, "Dd");
- else if (mdoc->meta.title != NULL)
- mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
- n->line, n->pos, "Dd after Dt");
- else if (mdoc->meta.os != NULL)
- mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
- n->line, n->pos, "Dd after Os");
-}
-
-static void
post_bf(POST_ARGS)
{
struct roff_node *np, *nch;
@@ -986,19 +948,12 @@ post_literal(POST_ARGS)
n = mdoc->last;
- if (n->type != ROFFT_BODY)
+ if (n->type != ROFFT_BODY || n->end != ENDBODY_NOT)
return;
if (n->child == NULL)
mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse,
n->line, n->pos, mdoc_macronames[n->tok]);
-
- if (n->tok == MDOC_Bd &&
- n->norm->Bd.type != DISP_literal &&
- n->norm->Bd.type != DISP_unfilled)
- return;
-
- mdoc->flags &= ~MDOC_LITERAL;
}
static void
@@ -1016,15 +971,16 @@ post_defaults(POST_ARGS)
return;
nn = mdoc->last;
- mdoc->next = ROFF_NEXT_CHILD;
switch (nn->tok) {
case MDOC_Ar:
+ mdoc->next = ROFF_NEXT_CHILD;
roff_word_alloc(mdoc, nn->line, nn->pos, "file");
roff_word_alloc(mdoc, nn->line, nn->pos, "...");
break;
case MDOC_Pa:
case MDOC_Mt:
+ mdoc->next = ROFF_NEXT_CHILD;
roff_word_alloc(mdoc, nn->line, nn->pos, "~");
break;
default:
@@ -1384,6 +1340,8 @@ post_bl(POST_ARGS)
default:
return;
}
+ if (nbody->end != ENDBODY_NOT)
+ return;
nchild = nbody->child;
if (nchild == NULL) {
@@ -1828,9 +1786,7 @@ post_sh_authors(POST_ARGS)
static void
post_sh_head(POST_ARGS)
{
- struct roff_node *n;
const char *goodsec;
- char *secname;
enum roff_sec sec;
/*
@@ -1840,20 +1796,18 @@ post_sh_head(POST_ARGS)
* manual sections.
*/
- secname = NULL;
- deroff(&secname, mdoc->last);
- sec = NULL == secname ? SEC_CUSTOM : a2sec(secname);
+ sec = mdoc->last->sec;
/* The NAME should be first. */
if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed)
mandoc_vmsg(MANDOCERR_NAMESEC_FIRST, mdoc->parse,
mdoc->last->line, mdoc->last->pos,
- "Sh %s", secname);
+ "Sh %s", secnames[sec]);
/* The SYNOPSIS gets special attention in other areas. */
- if (SEC_SYNOPSIS == sec) {
+ if (sec == SEC_SYNOPSIS) {
roff_setreg(mdoc->roff, "nS", 1, '=');
mdoc->flags |= MDOC_SYNOPSIS;
} else {
@@ -1865,26 +1819,10 @@ post_sh_head(POST_ARGS)
mdoc->lastsec = sec;
- /*
- * Set the section attribute for the current HEAD, for its
- * parent BLOCK, and for the HEAD children; the latter can
- * only be TEXT nodes, so no recursion is needed.
- * For other blocks and elements, including .Sh BODY, this is
- * done when allocating the node data structures, but for .Sh
- * BLOCK and HEAD, the section is still unknown at that time.
- */
-
- mdoc->last->parent->sec = sec;
- mdoc->last->sec = sec;
- for (n = mdoc->last->child; n != NULL; n = n->next)
- n->sec = sec;
-
/* We don't care about custom sections after this. */
- if (SEC_CUSTOM == sec) {
- free(secname);
+ if (sec == SEC_CUSTOM)
return;
- }
/*
* Check whether our non-custom section is being repeated or is
@@ -1894,12 +1832,12 @@ post_sh_head(POST_ARGS)
if (sec == mdoc->lastnamed)
mandoc_vmsg(MANDOCERR_SEC_REP, mdoc->parse,
mdoc->last->line, mdoc->last->pos,
- "Sh %s", secname);
+ "Sh %s", secnames[sec]);
if (sec < mdoc->lastnamed)
mandoc_vmsg(MANDOCERR_SEC_ORDER, mdoc->parse,
mdoc->last->line, mdoc->last->pos,
- "Sh %s", secname);
+ "Sh %s", secnames[sec]);
/* Mark the last named section. */
@@ -1907,10 +1845,8 @@ post_sh_head(POST_ARGS)
/* Check particular section/manual conventions. */
- if (mdoc->meta.msec == NULL) {
- free(secname);
+ if (mdoc->meta.msec == NULL)
return;
- }
goodsec = NULL;
switch (sec) {
@@ -1935,12 +1871,11 @@ post_sh_head(POST_ARGS)
goodsec = "9";
mandoc_vmsg(MANDOCERR_SEC_MSEC, mdoc->parse,
mdoc->last->line, mdoc->last->pos,
- "Sh %s for %s only", secname, goodsec);
+ "Sh %s for %s only", secnames[sec], goodsec);
break;
default:
break;
}
- free(secname);
}
static void
@@ -2043,44 +1978,26 @@ post_par(POST_ARGS)
}
static void
-pre_literal(PRE_ARGS)
-{
-
- pre_display(mdoc, n);
-
- if (n->type != ROFFT_BODY)
- return;
-
- /*
- * The `Dl' (note "el" not "one") and `Bd -literal' and `Bd
- * -unfilled' macros set MDOC_LITERAL on entrance to the body.
- */
-
- switch (n->tok) {
- case MDOC_Dl:
- mdoc->flags |= MDOC_LITERAL;
- break;
- case MDOC_Bd:
- if (DISP_literal == n->norm->Bd.type)
- mdoc->flags |= MDOC_LITERAL;
- if (DISP_unfilled == n->norm->Bd.type)
- mdoc->flags |= MDOC_LITERAL;
- break;
- default:
- abort();
- }
-}
-
-static void
post_dd(POST_ARGS)
{
struct roff_node *n;
char *datestr;
- if (mdoc->meta.date)
+ n = mdoc->last;
+ if (mdoc->meta.date != NULL) {
+ mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
+ n->line, n->pos, "Dd");
free(mdoc->meta.date);
+ } else if (mdoc->flags & MDOC_PBODY)
+ mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse,
+ n->line, n->pos, "Dd");
+ else if (mdoc->meta.title != NULL)
+ mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
+ n->line, n->pos, "Dd after Dt");
+ else if (mdoc->meta.os != NULL)
+ mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
+ n->line, n->pos, "Dd after Os");
- n = mdoc->last;
if (n->child == NULL || n->child->string[0] == '\0') {
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
mandoc_normdate(mdoc->parse, NULL, n->line, n->pos);
@@ -2108,6 +2025,18 @@ post_dt(POST_ARGS)
char *p;
n = mdoc->last;
+ if (mdoc->flags & MDOC_PBODY) {
+ mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse,
+ n->line, n->pos, "Dt");
+ goto out;
+ }
+
+ if (mdoc->meta.title != NULL)
+ mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
+ n->line, n->pos, "Dt");
+ else if (mdoc->meta.os != NULL)
+ mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
+ n->line, n->pos, "Dt after Os");
free(mdoc->meta.title);
free(mdoc->meta.msec);
@@ -2210,6 +2139,12 @@ post_os(POST_ARGS)
struct roff_node *n;
n = mdoc->last;
+ if (mdoc->meta.os != NULL)
+ mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
+ n->line, n->pos, "Os");
+ else if (mdoc->flags & MDOC_PBODY)
+ mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse,
+ n->line, n->pos, "Os");
/*
* Set the operating system by way of the `Os' macro.
@@ -2275,8 +2210,8 @@ post_ex(POST_ARGS)
mdoc->last = n;
}
-static enum roff_sec
-a2sec(const char *p)
+enum roff_sec
+mdoc_a2sec(const char *p)
{
int i;
diff --git a/roff.c b/roff.c
index 614758a0..12853cad 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.280 2015/10/15 23:35:55 schwarze Exp $ */
+/* $Id: roff.c,v 1.281 2015/10/20 02:01:32 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -1007,6 +1007,11 @@ roff_node_append(struct roff_man *man, struct roff_node *n)
switch (man->next) {
case ROFF_NEXT_SIBLING:
+ if (man->last->next != NULL) {
+ n->next = man->last->next;
+ man->last->next->prev = n;
+ } else
+ man->last->parent->last = n;
man->last->next = n;
n->prev = man->last;
n->parent = man->last->parent;
@@ -1014,12 +1019,12 @@ roff_node_append(struct roff_man *man, struct roff_node *n)
case ROFF_NEXT_CHILD:
man->last->child = n;
n->parent = man->last;
+ n->parent->last = n;
break;
default:
abort();
}
n->parent->nchild++;
- n->parent->last = n;
/*
* Copy over the normalised-data pointer of our parent. Not
@@ -1072,7 +1077,7 @@ roff_word_alloc(struct roff_man *man, int line, int pos, const char *word)
n->string = roff_strdup(man->roff, word);
roff_node_append(man, n);
if (man->macroset == MACROSET_MDOC)
- mdoc_valid_post(man);
+ n->flags |= MDOC_VALID | MDOC_ENDED;
else
man_valid_post(man);
man->next = ROFF_NEXT_SIBLING;
@@ -1160,7 +1165,7 @@ roff_addtbl(struct roff_man *man, const struct tbl_span *tbl)
n->span = tbl;
roff_node_append(man, n);
if (man->macroset == MACROSET_MDOC)
- mdoc_valid_post(man);
+ n->flags |= MDOC_VALID | MDOC_ENDED;
else
man_valid_post(man);
man->next = ROFF_NEXT_SIBLING;
diff --git a/roff_int.h b/roff_int.h
index 8a9591e4..a0794f1b 100644
--- a/roff_int.h
+++ b/roff_int.h
@@ -1,4 +1,4 @@
-/* $Id: roff_int.h,v 1.3 2015/04/19 14:57:38 schwarze Exp $ */
+/* $Id: roff_int.h,v 1.4 2015/10/20 02:01:32 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -43,7 +43,6 @@ void man_breakscope(struct roff_man *, int);
void man_valid_post(struct roff_man *);
void mdoc_valid_pre(struct roff_man *, struct roff_node *);
-void mdoc_valid_post(struct roff_man *);
void mdoc_argv_free(struct mdoc_arg *);
__END_DECLS