diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2010-05-17 22:11:42 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2010-05-17 22:11:42 +0000 |
commit | b11413460f4cfc6adeaaec03d30246715922f54d (patch) | |
tree | 4836abc5d313954c48af7a9145a26a861f309230 | |
parent | 4123a170dcf7bb0ee57516df099aa6efc10ef5e1 (diff) | |
download | mandoc-b11413460f4cfc6adeaaec03d30246715922f54d.tar.gz |
Enable the unified error/warning enumeration in mandoc.h that's
stringified in main.c.
Allow `An' to handle an argument and child (with a warning).
Allow `Rv' and `Ex' to work without a prior `Nm' as groff does (with a
warning).
Allow inconsistent column syntax to only raise a warning.
-rw-r--r-- | arch.c | 1 | ||||
-rw-r--r-- | att.c | 1 | ||||
-rw-r--r-- | lib.c | 1 | ||||
-rw-r--r-- | libman.h | 46 | ||||
-rw-r--r-- | libmdoc.h | 21 | ||||
-rw-r--r-- | main.c | 172 | ||||
-rw-r--r-- | man.c | 113 | ||||
-rw-r--r-- | man.h | 7 | ||||
-rw-r--r-- | man_action.c | 7 | ||||
-rw-r--r-- | man_argv.c | 7 | ||||
-rw-r--r-- | man_hash.c | 1 | ||||
-rw-r--r-- | man_html.c | 1 | ||||
-rw-r--r-- | man_macro.c | 22 | ||||
-rw-r--r-- | man_term.c | 1 | ||||
-rw-r--r-- | man_validate.c | 67 | ||||
-rw-r--r-- | mandoc.h | 66 | ||||
-rw-r--r-- | mdoc.c | 136 | ||||
-rw-r--r-- | mdoc.h | 9 | ||||
-rw-r--r-- | mdoc_action.c | 66 | ||||
-rw-r--r-- | mdoc_argv.c | 20 | ||||
-rw-r--r-- | mdoc_hash.c | 1 | ||||
-rw-r--r-- | mdoc_html.c | 8 | ||||
-rw-r--r-- | mdoc_macro.c | 32 | ||||
-rw-r--r-- | mdoc_strings.c | 1 | ||||
-rw-r--r-- | mdoc_term.c | 8 | ||||
-rw-r--r-- | mdoc_validate.c | 246 | ||||
-rw-r--r-- | msec.c | 1 | ||||
-rw-r--r-- | st.c | 1 | ||||
-rw-r--r-- | term.c | 1 | ||||
-rw-r--r-- | tree.c | 1 | ||||
-rw-r--r-- | vol.c | 1 |
31 files changed, 534 insertions, 532 deletions
@@ -22,6 +22,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" #define LINE(x, y) \ @@ -22,6 +22,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" #define LINE(x, y) \ @@ -22,6 +22,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" #define LINE(x, y) \ @@ -26,7 +26,7 @@ enum man_next { struct man { void *data; - struct man_cb cb; + mandocmsg msg; int pflags; /* parse flags (see man.h) */ int flags; /* parse flags */ #define MAN_HALT (1 << 0) /* badness happened: die */ @@ -41,30 +41,6 @@ struct man { struct man_meta meta; }; -enum merr { - WNPRINT = 0, - WDATE, - WLNSCOPE, - WLNSCOPE2, - WTSPACE, - WTQUOTE, - WNODATA, - WNOTITLE, - WESCAPE, - WNUMFMT, - WHEADARGS, - WBODYARGS, - WNHEADARGS, - WMACROFORM, - WEXITSCOPE, - WNOSCOPE, - WOLITERAL, - WNLITERAL, - WTITLECASE, - WBADCOMMENT, - WERRMAX -}; - #define MACRO_PROT_ARGS struct man *m, enum mant tok, int line, \ int ppos, int *pos, char *buf @@ -82,15 +58,10 @@ extern const struct man_macro *const man_macros; __BEGIN_DECLS -#define man_perr(m, l, p, t) \ - man_err((m), (l), (p), 1, (t)) -#define man_pwarn(m, l, p, t) \ - man_err((m), (l), (p), 0, (t)) -#define man_nerr(m, n, t) \ - man_err((m), (n)->line, (n)->pos, 1, (t)) -#define man_nwarn(m, n, t) \ - man_err((m), (n)->line, (n)->pos, 0, (t)) - +#define man_pmsg(m, l, p, t) \ + (*(m)->msg)((t), (m)->data, (l), (p), NULL) +#define man_nmsg(m, n, t) \ + (*(m)->msg)((t), (m)->data, (n)->line, (n)->pos, NULL) int man_word_alloc(struct man *, int, int, const char *); int man_block_alloc(struct man *, int, int, enum mant); int man_head_alloc(struct man *, int, int, enum mant); @@ -105,15 +76,14 @@ int man_args(struct man *, int, int *, char *, char **); #define ARGS_EOLN (0) #define ARGS_WORD (1) #define ARGS_QWORD (1) -int man_err(struct man *, int, int, int, enum merr); -int man_vwarn(struct man *, int, int, const char *, ...); -int man_verr(struct man *, int, int, const char *, ...); +int man_vmsg(struct man *, enum mandocerr, + int, int, const char *, ...); int man_valid_post(struct man *); int man_valid_pre(struct man *, const struct man_node *); int man_action_post(struct man *); int man_action_pre(struct man *, struct man_node *); int man_unscope(struct man *, - const struct man_node *, enum merr); + const struct man_node *, enum mandocerr); __END_DECLS @@ -26,7 +26,7 @@ enum mdoc_next { struct mdoc { void *data; - struct mdoc_cb cb; + mandocmsg msg; int flags; #define MDOC_HALT (1 << 0) /* error in parse: halt */ #define MDOC_LITERAL (1 << 1) /* in a literal scope */ @@ -142,19 +142,12 @@ extern const struct mdoc_macro *const mdoc_macros; __BEGIN_DECLS -#define mdoc_perr(m, l, p, t) \ - mdoc_err((m), (l), (p), 1, (t)) -#define mdoc_pwarn(m, l, p, t) \ - mdoc_err((m), (l), (p), 0, (t)) -#define mdoc_nerr(m, n, t) \ - mdoc_err((m), (n)->line, (n)->pos, 1, (t)) -#define mdoc_nwarn(m, n, t) \ - mdoc_err((m), (n)->line, (n)->pos, 0, (t)) - -int mdoc_err(struct mdoc *, int, int, int, enum merr); -int mdoc_verr(struct mdoc *, int, int, const char *, ...); -int mdoc_vwarn(struct mdoc *, int, int, const char *, ...); - +#define mdoc_pmsg(m, l, p, t) \ + (*(m)->msg)((t), (m)->data, (l), (p), NULL) +#define mdoc_nmsg(m, n, t) \ + (*(m)->msg)((t), (m)->data, (n)->line, (n)->pos, NULL) +int mdoc_vmsg(struct mdoc *, enum mandocerr, + int, int, const char *, ...); int mdoc_macro(MACRO_PROT_ARGS); int mdoc_word_alloc(struct mdoc *, int, int, const char *); @@ -81,17 +81,83 @@ struct curparse { #define FL_NIGN_MACRO (1 << 2) /* Don't ignore bad macros. */ #define FL_IGN_ERRORS (1 << 4) /* Ignore failed parse. */ #define FL_STRICT FL_NIGN_ESCAPE | \ - FL_NIGN_MACRO - enum intt inttype; /* Input parsers... */ - struct man *man; - struct mdoc *mdoc; - struct roff *roff; - enum outt outtype; /* Output devices... */ - out_mdoc outmdoc; - out_man outman; - out_free outfree; - void *outdata; - char outopts[BUFSIZ]; + FL_NIGN_MACRO /* ignore nothing */ + enum intt inttype; /* which parser to use */ + struct man *man; /* man parser */ + struct mdoc *mdoc; /* mdoc parser */ + struct roff *roff; /* roff parser (!NULL) */ + enum outt outtype; /* which output to use */ + out_mdoc outmdoc; /* mdoc output ptr */ + out_man outman; /* man output ptr */ + out_free outfree; /* free output ptr */ + void *outdata; /* data for output */ + char outopts[BUFSIZ]; /* buf of output opts */ +}; + +static const char * const mandocerrs[MANDOCERR_MAX] = { + "ok", + "text should be uppercase", + "sections out of conentional order", + "section name repeats", + "out of order prologue", + "repeated prologue entry", + "list type must come first", + "column syntax is inconsistent", + "bad standard", + "bad library", + "bad escape sequence", + "unterminated quoted string", + "argument requires the width argument", + "superfluous width argument", + "bad date argument", + "bad width argument", + "unknown manual sction", + "section not in conventional manual section", + "end of line whitespace", + "scope open on exit", + "NAME section must come first", + "bad Boolean value", + "child violates parent syntax", + "bad AT&T symbol", + "list type repeated", + "display type repeated", + "argument repeated", + "manual name not yet set", + "obsolete macro ignored", + "empty macro ignored", + "macro not allowed in body", + "macro not allowed in prologue", + "bad character", + "bad NAME section contents", + "no blank lines", + "no text in this context", + "bad comment style", + "unknown macro will be lost", + "line scope broken", + "scope broken", + "argument count wrong", + "request scope close w/none open", + "scope already open", + "macro requires line argument(s)", + "macro requires body argument(s)", + "macro requires argument(s)", + "no title in document", + "line argument(s) will be lost", + "body argument(s) will be lost", + "missing font type", + "missing display type", + "missing list type", + "displays may not be nested", + "no scope to rewind: syntax violated", + "scope broken, syntax violated", + "line scope broken, syntax violated", + "argument count wrong, violates syntax", + "child violates parent syntax", + "argument count wrong, violates syntax", + "no document body", + "no document prologue", + "utsname system call failed", + "memory exhausted", }; static void fdesc(struct curparse *); @@ -100,9 +166,7 @@ static int foptions(int *, char *); static struct man *man_init(struct curparse *); static struct mdoc *mdoc_init(struct curparse *); static struct roff *roff_init(struct curparse *); -static int merr(void *, int, int, const char *); /* DEPRECATED */ static int moptions(enum intt *, char *); -static int mwarn(void *, int, int, const char *); /* DEPRECATED */ static int mmsg(enum mandocerr, void *, int, int, const char *); static int pset(const char *, int, struct curparse *, @@ -220,10 +284,6 @@ static struct man * man_init(struct curparse *curp) { int pflags; - struct man_cb mancb; - - mancb.man_err = merr; - mancb.man_warn = mwarn; /* Defaults from mandoc.1. */ @@ -234,7 +294,7 @@ man_init(struct curparse *curp) if (curp->fflags & FL_NIGN_ESCAPE) pflags &= ~MAN_IGN_ESCAPE; - return(man_alloc(curp, pflags, &mancb)); + return(man_alloc(curp, pflags, mmsg)); } @@ -250,10 +310,6 @@ static struct mdoc * mdoc_init(struct curparse *curp) { int pflags; - struct mdoc_cb mdoccb; - - mdoccb.mdoc_err = merr; - mdoccb.mdoc_warn = mwarn; /* Defaults from mandoc.1. */ @@ -266,7 +322,7 @@ mdoc_init(struct curparse *curp) if (curp->fflags & FL_NIGN_MACRO) pflags &= ~MDOC_IGN_MACRO; - return(mdoc_alloc(curp, pflags, &mdoccb)); + return(mdoc_alloc(curp, pflags, mmsg)); } @@ -756,67 +812,20 @@ woptions(int *wflags, char *arg) } -/* ARGSUSED */ -static int -merr(void *arg, int line, int col, const char *msg) -{ - struct curparse *curp; - - curp = (struct curparse *)arg; - - (void)fprintf(stderr, "%s:%d:%d: error: %s\n", - curp->file, line, col + 1, msg); - - with_error = 1; - - return(0); -} - - -static int -mwarn(void *arg, int line, int col, const char *msg) -{ - struct curparse *curp; - - curp = (struct curparse *)arg; - - if ( ! (curp->wflags & WARN_WALL)) - return(1); - - (void)fprintf(stderr, "%s:%d:%d: warning: %s\n", - curp->file, line, col + 1, msg); - - with_warning = 1; - if (curp->wflags & WARN_WERR) { - with_error = 1; - return(0); - } - - return(1); -} - -static const char * const mandocerrs[MANDOCERR_MAX] = { - "ok", - "multi-line scope open on exit", - "request for scope closure when no matching scope is open: ignored", - "macro requires line argument(s): ignored", - "line arguments will be lost", - "memory exhausted" -}; - -/* - * XXX: this is experimental code that will eventually become the - * generic means of covering all warnings and errors! - */ -/* ARGSUSED */ static int mmsg(enum mandocerr t, void *arg, int ln, int col, const char *msg) { -#if 0 struct curparse *cp; cp = (struct curparse *)arg; + if (t <= MANDOCERR_ERROR) { + if ( ! (cp->wflags & WARN_WALL)) + return(1); + with_warning = 1; + } else + with_error = 1; + fprintf(stderr, "%s:%d:%d: %s", cp->file, ln, col + 1, mandocerrs[t]); @@ -824,6 +833,13 @@ mmsg(enum mandocerr t, void *arg, int ln, int col, const char *msg) fprintf(stderr, ": %s", msg); fputc('\n', stderr); -#endif + + /* This is superfluous, but whatever. */ + if (t > MANDOCERR_ERROR) + return(0); + if (cp->wflags & WARN_WERR) { + with_error = 1; + return(0); + } return(1); } @@ -27,32 +27,10 @@ #include <stdio.h> #include <string.h> +#include "mandoc.h" #include "libman.h" #include "libmandoc.h" -const char *const __man_merrnames[WERRMAX] = { - "invalid character", /* WNPRINT */ - "invalid date format", /* WDATE */ - "scope of prior line violated", /* WLNSCOPE */ - "over-zealous prior line scope violation", /* WLNSCOPE2 */ - "trailing whitespace", /* WTSPACE */ - "unterminated quoted parameter", /* WTQUOTE */ - "document has no body", /* WNODATA */ - "document has no title/section", /* WNOTITLE */ - "invalid escape sequence", /* WESCAPE */ - "invalid number format", /* WNUMFMT */ - "expected block head arguments", /* WHEADARGS */ - "expected block body arguments", /* WBODYARGS */ - "expected empty block head", /* WNHEADARGS */ - "ill-formed macro", /* WMACROFORM */ - "scope open on exit", /* WEXITSCOPE */ - "no scope context", /* WNOSCOPE */ - "literal context already open", /* WOLITERAL */ - "no literal context open", /* WNLITERAL */ - "document title should be uppercase", /* WTITLECASE */ - "deprecated comment style", /* WBADCOMMENT */ -}; - const char *const __man_macronames[MAN_MAX] = { "br", "TH", "SH", "SS", "TP", "LP", "PP", "P", @@ -116,18 +94,16 @@ man_free(struct man *man) struct man * -man_alloc(void *data, int pflags, const struct man_cb *cb) +man_alloc(void *data, int pflags, mandocmsg msg) { struct man *p; p = mandoc_calloc(1, sizeof(struct man)); - if (cb) - memcpy(&p->cb, cb, sizeof(struct man_cb)); - man_hash_init(); p->data = data; p->pflags = pflags; + p->msg = msg; man_alloc1(p); return(p); @@ -375,7 +351,7 @@ man_ptext(struct man *m, int line, char *buf, int offs) if ('\\' == buf[offs] && '.' == buf[offs + 1] && '"' == buf[offs + 2]) - return(man_pwarn(m, line, offs, WBADCOMMENT)); + return(man_pmsg(m, line, offs, MANDOCERR_BADCOMMENT)); /* Literal free-form text whitespace is preserved. */ @@ -407,7 +383,7 @@ man_ptext(struct man *m, int line, char *buf, int offs) if (' ' == buf[i - 1] || '\t' == buf[i - 1]) { if (i > 1 && '\\' != buf[i - 2]) - if ( ! man_pwarn(m, line, i - 1, WTSPACE)) + if ( ! man_pmsg(m, line, i - 1, MANDOCERR_EOLNSPACE)) return(0); for (--i; i && ' ' == buf[i]; i--) @@ -441,7 +417,7 @@ descope: if (MAN_ELINE & m->flags) { m->flags &= ~MAN_ELINE; - if ( ! man_unscope(m, m->last->parent, WERRMAX)) + if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX)) return(0); } @@ -449,7 +425,7 @@ descope: return(1); m->flags &= ~MAN_BLINE; - if ( ! man_unscope(m, m->last->parent, WERRMAX)) + if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX)) return(0); return(man_body_alloc(m, line, offs, m->last->tok)); } @@ -458,11 +434,13 @@ descope: static int macrowarn(struct man *m, int ln, const char *buf, int offs) { - if ( ! (MAN_IGN_MACRO & m->pflags)) - return(man_verr(m, ln, offs, "unknown macro: %s%s", - buf, strlen(buf) > 3 ? "..." : "")); - return(man_vwarn(m, ln, offs, "unknown macro: %s%s", - buf, strlen(buf) > 3 ? "..." : "")); + int rc; + + rc = man_vmsg(m, MANDOCERR_MACRO, ln, offs, + "unknown macro: %s%s", + buf, strlen(buf) > 3 ? "..." : ""); + + return(MAN_IGN_MACRO & m->pflags ? rc : 0); } @@ -510,17 +488,15 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) if (isgraph((u_char)buf[i])) continue; - return(man_perr(m, ln, i, WNPRINT)); + if ( ! man_pmsg(m, ln, i, MANDOCERR_BADCHAR)) + return(0); + i--; } mac[j] = '\0'; if (j == 4 || j < 1) { - if ( ! (MAN_IGN_MACRO & m->pflags)) { - (void)man_perr(m, ln, ppos, WMACROFORM); - goto err; - } - if ( ! man_pwarn(m, ln, ppos, WMACROFORM)) + if ( ! macrowarn(m, ln, mac, ppos)) goto err; return(1); } @@ -542,7 +518,7 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) */ if ('\0' == buf[i] && ' ' == buf[i - 1]) - if ( ! man_pwarn(m, ln, i - 1, WTSPACE)) + if ( ! man_pmsg(m, ln, i - 1, MANDOCERR_EOLNSPACE)) goto err; /* @@ -564,8 +540,10 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) * I hate man macros. * Flat-out disallow this madness. */ - if (MAN_NSCOPED & man_macros[m->last->tok].flags) - return(man_perr(m, ln, ppos, WLNSCOPE)); + if (MAN_NSCOPED & man_macros[m->last->tok].flags) { + man_pmsg(m, ln, ppos, MANDOCERR_SYNTLINESCOPE); + return(0); + } n = m->last; @@ -573,7 +551,7 @@ man_pmacro(struct man *m, int ln, char *buf, int offs) assert(NULL == n->child); assert(0 == n->nchild); - if ( ! man_nwarn(m, n, WLNSCOPE)) + if ( ! man_nmsg(m, n, MANDOCERR_LINESCOPE)) return(0); man_node_delete(m, n); @@ -630,7 +608,7 @@ out: assert(MAN_BLINE & m->flags); m->flags &= ~MAN_BLINE; - if ( ! man_unscope(m, m->last->parent, WERRMAX)) + if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX)) return(0); return(man_body_alloc(m, ln, offs, m->last->tok)); @@ -642,49 +620,16 @@ err: /* Error out. */ int -man_verr(struct man *man, int ln, int pos, const char *fmt, ...) +man_vmsg(struct man *man, enum mandocerr t, + int ln, int pos, const char *fmt, ...) { char buf[256]; va_list ap; - if (NULL == man->cb.man_err) - return(0); - va_start(ap, fmt); - (void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap); + vsnprintf(buf, sizeof(buf) - 1, fmt, ap); va_end(ap); - return((*man->cb.man_err)(man->data, ln, pos, buf)); -} - - -int -man_vwarn(struct man *man, int ln, int pos, const char *fmt, ...) -{ - char buf[256]; - va_list ap; - - if (NULL == man->cb.man_warn) - return(0); - - va_start(ap, fmt); - (void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap); - va_end(ap); - return((*man->cb.man_warn)(man->data, ln, pos, buf)); -} - - -int -man_err(struct man *m, int line, int pos, int iserr, enum merr type) -{ - const char *p; - - p = __man_merrnames[(int)type]; - assert(p); - - if (iserr) - return(man_verr(m, line, pos, p)); - - return(man_vwarn(m, line, pos, p)); + return((*man->msg)(t, man->data, ln, pos, buf)); } @@ -100,17 +100,12 @@ struct man_node { extern const char *const *man_macronames; -struct man_cb { - int (*man_warn)(void *, int, int, const char *); - int (*man_err)(void *, int, int, const char *); -}; - __BEGIN_DECLS struct man; void man_free(struct man *); -struct man *man_alloc(void *, int, const struct man_cb *); +struct man *man_alloc(void *, int, mandocmsg); void man_reset(struct man *); int man_parseln(struct man *, int, char *, int); int man_endparse(struct man *); diff --git a/man_action.c b/man_action.c index ffa2b943..0aa0555a 100644 --- a/man_action.c +++ b/man_action.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "libman.h" #include "libmandoc.h" @@ -103,7 +104,7 @@ post_fi(struct man *m) { if ( ! (MAN_LITERAL & m->flags)) - if ( ! man_nwarn(m, m->last, WNLITERAL)) + if ( ! man_nmsg(m, m->last, MANDOCERR_NOSCOPE)) return(0); m->flags &= ~MAN_LITERAL; return(1); @@ -115,7 +116,7 @@ post_nf(struct man *m) { if (MAN_LITERAL & m->flags) - if ( ! man_nwarn(m, m->last, WOLITERAL)) + if ( ! man_nmsg(m, m->last, MANDOCERR_SCOPEREP)) return(0); m->flags |= MAN_LITERAL; return(1); @@ -159,7 +160,7 @@ post_TH(struct man *m) m->meta.date = mandoc_a2time (MTIME_ISO_8601, n->string); if (0 == m->meta.date) { - if ( ! man_nwarn(m, n, WDATE)) + if ( ! man_nmsg(m, n, MANDOCERR_BADDATE)) return(0); m->meta.date = time(NULL); } @@ -24,6 +24,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "libman.h" @@ -57,7 +58,7 @@ man_args(struct man *m, int line, int *pos, char *buf, char **v) } if (0 == buf[*pos]) { - if ( ! man_pwarn(m, line, *pos, WTQUOTE)) + if ( ! man_pmsg(m, line, *pos, MANDOCERR_BADQUOTE)) return(ARGS_ERROR); return(ARGS_QWORD); } @@ -71,7 +72,7 @@ man_args(struct man *m, int line, int *pos, char *buf, char **v) (*pos)++; if (0 == buf[*pos]) - if ( ! man_pwarn(m, line, *pos, WTSPACE)) + if ( ! man_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE)) return(ARGS_ERROR); return(ARGS_QWORD); @@ -95,7 +96,7 @@ man_args(struct man *m, int line, int *pos, char *buf, char **v) (*pos)++; if (0 == buf[*pos]) - if ( ! man_pwarn(m, line, *pos, WTSPACE)) + if ( ! man_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE)) return(ARGS_ERROR); return(ARGS_WORD); @@ -26,6 +26,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "libman.h" #define HASH_DEPTH 6 @@ -26,6 +26,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "out.h" #include "html.h" #include "man.h" diff --git a/man_macro.c b/man_macro.c index a3394a11..2c9c0e39 100644 --- a/man_macro.c +++ b/man_macro.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "libman.h" enum rew { @@ -43,7 +44,7 @@ static enum rew rew_dohalt(enum mant, enum man_type, static enum rew rew_block(enum mant, enum man_type, const struct man_node *); static int rew_warn(struct man *, - struct man_node *, enum merr); + struct man_node *, enum mandocerr); const struct man_macro __man_macros[MAN_MAX] = { { in_line_eoln, MAN_NSCOPED }, /* br */ @@ -91,25 +92,26 @@ const struct man_macro * const man_macros = __man_macros; * Warn when "n" is an explicit non-roff macro. */ static int -rew_warn(struct man *m, struct man_node *n, enum merr er) +rew_warn(struct man *m, struct man_node *n, enum mandocerr er) { - if (er == WERRMAX || MAN_BLOCK != n->type) + if (er == MANDOCERR_MAX || MAN_BLOCK != n->type) return(1); if (MAN_VALID & n->flags) return(1); if ( ! (MAN_EXPLICIT & man_macros[n->tok].flags)) return(1); - return(man_nwarn(m, n, er)); + return(man_nmsg(m, n, er)); } /* - * Rewind scope. If a code "er" != WERRMAX has been provided, it will - * be used if an explicit block scope is being closed out. + * Rewind scope. If a code "er" != MANDOCERR_MAX has been provided, it + * will be used if an explicit block scope is being closed out. */ int -man_unscope(struct man *m, const struct man_node *n, enum merr er) +man_unscope(struct man *m, const struct man_node *n, + enum mandocerr er) { assert(n); @@ -248,7 +250,7 @@ rew_scope(enum man_type type, struct man *m, enum mant tok) */ assert(n); - return(man_unscope(m, n, WERRMAX)); + return(man_unscope(m, n, MANDOCERR_MAX)); } @@ -276,7 +278,7 @@ blk_close(MACRO_PROT_ARGS) break; if (NULL == nn) - if ( ! man_pwarn(m, line, ppos, WNOSCOPE)) + if ( ! man_pmsg(m, line, ppos, MANDOCERR_NOSCOPE)) return(0); if ( ! rew_scope(MAN_BODY, m, ntok)) @@ -478,6 +480,6 @@ int man_macroend(struct man *m) { - return(man_unscope(m, m->first, WEXITSCOPE)); + return(man_unscope(m, m->first, MANDOCERR_SCOPEEXIT)); } @@ -26,6 +26,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "out.h" #include "man.h" #include "term.h" diff --git a/man_validate.c b/man_validate.c index 1bc128a0..c568e4cb 100644 --- a/man_validate.c +++ b/man_validate.c @@ -27,6 +27,7 @@ #include <stdarg.h> #include <stdlib.h> +#include "mandoc.h" #include "libman.h" #include "libmandoc.h" @@ -151,17 +152,18 @@ check_root(CHKARGS) { if (MAN_BLINE & m->flags) - return(man_nwarn(m, n, WEXITSCOPE)); + return(man_nmsg(m, n, MANDOCERR_SCOPEEXIT)); if (MAN_ELINE & m->flags) - return(man_nwarn(m, n, WEXITSCOPE)); + return(man_nmsg(m, n, MANDOCERR_SCOPEEXIT)); m->flags &= ~MAN_BLINE; m->flags &= ~MAN_ELINE; - if (NULL == m->first->child) - return(man_nerr(m, n, WNODATA)); - if (NULL == m->meta.title) { - if ( ! man_nwarn(m, n, WNOTITLE)) + if (NULL == m->first->child) { + man_nmsg(m, n, MANDOCERR_NODOCBODY); + return(0); + } else if (NULL == m->meta.title) { + if ( ! man_nmsg(m, n, MANDOCERR_NOTITLE)) return(0); /* * If a title hasn't been set, do so now (by @@ -184,12 +186,15 @@ check_title(CHKARGS) const char *p; assert(n->child); - if ('\0' == *n->child->string) - return(man_nerr(m, n, WNOTITLE)); + /* FIXME: is this sufficient? */ + if ('\0' == *n->child->string) { + man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT); + return(0); + } for (p = n->child->string; '\0' != *p; p++) if (isalpha((u_char)*p) && ! isupper((u_char)*p)) - if ( ! man_nwarn(m, n, WTITLECASE)) + if ( ! man_nmsg(m, n, MANDOCERR_UPPERCASE)) return(0); return(1); @@ -212,17 +217,16 @@ check_text(CHKARGS) pos += c - 1; continue; } - if ( ! (MAN_IGN_ESCAPE & m->pflags)) - return(man_perr(m, n->line, pos, WESCAPE)); - if ( ! man_pwarn(m, n->line, pos, WESCAPE)) - return(0); - continue; + + c = man_pmsg(m, n->line, pos, MANDOCERR_BADESCAPE); + if ( ! (MAN_IGN_ESCAPE & m->pflags) && ! c) + return(c); } if ('\t' == *p || isprint((u_char)*p)) continue; - - return(man_pwarn(m, n->line, pos, WNPRINT)); + if ( ! man_pmsg(m, n->line, pos, MANDOCERR_BADCHAR)) + return(0); } return(1); @@ -235,9 +239,10 @@ check_##name(CHKARGS) \ { \ if (n->nchild ineq (x)) \ return(1); \ - return(man_verr(m, n->line, n->pos, \ - "expected line arguments %s %d, have %d", \ - #ineq, (x), n->nchild)); \ + man_vmsg(m, MANDOCERR_SYNTARGCOUNT, n->line, n->pos, \ + "line arguments %s %d (have %d)", \ + #ineq, (x), n->nchild); \ + return(0); \ } INEQ_DEFINE(0, ==, eq0) @@ -250,10 +255,12 @@ static int check_sec(CHKARGS) { - if (MAN_BODY == n->type && 0 == n->nchild) - return(man_nwarn(m, n, WBODYARGS)); - if (MAN_HEAD == n->type && 0 == n->nchild) - return(man_nerr(m, n, WHEADARGS)); + if (MAN_HEAD == n->type && 0 == n->nchild) { + man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT); + return(0); + } else if (MAN_BODY == n->type && 0 == n->nchild) + return(man_nmsg(m, n, MANDOCERR_NOBODY)); + return(1); } @@ -263,7 +270,7 @@ check_part(CHKARGS) { if (MAN_BODY == n->type && 0 == n->nchild) - return(man_nwarn(m, n, WBODYARGS)); + return(man_nmsg(m, n, MANDOCERR_NOBODY)); return(1); } @@ -284,7 +291,7 @@ check_par(CHKARGS) default: if (n->nchild) break; - return(man_nwarn(m, n, WBODYARGS)); + return(man_nmsg(m, n, MANDOCERR_NOBODY)); } if (MAN_HEAD == n->type) switch (n->tok) { @@ -295,11 +302,11 @@ check_par(CHKARGS) case (MAN_LP): if (0 == n->nchild) break; - return(man_nwarn(m, n, WNHEADARGS)); + return(man_nmsg(m, n, MANDOCERR_ARGSLOST)); default: if (n->nchild) break; - return(man_nwarn(m, n, WHEADARGS)); + return(man_nmsg(m, n, MANDOCERR_NOARGS)); } return(1); @@ -311,8 +318,10 @@ check_bline(CHKARGS) { assert( ! (MAN_ELINE & m->flags)); - if (MAN_BLINE & m->flags) - return(man_nerr(m, n, WLNSCOPE)); + if (MAN_BLINE & m->flags) { + man_nmsg(m, n, MANDOCERR_SYNTLINESCOPE); + return(0); + } return(1); } @@ -21,14 +21,76 @@ __BEGIN_DECLS enum mandocerr { MANDOCERR_OK, + MANDOCERR_UPPERCASE, /* text should be uppercase */ + MANDOCERR_SECOOO, /* sections out of conentional order */ + MANDOCERR_SECREP, /* section name repeats */ + MANDOCERR_PROLOGOOO, /* out of order prologue */ + MANDOCERR_PROLOGREP, /* repeated prologue entry */ + MANDOCERR_LISTFIRST, /* list type must come first */ + MANDOCERR_COLUMNS, /* column syntax is inconsistent */ + MANDOCERR_BADSTANDARD, /* bad standard */ + MANDOCERR_BADLIB, /* bad library */ + MANDOCERR_BADESCAPE, /* bad escape sequence */ + MANDOCERR_BADQUOTE, /* unterminated quoted string */ + MANDOCERR_NOWIDTHARG, /* argument requires the width argument */ + MANDOCERR_WIDTHARG, /* superfluous width argument */ + MANDOCERR_BADDATE, /* bad date argument */ + MANDOCERR_BADWIDTH, /* bad width argument */ + MANDOCERR_BADMSEC, /* unknown manual sction */ + MANDOCERR_SECMSEC, /* section not in conventional manual section */ + MANDOCERR_EOLNSPACE, /* end of line whitespace */ MANDOCERR_SCOPEEXIT, /* scope open on exit */ #define MANDOCERR_WARNING MANDOCERR_SCOPEEXIT + MANDOCERR_NAMESECFIRST, /* NAME section must come first */ + MANDOCERR_BADBOOL, /* bad Boolean value */ + MANDOCERR_CHILD, /* child violates parent syntax */ + MANDOCERR_BADATT, /* bad AT&T symbol */ + MANDOCERR_LISTREP, /* list type repeated */ + MANDOCERR_DISPREP, /* display type repeated */ + MANDOCERR_ARGVREP, /* argument repeated */ + MANDOCERR_NONAME, /* manual name not yet set */ + MANDOCERR_MACROOBS, /* obsolete macro ignored */ + MANDOCERR_MACROEMPTY, /* empty macro ignored */ + MANDOCERR_BADBODY, /* macro not allowed in body */ + MANDOCERR_BADPROLOG, /* macro not allowed in prologue */ + MANDOCERR_BADCHAR, /* bad character */ + MANDOCERR_BADNAMESEC, /* bad NAME section contents */ + MANDOCERR_NOBLANKLN, /* no blank lines */ + MANDOCERR_NOTEXT, /* no text in this context */ + MANDOCERR_BADCOMMENT, /* bad comment style */ + MANDOCERR_MACRO, /* unknown macro will be lost */ + MANDOCERR_LINESCOPE, /* line scope broken */ + MANDOCERR_SCOPE, /* scope broken */ + MANDOCERR_ARGCOUNT, /* argument count wrong */ MANDOCERR_NOSCOPE, /* request scope close w/none open */ - MANDOCERR_NOARGS, /* macro requires argument(s) */ - MANDOCERR_ARGSLOST, /* line arguments will be lost */ + MANDOCERR_SCOPEREP, /* scope already open */ + /* FIXME: merge following with MANDOCERR_ARGCOUNT */ + MANDOCERR_NOARGS, /* macro requires line argument(s) */ + MANDOCERR_NOBODY, /* macro requires body argument(s) */ + MANDOCERR_NOARGV, /* macro requires argument(s) */ + MANDOCERR_NOTITLE, /* no title in document */ + MANDOCERR_ARGSLOST, /* line argument(s) will be lost */ + MANDOCERR_BODYLOST, /* body argument(s) will be lost */ #define MANDOCERR_ERROR MANDOCERR_ARGSLOST + /* FIXME: this should be a MANDOCERR_ERROR */ + MANDOCERR_FONTTYPE, /* missing font type */ + /* FIXME: this should be a MANDOCERR_ERROR */ + MANDOCERR_DISPTYPE, /* missing display type */ + /* FIXME: this should be a MANDOCERR_ERROR */ + MANDOCERR_LISTTYPE, /* missing list type */ + /* FIXME: this should be a MANDOCERR_ERROR */ + MANDOCERR_NESTEDDISP, /* displays may not be nested */ + MANDOCERR_SYNTNOSCOPE, /* request scope close w/none open */ + MANDOCERR_SYNTSCOPE, /* scope broken, syntax violated */ + MANDOCERR_SYNTLINESCOPE, /* line scope broken, syntax violated */ + MANDOCERR_SYNTARGVCOUNT, /* argument count wrong, violates syntax */ + MANDOCERR_SYNTCHILD, /* child violates parent syntax */ + MANDOCERR_SYNTARGCOUNT, /* argument count wrong, violates syntax */ + MANDOCERR_NODOCBODY, /* no document body */ + MANDOCERR_NODOCPROLOG, /* no document prologue */ + MANDOCERR_UTSNAME, /* utsname() system call failed */ MANDOCERR_MEM, /* memory exhausted */ #define MANDOCERR_FATAL MANDOCERR_MEM @@ -28,64 +28,10 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" #include "libmandoc.h" -const char *const __mdoc_merrnames[MERRMAX] = { - "trailing whitespace", /* ETAILWS */ - "unexpected quoted parameter", /* EQUOTPARM */ - "unterminated quoted parameter", /* EQUOTTERM */ - "argument parameter suggested", /* EARGVAL */ - "macro disallowed in prologue", /* EBODYPROL */ - "macro disallowed in body", /* EPROLBODY */ - "text disallowed in prologue", /* ETEXTPROL */ - "blank line disallowed", /* ENOBLANK */ - "text parameter too long", /* ETOOLONG */ - "invalid escape sequence", /* EESCAPE */ - "invalid character", /* EPRINT */ - "document has no body", /* ENODAT */ - "document has no prologue", /* ENOPROLOGUE */ - "expected line arguments", /* ELINE */ - "invalid AT&T argument", /* EATT */ - "default name not yet set", /* ENAME */ - "missing list type", /* ELISTTYPE */ - "missing display type", /* EDISPTYPE */ - "too many display types", /* EMULTIDISP */ - "too many list types", /* EMULTILIST */ - "NAME section must be first", /* ESECNAME */ - "badly-formed NAME section", /* ENAMESECINC */ - "argument repeated", /* EARGREP */ - "expected boolean parameter", /* EBOOL */ - "inconsistent column syntax", /* ECOLMIS */ - "nested display invalid", /* ENESTDISP */ - "width argument missing", /* EMISSWIDTH */ - "invalid section for this manual section", /* EWRONGMSEC */ - "section out of conventional order", /* ESECOOO */ - "section repeated", /* ESECREP */ - "invalid standard argument", /* EBADSTAND */ - "multi-line arguments discouraged", /* ENOMULTILINE */ - "multi-line arguments suggested", /* EMULTILINE */ - "line arguments discouraged", /* ENOLINE */ - "prologue macro out of conventional order", /* EPROLOOO */ - "prologue macro repeated", /* EPROLREP */ - "invalid manual section", /* EBADMSEC */ - "invalid font mode", /* EFONT */ - "invalid date syntax", /* EBADDATE */ - "invalid number format", /* ENUMFMT */ - "superfluous width argument", /* ENOWIDTH */ - "system: utsname error", /* EUTSNAME */ - "obsolete macro", /* EOBS */ - "end-of-line scope violation", /* EIMPBRK */ - "empty macro ignored", /* EIGNE */ - "unclosed explicit scope", /* EOPEN */ - "unterminated quoted phrase", /* EQUOTPHR */ - "closure macro without prior context", /* ENOCTX */ - "no description found for library", /* ELIB */ - "bad child for parent context", /* EBADCHILD */ - "list arguments preceding type", /* ENOTYPE */ - "deprecated comment style", /* EBADCOMMENT */ -}; - const char *const __mdoc_macronames[MDOC_MAX] = { "Ap", "Dd", "Dt", "Os", "Sh", "Ss", "Pp", "D1", @@ -245,15 +191,13 @@ mdoc_free(struct mdoc *mdoc) * Allocate volatile and non-volatile parse resources. */ struct mdoc * -mdoc_alloc(void *data, int pflags, const struct mdoc_cb *cb) +mdoc_alloc(void *data, int pflags, mandocmsg msg) { struct mdoc *p; p = mandoc_calloc(1, sizeof(struct mdoc)); - if (cb) - memcpy(&p->cb, cb, sizeof(struct mdoc_cb)); - + p->msg = msg; p->data = data; p->pflags = pflags; @@ -299,52 +243,17 @@ mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs) int -mdoc_verr(struct mdoc *mdoc, int ln, int pos, - const char *fmt, ...) -{ - char buf[256]; - va_list ap; - - if (NULL == mdoc->cb.mdoc_err) - return(0); - - va_start(ap, fmt); - (void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap); - va_end(ap); - - return((*mdoc->cb.mdoc_err)(mdoc->data, ln, pos, buf)); -} - - -int -mdoc_vwarn(struct mdoc *mdoc, int ln, int pos, const char *fmt, ...) +mdoc_vmsg(struct mdoc *mdoc, enum mandocerr t, + int ln, int pos, const char *fmt, ...) { char buf[256]; va_list ap; - if (NULL == mdoc->cb.mdoc_warn) - return(0); - va_start(ap, fmt); - (void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap); + vsnprintf(buf, sizeof(buf) - 1, fmt, ap); va_end(ap); - return((*mdoc->cb.mdoc_warn)(mdoc->data, ln, pos, buf)); -} - - -int -mdoc_err(struct mdoc *m, int line, int pos, int iserr, enum merr type) -{ - const char *p; - - p = __mdoc_merrnames[(int)type]; - assert(p); - - if (iserr) - return(mdoc_verr(m, line, pos, p)); - - return(mdoc_vwarn(m, line, pos, p)); + return((*mdoc->msg)(t, mdoc->data, ln, pos, buf)); } @@ -358,13 +267,13 @@ mdoc_macro(struct mdoc *m, enum mdoct tok, if (MDOC_PROLOGUE & mdoc_macros[tok].flags && MDOC_PBODY & m->flags) - return(mdoc_perr(m, ln, pp, EPROLBODY)); + return(mdoc_pmsg(m, ln, pp, MANDOCERR_BADBODY)); /* If we're in the prologue, deny "body" macros. */ if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) && ! (MDOC_PBODY & m->flags)) { - if ( ! mdoc_pwarn(m, ln, pp, EBODYPROL)) + if ( ! mdoc_pmsg(m, ln, pp, MANDOCERR_BADPROLOG)) return(0); if (NULL == m->meta.title) m->meta.title = mandoc_strdup("unknown"); @@ -640,12 +549,12 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) if ('\\' == buf[offs] && '.' == buf[offs + 1] && '"' == buf[offs + 2]) - return(mdoc_pwarn(m, line, offs, EBADCOMMENT)); + return(mdoc_pmsg(m, line, offs, MANDOCERR_BADCOMMENT)); /* No text before an initial macro. */ if (SEC_NONE == m->lastnamed) - return(mdoc_perr(m, line, offs, ETEXTPROL)); + return(mdoc_pmsg(m, line, offs, MANDOCERR_NOTEXT)); /* Literal just gets pulled in as-is. */ @@ -658,7 +567,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) /* Skip to first non-space. */ ; if ('\0' == buf[i]) { - if ( ! mdoc_pwarn(m, line, offs, ENOBLANK)) + if ( ! mdoc_pmsg(m, line, offs, MANDOCERR_NOBLANKLN)) return(0); /* @@ -683,7 +592,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) if (' ' == buf[i - 1] || '\t' == buf[i - 1]) { if (i > 1 && '\\' != buf[i - 2]) - if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS)) + if ( ! mdoc_pmsg(m, line, i - 1, MANDOCERR_EOLNSPACE)) return(0); for (--i; i && ' ' == buf[i]; i--) @@ -717,11 +626,14 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs) static int macrowarn(struct mdoc *m, int ln, const char *buf, int offs) { - if ( ! (MDOC_IGN_MACRO & m->pflags)) - return(mdoc_verr(m, ln, offs, "unknown macro: %s%s", - buf, strlen(buf) > 3 ? "..." : "")); - return(mdoc_vwarn(m, ln, offs, "unknown macro: %s%s", - buf, strlen(buf) > 3 ? "..." : "")); + int rc; + + rc = mdoc_vmsg(m, MANDOCERR_MACRO, ln, offs, + "unknown macro: %s%s", + buf, strlen(buf) > 3 ? "..." : ""); + + /* FIXME: logic should be in driver. */ + return(MDOC_IGN_MACRO & m->pflags ? rc : 0); } @@ -769,7 +681,9 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs) if (isgraph((u_char)buf[i])) continue; - return(mdoc_perr(m, ln, i, EPRINT)); + if ( ! mdoc_pmsg(m, ln, i, MANDOCERR_BADCHAR)) + return(0); + i--; } mac[j] = '\0'; @@ -797,7 +711,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs) */ if ('\0' == buf[i] && ' ' == buf[i - 1]) - if ( ! mdoc_pwarn(m, ln, i - 1, ETAILWS)) + if ( ! mdoc_pmsg(m, ln, i - 1, MANDOCERR_EOLNSPACE)) goto err; /* @@ -278,13 +278,6 @@ struct mdoc_node { #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 { - int (*mdoc_err)(void *, int, int, const char *); - int (*mdoc_warn)(void *, int, int, const char *); -}; - /* See mdoc.3 for documentation. */ extern const char *const *mdoc_macronames; @@ -297,7 +290,7 @@ struct mdoc; /* See mdoc.3 for documentation. */ void mdoc_free(struct mdoc *); -struct mdoc *mdoc_alloc(void *, int, const struct mdoc_cb *); +struct mdoc *mdoc_alloc(void *, int, mandocmsg); void mdoc_reset(struct mdoc *); int mdoc_parseln(struct mdoc *, int, char *, int); const struct mdoc_node *mdoc_node(const struct mdoc *); diff --git a/mdoc_action.c b/mdoc_action.c index cb949df6..12b62d1b 100644 --- a/mdoc_action.c +++ b/mdoc_action.c @@ -28,6 +28,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" #include "libmandoc.h" @@ -269,12 +270,21 @@ concat(struct mdoc *m, char *p, const struct mdoc_node *n, size_t sz) p[0] = '\0'; for ( ; n; n = n->next) { assert(MDOC_TEXT == n->type); - if (strlcat(p, n->string, sz) >= sz) - return(mdoc_nerr(m, n, ETOOLONG)); + /* + * XXX: yes, these can technically be resized, but it's + * highly unlikely that we're going to get here, so let + * it slip for now. + */ + if (strlcat(p, n->string, sz) >= sz) { + mdoc_nmsg(m, n, MANDOCERR_MEM); + return(0); + } if (NULL == n->next) continue; - if (strlcat(p, " ", sz) >= sz) - return(mdoc_nerr(m, n, ETOOLONG)); + if (strlcat(p, " ", sz) >= sz) { + mdoc_nmsg(m, n, MANDOCERR_MEM); + return(0); + } } return(1); @@ -288,14 +298,16 @@ concat(struct mdoc *m, char *p, const struct mdoc_node *n, size_t sz) static int post_std(POST_ARGS) { - struct mdoc_node *nn; + struct mdoc_node *nn; if (n->child) return(1); + if (NULL == m->meta.name) + return(1); nn = n; m->next = MDOC_NEXT_CHILD; - assert(m->meta.name); + if ( ! mdoc_word_alloc(m, n->line, n->pos, m->meta.name)) return(0); m->last = nn; @@ -453,7 +465,7 @@ post_sh(POST_ARGS) break; if (*m->meta.msec == '9') break; - return(mdoc_nwarn(m, n, EWRONGMSEC)); + return(mdoc_nmsg(m, n, MANDOCERR_SECMSEC)); default: break; } @@ -517,7 +529,7 @@ post_dt(POST_ARGS) if (cp) { m->meta.vol = mandoc_strdup(cp); m->meta.msec = mandoc_strdup(nn->string); - } else if (mdoc_nwarn(m, n, EBADMSEC)) { + } else if (mdoc_nmsg(m, n, MANDOCERR_BADMSEC)) { m->meta.vol = mandoc_strdup(nn->string); m->meta.msec = mandoc_strdup(nn->string); } else @@ -574,19 +586,32 @@ post_os(POST_ARGS) if ( ! concat(m, buf, n->child, BUFSIZ)) return(0); + /* XXX: yes, these can all be dynamically-adjusted buffers, but + * it's really not worth the extra hackery. + */ + if ('\0' == buf[0]) { #ifdef OSNAME - if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) - return(mdoc_nerr(m, n, EUTSNAME)); + if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) { + mdoc_nmsg(m, n, MANDOCERR_MEM); + return(0); + } #else /*!OSNAME */ if (-1 == uname(&utsname)) - return(mdoc_nerr(m, n, EUTSNAME)); - if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ) - return(mdoc_nerr(m, n, ETOOLONG)); - if (strlcat(buf, " ", 64) >= BUFSIZ) - return(mdoc_nerr(m, n, ETOOLONG)); - if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ) - return(mdoc_nerr(m, n, ETOOLONG)); + return(mdoc_nmsg(m, n, MANDOCERR_UTSNAME)); + + if (strlcat(buf, utsname.sysname, BUFSIZ) >= BUFSIZ) { + mdoc_nmsg(m, n, MANDOCERR_MEM); + return(0); + } + if (strlcat(buf, " ", 64) >= BUFSIZ) { + mdoc_nmsg(m, n, MANDOCERR_MEM); + return(0); + } + if (strlcat(buf, utsname.release, BUFSIZ) >= BUFSIZ) { + mdoc_nmsg(m, n, MANDOCERR_MEM); + return(0); + } #endif /*!OSNAME*/ } @@ -621,7 +646,7 @@ post_bl_tagwidth(POST_ARGS) if (MDOC_TEXT != nn->type) { sz = mdoc_macro2len(nn->tok); if (sz == 0) { - if ( ! mdoc_nwarn(m, n, ENOWIDTH)) + if ( ! mdoc_nmsg(m, n, MANDOCERR_NOWIDTHARG)) return(0); sz = 10; } @@ -684,12 +709,11 @@ post_bl_width(POST_ARGS) */ if (0 == strcmp(p, "Ds")) - /* XXX: make into a macro. */ width = 6; else if (MDOC_MAX == (tok = mdoc_hash_find(p))) return(1); else if (0 == (width = mdoc_macro2len(tok))) - return(mdoc_nwarn(m, n, ENOWIDTH)); + return(mdoc_nmsg(m, n, MANDOCERR_BADWIDTH)); /* The value already exists: free and reallocate it. */ @@ -848,7 +872,7 @@ post_dd(POST_ARGS) (MTIME_MDOCDATE | MTIME_CANONICAL, buf); if (0 == m->meta.date) { - if ( ! mdoc_nwarn(m, n, EBADDATE)) + if ( ! mdoc_nmsg(m, n, MANDOCERR_BADDATE)) return(0); m->meta.date = time(NULL); } diff --git a/mdoc_argv.c b/mdoc_argv.c index 33d03062..f67a08bd 100644 --- a/mdoc_argv.c +++ b/mdoc_argv.c @@ -26,6 +26,7 @@ #include <stdio.h> #include <string.h> +#include "mandoc.h" #include "libmdoc.h" #include "libmandoc.h" @@ -407,7 +408,7 @@ args(struct mdoc *m, int line, int *pos, * is unterminated. */ if (MDOC_PHRASELIT & m->flags) - if ( ! mdoc_pwarn(m, line, *pos, EQUOTTERM)) + if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE)) return(ARGS_ERROR); m->flags &= ~MDOC_PHRASELIT; @@ -440,7 +441,7 @@ args(struct mdoc *m, int line, int *pos, return(ARGS_PUNCT); if (ARGS_NOWARN & fl) return(ARGS_PUNCT); - if ( ! mdoc_pwarn(m, line, *pos, ETAILWS)) + if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE)) return(ARGS_ERROR); return(ARGS_PUNCT); } @@ -495,7 +496,7 @@ args(struct mdoc *m, int line, int *pos, /* Whitespace check for eoln case... */ if (0 == *p && ' ' == *(p - 1) && ! (ARGS_NOWARN & fl)) - if ( ! mdoc_pwarn(m, line, *pos, ETAILWS)) + if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE)) return(ARGS_ERROR); *pos += (int)(p - *v); @@ -540,7 +541,7 @@ args(struct mdoc *m, int line, int *pos, if ('\0' == buf[*pos]) { if (ARGS_NOWARN & fl || MDOC_PPHRASE & m->flags) return(ARGS_QWORD); - if ( ! mdoc_pwarn(m, line, *pos, EQUOTTERM)) + if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE)) return(ARGS_ERROR); return(ARGS_QWORD); } @@ -555,7 +556,7 @@ args(struct mdoc *m, int line, int *pos, (*pos)++; if (0 == buf[*pos] && ! (ARGS_NOWARN & fl)) - if ( ! mdoc_pwarn(m, line, *pos, ETAILWS)) + if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE)) return(ARGS_ERROR); return(ARGS_QWORD); @@ -579,7 +580,7 @@ args(struct mdoc *m, int line, int *pos, (*pos)++; if ('\0' == buf[*pos] && ! (ARGS_NOWARN & fl)) - if ( ! mdoc_pwarn(m, line, *pos, ETAILWS)) + if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE)) return(ARGS_ERROR); return(ARGS_WORD); @@ -751,10 +752,11 @@ argv_single(struct mdoc *m, int line, ppos = *pos; ac = args(m, line, pos, buf, 0, &p); - if (ARGS_ERROR == ac) + if (ARGS_EOLN == ac) { + mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTARGVCOUNT); + return(0); + } else if (ARGS_ERROR == ac) return(0); - if (ARGS_EOLN == ac) - return(mdoc_perr(m, line, ppos, EARGVAL)); v->sz = 1; v->value = mandoc_malloc(sizeof(char *)); diff --git a/mdoc_hash.c b/mdoc_hash.c index 216f721c..93d73f48 100644 --- a/mdoc_hash.c +++ b/mdoc_hash.c @@ -27,6 +27,7 @@ #include <stdio.h> #include <string.h> +#include "mandoc.h" #include "libmdoc.h" static u_char table[27 * 12]; diff --git a/mdoc_html.c b/mdoc_html.c index 9da1779e..3ccb2cf7 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -27,6 +27,7 @@ #include <string.h> #include <unistd.h> +#include "mandoc.h" #include "out.h" #include "html.h" #include "mdoc.h" @@ -729,6 +730,9 @@ mdoc_nm_pre(MDOC_ARGS) { struct htmlpair tag; + if (NULL == n->child && NULL == m->name) + return(1); + if (SEC_SYNOPSIS == n->sec && n->prev && MDOC_LINE & n->flags) { bufcat_style(h, "clear", "both"); @@ -1181,7 +1185,7 @@ mdoc_ex_pre(MDOC_ARGS) h->flags &= ~HTML_NOSPACE; } - if (n->child->next) + if (n->child && n->child->next) print_text(h, "utilities exit"); else print_text(h, "utility exits"); @@ -1951,7 +1955,7 @@ mdoc_rv_pre(MDOC_ARGS) print_text(h, "()"); } - if (n->child->next) + if (n->child && n->child->next) print_text(h, "functions return"); else print_text(h, "function returns"); diff --git a/mdoc_macro.c b/mdoc_macro.c index 87f87f18..9919f545 100644 --- a/mdoc_macro.c +++ b/mdoc_macro.c @@ -25,6 +25,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" #include "libmandoc.h" @@ -195,6 +196,7 @@ swarn(struct mdoc *mdoc, enum mdoc_type type, int line, int pos, const struct mdoc_node *p) { const char *n, *t, *tt; + int rc; n = t = "<root>"; tt = "block"; @@ -227,13 +229,11 @@ swarn(struct mdoc *mdoc, enum mdoc_type type, break; } - if ( ! (MDOC_IGN_SCOPE & mdoc->pflags)) - return(mdoc_verr(mdoc, line, pos, - "%s scope breaks %s scope of %s", - tt, t, n)); - return(mdoc_vwarn(mdoc, line, pos, - "%s scope breaks %s scope of %s", - tt, t, n)); + rc = mdoc_vmsg(mdoc, MANDOCERR_SCOPE, line, pos, + "%s scope breaks %s of %s", tt, t, n); + + /* FIXME: logic should be in driver. */ + return(MDOC_IGN_SCOPE & mdoc->pflags ? rc : 0); } @@ -256,7 +256,8 @@ mdoc_macroend(struct mdoc *m) continue; if ( ! (MDOC_EXPLICIT & mdoc_macros[n->tok].flags)) continue; - return(mdoc_nerr(m, n, EOPEN)); + mdoc_nmsg(m, n, MANDOCERR_SYNTSCOPE); + return(0); } /* Rewind to the first. */ @@ -588,7 +589,9 @@ rew_sub(enum mdoc_type t, struct mdoc *m, return(1); if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) return(1); - return(mdoc_perr(m, line, ppos, ENOCTX)); + /* FIXME: shouldn't raise an error */ + mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTNOSCOPE); + return(0); } if (REWIND_REWIND == c) break; @@ -686,8 +689,9 @@ blk_exp_close(MACRO_PROT_ARGS) } if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { + /* FIXME: do this in validate */ if (buf[*pos]) - if ( ! mdoc_pwarn(m, line, ppos, ENOLINE)) + if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_ARGSLOST)) return(0); if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) @@ -831,7 +835,7 @@ in_line(MACRO_PROT_ARGS) return(0); } else if ( ! nc && 0 == cnt) { mdoc_argv_free(arg); - if ( ! mdoc_pwarn(m, line, ppos, EIGNE)) + if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY)) return(0); } if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) @@ -892,7 +896,7 @@ in_line(MACRO_PROT_ARGS) return(0); } else if ( ! nc && 0 == cnt) { mdoc_argv_free(arg); - if ( ! mdoc_pwarn(m, line, ppos, EIGNE)) + if ( ! mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY)) return(0); } @@ -1198,7 +1202,7 @@ blk_part_imp(MACRO_PROT_ARGS) if (body == n) break; - if (NULL == n && ! mdoc_nwarn(m, body, EIMPBRK)) + if (NULL == n && ! mdoc_nmsg(m, body, MANDOCERR_SCOPE)) return(0); if (n && ! rew_last(m, body)) @@ -1564,7 +1568,7 @@ static int obsolete(MACRO_PROT_ARGS) { - return(mdoc_pwarn(m, line, ppos, EOBS)); + return(mdoc_pmsg(m, line, ppos, MANDOCERR_MACROOBS)); } diff --git a/mdoc_strings.c b/mdoc_strings.c index 675d0769..5e647fe3 100644 --- a/mdoc_strings.c +++ b/mdoc_strings.c @@ -26,6 +26,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" static const char * const secnames[SEC__MAX] = { diff --git a/mdoc_term.c b/mdoc_term.c index fe43bd58..31d435b1 100644 --- a/mdoc_term.c +++ b/mdoc_term.c @@ -27,6 +27,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "out.h" #include "term.h" #include "mdoc.h" @@ -1085,6 +1086,8 @@ static int termp_nm_pre(DECL_ARGS) { + if (NULL == n->child && NULL == m->name) + if (SEC_SYNOPSIS == n->sec && MDOC_LINE & n->flags) term_newln(p); @@ -1092,6 +1095,7 @@ termp_nm_pre(DECL_ARGS) if (NULL == n->child) term_word(p, m->name); + return(1); } @@ -1216,7 +1220,7 @@ termp_rv_pre(DECL_ARGS) term_word(p, "()"); } - if (n->child->next) + if (n->child && n->child->next) term_word(p, "functions return"); else term_word(p, "function returns"); @@ -1255,7 +1259,7 @@ termp_ex_pre(DECL_ARGS) p->flags &= ~TERMP_NOSPACE; } - if (n->child->next) + if (n->child && n->child->next) term_word(p, "utilities exit"); else term_word(p, "utility exits"); diff --git a/mdoc_validate.c b/mdoc_validate.c index 0b3bf0f4..48dc1c88 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -26,6 +26,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "libmdoc.h" #include "libmandoc.h" @@ -321,8 +322,9 @@ warn_count(struct mdoc *m, const char *k, int want, const char *v, int has) { - return(mdoc_vwarn(m, m->last->line, m->last->pos, - "suggests %s %s %d (has %d)", v, k, want, has)); + return(mdoc_vmsg(m, MANDOCERR_ARGCOUNT, + m->last->line, m->last->pos, + "%s %s %d (have %d)", v, k, want, has)); } @@ -331,8 +333,11 @@ err_count(struct mdoc *m, const char *k, int want, const char *v, int has) { - return(mdoc_verr(m, m->last->line, m->last->pos, - "requires %s %s %d (has %d)", v, k, want, has)); + mdoc_vmsg(m, MANDOCERR_SYNTARGCOUNT, + m->last->line, m->last->pos, + "%s %s %d (have %d)", + v, k, want, has); + return(0); } @@ -405,7 +410,7 @@ check_stdarg(PRE_ARGS) if (n->args && 1 == n->args->argc) if (MDOC_Std == n->args->argv[0].arg) return(1); - return(mdoc_nwarn(mdoc, n, EARGVAL)); + return(mdoc_nmsg(mdoc, n, MANDOCERR_NOARGV)); } @@ -437,10 +442,10 @@ check_argv(struct mdoc *m, const struct mdoc_node *n, return(0); if (MDOC_Std == v->arg) { - /* `Nm' name must be set. */ if (v->sz || m->meta.name) return(1); - return(mdoc_nerr(m, n, ENAME)); + if ( ! mdoc_nmsg(m, n, MANDOCERR_NONAME)) + return(0); } return(1); @@ -455,10 +460,10 @@ check_text(struct mdoc *mdoc, int line, int pos, const char *p) for ( ; *p; p++, pos++) { if ('\t' == *p) { if ( ! (MDOC_LITERAL & mdoc->flags)) - if ( ! mdoc_pwarn(mdoc, line, pos, EPRINT)) + if ( ! mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADCHAR)) return(0); } else if ( ! isprint((u_char)*p)) - if ( ! mdoc_pwarn(mdoc, line, pos, EPRINT)) + if ( ! mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADCHAR)) return(0); if ('\\' != *p) @@ -470,10 +475,10 @@ check_text(struct mdoc *mdoc, int line, int pos, const char *p) pos += c - 1; continue; } - if ( ! (MDOC_IGN_ESCAPE & mdoc->pflags)) - return(mdoc_perr(mdoc, line, pos, EESCAPE)); - if ( ! mdoc_pwarn(mdoc, line, pos, EESCAPE)) - return(0); + + c = mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADESCAPE); + if ( ! (MDOC_IGN_ESCAPE & mdoc->pflags) && ! c) + return(c); } return(1); @@ -491,8 +496,11 @@ check_parent(PRE_ARGS, enum mdoct tok, enum mdoc_type t) (t == n->parent->type)) return(1); - return(mdoc_verr(mdoc, n->line, n->pos, "require parent %s", - MDOC_ROOT == t ? "<root>" : mdoc_macronames[tok])); + mdoc_vmsg(mdoc, MANDOCERR_SYNTCHILD, + n->line, n->pos, "want parent %s", + MDOC_ROOT == t ? "<root>" : + mdoc_macronames[tok]); + return(0); } @@ -515,7 +523,8 @@ pre_display(PRE_ARGS) if (NULL == node) return(1); - return(mdoc_nerr(mdoc, n, ENESTDISP)); + mdoc_nmsg(mdoc, n, MANDOCERR_NESTEDDISP); + return(0); } @@ -526,8 +535,10 @@ pre_bl(PRE_ARGS) if (MDOC_BLOCK != n->type) return(1); - if (NULL == n->args) - return(mdoc_nerr(mdoc, n, ELISTTYPE)); + if (NULL == n->args) { + mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE); + return(0); + } /* Make sure that only one type of list is specified. */ @@ -567,7 +578,7 @@ pre_bl(PRE_ARGS) * FIXME: this should occur in mdoc_action.c. */ if (type >= 0) { - if ( ! mdoc_nwarn(mdoc, n, EMULTILIST)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTREP)) return(0); mdoc_argn_free(n->args, pos); break; @@ -575,20 +586,22 @@ pre_bl(PRE_ARGS) type = n->args->argv[pos].arg; break; case (MDOC_Compact): - if (type < 0 && ! mdoc_nwarn(mdoc, n, ENOTYPE)) + if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST)) return(0); break; case (MDOC_Width): if (width >= 0) - return(mdoc_nerr(mdoc, n, EARGREP)); - if (type < 0 && ! mdoc_nwarn(mdoc, n, ENOTYPE)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP)) + return(0); + if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST)) return(0); width = n->args->argv[pos].arg; break; case (MDOC_Offset): if (offset >= 0) - return(mdoc_nerr(mdoc, n, EARGREP)); - if (type < 0 && ! mdoc_nwarn(mdoc, n, ENOTYPE)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP)) + return(0); + if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST)) return(0); offset = n->args->argv[pos].arg; break; @@ -596,8 +609,10 @@ pre_bl(PRE_ARGS) break; } - if (type < 0) - return(mdoc_nerr(mdoc, n, ELISTTYPE)); + if (type < 0) { + mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE); + return(0); + } /* * Validate the width field. Some list types don't need width @@ -607,7 +622,7 @@ pre_bl(PRE_ARGS) switch (type) { case (MDOC_Tag): - if (width < 0 && ! mdoc_nwarn(mdoc, n, EMISSWIDTH)) + if (width < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG)) return(0); break; case (MDOC_Column): @@ -619,7 +634,7 @@ pre_bl(PRE_ARGS) case (MDOC_Inset): /* FALLTHROUGH */ case (MDOC_Item): - if (width >= 0 && ! mdoc_nwarn(mdoc, n, ENOWIDTH)) + if (width >= 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_WIDTHARG)) return(0); break; default: @@ -637,8 +652,10 @@ pre_bd(PRE_ARGS) if (MDOC_BLOCK != n->type) return(1); - if (NULL == n->args) - return(mdoc_nerr(mdoc, n, EDISPTYPE)); + if (NULL == n->args) { + mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE); + return(0); + } /* Make sure that only one type of display is specified. */ @@ -657,14 +674,17 @@ pre_bd(PRE_ARGS) case (MDOC_Literal): if (0 == type++) break; - return(mdoc_nerr(mdoc, n, EMULTIDISP)); + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPREP)) + return(0); + break; default: break; } if (type) return(1); - return(mdoc_nerr(mdoc, n, EDISPTYPE)); + mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE); + return(0); } @@ -694,6 +714,10 @@ pre_it(PRE_ARGS) if (MDOC_BLOCK != n->type) return(1); + /* + * FIXME: this can probably be lifted if we make the It into + * something else on-the-fly? + */ return(check_parent(mdoc, n, MDOC_Bl, MDOC_BODY)); } @@ -704,8 +728,11 @@ pre_an(PRE_ARGS) if (NULL == n->args || 1 == n->args->argc) return(1); - return(mdoc_verr(mdoc, n->line, n->pos, - "only one argument allowed")); + mdoc_vmsg(mdoc, MANDOCERR_SYNTARGCOUNT, + n->line, n->pos, + "line arguments == 1 (have %d)", + n->args->argc); + return(0); } @@ -724,10 +751,10 @@ pre_dt(PRE_ARGS) /* FIXME: make sure is capitalised. */ if (0 == mdoc->meta.date || mdoc->meta.os) - if ( ! mdoc_nwarn(mdoc, n, EPROLOOO)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO)) return(0); if (mdoc->meta.title) - if ( ! mdoc_nwarn(mdoc, n, EPROLREP)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP)) return(0); return(1); } @@ -738,10 +765,10 @@ pre_os(PRE_ARGS) { if (NULL == mdoc->meta.title || 0 == mdoc->meta.date) - if ( ! mdoc_nwarn(mdoc, n, EPROLOOO)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO)) return(0); if (mdoc->meta.os) - if ( ! mdoc_nwarn(mdoc, n, EPROLREP)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP)) return(0); return(1); } @@ -752,10 +779,10 @@ pre_dd(PRE_ARGS) { if (mdoc->meta.title || mdoc->meta.os) - if ( ! mdoc_nwarn(mdoc, n, EPROLOOO)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGOOO)) return(0); if (mdoc->meta.date) - if ( ! mdoc_nwarn(mdoc, n, EPROLREP)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_PROLOGREP)) return(0); return(1); } @@ -772,13 +799,18 @@ post_bf(POST_ARGS) head = mdoc->last->head; - if (mdoc->last->args && head->child) - return(mdoc_nerr(mdoc, mdoc->last, ELINE)); - else if (mdoc->last->args) + if (mdoc->last->args && head->child) { + /* FIXME: this should provide a default. */ + mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SYNTARGVCOUNT); + return(0); + } else if (mdoc->last->args) return(1); - if (NULL == head->child || MDOC_TEXT != head->child->type) - return(mdoc_nerr(mdoc, mdoc->last, ELINE)); + if (NULL == head->child || MDOC_TEXT != head->child->type) { + /* FIXME: this should provide a default. */ + mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SYNTARGVCOUNT); + return(0); + } p = head->child->string; @@ -789,7 +821,8 @@ post_bf(POST_ARGS) else if (0 == strcmp(p, "Sy")) return(1); - return(mdoc_nerr(mdoc, head, EFONT)); + mdoc_nmsg(mdoc, head, MANDOCERR_FONTTYPE); + return(0); } @@ -799,7 +832,7 @@ post_lb(POST_ARGS) if (mdoc_a2lib(mdoc->last->child->string)) return(1); - return(mdoc_nwarn(mdoc, mdoc->last, ELIB)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADLIB)); } @@ -822,7 +855,7 @@ post_vt(POST_ARGS) for (n = mdoc->last->child; n; n = n->next) if (MDOC_TEXT != n->type) - if ( ! mdoc_nwarn(mdoc, n, EBADCHILD)) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_CHILD)) return(0); return(1); @@ -837,7 +870,7 @@ post_nm(POST_ARGS) return(1); if (mdoc->meta.name) return(1); - return(mdoc_nerr(mdoc, mdoc->last, ENAME)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME)); } @@ -847,11 +880,10 @@ post_at(POST_ARGS) if (NULL == mdoc->last->child) return(1); - if (MDOC_TEXT != mdoc->last->child->type) - return(mdoc_nerr(mdoc, mdoc->last, EATT)); + assert(MDOC_TEXT == mdoc->last->child->type); if (mdoc_a2att(mdoc->last->child->string)) return(1); - return(mdoc_nwarn(mdoc, mdoc->last, EATT)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADATT)); } @@ -862,12 +894,12 @@ post_an(POST_ARGS) if (mdoc->last->args) { if (NULL == mdoc->last->child) return(1); - return(mdoc_nerr(mdoc, mdoc->last, ENOLINE)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGCOUNT)); } if (mdoc->last->child) return(1); - return(mdoc_nerr(mdoc, mdoc->last, ELINE)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS)); } @@ -881,8 +913,10 @@ post_it(POST_ARGS) return(1); n = mdoc->last->parent->parent; - if (NULL == n->args) - return(mdoc_nerr(mdoc, mdoc->last, ELISTTYPE)); + if (NULL == n->args) { + mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_LISTTYPE); + return(0); + } /* Some types require block-head, some not. */ @@ -919,13 +953,15 @@ post_it(POST_ARGS) break; } - if (-1 == type) - return(mdoc_nerr(mdoc, mdoc->last, ELISTTYPE)); + if (-1 == type) { + mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_LISTTYPE); + return(0); + } switch (type) { case (MDOC_Tag): if (NULL == mdoc->last->head->child) - if ( ! mdoc_nwarn(mdoc, mdoc->last, ELINE)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS)) return(0); break; case (MDOC_Hang): @@ -936,10 +972,10 @@ post_it(POST_ARGS) /* FALLTHROUGH */ case (MDOC_Diag): if (NULL == mdoc->last->head->child) - if ( ! mdoc_nwarn(mdoc, mdoc->last, ELINE)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS)) return(0); if (NULL == mdoc->last->body->child) - if ( ! mdoc_nwarn(mdoc, mdoc->last, EMULTILINE)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY)) return(0); break; case (MDOC_Bullet): @@ -952,36 +988,38 @@ post_it(POST_ARGS) /* FALLTHROUGH */ case (MDOC_Item): if (mdoc->last->head->child) - if ( ! mdoc_nwarn(mdoc, mdoc->last, ENOLINE)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGSLOST)) return(0); if (NULL == mdoc->last->body->child) - if ( ! mdoc_nwarn(mdoc, mdoc->last, EMULTILINE)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY)) return(0); break; case (MDOC_Column): if (NULL == mdoc->last->head->child) - if ( ! mdoc_nwarn(mdoc, mdoc->last, ELINE)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS)) return(0); if (mdoc->last->body->child) - if ( ! mdoc_nwarn(mdoc, mdoc->last, ENOMULTILINE)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BODYLOST)) return(0); c = mdoc->last->child; for (i = 0; c && MDOC_HEAD == c->type; c = c->next) i++; if (i < cols) { - if ( ! mdoc_vwarn(mdoc, mdoc->last->line, - mdoc->last->pos, "column " - "mismatch: have %d, want %d", - i, cols)) + if ( ! mdoc_vmsg(mdoc, MANDOCERR_ARGCOUNT, + mdoc->last->line, + mdoc->last->pos, + "columns == %d (have %d)", + cols, i)) return(0); break; } else if (i == cols || i == cols + 1) break; - return(mdoc_verr(mdoc, mdoc->last->line, - mdoc->last->pos, "column mismatch: " - "have %d, want %d", i, cols)); + mdoc_vmsg(mdoc, MANDOCERR_SYNTARGCOUNT, + mdoc->last->line, mdoc->last->pos, + "columns == %d (have %d)", cols, i); + return(0); default: break; } @@ -1004,7 +1042,7 @@ post_bl_head(POST_ARGS) a = &n->args->argv[i]; if (a->arg == MDOC_Column) { if (a->sz && mdoc->last->nchild) - return(mdoc_nerr(mdoc, n, ECOLMIS)); + return(mdoc_nmsg(mdoc, n, MANDOCERR_COLUMNS)); return(1); } } @@ -1039,7 +1077,8 @@ post_bl(POST_ARGS) continue; if (MDOC_Sm == n->tok) continue; - return(mdoc_nerr(mdoc, n, EBADCHILD)); + mdoc_nmsg(mdoc, n, MANDOCERR_SYNTCHILD); + return(0); } return(1); @@ -1064,7 +1103,7 @@ ebool(struct mdoc *mdoc) if (NULL == n) return(1); - return(mdoc_nerr(mdoc, n, EBOOL)); + return(mdoc_nmsg(mdoc, n, MANDOCERR_BADBOOL)); } @@ -1073,16 +1112,17 @@ post_root(POST_ARGS) { if (NULL == mdoc->first->child) - return(mdoc_nerr(mdoc, mdoc->first, ENODAT)); - if ( ! (MDOC_PBODY & mdoc->flags)) - return(mdoc_nerr(mdoc, mdoc->first, ENOPROLOGUE)); - - if (MDOC_BLOCK != mdoc->first->child->type) - return(mdoc_nerr(mdoc, mdoc->first, ENODAT)); - if (MDOC_Sh != mdoc->first->child->tok) - return(mdoc_nerr(mdoc, mdoc->first, ENODAT)); + mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCBODY); + else if ( ! (MDOC_PBODY & mdoc->flags)) + mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCPROLOG); + else if (MDOC_BLOCK != mdoc->first->child->type) + mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCBODY); + else if (MDOC_Sh != mdoc->first->child->tok) + mdoc_nmsg(mdoc, mdoc->first, MANDOCERR_NODOCBODY); + else + return(1); - return(1); + return(0); } @@ -1092,7 +1132,7 @@ post_st(POST_ARGS) if (mdoc_a2st(mdoc->last->child->string)) return(1); - return(mdoc_nwarn(mdoc, mdoc->last, EBADSTAND)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADSTANDARD)); } @@ -1135,7 +1175,8 @@ post_rs(POST_ARGS) case(MDOC__V): break; default: - return(mdoc_nerr(mdoc, nn, EBADCHILD)); + mdoc_nmsg(mdoc, nn, MANDOCERR_SYNTCHILD); + return(0); } return(1); @@ -1170,21 +1211,21 @@ post_sh_body(POST_ARGS) */ if (NULL == (n = mdoc->last->child)) - return(mdoc_nwarn(mdoc, mdoc->last, ENAMESECINC)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC)); for ( ; n && n->next; n = n->next) { if (MDOC_ELEM == n->type && MDOC_Nm == n->tok) continue; if (MDOC_TEXT == n->type) continue; - if ( ! mdoc_nwarn(mdoc, mdoc->last, ENAMESECINC)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC)) return(0); } assert(n); if (MDOC_BLOCK == n->type && MDOC_Nd == n->tok) return(1); - return(mdoc_nwarn(mdoc, mdoc->last, ENAMESECINC)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADNAMESEC)); } @@ -1202,18 +1243,27 @@ post_sh_head(POST_ARGS) * certain manual sections. */ - buf[0] = 0; + buf[0] = '\0'; + + /* + * FIXME: yes, these can use a dynamic buffer, but I don't do so + * in the interests of simplicity. + */ for (n = mdoc->last->child; n; n = n->next) { /* XXX - copied from compact(). */ assert(MDOC_TEXT == n->type); - if (strlcat(buf, n->string, 64) >= 64) - return(mdoc_nerr(mdoc, n, ETOOLONG)); + if (strlcat(buf, n->string, 64) >= 64) { + mdoc_nmsg(mdoc, n, MANDOCERR_MEM); + return(0); + } if (NULL == n->next) continue; - if (strlcat(buf, " ", 64) >= 64) - return(mdoc_nerr(mdoc, n, ETOOLONG)); + if (strlcat(buf, " ", 64) >= 64) { + mdoc_nmsg(mdoc, n, MANDOCERR_MEM); + return(0); + } } sec = mdoc_str2sec(buf); @@ -1224,18 +1274,18 @@ post_sh_head(POST_ARGS) */ if (SEC_NAME != sec && SEC_NONE == mdoc->lastnamed) - if ( ! mdoc_nwarn(mdoc, mdoc->last, ESECNAME)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NAMESECFIRST)) return(0); if (SEC_CUSTOM == sec) return(1); if (sec == mdoc->lastnamed) - if ( ! mdoc_nwarn(mdoc, mdoc->last, ESECREP)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECREP)) return(0); if (sec < mdoc->lastnamed) - if ( ! mdoc_nwarn(mdoc, mdoc->last, ESECOOO)) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECOOO)) return(0); /* @@ -1252,7 +1302,7 @@ post_sh_head(POST_ARGS) break; if (*mdoc->meta.msec == '9') break; - return(mdoc_nwarn(mdoc, mdoc->last, EWRONGMSEC)); + return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECMSEC)); default: break; } @@ -21,6 +21,7 @@ #include <stdlib.h> #include <string.h> +#include "mandoc.h" #include "libmdoc.h" #define LINE(x, y) \ @@ -22,6 +22,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" #define LINE(x, y) \ @@ -27,6 +27,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "chars.h" #include "out.h" #include "term.h" @@ -23,6 +23,7 @@ #include <stdlib.h> #include <time.h> +#include "mandoc.h" #include "mdoc.h" #include "man.h" #include "main.h" @@ -22,6 +22,7 @@ #include <string.h> #include <time.h> +#include "mandoc.h" #include "libmdoc.h" #define LINE(x, y) \ |