diff options
-rw-r--r-- | argv.c | 52 | ||||
-rw-r--r-- | macro.c | 328 | ||||
-rw-r--r-- | mdoc.c | 115 | ||||
-rw-r--r-- | mdoc.h | 2 | ||||
-rw-r--r-- | mdocml.c | 101 | ||||
-rw-r--r-- | private.h | 36 | ||||
-rw-r--r-- | validate.c | 58 |
7 files changed, 368 insertions, 324 deletions
@@ -27,14 +27,14 @@ static int lookup(int, const char *); -static int parse(struct mdoc *, int, +static int parse(struct mdoc *, int, int, struct mdoc_arg *, int *, char *); static int postparse(struct mdoc *, int, const struct mdoc_arg *, int); int -mdoc_args(struct mdoc *mdoc, int tok, int *pos, char *buf, int fl, char **v) +mdoc_args(struct mdoc *mdoc, int line, int *pos, char *buf, int fl, char **v) { int i; @@ -42,11 +42,11 @@ mdoc_args(struct mdoc *mdoc, int tok, int *pos, char *buf, int fl, char **v) return(ARGS_EOLN); if ('\"' == buf[*pos] && ! (fl & ARGS_QUOTED)) - if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_QUOTED)) + if ( ! mdoc_pwarn(mdoc, line, *pos, WARN_SYNTAX_QUOTED)) return(ARGS_ERROR); if ('-' == buf[*pos]) - if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_ARGLIKE)) + if ( ! mdoc_pwarn(mdoc, line, *pos, WARN_SYNTAX_ARGLIKE)) return(ARGS_ERROR); if ((fl & ARGS_DELIM) && mdoc_iscdelim(buf[*pos])) { @@ -89,7 +89,7 @@ mdoc_args(struct mdoc *mdoc, int tok, int *pos, char *buf, int fl, char **v) if (buf[*pos]) return(ARGS_WORD); - if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN)) + if ( ! mdoc_pwarn(mdoc, line, *pos, WARN_SYNTAX_WS_EOLN)) return(ARGS_ERROR); return(ARGS_WORD); @@ -107,7 +107,7 @@ mdoc_args(struct mdoc *mdoc, int tok, int *pos, char *buf, int fl, char **v) (*pos)++; if (0 == buf[*pos]) { - (void)mdoc_err(mdoc, tok, *pos, ERR_SYNTAX_UNQUOTE); + (void)mdoc_perr(mdoc, line, *pos, ERR_SYNTAX_UNQUOTE); return(ARGS_ERROR); } @@ -121,7 +121,7 @@ mdoc_args(struct mdoc *mdoc, int tok, int *pos, char *buf, int fl, char **v) if (buf[*pos]) return(ARGS_WORD); - if ( ! mdoc_warn(mdoc, tok, *pos, WARN_SYNTAX_WS_EOLN)) + if ( ! mdoc_pwarn(mdoc, line, *pos, WARN_SYNTAX_WS_EOLN)) return(ARGS_ERROR); return(ARGS_WORD); @@ -291,7 +291,7 @@ lookup(int tok, const char *argv) static int -postparse(struct mdoc *mdoc, int tok, const struct mdoc_arg *v, int pos) +postparse(struct mdoc *mdoc, int line, const struct mdoc_arg *v, int pos) { switch (v->arg) { @@ -308,7 +308,7 @@ postparse(struct mdoc *mdoc, int tok, const struct mdoc_arg *v, int pos) break; if (xstrcmp(v->value[0], "indent-two")) break; - return(mdoc_err(mdoc, tok, pos, ERR_SYNTAX_ARGBAD)); + return(mdoc_perr(mdoc, line, pos, ERR_SYNTAX_ARGBAD)); default: break; } @@ -318,7 +318,7 @@ postparse(struct mdoc *mdoc, int tok, const struct mdoc_arg *v, int pos) static int -parse(struct mdoc *mdoc, int tok, +parse(struct mdoc *mdoc, int line, int tok, struct mdoc_arg *v, int *pos, char *buf) { char *p; @@ -335,16 +335,16 @@ parse(struct mdoc *mdoc, int tok, /* * This has a single value for an argument. */ - c = mdoc_args(mdoc, tok, pos, buf, ARGS_QUOTED, &p); + c = mdoc_args(mdoc, line, pos, buf, ARGS_QUOTED, &p); if (ARGS_ERROR == c) return(0); - else if (ARGS_EOLN == c) - return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGVAL)); - - v->sz = 1; - v->value = xcalloc(1, sizeof(char *)); - v->value[0] = p; - break; + else if (ARGS_EOLN != c) { + v->sz = 1; + v->value = xcalloc(1, sizeof(char *)); + v->value[0] = p; + break; + } + return(mdoc_perr(mdoc, line, ppos, ERR_SYNTAX_ARGVAL)); case(MDOC_Column): /* @@ -355,7 +355,7 @@ parse(struct mdoc *mdoc, int tok, v->sz = 0; v->value = xcalloc(MDOC_LINEARG_MAX, sizeof(char *)); for (i = 0; i < MDOC_LINEARG_MAX; i++) { - c = mdoc_args(mdoc, tok, pos, buf, ARGS_QUOTED, &p); + c = mdoc_args(mdoc, line, pos, buf, ARGS_QUOTED, &p); if (ARGS_ERROR == c) { free(v->value); return(0); @@ -365,9 +365,11 @@ parse(struct mdoc *mdoc, int tok, } if (0 == i) { free(v->value); - return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGVAL)); + return(mdoc_perr(mdoc, line, ppos, + ERR_SYNTAX_ARGVAL)); } else if (MDOC_LINEARG_MAX == i) - return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGMANY)); + return(mdoc_perr(mdoc, line, ppos, + ERR_SYNTAX_ARGMANY)); v->sz = i; break; @@ -383,7 +385,7 @@ parse(struct mdoc *mdoc, int tok, int -mdoc_argv(struct mdoc *mdoc, int tok, +mdoc_argv(struct mdoc *mdoc, int line, int tok, struct mdoc_arg *v, int *pos, char *buf) { int i, ppos; @@ -409,7 +411,7 @@ mdoc_argv(struct mdoc *mdoc, int tok, buf[(*pos)++] = 0; if (MDOC_ARG_MAX == (v->arg = lookup(tok, argv))) { - (void)mdoc_err(mdoc, tok, i, ERR_SYNTAX_ARG); + (void)mdoc_perr(mdoc, line, i, ERR_SYNTAX_ARG); return(ARGV_ERROR); } @@ -419,9 +421,9 @@ mdoc_argv(struct mdoc *mdoc, int tok, /* FIXME: whitespace if no value. */ ppos = *pos; - if ( ! parse(mdoc, tok, v, pos, buf)) + if ( ! parse(mdoc, line, tok, v, pos, buf)) return(ARGV_ERROR); - if ( ! postparse(mdoc, tok, v, ppos)) + if ( ! postparse(mdoc, line, v, ppos)) return(ARGV_ERROR); return(ARGV_ARG); @@ -29,12 +29,12 @@ /* FIXME: maxlineargs should be per LINE, no per TOKEN. */ -static int rewind_elem(struct mdoc *, int, int); -static int rewind_impblock(struct mdoc *, int, int); -static int rewind_expblock(struct mdoc *, int, int, int); -static int rewind_head(struct mdoc *, int, int); -static int rewind_body(struct mdoc *, int, int, int); -static int rewind_last(struct mdoc *, int, struct mdoc_node *); +static int rewind_elem(struct mdoc *, int); +static int rewind_impblock(struct mdoc *, int); +static int rewind_expblock(struct mdoc *, int); +static int rewind_head(struct mdoc *, int); +static int rewind_body(struct mdoc *, int); +static int rewind_last(struct mdoc *, struct mdoc_node *); static int append_delims(struct mdoc *, int, int, int *, char *); static int lookup(struct mdoc *, int, const char *); @@ -51,27 +51,28 @@ lookup(struct mdoc *mdoc, int from, const char *p) static int -rewind_last(struct mdoc *mdoc, int ppos, struct mdoc_node *to) +rewind_last(struct mdoc *mdoc, struct mdoc_node *to) { assert(to); while (mdoc->last != to) { - if ( ! mdoc_valid_post(mdoc, ppos)) + if ( ! mdoc_valid_post(mdoc)) return(0); - if ( ! mdoc_action(mdoc, ppos)) + if ( ! mdoc_action_post(mdoc)) return(0); mdoc->last = mdoc->last->parent; assert(mdoc->last); } + mdoc->next = MDOC_NEXT_SIBLING; - if ( ! mdoc_valid_post(mdoc, ppos)) + if ( ! mdoc_valid_post(mdoc)) return(0); - return(mdoc_action(mdoc, ppos)); + return(mdoc_action_post(mdoc)); } static int -rewind_elem(struct mdoc *mdoc, int ppos, int tok) +rewind_elem(struct mdoc *mdoc, int tok) { struct mdoc_node *n; @@ -81,38 +82,42 @@ rewind_elem(struct mdoc *mdoc, int ppos, int tok) assert(MDOC_ELEM == n->type); assert(tok == n->data.elem.tok); - return(rewind_last(mdoc, ppos, n)); + return(rewind_last(mdoc, n)); } static int -rewind_body(struct mdoc *mdoc, int ppos, int tok, int tt) +rewind_body(struct mdoc *mdoc, int tok) { struct mdoc_node *n; int t; + assert(mdoc->last); + /* LINTED */ for (n = mdoc->last; n; n = n->parent) { if (MDOC_BODY != n->type) continue; - if (tt == (t = n->data.head.tok)) + if (tok == (t = n->data.head.tok)) break; if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags)) continue; - return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK)); + return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK)); } assert(n); - return(rewind_last(mdoc, ppos, n)); + return(rewind_last(mdoc, n)); } static int -rewind_head(struct mdoc *mdoc, int ppos, int tok) +rewind_head(struct mdoc *mdoc, int tok) { struct mdoc_node *n; int t; + assert(mdoc->last); + /* LINTED */ for (n = mdoc->last; n; n = n->parent) { if (MDOC_HEAD != n->type) @@ -121,16 +126,16 @@ rewind_head(struct mdoc *mdoc, int ppos, int tok) break; if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags)) continue; - return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK)); + return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK)); } assert(n); - return(rewind_last(mdoc, ppos, n)); + return(rewind_last(mdoc, n)); } static int -rewind_expblock(struct mdoc *mdoc, int ppos, int tok, int tt) +rewind_expblock(struct mdoc *mdoc, int tok) { struct mdoc_node *n; int t; @@ -138,27 +143,26 @@ rewind_expblock(struct mdoc *mdoc, int ppos, int tok, int tt) assert(mdoc->last); /* LINTED */ - for (n = mdoc->last->parent; n; n = n->parent) { - if (MDOC_BLOCK != n->type) + for (n = mdoc->last; n; n = n->parent) { + if (MDOC_BLOCK != n->type) continue; - if (tt == (t = n->data.block.tok)) + if (tok == (t = n->data.block.tok)) break; if (MDOC_NESTED & mdoc_macros[t].flags) continue; - return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK)); + return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK)); } - if (NULL == n) - return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_NOCTX)); - return(rewind_last(mdoc, ppos, n)); + assert(n); + return(rewind_last(mdoc, n)); } static int -rewind_impblock(struct mdoc *mdoc, int ppos, int tok) +rewind_impblock(struct mdoc *mdoc, int tok) { - struct mdoc_node *n; int t; + struct mdoc_node *n; n = mdoc->last ? mdoc->last->parent : NULL; @@ -170,14 +174,14 @@ rewind_impblock(struct mdoc *mdoc, int ppos, int tok) break; if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags)) continue; - if (MDOC_NESTED & mdoc_macros[tok].flags) + if (MDOC_NESTED & mdoc_macros[t].flags) return(1); - return(mdoc_err(mdoc, tok, ppos, ERR_SCOPE_BREAK)); + return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK)); } if (NULL == n) return(1); - return(rewind_last(mdoc, ppos, n)); + return(rewind_last(mdoc, n)); } @@ -193,13 +197,14 @@ append_delims(struct mdoc *mdoc, int tok, for (;;) { lastarg = *pos; - c = mdoc_args(mdoc, tok, pos, buf, 0, &p); + c = mdoc_args(mdoc, line, pos, buf, 0, &p); if (ARGS_ERROR == c) return(0); else if (ARGS_EOLN == c) break; assert(mdoc_isdelim(p)); - mdoc_word_alloc(mdoc, line, lastarg, p); + if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + return(0); mdoc->next = MDOC_NEXT_SIBLING; } @@ -211,7 +216,7 @@ append_delims(struct mdoc *mdoc, int tok, int macro_close_explicit(MACRO_PROT_ARGS) { - int tt, j, c, lastarg, maxargs, flushed; + int tt, j, c, lastarg, maxargs, flushed; char *p; switch (tok) { @@ -275,21 +280,20 @@ macro_close_explicit(MACRO_PROT_ARGS) } if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { - if ( ! rewind_expblock(mdoc, ppos, tok, tt)) - return(0); - if (0 != buf[*pos]) - return(mdoc_err(mdoc, tok, *pos, ERR_ARGS_EQ0)); - return(1); + if (buf[*pos]) + return(rewind_expblock(mdoc, tt)); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_EQ0)); } - if ( ! rewind_body(mdoc, ppos, tok, tt)) + if ( ! rewind_body(mdoc, tt)) return(0); lastarg = ppos; flushed = 0; if (maxargs > 0) { - mdoc_tail_alloc(mdoc, line, ppos, tt); + if ( ! mdoc_tail_alloc(mdoc, line, ppos, tt)) + return(0); mdoc->next = MDOC_NEXT_CHILD; } @@ -297,12 +301,12 @@ macro_close_explicit(MACRO_PROT_ARGS) lastarg = *pos; if (j == maxargs && ! flushed) { - if ( ! rewind_expblock(mdoc, ppos, tok, tt)) + if ( ! rewind_expblock(mdoc, tt)) return(0); flushed = 1; } - c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p); + c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p); if (ARGS_ERROR == c) return(0); if (ARGS_PUNCT == c) @@ -312,7 +316,7 @@ macro_close_explicit(MACRO_PROT_ARGS) if (MDOC_MAX != (c = lookup(mdoc, tok, p))) { if ( ! flushed) { - if ( ! rewind_expblock(mdoc, ppos, tok, tt)) + if ( ! rewind_expblock(mdoc, tt)) return(0); flushed = 1; } @@ -321,16 +325,16 @@ macro_close_explicit(MACRO_PROT_ARGS) break; } - mdoc_word_alloc(mdoc, line, lastarg, p); + if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + return(0); mdoc->next = MDOC_NEXT_SIBLING; } if (MDOC_LINEARG_MAX == j) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); - if ( ! flushed) - if ( ! rewind_expblock(mdoc, ppos, tok, tt)) - return(0); + if ( ! flushed && ! rewind_expblock(mdoc, tt)) + return(0); if (ppos > 1) return(1); @@ -350,17 +354,17 @@ macro_close_explicit(MACRO_PROT_ARGS) int macro_text(MACRO_PROT_ARGS) { - int lastarg, lastpunct, c, sz, fl, argc; + int la, lastpunct, c, sz, fl, argc; struct mdoc_arg argv[MDOC_LINEARG_MAX]; char *p; - lastarg = ppos; + la = ppos; lastpunct = 0; for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) { - lastarg = *pos; + la = *pos; - c = mdoc_argv(mdoc, tok, &argv[argc], pos, buf); + c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf); if (ARGV_EOLN == c || ARGV_WORD == c) break; else if (ARGV_ARG == c) @@ -369,28 +373,39 @@ macro_text(MACRO_PROT_ARGS) return(0); } - if ( ! mdoc_valid_pre(mdoc, tok, ppos, argc, argv)) { + if (MDOC_LINEARG_MAX == argc) { + mdoc_argv_free(argc, argv); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); + } + + c = mdoc_elem_alloc(mdoc, line, la, tok, argc, argv); + + if (0 == c) { mdoc_argv_free(argc, argv); return(0); } + mdoc->next = MDOC_NEXT_CHILD; + fl = ARGS_DELIM; if (MDOC_QUOTABLE & mdoc_macros[tok].flags) fl |= ARGS_QUOTED; - mdoc_elem_alloc(mdoc, line, lastarg, tok, argc, argv); - mdoc->next = MDOC_NEXT_CHILD; - for (lastpunct = sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) { - lastarg = *pos; + la = *pos; if (lastpunct) { - mdoc_elem_alloc(mdoc, line, lastarg, tok, argc, argv); + c = mdoc_elem_alloc(mdoc, line, + la, tok, argc, argv); + if (0 == c) { + mdoc_argv_free(argc, argv); + return(0); + } mdoc->next = MDOC_NEXT_CHILD; lastpunct = 0; } - c = mdoc_args(mdoc, tok, pos, buf, fl, &p); + c = mdoc_args(mdoc, line, pos, buf, fl, &p); if (ARGS_ERROR == c) { mdoc_argv_free(argc, argv); return(0); @@ -402,12 +417,14 @@ macro_text(MACRO_PROT_ARGS) break; if (MDOC_MAX != (c = lookup(mdoc, tok, p))) { - if ( ! rewind_elem(mdoc, ppos, tok)) { + if ( ! rewind_elem(mdoc, tok)) { mdoc_argv_free(argc, argv); return(0); } mdoc_argv_free(argc, argv); - if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf)) + + c = mdoc_macro(mdoc, c, line, la, pos, buf); + if (0 == c) return(0); if (ppos > 1) return(1); @@ -415,22 +432,23 @@ macro_text(MACRO_PROT_ARGS) } if (mdoc_isdelim(p)) { - if ( ! rewind_elem(mdoc, ppos, tok)) { + if ( ! rewind_elem(mdoc, tok)) { mdoc_argv_free(argc, argv); return(0); } lastpunct = 1; } - mdoc_word_alloc(mdoc, line, lastarg, p); + if ( ! mdoc_word_alloc(mdoc, line, la, p)) + return(0); mdoc->next = MDOC_NEXT_SIBLING; } mdoc_argv_free(argc, argv); if (sz == MDOC_LINEARG_MAX) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); - if ( ! rewind_elem(mdoc, ppos, tok)) + if ( ! rewind_elem(mdoc, tok)) return(0); if (ppos > 1) return(1); @@ -439,7 +457,7 @@ macro_text(MACRO_PROT_ARGS) /* - * Multi-line-scoped macro. + * Implicit- or explicit-end multi-line scoped macro. */ int macro_scoped(MACRO_PROT_ARGS) @@ -451,14 +469,12 @@ macro_scoped(MACRO_PROT_ARGS) assert ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)); if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) - if ( ! rewind_impblock(mdoc, ppos, tok)) + if ( ! rewind_impblock(mdoc, tok)) return(0); - lastarg = ppos; - for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) { lastarg = *pos; - c = mdoc_argv(mdoc, tok, &argv[argc], pos, buf); + c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf); if (ARGV_EOLN == c || ARGV_WORD == c) break; else if (ARGV_ARG == c) @@ -467,31 +483,38 @@ macro_scoped(MACRO_PROT_ARGS) return(0); } - if ( ! mdoc_valid_pre(mdoc, tok, ppos, argc, argv)) { + if (MDOC_LINEARG_MAX == argc) { mdoc_argv_free(argc, argv); - return(0); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); } - mdoc_block_alloc(mdoc, line, ppos, tok, (size_t)argc, argv); - mdoc->next = MDOC_NEXT_CHILD; - + c = mdoc_block_alloc(mdoc, line, ppos, + tok, (size_t)argc, argv); mdoc_argv_free(argc, argv); + if (0 == c) + return(0); + + mdoc->next = MDOC_NEXT_CHILD; + if (0 == buf[*pos]) { - mdoc_head_alloc(mdoc, line, ppos, tok); - if ( ! rewind_head(mdoc, ppos, tok)) + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + return(0); + if ( ! rewind_head(mdoc, tok)) + return(0); + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - mdoc_body_alloc(mdoc, line, ppos, tok); mdoc->next = MDOC_NEXT_CHILD; return(1); } - mdoc_head_alloc(mdoc, line, ppos, tok); + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + return(0); mdoc->next = MDOC_NEXT_CHILD; for (j = 0; j < MDOC_LINEARG_MAX; j++) { lastarg = *pos; - c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p); + c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p); if (ARGS_ERROR == c) return(0); @@ -501,7 +524,8 @@ macro_scoped(MACRO_PROT_ARGS) break; if (MDOC_MAX == (c = lookup(mdoc, tok, p))) { - mdoc_word_alloc(mdoc, line, lastarg, p); + if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + return(0); mdoc->next = MDOC_NEXT_SIBLING; continue; } @@ -512,14 +536,15 @@ macro_scoped(MACRO_PROT_ARGS) } if (j == MDOC_LINEARG_MAX) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); - if ( ! rewind_head(mdoc, ppos, tok)) + if ( ! rewind_head(mdoc, tok)) return(0); if (1 == ppos && ! append_delims(mdoc, tok, line, pos, buf)) return(0); - mdoc_body_alloc(mdoc, line, ppos, tok); + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + return(0); mdoc->next = MDOC_NEXT_CHILD; return(1); @@ -537,22 +562,19 @@ macro_scoped_line(MACRO_PROT_ARGS) int lastarg, c, j; char *p; - mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL); + if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL)) + return(0); mdoc->next = MDOC_NEXT_CHILD; - mdoc_head_alloc(mdoc, line, ppos, tok); + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + return(0); mdoc->next = MDOC_NEXT_CHILD; /* XXX - no known argument macros. */ - if ( ! mdoc_valid_pre(mdoc, tok, ppos, 0, NULL)) - return(0); - - /* Process line parameters. */ - for (lastarg = ppos, j = 0; j < MDOC_LINEARG_MAX; j++) { lastarg = *pos; - c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p); + c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p); if (ARGS_ERROR == c) return(0); @@ -562,7 +584,8 @@ macro_scoped_line(MACRO_PROT_ARGS) break; if (MDOC_MAX == (c = lookup(mdoc, tok, p))) { - mdoc_word_alloc(mdoc, line, lastarg, p); + if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + return(0); mdoc->next = MDOC_NEXT_SIBLING; continue; } @@ -573,18 +596,22 @@ macro_scoped_line(MACRO_PROT_ARGS) } if (j == MDOC_LINEARG_MAX) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); if (1 == ppos) { - if ( ! rewind_head(mdoc, ppos, tok)) + if ( ! rewind_head(mdoc, tok)) return(0); if ( ! append_delims(mdoc, tok, line, pos, buf)) return(0); } - return(rewind_impblock(mdoc, ppos, tok)); + return(rewind_impblock(mdoc, tok)); } +/* + * Constant-scope macros accept a fixed number of arguments and behave + * like constant macros except that they're scoped across lines. + */ int macro_constant_scoped(MACRO_PROT_ARGS) { @@ -603,20 +630,20 @@ macro_constant_scoped(MACRO_PROT_ARGS) break; } - if ( ! mdoc_valid_pre(mdoc, tok, ppos, 0, NULL)) - return(0); - - mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL); + if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL)) + return(0); mdoc->next = MDOC_NEXT_CHILD; if (0 == maxargs) { - mdoc_head_alloc(mdoc, line, ppos, tok); - if ( ! rewind_head(mdoc, ppos, tok)) + if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + return(0); + if ( ! rewind_head(mdoc, tok)) + return(0); + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - mdoc_body_alloc(mdoc, line, ppos, tok); flushed = 1; - } else - mdoc_head_alloc(mdoc, line, ppos, tok); + } else if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + return(0); mdoc->next = MDOC_NEXT_CHILD; @@ -624,14 +651,15 @@ macro_constant_scoped(MACRO_PROT_ARGS) lastarg = *pos; if (j == maxargs && ! flushed) { - if ( ! rewind_head(mdoc, ppos, tok)) + if ( ! rewind_head(mdoc, tok)) return(0); flushed = 1; - mdoc_body_alloc(mdoc, line, ppos, tok); + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + return(0); mdoc->next = MDOC_NEXT_CHILD; } - c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p); + c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p); if (ARGS_ERROR == c) return(0); if (ARGS_PUNCT == c) @@ -641,10 +669,11 @@ macro_constant_scoped(MACRO_PROT_ARGS) if (MDOC_MAX != (c = lookup(mdoc, tok, p))) { if ( ! flushed) { - if ( ! rewind_head(mdoc, ppos, tok)) + if ( ! rewind_head(mdoc, tok)) return(0); flushed = 1; - mdoc_body_alloc(mdoc, line, ppos, tok); + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + return(0); mdoc->next = MDOC_NEXT_CHILD; } if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf)) @@ -653,24 +682,27 @@ macro_constant_scoped(MACRO_PROT_ARGS) } if ( ! flushed && mdoc_isdelim(p)) { - if ( ! rewind_head(mdoc, ppos, tok)) + if ( ! rewind_head(mdoc, tok)) return(0); flushed = 1; - mdoc_body_alloc(mdoc, line, ppos, tok); + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + return(0); mdoc->next = MDOC_NEXT_CHILD; } - mdoc_word_alloc(mdoc, line, lastarg, p); + if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + return(0); mdoc->next = MDOC_NEXT_SIBLING; } if (MDOC_LINEARG_MAX == j) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); if ( ! flushed) { - if ( ! rewind_head(mdoc, ppos, tok)) + if ( ! rewind_head(mdoc, tok)) + return(0); + if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) return(0); - mdoc_body_alloc(mdoc, line, ppos, tok); mdoc->next = MDOC_NEXT_CHILD; } @@ -713,7 +745,7 @@ macro_constant_delimited(MACRO_PROT_ARGS) for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) { lastarg = *pos; - c = mdoc_argv(mdoc, tok, &argv[argc], pos, buf); + c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf); if (ARGV_EOLN == c || ARGV_WORD == c) break; else if (ARGV_ARG == c) @@ -722,26 +754,24 @@ macro_constant_delimited(MACRO_PROT_ARGS) return(0); } - if ( ! mdoc_valid_pre(mdoc, tok, ppos, argc, argv)) { - mdoc_argv_free(argc, argv); + c = mdoc_elem_alloc(mdoc, line, lastarg, tok, argc, argv); + mdoc_argv_free(argc, argv); + + if (0 == c) return(0); - } - mdoc_elem_alloc(mdoc, line, lastarg, tok, argc, argv); mdoc->next = MDOC_NEXT_CHILD; - mdoc_argv_free(argc, argv); - for (j = 0; j < MDOC_LINEARG_MAX; j++) { lastarg = *pos; if (j == maxargs && ! flushed) { - if ( ! rewind_elem(mdoc, ppos, tok)) + if ( ! rewind_elem(mdoc, tok)) return(0); flushed = 1; } - c = mdoc_args(mdoc, tok, pos, buf, ARGS_DELIM, &p); + c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p); if (ARGS_ERROR == c) return(0); if (ARGS_PUNCT == c) @@ -750,7 +780,7 @@ macro_constant_delimited(MACRO_PROT_ARGS) break; if (MDOC_MAX != (c = lookup(mdoc, tok, p))) { - if ( ! flushed && ! rewind_elem(mdoc, ppos, tok)) + if ( ! flushed && ! rewind_elem(mdoc, tok)) return(0); flushed = 1; if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf)) @@ -759,19 +789,20 @@ macro_constant_delimited(MACRO_PROT_ARGS) } if ( ! flushed && mdoc_isdelim(p)) { - if ( ! rewind_elem(mdoc, ppos, tok)) + if ( ! rewind_elem(mdoc, tok)) return(0); flushed = 1; } - mdoc_word_alloc(mdoc, line, lastarg, p); + if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + return(0); mdoc->next = MDOC_NEXT_SIBLING; } if (MDOC_LINEARG_MAX == j) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); - if ( ! flushed && rewind_elem(mdoc, ppos, tok)) + if ( ! flushed && rewind_elem(mdoc, tok)) return(0); if (ppos > 1) @@ -791,8 +822,7 @@ macro_constant(MACRO_PROT_ARGS) struct mdoc_arg argv[MDOC_LINEARG_MAX]; char *p; - /*assert( ! (MDOC_PARSED & mdoc_macros[tok].flags));*/ - /*FIXME*/ + /* FIXME: parsing macros! */ fl = 0; if (MDOC_QUOTABLE & mdoc_macros[tok].flags) @@ -800,7 +830,7 @@ macro_constant(MACRO_PROT_ARGS) for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) { lastarg = *pos; - c = mdoc_argv(mdoc, tok, &argv[argc], pos, buf); + c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf); if (ARGV_EOLN == c) break; else if (ARGV_ARG == c) @@ -812,32 +842,34 @@ macro_constant(MACRO_PROT_ARGS) return(0); } - if (MDOC_LINEARG_MAX == argc) { - mdoc_argv_free(argc, argv); - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); - } + c = mdoc_elem_alloc(mdoc, line, ppos, tok, argc, argv); + mdoc_argv_free(argc, argv); + + if (0 == c) + return(0); - mdoc_elem_alloc(mdoc, line, ppos, tok, argc, argv); mdoc->next = MDOC_NEXT_CHILD; - mdoc_argv_free(argc, argv); + if (MDOC_LINEARG_MAX == argc) + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); for (sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) { lastarg = *pos; - c = mdoc_args(mdoc, tok, pos, buf, fl, &p); + c = mdoc_args(mdoc, line, pos, buf, fl, &p); if (ARGS_ERROR == c) return(0); if (ARGS_EOLN == c) break; - mdoc_word_alloc(mdoc, line, lastarg, p); + if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + return(0); mdoc->next = MDOC_NEXT_SIBLING; } if (MDOC_LINEARG_MAX == sz + argc) - return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY)); + return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY)); - return(rewind_elem(mdoc, ppos, tok)); + return(rewind_elem(mdoc, tok)); } @@ -846,7 +878,7 @@ int macro_obsolete(MACRO_PROT_ARGS) { - return(mdoc_warn(mdoc, tok, ppos, WARN_IGN_OBSOLETE)); + return(mdoc_pwarn(mdoc, line, ppos, WARN_IGN_OBSOLETE)); } @@ -856,5 +888,5 @@ macro_end(struct mdoc *mdoc) assert(mdoc->first); assert(mdoc->last); - return(rewind_last(mdoc, -1, mdoc->first)); + return(rewind_last(mdoc, mdoc->first)); } @@ -126,16 +126,16 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Va */ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */ { macro_text, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */ - { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %A */ - { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %B */ + { macro_constant, MDOC_QUOTABLE }, /* %A */ + { macro_constant, MDOC_QUOTABLE }, /* %B */ { macro_constant, MDOC_QUOTABLE }, /* %D */ - { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %I */ - { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %J */ + { macro_constant, MDOC_QUOTABLE }, /* %I */ + { macro_constant, MDOC_QUOTABLE }, /* %J */ { macro_constant, MDOC_QUOTABLE }, /* %N */ { macro_constant, MDOC_QUOTABLE }, /* %O */ { macro_constant, MDOC_QUOTABLE }, /* %P */ { macro_constant, MDOC_QUOTABLE }, /* %R */ - { macro_constant, MDOC_QUOTABLE | MDOC_PARSED }, /* %T */ + { macro_constant, MDOC_QUOTABLE }, /* %T */ { macro_constant, MDOC_QUOTABLE }, /* %V */ { macro_close_explicit, MDOC_CALLABLE | MDOC_PARSED }, /* Ac */ { macro_constant_scoped, MDOC_CALLABLE | MDOC_PARSED }, /* Ao */ @@ -206,7 +206,7 @@ static void argcpy(struct mdoc_arg *, const struct mdoc_arg *); static void mdoc_node_freelist(struct mdoc_node *); -static void mdoc_node_append(struct mdoc *, int, +static int mdoc_node_append(struct mdoc *, struct mdoc_node *); static void mdoc_elem_free(struct mdoc_elem *); static void mdoc_text_free(struct mdoc_text *); @@ -276,11 +276,12 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf) return(0); if ('.' != *buf) { - if (SEC_PROLOGUE == mdoc->sec_lastn) - return(mdoc_err(mdoc, -1, 0, ERR_SYNTAX_NOTEXT)); - mdoc_word_alloc(mdoc, line, 0, buf); - mdoc->next = MDOC_NEXT_SIBLING; - return(1); + if (SEC_PROLOGUE != mdoc->sec_lastn) { + mdoc_word_alloc(mdoc, line, 0, buf); + mdoc->next = MDOC_NEXT_SIBLING; + return(1); + } + return(mdoc_perr(mdoc, line, 0, ERR_SYNTAX_NOTEXT)); } if (buf[1] && '\\' == buf[1]) @@ -293,10 +294,10 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf) if (i == (int)sizeof(tmp)) { mdoc->flags |= MDOC_HALT; - return(mdoc_err(mdoc, -1, 1, ERR_MACRO_NOTSUP)); + return(mdoc_perr(mdoc, line, 1, ERR_MACRO_NOTSUP)); } else if (i <= 2) { mdoc->flags |= MDOC_HALT; - return(mdoc_err(mdoc, -1, 1, ERR_MACRO_NOTSUP)); + return(mdoc_perr(mdoc, line, 1, ERR_MACRO_NOTSUP)); } i--; @@ -306,7 +307,7 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf) if (MDOC_MAX == (c = mdoc_find(mdoc, tmp))) { mdoc->flags |= MDOC_HALT; - return(mdoc_err(mdoc, c, 1, ERR_MACRO_NOTSUP)); + return(mdoc_perr(mdoc, line, 1, ERR_MACRO_NOTSUP)); } while (buf[i] && isspace(buf[i])) @@ -321,68 +322,69 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf) void -mdoc_msg(struct mdoc *mdoc, int pos, const char *fmt, ...) +mdoc_msg(struct mdoc *mdoc, const char *fmt, ...) { - va_list ap; - char buf[256]; + struct mdoc_node *n; + va_list ap; + char buf[256]; if (NULL == mdoc->cb.mdoc_msg) return; + n = mdoc->last; + assert(n); + va_start(ap, fmt); (void)vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - (*mdoc->cb.mdoc_msg)(mdoc->data, pos, buf); + (*mdoc->cb.mdoc_msg)(mdoc->data, n->line, n->pos, buf); } int -mdoc_err(struct mdoc *mdoc, int tok, int pos, enum mdoc_err type) +mdoc_perr(struct mdoc *mdoc, + int line, int pos, enum mdoc_err type) { if (NULL == mdoc->cb.mdoc_err) return(0); - return((*mdoc->cb.mdoc_err)(mdoc->data, tok, pos, type)); + return((*mdoc->cb.mdoc_err)(mdoc->data, line, pos, type)); } int -mdoc_warn(struct mdoc *mdoc, int tok, int pos, enum mdoc_warn type) +mdoc_pwarn(struct mdoc *mdoc, + int line, int pos, enum mdoc_warn type) { if (NULL == mdoc->cb.mdoc_warn) return(0); - return((*mdoc->cb.mdoc_warn)(mdoc->data, tok, pos, type)); + return((*mdoc->cb.mdoc_warn)(mdoc->data, line, pos, type)); } int mdoc_macro(struct mdoc *mdoc, int tok, - int line, int ppos, int *pos, char *buf) + int ln, int ppos, int *pos, char *buf) { if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) && SEC_PROLOGUE == mdoc->sec_lastn) - return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE)); + return(mdoc_perr(mdoc, ln, ppos, ERR_SEC_PROLOGUE)); - if (NULL == (mdoc_macros[tok].fp)) { - (void)mdoc_err(mdoc, tok, ppos, ERR_MACRO_NOTSUP); - return(0); - } + if (NULL == (mdoc_macros[tok].fp)) + return(mdoc_perr(mdoc, ln, ppos, ERR_MACRO_NOTSUP)); - if (1 != ppos && ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { - (void)mdoc_err(mdoc, tok, ppos, ERR_MACRO_NOTCALL); - return(0); - } + if (1 != ppos && ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) + return(mdoc_perr(mdoc, ln, ppos, ERR_MACRO_NOTCALL)); - return((*mdoc_macros[tok].fp)(mdoc, tok, - line, ppos, pos, buf)); + return((*mdoc_macros[tok].fp)(mdoc, tok, ln, ppos, pos, buf)); } -static void -mdoc_node_append(struct mdoc *mdoc, int pos, struct mdoc_node *p) +static int +mdoc_node_append(struct mdoc *mdoc, struct mdoc_node *p) { const char *nn, *on, *nt, *ot, *act; @@ -418,10 +420,14 @@ mdoc_node_append(struct mdoc *mdoc, int pos, struct mdoc_node *p) if (NULL == mdoc->first) { assert(NULL == mdoc->last); + if ( ! mdoc_valid_pre(mdoc, p)) + return(0); + if ( ! mdoc_action_pre(mdoc, p)) + return(0); mdoc->first = p; mdoc->last = p; - mdoc_msg(mdoc, pos, "parse: root %s `%s'", nt, nn); - return; + mdoc_msg(mdoc, "parse: root %s `%s'", nt, nn); + return(1); } switch (mdoc->last->type) { @@ -471,14 +477,17 @@ mdoc_node_append(struct mdoc *mdoc, int pos, struct mdoc_node *p) /* NOTREACHED */ } - mdoc_msg(mdoc, pos, "parse: %s `%s' %s of %s `%s'", - nt, nn, act, ot, on); - + if ( ! mdoc_valid_pre(mdoc, p)) + return(0); + if ( ! mdoc_action_pre(mdoc, p)) + return(0); mdoc->last = p; + mdoc_msg(mdoc, "parse: %s of %s `%s'", act, ot, on); + return(1); } -void +int mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, int tok) { struct mdoc_node *p; @@ -493,11 +502,11 @@ mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, int tok) p->type = MDOC_TAIL; p->data.tail.tok = tok; - mdoc_node_append(mdoc, pos, p); + return(mdoc_node_append(mdoc, p)); } -void +int mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, int tok) { struct mdoc_node *p; @@ -512,11 +521,11 @@ mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, int tok) p->type = MDOC_HEAD; p->data.head.tok = tok; - mdoc_node_append(mdoc, pos, p); + return(mdoc_node_append(mdoc, p)); } -void +int mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, int tok) { struct mdoc_node *p; @@ -531,11 +540,11 @@ mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, int tok) p->type = MDOC_BODY; p->data.body.tok = tok; - mdoc_node_append(mdoc, pos, p); + return(mdoc_node_append(mdoc, p)); } -void +int mdoc_block_alloc(struct mdoc *mdoc, int line, int pos, int tok, size_t argsz, const struct mdoc_arg *args) { @@ -550,11 +559,11 @@ mdoc_block_alloc(struct mdoc *mdoc, int line, int pos, p->data.block.argc = argsz; p->data.block.argv = argdup(argsz, args); - mdoc_node_append(mdoc, pos, p); + return(mdoc_node_append(mdoc, p)); } -void +int mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos, int tok, size_t argsz, const struct mdoc_arg *args) { @@ -569,11 +578,11 @@ mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos, p->data.elem.argc = argsz; p->data.elem.argv = argdup(argsz, args); - mdoc_node_append(mdoc, pos, p); + return(mdoc_node_append(mdoc, p)); } -void +int mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *word) { @@ -585,7 +594,7 @@ mdoc_word_alloc(struct mdoc *mdoc, p->type = MDOC_TEXT; p->data.text.string = xstrdup(word); - mdoc_node_append(mdoc, pos, p); + return(mdoc_node_append(mdoc, p)); } @@ -421,7 +421,7 @@ struct mdoc_node { struct mdoc_cb { int (*mdoc_err)(void *, int, int, enum mdoc_err); int (*mdoc_warn)(void *, int, int, enum mdoc_warn); - void (*mdoc_msg)(void *, int, const char *); + void (*mdoc_msg)(void *, int, int, const char *); }; extern const char *const *mdoc_macronames; @@ -57,7 +57,7 @@ static int buf_leave(struct md_parse *, int); static int msg_err(void *, int, int, enum mdoc_err); static int msg_warn(void *, int, int, enum mdoc_warn); -static void msg_msg(void *, int, const char *); +static void msg_msg(void *, int, int, const char *); #ifdef __linux__ extern int getsubopt(char **, char *const *, char **); @@ -318,15 +318,15 @@ parse_begin(struct md_parse *p) static int -msg_err(void *arg, int tok, int col, enum mdoc_err type) +msg_err(void *arg, int line, int col, enum mdoc_err type) { - char *fmt, *lit; + char *lit; struct md_parse *p; int i; p = (struct md_parse *)arg; - fmt = lit = NULL; + lit = NULL; switch (type) { case (ERR_SYNTAX_NOTEXT): @@ -342,59 +342,59 @@ msg_err(void *arg, int tok, int col, enum mdoc_err type) lit = "syntax: whitespace in argument"; break; case (ERR_SYNTAX_ARGFORM): - fmt = "syntax: macro `%s' arguments malformed"; + lit = "syntax: macro arguments malformed"; break; case (ERR_SYNTAX_NOPUNCT): - fmt = "syntax: macro `%s' doesn't understand punctuation"; + lit = "syntax: macro doesn't understand punctuation"; break; case (ERR_SYNTAX_ARG): - fmt = "syntax: unknown argument for macro `%s'"; + lit = "syntax: unknown argument for macro"; break; case (ERR_SCOPE_BREAK): /* Which scope is broken? */ - fmt = "scope: macro `%s' breaks prior explicit scope"; + lit = "scope: macro breaks prior explicit scope"; break; case (ERR_SCOPE_NOCTX): - fmt = "scope: closure macro `%s' has no context"; + lit = "scope: closure macro has no context"; break; case (ERR_SCOPE_NONEST): - fmt = "scope: macro `%s' may not be nested in the current context"; + lit = "scope: macro may not be nested in the current context"; break; case (ERR_MACRO_NOTSUP): lit = "macro not supported"; break; case (ERR_MACRO_NOTCALL): - fmt = "macro `%s' not callable"; + lit = "macro not callable"; break; case (ERR_SEC_PROLOGUE): - fmt = "macro `%s' cannot be called in the prologue"; + lit = "macro cannot be called in the prologue"; break; case (ERR_SEC_NPROLOGUE): - fmt = "macro `%s' called outside of prologue"; + lit = "macro called outside of prologue"; break; case (ERR_ARGS_EQ0): - fmt = "macro `%s' expects zero arguments"; + lit = "macro expects zero arguments"; break; case (ERR_ARGS_EQ1): - fmt = "macro `%s' expects one argument"; + lit = "macro expects one argument"; break; case (ERR_ARGS_GE1): - fmt = "macro `%s' expects one or more arguments"; + lit = "macro expects one or more arguments"; break; case (ERR_ARGS_LE2): - fmt = "macro `%s' expects two or fewer arguments"; + lit = "macro expects two or fewer arguments"; break; case (ERR_ARGS_LE8): - fmt = "macro `%s' expects eight or fewer arguments"; + lit = "macro expects eight or fewer arguments"; break; case (ERR_ARGS_MANY): - fmt = "macro `%s' has too many arguments"; + lit = "macro has too many arguments"; break; case (ERR_SEC_PROLOGUE_OO): - fmt = "prologue macro `%s' is out-of-order"; + lit = "prologue macro is out-of-order"; break; case (ERR_SEC_PROLOGUE_REP): - fmt = "prologue macro `%s' repeated"; + lit = "prologue macro repeated"; break; case (ERR_SEC_NAME): lit = "`NAME' section must be first"; @@ -425,22 +425,12 @@ msg_err(void *arg, int tok, int col, enum mdoc_err type) /* NOTREACHED */ } - if (fmt) { - (void)fprintf(stderr, "%s:%d: error: ", - p->name, p->lnn); - (void)fprintf(stderr, fmt, mdoc_macronames[tok]); - } else - (void)fprintf(stderr, "%s:%d: error: %s", - p->name, p->lnn, lit); + (void)fprintf(stderr, "%s:%d: error: %s", p->name, p->lnn, lit); if (p->dbg < 1) { - if (-1 != col) - (void)fprintf(stderr, " (column %d)\n", col); - return(0); - } else if (-1 == col) { - (void)fprintf(stderr, "\nFrom: %s\n", p->line); + (void)fprintf(stderr, " (column %d)\n", col); return(0); - } + } (void)fprintf(stderr, "\nFrom: %s\n ", p->line); for (i = 0; i < col; i++) @@ -452,7 +442,7 @@ msg_err(void *arg, int tok, int col, enum mdoc_err type) static void -msg_msg(void *arg, int col, const char *msg) +msg_msg(void *arg, int line, int col, const char *msg) { struct md_parse *p; int i; @@ -462,14 +452,10 @@ msg_msg(void *arg, int col, const char *msg) if (p->dbg < 2) return; - (void)printf("%s:%d: %s", p->name, p->lnn, msg); + (void)printf("%s:%d: %s", p->name, line, msg); if (p->dbg < 3) { - if (-1 != col) - (void)printf(" (column %d)\n", col); - return; - } else if (-1 == col) { - (void)printf("\nFrom %s\n", p->line); + (void)printf(" (column %d)\n", col); return; } @@ -481,9 +467,9 @@ msg_msg(void *arg, int col, const char *msg) static int -msg_warn(void *arg, int tok, int col, enum mdoc_warn type) +msg_warn(void *arg, int line, int col, enum mdoc_warn type) { - char *fmt, *lit; + char *lit; struct md_parse *p; int i; extern char *__progname; @@ -493,7 +479,7 @@ msg_warn(void *arg, int tok, int col, enum mdoc_warn type) if ( ! (p->warn & MD_WARN_ALL)) return(1); - fmt = lit = NULL; + lit = NULL; switch (type) { case (WARN_SYNTAX_WS_EOLN): @@ -515,45 +501,38 @@ msg_warn(void *arg, int tok, int col, enum mdoc_warn type) lit = "section is out of conventional order"; break; case (WARN_ARGS_GE1): - fmt = "macro `%s' suggests one or more arguments"; + lit = "macro suggests one or more arguments"; break; case (WARN_ARGS_EQ0): - fmt = "macro `%s' suggests zero arguments"; + lit = "macro suggests zero arguments"; break; case (WARN_IGN_AFTER_BLK): - fmt = "ignore: macro `%s' ignored after block macro"; + lit = "ignore: macro ignored after block macro"; break; case (WARN_IGN_OBSOLETE): - fmt = "ignore: macro `%s' is obsolete"; + lit = "ignore: macro is obsolete"; break; case (WARN_IGN_BEFORE_BLK): - fmt = "ignore: macro before block macro `%s' ignored"; + lit = "ignore: macro before block macro ignored"; break; case (WARN_COMPAT_TROFF): - fmt = "compat: macro `%s' behaves differently in troff and nroff"; + lit = "compat: macro behaves differently in troff and nroff"; break; default: abort(); /* NOTREACHED */ } - if (fmt) { - (void)fprintf(stderr, "%s:%d: warning: ", - p->name, p->lnn); - (void)fprintf(stderr, fmt, mdoc_macronames[tok]); - } else - (void)fprintf(stderr, "%s:%d: warning: %s", - p->name, p->lnn, lit); - if (col >= 0 && p->dbg >= 1) { + (void)fprintf(stderr, "%s:%d: warning: %s", p->name, line, lit); + + if (p->dbg >= 1) { (void)fprintf(stderr, "\nFrom: %s\n ", p->line); for (i = 0; i < col; i++) (void)fprintf(stderr, " "); (void)fprintf(stderr, "^\n"); - } else if (col >= 0) + } else (void)fprintf(stderr, " (column %d)\n", col); - else - (void)fprintf(stderr, "\n"); if (p->warn & MD_WARN_ERR) { (void)fprintf(stderr, "%s: considering warnings as " @@ -59,20 +59,28 @@ extern const struct mdoc_macro *const mdoc_macros; __BEGIN_DECLS -int mdoc_err(struct mdoc *, int, int, enum mdoc_err); -int mdoc_warn(struct mdoc *, int, int, enum mdoc_warn); -void mdoc_msg(struct mdoc *, int, const char *, ...); +#define mdoc_vwarn(m, n, t) \ + mdoc_pwarn((m), (n)->line, (n)->pos, (t)) +#define mdoc_verr(m, n, t) \ + mdoc_perr((m), (n)->line, (n)->pos, (t)) +#define mdoc_warn(m, t) \ + mdoc_pwarn((m), (m)->last->line, (m)->last->pos, (t)) +#define mdoc_err(m, t) \ + mdoc_perr((m), (m)->last->line, (m)->last->pos, (t)) +int mdoc_pwarn(struct mdoc *, int, int, enum mdoc_warn); +int mdoc_perr(struct mdoc *, int, int, enum mdoc_err); +void mdoc_msg(struct mdoc *, const char *, ...); int mdoc_macro(MACRO_PROT_ARGS); int mdoc_find(const struct mdoc *, const char *); -void mdoc_word_alloc(struct mdoc *, +int mdoc_word_alloc(struct mdoc *, int, int, const char *); -void mdoc_elem_alloc(struct mdoc *, int, int, +int mdoc_elem_alloc(struct mdoc *, int, int, int, size_t, const struct mdoc_arg *); -void mdoc_block_alloc(struct mdoc *, int, int, +int mdoc_block_alloc(struct mdoc *, int, int, int, size_t, const struct mdoc_arg *); -void mdoc_head_alloc(struct mdoc *, int, int, int); -void mdoc_tail_alloc(struct mdoc *, int, int, int); -void mdoc_body_alloc(struct mdoc *, int, int, int); +int mdoc_head_alloc(struct mdoc *, int, int, int); +int mdoc_tail_alloc(struct mdoc *, int, int, int); +int mdoc_body_alloc(struct mdoc *, int, int, int); void mdoc_node_free(struct mdoc_node *); void mdoc_sibling(struct mdoc *, int, struct mdoc_node **, struct mdoc_node **, struct mdoc_node *); @@ -88,12 +96,12 @@ enum mdoc_arch mdoc_atoarch(const char *); enum mdoc_att mdoc_atoatt(const char *); time_t mdoc_atotime(const char *); -int mdoc_valid_pre(struct mdoc *, int, int, - int, const struct mdoc_arg *); -int mdoc_valid_post(struct mdoc *, int); -int mdoc_action(struct mdoc *, int); +int mdoc_valid_pre(struct mdoc *, struct mdoc_node *); +int mdoc_valid_post(struct mdoc *); +int mdoc_action_pre(struct mdoc *, struct mdoc_node *); +int mdoc_action_post(struct mdoc *); -int mdoc_argv(struct mdoc *, int, +int mdoc_argv(struct mdoc *, int, int, struct mdoc_arg *, int *, char *); #define ARGV_ERROR (-1) #define ARGV_EOLN (0) @@ -22,9 +22,8 @@ #include "private.h" -typedef int (*v_pre)(struct mdoc *, int, int, - int, const struct mdoc_arg *); -typedef int (*v_post)(struct mdoc *, int, int); +typedef int (*v_pre)(struct mdoc *, struct mdoc_node *); +typedef int (*v_post)(struct mdoc *); struct valids { @@ -33,11 +32,10 @@ struct valids { }; -static int pre_sh(struct mdoc *, int, int, - int, const struct mdoc_arg *); -static int post_headchild_err_ge1(struct mdoc *, int, int); -static int post_headchild_err_le8(struct mdoc *, int, int); -static int post_bodychild_warn_ge1(struct mdoc *, int, int); +static int pre_sh(struct mdoc *, struct mdoc_node *); +static int post_headchild_err_ge1(struct mdoc *); +static int post_headchild_err_le8(struct mdoc *); +static int post_bodychild_warn_ge1(struct mdoc *); static v_post posts_sh[] = { post_headchild_err_ge1, post_bodychild_warn_ge1, @@ -155,7 +153,7 @@ const struct valids mdoc_valids[MDOC_MAX] = { static int -post_bodychild_warn_ge1(struct mdoc *mdoc, int tok, int pos) +post_bodychild_warn_ge1(struct mdoc *mdoc) { if (MDOC_BODY != mdoc->last->type) @@ -163,24 +161,24 @@ post_bodychild_warn_ge1(struct mdoc *mdoc, int tok, int pos) if (mdoc->last->child) return(1); - return(mdoc_warn(mdoc, tok, pos, WARN_ARGS_GE1)); + return(mdoc_warn(mdoc, WARN_ARGS_GE1)); } static int -post_headchild_err_ge1(struct mdoc *mdoc, int tok, int pos) +post_headchild_err_ge1(struct mdoc *mdoc) { if (MDOC_HEAD != mdoc->last->type) return(1); if (mdoc->last->child) return(1); - return(mdoc_err(mdoc, tok, pos, ERR_ARGS_GE1)); + return(mdoc_err(mdoc, ERR_ARGS_GE1)); } static int -post_headchild_err_le8(struct mdoc *mdoc, int tok, int pos) +post_headchild_err_le8(struct mdoc *mdoc) { int i; struct mdoc_node *n; @@ -191,13 +189,12 @@ post_headchild_err_le8(struct mdoc *mdoc, int tok, int pos) /* Do nothing. */ ; if (i <= 8) return(1); - return(mdoc_err(mdoc, tok, pos, ERR_ARGS_LE8)); + return(mdoc_err(mdoc, ERR_ARGS_LE8)); } static int -pre_sh(struct mdoc *mdoc, int tok, int pos, - int argc, const struct mdoc_arg *argv) +pre_sh(struct mdoc *mdoc, struct mdoc_node *node) { return(1); @@ -205,18 +202,35 @@ pre_sh(struct mdoc *mdoc, int tok, int pos, int -mdoc_valid_pre(struct mdoc *mdoc, int tok, int pos, - int argc, const struct mdoc_arg *argv) +mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *node) { + int t; + + switch (node->type) { + case (MDOC_BODY): + t = mdoc->last->data.body.tok; + break; + case (MDOC_ELEM): + t = mdoc->last->data.elem.tok; + break; + case (MDOC_BLOCK): + t = mdoc->last->data.block.tok; + break; + case (MDOC_HEAD): + t = mdoc->last->data.head.tok; + break; + default: + return(1); + } - if (NULL == mdoc_valids[tok].pre) + if (NULL == mdoc_valids[t].pre) return(1); - return((*mdoc_valids[tok].pre)(mdoc, tok, pos, argc, argv)); + return((*mdoc_valids[t].pre)(mdoc, node)); } int -mdoc_valid_post(struct mdoc *mdoc, int pos) +mdoc_valid_post(struct mdoc *mdoc) { v_post *p; int t; @@ -242,7 +256,7 @@ mdoc_valid_post(struct mdoc *mdoc, int pos) return(1); for (p = mdoc_valids[t].post; *p; p++) - if ( ! (*p)(mdoc, t, pos)) + if ( ! (*p)(mdoc)) return(0); return(1); |