diff options
-rw-r--r-- | macro.c | 66 | ||||
-rw-r--r-- | mdoc.c | 4 | ||||
-rw-r--r-- | mdoc.h | 7 | ||||
-rw-r--r-- | mdoclint.1 | 42 | ||||
-rw-r--r-- | mdocterm.1 | 49 | ||||
-rw-r--r-- | mdocterm.c | 27 | ||||
-rw-r--r-- | mdoctree.1 | 43 | ||||
-rw-r--r-- | mmain.c | 11 | ||||
-rw-r--r-- | validate.c | 7 |
9 files changed, 198 insertions, 58 deletions
@@ -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); @@ -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(); @@ -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); @@ -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: @@ -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 , @@ -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); } @@ -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: @@ -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); } @@ -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); |