summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--macro.c66
-rw-r--r--mdoc.c4
-rw-r--r--mdoc.h7
-rw-r--r--mdoclint.142
-rw-r--r--mdocterm.149
-rw-r--r--mdocterm.c27
-rw-r--r--mdoctree.143
-rw-r--r--mmain.c11
-rw-r--r--validate.c7
9 files changed, 198 insertions, 58 deletions
diff --git a/macro.c b/macro.c
index 7de4908b..c1dedefa 100644
--- a/macro.c
+++ b/macro.c
@@ -60,6 +60,8 @@ static int append_delims(struct mdoc *, int, int *, char *);
static int lookup(struct mdoc *, int, int, int, const char *);
static int pwarn(struct mdoc *, int, int, int);
static int perr(struct mdoc *, int, int, int);
+static int scopewarn(struct mdoc *, enum mdoc_type, int, int,
+ const struct mdoc_node *);
#define WMACPARM (1)
#define WOBS (2)
@@ -192,7 +194,7 @@ perr(struct mdoc *mdoc, int line, int pos, int type)
switch (type) {
case (ENOCTX):
c = mdoc_perr(mdoc, line, pos,
- "closing macro has prior context");
+ "closing macro has no prior context");
break;
case (ENOPARMS):
c = mdoc_perr(mdoc, line, pos,
@@ -228,6 +230,53 @@ pwarn(struct mdoc *mdoc, int line, int pos, int type)
static int
+scopewarn(struct mdoc *mdoc, enum mdoc_type type,
+ int line, int pos, const struct mdoc_node *p)
+{
+ const char *n, *t, *tt;
+
+ n = t = "<root>";
+ tt = "block";
+
+ switch (p->type) {
+ case (MDOC_BODY):
+ tt = "multi-line";
+ break;
+ case (MDOC_HEAD):
+ tt = "line";
+ break;
+ default:
+ break;
+ }
+
+ switch (p->type) {
+ case (MDOC_BLOCK):
+ n = mdoc_macronames[p->tok];
+ t = "block";
+ break;
+ case (MDOC_BODY):
+ n = mdoc_macronames[p->tok];
+ t = "multi-line";
+ break;
+ case (MDOC_HEAD):
+ n = mdoc_macronames[p->tok];
+ t = "line";
+ break;
+ default:
+ break;
+ }
+
+ if ( ! (MDOC_IGN_SCOPE & mdoc->pflags))
+ return(mdoc_perr(mdoc, line, pos,
+ "%s scope breaks %s scope of %s",
+ tt, t, n));
+ return(mdoc_pwarn(mdoc, line, pos, WARN_SYNTAX,
+ "%s scope breaks %s scope of %s",
+ tt, t, n));
+}
+
+
+static int
lookup(struct mdoc *mdoc, int line, int pos, int from, const char *p)
{
int res;
@@ -512,9 +561,8 @@ rewind_subblock(enum mdoc_type type, struct mdoc *mdoc,
break;
else if (rewind_dobreak(tok, n))
continue;
- return(mdoc_perr(mdoc, line, ppos,
- "scope breaks %s", MDOC_ROOT == n->type ?
- "<root>" : mdoc_macronames[n->tok]));
+ if ( ! scopewarn(mdoc, type, line, ppos, n))
+ return(0);
}
assert(n);
@@ -537,9 +585,8 @@ rewind_expblock(struct mdoc *mdoc, int tok, int line, int ppos)
break;
else if (rewind_dobreak(tok, n))
continue;
- return(mdoc_perr(mdoc, line, ppos,
- "scope breaks %s", MDOC_ROOT == n->type ?
- "<root>" : mdoc_macronames[n->tok]));
+ if ( ! scopewarn(mdoc, MDOC_BLOCK, line, ppos, n))
+ return(0);
}
assert(n);
@@ -562,9 +609,8 @@ rewind_impblock(struct mdoc *mdoc, int tok, int line, int ppos)
break;
else if (rewind_dobreak(tok, n))
continue;
- return(mdoc_perr(mdoc, line, ppos,
- "scope breaks %s", MDOC_ROOT == n->type ?
- "<root>" : mdoc_macronames[n->tok]));
+ if ( ! scopewarn(mdoc, MDOC_BLOCK, line, ppos, n))
+ return(0);
}
assert(n);
diff --git a/mdoc.c b/mdoc.c
index 8e9e1d9a..b533470c 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -129,7 +129,7 @@ mdoc_free(struct mdoc *mdoc)
struct mdoc *
-mdoc_alloc(void *data, const struct mdoc_cb *cb)
+mdoc_alloc(void *data, int pflags, const struct mdoc_cb *cb)
{
struct mdoc *p;
@@ -142,7 +142,7 @@ mdoc_alloc(void *data, const struct mdoc_cb *cb)
p->last = xcalloc(1, sizeof(struct mdoc_node));
p->last->type = MDOC_ROOT;
p->first = p->last;
-
+ p->pflags = pflags;
p->next = MDOC_NEXT_CHILD;
p->htab = mdoc_tokhash_alloc();
diff --git a/mdoc.h b/mdoc.h
index 62eaa947..1dace83c 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -251,6 +251,8 @@ struct mdoc_node {
#define MDOC_ACTED (1 << 1)
enum mdoc_type type;
enum mdoc_sec sec;
+
+ /* FIXME: union/struct this with #defines. */
struct mdoc_arg *args; /* BLOCK/ELEM */
struct mdoc_node *head; /* BLOCK */
struct mdoc_node *body; /* BLOCK */
@@ -258,7 +260,8 @@ struct mdoc_node {
char *string; /* TEXT */
};
-#define MDOC_IGN_SCOPE (1 << 0)
+#define MDOC_IGN_SCOPE (1 << 0) /* Ignore scope violations. */
+#define MDOC_IGN_ESCAPE (1 << 1) /* Ignore bad escape sequences. */
/* Call-backs for parse messages. */
struct mdoc_cb {
@@ -282,7 +285,7 @@ struct mdoc;
void mdoc_free(struct mdoc *);
/* Allocate a new parser instance. */
-struct mdoc *mdoc_alloc(void *data, const struct mdoc_cb *);
+struct mdoc *mdoc_alloc(void *, int, const struct mdoc_cb *);
/* Set parse options. */
void mdoc_setflags(struct mdoc *, int);
diff --git a/mdoclint.1 b/mdoclint.1
index 949ba761..1cfc0fb2 100644
--- a/mdoclint.1
+++ b/mdoclint.1
@@ -26,7 +26,8 @@
.\" SECTION
.Sh SYNOPSIS
.Nm mdoclint
-.Op Fl v
+.Op Fl vV
+.Op Fl f Ns Ar options...
.Op Fl W Ns Ar err...
.Op Ar infile
.\" SECTION
@@ -37,11 +38,19 @@ utility parses a BSD
.Dq mdoc
manual pages and validates its syntax tree. The arguments are as
follows:
-.Bl -tag -width "\-Werr... "
+.Bl -tag -width XXXXXXXXXXXX -offset XXXX
.\" ITEM
.It Fl v
Print verbose parsing output.
.\" ITEM
+.It Fl V
+Print version and exit.
+.\" ITEM
+.It Fl f Ns Ar option...
+Override default compiler behaviour. See
+.Sx Compiler Options
+for details.
+.\" ITEM
.It Fl W Ns Ar err...
Print warning messages. May be set to
.Fl W Ns Ar all
@@ -76,20 +85,31 @@ input, documented at
.Xr mdoc 7
and
.Xr mdoc.samples 7 ,
-into an abstract syntax tree.
-.\" PARAGRAPH
-.Pp
-By default,
-.Nm
-reads from stdin.
+into an abstract syntax tree. By default, it reads from stdin.
.\" PARAGRAPH
.Pp
.Ex -std mdoclint
+.\" SUB-SECTION
+.Ss Compiler Options
+Default compiler behaviour may be overriden with the
+.Fl f
+flag. The available options are as follows:
+.Bl -tag -width XXXXXXXXXXXX -offset XXXX
+.It Fl f Ns Ar ign-scope
+When rewinding the scope of a block macro, forces the compiler to ignore
+scope violations. This can seriously mangle the resulting tree.
+.It Fl f Ns Ar ign-escape
+Ignore invalid escape sequences.
+.El
.\" PARAGRAPH
.Pp
-.Nm
-is
-.Ud
+As with the
+.Fl W
+flag, multiple
+.Fl f
+options may be grouped and delimited with a comma. Using
+.Fl f Ns Ar ign-scope,ign-escape ,
+for example, will try to ignore scope and character-escape errors.
.\" SECTION
.Sh EXAMPLES
To validate this manual page:
diff --git a/mdocterm.1 b/mdocterm.1
index 3c6e3409..687b657d 100644
--- a/mdocterm.1
+++ b/mdocterm.1
@@ -26,7 +26,8 @@
.\" SECTION
.Sh SYNOPSIS
.Nm mdocmterm
-.Op Fl v
+.Op Fl vV
+.Op Fl f Ns Ar option...
.Op Fl W Ns Ar err...
.Op Ar infile
.\" SECTION
@@ -36,11 +37,19 @@ The
utility formats a BSD
.Dq mdoc
manual page for display on the terminal. The arguments are as follows:
-.Bl -tag -width "\-Werr... "
+.Bl -tag -width XXXXXXXXXXXX
.\" ITEM
.It Fl v
Print verbose parsing output.
.\" ITEM
+.It Fl v
+Print version and exit.
+.\" ITEM
+.It Fl f Ns Ar option...
+Override default compiler behaviour. See
+.Sx Compiler Options
+for details.
+.\" ITEM
.It Fl W Ns Ar err...
Print warning messages. May be set to
.Fl W Ns Ar all
@@ -75,20 +84,38 @@ input, documented at
.Xr mdoc 7
and
.Xr mdoc.samples 7 ,
-into an abstract syntax tree.
-.\" PARAGRAPH
+into an abstract syntax tree.
.Pp
-By default,
-.Nm
-reads from stdin and prints terminal-encoded output to stdout.
+By default,
+.Nm
+reads from stdin and prints ANSI
+.Qq raw
+terminal-encoded output to stdout, at this time to a fixed column with
+of 78 characters.
.\" PARAGRAPH
.Pp
.Ex -std mdocmterm
+.\" SUB-SECTION
+.Ss Compiler Options
+Default compiler behaviour may be overriden with the
+.Fl f
+flag. The available options are as follows:
+.Bl -tag -width XXXXXXXXXXXX -offset XXXX
+.It Fl f Ns Ar ign-scope
+When rewinding the scope of a block macro, forces the compiler to ignore
+scope violations. This can seriously mangle the resulting tree.
+.It Fl f Ns Ar ign-escape
+Ignore invalid escape sequences.
+.El
.\" PARAGRAPH
.Pp
-.Nm
-is
-.Ud
+As with the
+.Fl W
+flag, multiple
+.Fl f
+options may be grouped and delimited with a comma. Using
+.Fl f Ns Ar ign-scope,ign-escape ,
+for example, will try to ignore scope and character-escape errors.
.\" SUB-SECTION
.Ss Character Escapes
This section documents the character-escapes accepted by
@@ -224,7 +251,7 @@ To display this manual page:
.Pp
To pipe a manual page to the pager:
.Pp
-.D1 % mdocterm mdocterm.1 | less \-R
+.D1 % mdocterm mdocterm.1 2>&1 | less \-R
.\" SECTION
.Sh SEE ALSO
.Xr mdoctree 1 ,
diff --git a/mdocterm.c b/mdocterm.c
index 46702e21..a419880b 100644
--- a/mdocterm.c
+++ b/mdocterm.c
@@ -681,24 +681,34 @@ pescape(struct termp *p, const char *word, size_t *i, size_t len)
{
size_t j;
- (*i)++;
- assert(*i < len);
+ if (++(*i) >= len) {
+ warnx("ignoring bad escape sequence");
+ return;
+ }
if ('(' == word[*i]) {
(*i)++;
- assert(*i + 1 < len);
+ if (*i + 1 >= len) {
+ warnx("ignoring bad escape sequence");
+ return;
+ }
nescape(p, &word[*i], 2);
(*i)++;
return;
} else if ('*' == word[*i]) {
- /* XXX - deprecated! */
(*i)++;
- assert(*i < len);
+ if (*i >= len) {
+ warnx("ignoring bad escape sequence");
+ return;
+ }
switch (word[*i]) {
case ('('):
(*i)++;
- assert(*i + 1 < len);
+ if (*i + 1 >= len) {
+ warnx("ignoring bad escape sequence");
+ return;
+ }
nescape(p, &word[*i], 2);
(*i)++;
return;
@@ -718,7 +728,10 @@ pescape(struct termp *p, const char *word, size_t *i, size_t len)
for (j = 0; word[*i] && ']' != word[*i]; (*i)++, j++)
/* Loop... */ ;
- assert(word[*i]);
+ if (0 == word[*i]) {
+ warnx("ignoring bad escape sequence");
+ return;
+ }
nescape(p, &word[*i - j], j);
}
diff --git a/mdoctree.1 b/mdoctree.1
index 0c564811..fcd20fec 100644
--- a/mdoctree.1
+++ b/mdoctree.1
@@ -26,7 +26,8 @@
.\" SECTION
.Sh SYNOPSIS
.Nm mdoctree
-.Op Fl v
+.Op Fl vV
+.Op Fl f Ns Ar options...
.Op Fl W Ns Ar err...
.Op Ar infile
.\" SECTION
@@ -39,11 +40,19 @@ manual pages and prints its syntax tree. It's commonly used to see the
syntax tree of a document when building new
.Xr mdoc 3
utilities. The arguments are as follows:
-.Bl -tag -width "\-Werr... "
+.Bl -tag -width XXXXXXXXXXXX
.\" ITEM
.It Fl v
Print verbose parsing output.
.\" ITEM
+.It Fl V
+Print version and exit.
+.\" ITEM
+.It Fl f Ns Ar option...
+Override default compiler behaviour. See
+.Sx Compiler Options
+for details.
+.\" ITEM
.It Fl W Ns Ar err...
Print warning messages. May be set to
.Fl W Ns Ar all
@@ -78,20 +87,32 @@ input, documented at
.Xr mdoc 7
and
.Xr mdoc.samples 7 ,
-into an abstract syntax tree.
-.\" PARAGRAPH
-.Pp
-By default,
-.Nm
-reads from stdin and prints the syntax tree to stdout.
+into an abstract syntax tree. By default, it reads from stdin and
+prints the syntax tree to stdout.
.\" PARAGRAPH
.Pp
.Ex -std mdoctree
+.\" SUB-SECTION
+.Ss Compiler Options
+Default compiler behaviour may be overriden with the
+.Fl f
+flag. The available options are as follows:
+.Bl -tag -width XXXXXXXXXXXX -offset XXXX
+.It Fl f Ns Ar ign-scope
+When rewinding the scope of a block macro, forces the compiler to ignore
+scope violations. This can seriously mangle the resulting tree.
+.It Fl f Ns Ar ign-escape
+Ignore invalid escape sequences.
+.El
.\" PARAGRAPH
.Pp
-.Nm
-is
-.Ud
+As with the
+.Fl W
+flag, multiple
+.Fl f
+options may be grouped and delimited with a comma. Using
+.Fl f Ns Ar ign-scope,ign-escape ,
+for example, will try to ignore scope and character-escape errors.
.\" SECTION
.Sh EXAMPLES
To validate this manual page:
diff --git a/mmain.c b/mmain.c
index dc70c37d..8f57a8c1 100644
--- a/mmain.c
+++ b/mmain.c
@@ -71,7 +71,7 @@ void
mmain_usage(const char *help)
{
- warnx("usage: %s %s%s[-v] [-Wwarn...] [infile]", __progname,
+ warnx("usage: %s %s%s[-v] [-foption...] [-Wwarn...] [infile]", __progname,
help ? help : "", help ? " " : "");
}
@@ -198,7 +198,7 @@ mmain_mdoc(struct mmain *p)
/* Allocate the parser. */
- p->mdoc = mdoc_alloc(p, &cb);
+ p->mdoc = mdoc_alloc(p, p->pflags, &cb);
/* Parse the input file. */
@@ -217,14 +217,18 @@ static int
optsopt(struct mmain *p, char *arg)
{
char *v;
- char *toks[] = { "ignore-scope", NULL };
+ char *toks[] = { "ign-scope", "ign-escape", NULL };
while (*arg)
switch (getsubopt(&arg, toks, &v)) {
case (0):
p->pflags |= MDOC_IGN_SCOPE;
break;
+ case (1):
+ p->pflags |= MDOC_IGN_ESCAPE;
+ break;
default:
+ /* FIXME: report? */
return(0);
}
@@ -254,6 +258,7 @@ optswarn(struct mmain *p, char *arg)
p->warn |= MD_WARN_ERR;
break;
default:
+ /* FIXME: report? */
return(0);
}
diff --git a/validate.c b/validate.c
index 271e8e49..fbd54780 100644
--- a/validate.c
+++ b/validate.c
@@ -685,7 +685,12 @@ check_text(struct mdoc *mdoc, int line, int pos, const char *p)
p += (int)c - 1;
continue;
}
- return(mdoc_perr(mdoc, line, pos, "invalid escape"));
+ if ( ! (MDOC_IGN_ESCAPE & mdoc->pflags))
+ return(mdoc_perr(mdoc, line, pos,
+ "invalid escape sequence"));
+ if ( ! mdoc_pwarn(mdoc, line, pos, WARN_SYNTAX,
+ "invalid escape sequence"))
+ return(0);
}
return(1);