summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-01-10 12:53:07 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-01-10 12:53:07 +0000
commitb0911daecba940ec62df1e631a2f8a01d7ffe641 (patch)
tree46f9e09923d3ddcc524aa04bdc519661509a8142
parent6a8c332380e498f7df739486f006b1a0d4bb4623 (diff)
downloadmandoc-b0911daecba940ec62df1e631a2f8a01d7ffe641.tar.gz
Introduce flags NODE_NOSRC and NODE_NOPRT for AST nodes.
Use them to mark generated nodes and nodes that shall not produce output. Let -Ttree output mode display these new flags. Use NODE_NOSRC for .Ar, .Mt, and .Pa default arguments. Use NODE_NOPRT for .Dd, .Dt, and .Os. These will help to make handling of text production macros more rigorous.
-rw-r--r--mandoc.16
-rw-r--r--mdoc_html.c3
-rw-r--r--mdoc_man.c5
-rw-r--r--mdoc_term.c13
-rw-r--r--mdoc_validate.c29
-rw-r--r--roff.h6
-rw-r--r--tree.c4
7 files changed, 48 insertions, 18 deletions
diff --git a/mandoc.1 b/mandoc.1
index 10623355..a4dc4233 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -529,6 +529,12 @@ The input column number (starting at one).
A closing parenthesis if the node is a closing delimiter.
.It
A full stop if the node ends a sentence.
+.It
+NOSRC if the node is not in the input file,
+but automatically generated from macros.
+.It
+NOPRT if the node is not supposed to generate output
+for any output format.
.El
.El
.Sh ENVIRONMENT
diff --git a/mdoc_html.c b/mdoc_html.c
index b78a30fa..fffe10f3 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -377,6 +377,9 @@ print_mdoc_node(MDOC_ARGS)
int child;
struct tag *t;
+ if (n->flags & NODE_NOPRT)
+ return;
+
child = 1;
t = h->tags.head;
n->flags &= ~MDOC_ENDED;
diff --git a/mdoc_man.c b/mdoc_man.c
index 40baf261..99644281 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -1,6 +1,6 @@
/* $Id$ */
/*
- * Copyright (c) 2011-2016 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011-2017 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
@@ -575,6 +575,9 @@ print_node(DECL_ARGS)
struct roff_node *sub;
int cond, do_sub;
+ if (n->flags & NODE_NOPRT)
+ return;
+
/*
* Break the line if we were parsed subsequent the current node.
* This makes the page structure be more consistent.
diff --git a/mdoc_term.c b/mdoc_term.c
index 97923a3d..6cdf9d84 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -285,6 +285,8 @@ terminal_mdoc(void *arg, const struct roff_man *mdoc)
p->defindent = 5;
term_begin(p, print_mdoc_head, print_mdoc_foot,
&mdoc->meta);
+ while (n != NULL && n->flags & NODE_NOPRT)
+ n = n->next;
if (n != NULL) {
if (n->tok != MDOC_Sh)
term_vspace(p);
@@ -311,6 +313,9 @@ print_mdoc_node(DECL_ARGS)
struct termpair npair;
size_t offset, rmargin;
+ if (n->flags & NODE_NOPRT)
+ return;
+
chld = 1;
offset = p->offset;
rmargin = p->rmargin;
@@ -564,6 +569,8 @@ print_bvspace(struct termp *p,
/* Do not vspace directly after Ss/Sh. */
nn = n;
+ while (nn->prev != NULL && nn->prev->flags & NODE_NOPRT)
+ nn = nn->prev;
while (nn->prev == NULL) {
do {
nn = nn->parent;
@@ -1718,11 +1725,15 @@ termp_pf_post(DECL_ARGS)
static int
termp_ss_pre(DECL_ARGS)
{
+ struct roff_node *nn;
switch (n->type) {
case ROFFT_BLOCK:
term_newln(p);
- if (n->prev)
+ for (nn = n->prev; nn != NULL; nn = nn->prev)
+ if ((nn->flags & NODE_NOPRT) == 0)
+ break;
+ if (nn != NULL)
term_vspace(p);
break;
case ROFFT_HEAD:
diff --git a/mdoc_validate.c b/mdoc_validate.c
index bae79cbf..a6225b49 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -945,12 +945,15 @@ post_defaults(POST_ARGS)
case MDOC_Ar:
mdoc->next = ROFF_NEXT_CHILD;
roff_word_alloc(mdoc, nn->line, nn->pos, "file");
+ mdoc->last->flags |= NODE_NOSRC;
roff_word_alloc(mdoc, nn->line, nn->pos, "...");
+ mdoc->last->flags |= NODE_NOSRC;
break;
case MDOC_Pa:
case MDOC_Mt:
mdoc->next = ROFF_NEXT_CHILD;
roff_word_alloc(mdoc, nn->line, nn->pos, "~");
+ mdoc->last->flags |= NODE_NOSRC;
break;
default:
abort();
@@ -1941,6 +1944,8 @@ post_dd(POST_ARGS)
char *datestr;
n = mdoc->last;
+ n->flags |= NODE_NOPRT;
+
if (mdoc->meta.date != NULL) {
mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
n->line, n->pos, "Dd");
@@ -1958,7 +1963,7 @@ post_dd(POST_ARGS)
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);
- goto out;
+ return;
}
datestr = NULL;
@@ -1970,8 +1975,6 @@ post_dd(POST_ARGS)
datestr, n->line, n->pos);
free(datestr);
}
-out:
- roff_node_delete(mdoc, n);
}
static void
@@ -1982,10 +1985,12 @@ post_dt(POST_ARGS)
char *p;
n = mdoc->last;
+ n->flags |= NODE_NOPRT;
+
if (mdoc->flags & MDOC_PBODY) {
mandoc_msg(MANDOCERR_DT_LATE, mdoc->parse,
n->line, n->pos, "Dt");
- goto out;
+ return;
}
if (mdoc->meta.title != NULL)
@@ -2037,7 +2042,7 @@ post_dt(POST_ARGS)
mdoc->parse, n->line, n->pos,
"Dt %s", mdoc->meta.title);
mdoc->meta.vol = mandoc_strdup("LOCAL");
- goto out; /* msec and arch remain NULL. */
+ return; /* msec and arch remain NULL. */
}
mdoc->meta.msec = mandoc_strdup(nn->string);
@@ -2055,7 +2060,7 @@ post_dt(POST_ARGS)
/* Optional third argument: architecture. */
if ((nn = nn->next) == NULL)
- goto out;
+ return;
for (p = nn->string; *p != '\0'; p++)
*p = tolower((unsigned char)*p);
@@ -2066,9 +2071,6 @@ post_dt(POST_ARGS)
if ((nn = nn->next) != NULL)
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse,
nn->line, nn->pos, "Dt ... %s", nn->string);
-
-out:
- roff_node_delete(mdoc, n);
}
static void
@@ -2096,6 +2098,8 @@ post_os(POST_ARGS)
struct roff_node *n;
n = mdoc->last;
+ n->flags |= NODE_NOPRT;
+
if (mdoc->meta.os != NULL)
mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
n->line, n->pos, "Os");
@@ -2116,11 +2120,11 @@ post_os(POST_ARGS)
mdoc->meta.os = NULL;
deroff(&mdoc->meta.os, n);
if (mdoc->meta.os)
- goto out;
+ return;
if (mdoc->defos) {
mdoc->meta.os = mandoc_strdup(mdoc->defos);
- goto out;
+ return;
}
#ifdef OSNAME
@@ -2137,9 +2141,6 @@ post_os(POST_ARGS)
}
mdoc->meta.os = mandoc_strdup(defbuf);
#endif /*!OSNAME*/
-
-out:
- roff_node_delete(mdoc, n);
}
/*
diff --git a/roff.h b/roff.h
index 19ec50f4..872d3937 100644
--- a/roff.h
+++ b/roff.h
@@ -1,7 +1,7 @@
-/* $OpenBSD$ */
+/* $Id$ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013, 2014, 2015, 2017 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
@@ -109,6 +109,8 @@ struct roff_node {
#define MAN_VALID MDOC_VALID
#define MAN_EOS MDOC_EOS
#define MAN_LINE MDOC_LINE
+#define NODE_NOSRC (1 << 8) /* Generated node, not in input file. */
+#define NODE_NOPRT (1 << 9) /* Shall not print anything. */
int prev_font; /* Before entering this node. */
int aux; /* Decoded node data, type-dependent. */
enum roff_type type; /* AST node type. */
diff --git a/tree.c b/tree.c
index 61a8e19a..3348cb4e 100644
--- a/tree.c
+++ b/tree.c
@@ -168,6 +168,10 @@ print_mdoc(const struct roff_node *n, int indent)
putchar(')');
if (MDOC_EOS & n->flags)
putchar('.');
+ if (NODE_NOSRC & n->flags)
+ printf(" NOSRC");
+ if (NODE_NOPRT & n->flags)
+ printf(" NOPRT");
putchar('\n');
}