diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | mdoc.c | 25 | ||||
-rw-r--r-- | mdoc.h | 1 | ||||
-rw-r--r-- | mdoclint.1 | 17 | ||||
-rw-r--r-- | mdocterm.1 | 17 | ||||
-rw-r--r-- | mdoctree.1 | 23 | ||||
-rw-r--r-- | mmain.c | 48 |
7 files changed, 114 insertions, 21 deletions
@@ -1,7 +1,7 @@ .SUFFIXES: .html .sgml -VERSION = 1.4.2 -VDATE = 8 March 2009 +VERSION = 1.4.4 +VDATE = 9 March 2009 BINDIR = $(PREFIX)/bin INCLUDEDIR = $(PREFIX)/include @@ -38,6 +38,7 @@ static int mdoc_node_append(struct mdoc *, static int parsetext(struct mdoc *, int, char *); static int parsemacro(struct mdoc *, int, char *); +static int macrowarn(struct mdoc *, int, const char *); const char *const __mdoc_macronames[MDOC_MAX] = { @@ -495,6 +496,19 @@ parsetext(struct mdoc *mdoc, int line, char *buf) } +static int +macrowarn(struct mdoc *m, int ln, const char *buf) +{ + if ( ! (MDOC_IGN_MACRO & m->pflags)) + return(mdoc_perr(m, ln, 1, "unknown macro: %s%s", + buf, buf[3] ? "..." : "")); + return(mdoc_pwarn(m, ln, 1, WARN_SYNTAX, + "unknown macro: %s%s", + buf, buf[3] ? "..." : "")); +} + + + /* * Parse a macro line, that is, a line beginning with the control * character. @@ -525,14 +539,15 @@ parsemacro(struct mdoc *m, int ln, char *buf) mac[i - 1] = 0; if (i == 5 || i <= 2) { - (void)mdoc_perr(m, ln, 1, "unknown macro: %s%s", - mac, i == 5 ? "..." : ""); - goto err; + if ( ! macrowarn(m, ln, mac)) + goto err; + return(1); } if (MDOC_MAX == (c = mdoc_tokhash_find(m->htab, mac))) { - (void)mdoc_perr(m, ln, 1, "unknown macro: %s", mac); - goto err; + if ( ! macrowarn(m, ln, mac)) + goto err; + return(1); } /* The macro is sane. Jump to the next word. */ @@ -264,6 +264,7 @@ struct mdoc_node { #define MDOC_IGN_SCOPE (1 << 0) /* Ignore scope violations. */ #define MDOC_IGN_ESCAPE (1 << 1) /* Ignore bad escape sequences. */ +#define MDOC_IGN_MACRO (1 << 2) /* Ignore unknown macros. */ /* Call-backs for parse messages. */ struct mdoc_cb { @@ -100,6 +100,8 @@ 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. +.It Fl f Ns Ar ign-macro +Ignore unknown macros at the start of input lines. .El .\" PARAGRAPH .Pp @@ -110,6 +112,21 @@ flag, multiple 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 Input Encoding +The +.Nm +utility expects its input to be 7-bit ASCII as defined in +.Xr ascii 7 . +The only non-graphing characters accepted are spaces, +.Sq \ , +and tabs, +.Sq \et . +Tabs are only accepted in literal block-displays and as column +delimiters. +.Pp +Only Unix-style newlines (\en) are accepted; if the newline is escaped, +the line is concatenated with the next. .\" SECTION .Sh EXAMPLES To validate this manual page: @@ -106,6 +106,8 @@ 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. +.It Fl f Ns Ar ign-macro +Ignore unknown macros at the start of input lines. .El .\" PARAGRAPH .Pp @@ -117,6 +119,21 @@ 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 Input Encoding +The +.Nm +utility expects its input to be 7-bit ASCII as defined in +.Xr ascii 7 . +The only non-graphing characters accepted are spaces, +.Sq \ , +and tabs, +.Sq \et . +Tabs are only accepted in literal block-displays and as column +delimiters. +.Pp +Only Unix-style newlines (\en) are accepted; if the newline is escaped, +the line is concatenated with the next. +.\" SUB-SECTION .Ss Character Escapes This section documents the character-escapes accepted by .Xr mdocterm 1 . @@ -103,6 +103,8 @@ 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. +.It Fl f Ns Ar ign-macro +Ignore unknown macros at the start of input lines. .El .\" PARAGRAPH .Pp @@ -113,6 +115,27 @@ flag, multiple 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 Input Encoding +The +.Nm +utility expects its input to be 7-bit ASCII as defined in +.Xr ascii 7 . +The only non-graphing characters accepted are spaces, +.Sq \ , +and tabs, +.Sq \et . +Tabs are only accepted in literal block-displays and as column +delimiters. +.Pp +Only Unix-style newlines (\en) are accepted; if the newline is escaped, +the line is concatenated with the next. +.\" SUB-SECTION +.Ss Character Escapes +Since +.Nm +doesn't format its output, character escapes are displayed as passed +into the compiler. .\" SECTION .Sh EXAMPLES To validate this manual page: @@ -217,7 +217,8 @@ static int optsopt(struct mmain *p, char *arg) { char *v; - char *toks[] = { "ign-scope", "ign-escape", NULL }; + char *toks[] = { "ign-scope", "ign-escape", + "ign-macro", NULL }; while (*arg) switch (getsubopt(&arg, toks, &v)) { @@ -227,8 +228,11 @@ optsopt(struct mmain *p, char *arg) case (1): p->pflags |= MDOC_IGN_ESCAPE; break; + case (2): + p->pflags |= MDOC_IGN_MACRO; + break; default: - /* FIXME: report? */ + warnx("unknown -f argument"); return(0); } @@ -258,7 +262,7 @@ optswarn(struct mmain *p, char *arg) p->warn |= MD_WARN_ERR; break; default: - /* FIXME: report? */ + warnx("unknown -W argument"); return(0); } @@ -270,10 +274,10 @@ static int parse(struct mmain *p) { ssize_t sz; - int i, pos, len, lnn; - char *line; + int j, i, pos, len, lnn; + char *ln; - for (line = NULL, lnn = 1, len = pos = 0; ; ) { + for (ln = NULL, lnn = 1, len = pos = 0; ; ) { if (-1 == (sz = read(p->fdin, p->buf, p->bufsz))) { warn("%s", p->in); return(0); @@ -283,27 +287,43 @@ parse(struct mmain *p) for (i = 0; i < (int)sz; i++) { if (pos >= len) { len += MD_LINE_SZ; - line = realloc(line, (size_t)len); - if (NULL == line) + ln = realloc(ln, (size_t)len); + if (NULL == ln) err(1, "realloc"); } if ('\n' != p->buf[i]) { - line[pos++] = p->buf[i]; + ln[pos++] = p->buf[i]; continue; } - line[pos] = 0; - if ( ! mdoc_parseln(p->mdoc, lnn, line)) - return(0); + /* Check for escaped newline. */ + + if (pos > 0 && '\\' == ln[pos - 1]) { + for (j = pos - 1; j >= 0; j--) + if ('\\' != ln[j]) + break; + if ( ! ((pos - j) % 2)) { + pos--; + lnn++; + continue; + } + } + + ln[pos] = 0; + if ( ! mdoc_parseln(p->mdoc, lnn, ln)) + return(0); lnn++; pos = 0; } } - if (line) - free(line); + if (pos > 0) + warnx("%s: file not eof-terminated", p->in); + + if (ln) + free(ln); return(mdoc_endparse(p->mdoc)); } |