=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.13 retrieving revision 1.18 diff -u -p -r1.13 -r1.18 --- mandoc/mdoc_validate.c 2009/06/17 11:02:06 1.13 +++ mandoc/mdoc_validate.c 2009/07/04 09:01:55 1.18 @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.13 2009/06/17 11:02:06 kristaps Exp $ */ +/* $Id: mdoc_validate.c,v 1.18 2009/07/04 09:01:55 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -23,6 +23,7 @@ #include #include "libmdoc.h" +#include "libmandoc.h" /* FIXME: .Bl -diag can't have non-text children in HEAD. */ /* TODO: ignoring Pp (it's superfluous in some invocations). */ @@ -46,6 +47,7 @@ enum merr { EMULTILIST, EARGREP, EBOOL, + ECOLMIS, ENESTDISP }; @@ -54,7 +56,6 @@ enum mwarn { WNOWIDTH, WMISSWIDTH, WESCAPE, - WDEPESC, WDEPCOL, WWRONGMSEC, WSECOOO, @@ -98,7 +99,6 @@ static int err_child_gt(struct mdoc *, const char *, i static int warn_child_gt(struct mdoc *, const char *, int); static int err_child_eq(struct mdoc *, const char *, int); static int warn_child_eq(struct mdoc *, const char *, int); -static int count_child(struct mdoc *); static int warn_print(struct mdoc *, int, int); static int warn_count(struct mdoc *, const char *, int, const char *, int); @@ -138,6 +138,7 @@ static int post_args(POST_ARGS); static int post_at(POST_ARGS); static int post_bf(POST_ARGS); static int post_bl(POST_ARGS); +static int post_bl_head(POST_ARGS); static int post_it(POST_ARGS); static int post_nm(POST_ARGS); static int post_root(POST_ARGS); @@ -174,7 +175,7 @@ static v_post posts_wtext[] = { ewarn_ge1, NULL }; static v_post posts_notext[] = { eerr_eq0, NULL }; static v_post posts_wline[] = { bwarn_ge1, herr_eq0, NULL }; static v_post posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL }; -static v_post posts_bl[] = { herr_eq0, bwarn_ge1, post_bl, NULL }; +static v_post posts_bl[] = { bwarn_ge1, post_bl, NULL }; static v_post posts_it[] = { post_it, NULL }; static v_post posts_in[] = { ewarn_eq1, NULL }; static v_post posts_ss[] = { herr_ge1, NULL }; @@ -425,6 +426,9 @@ perr(struct mdoc *m, int line, int pos, enum merr type case (ENODATA): p = "document has no data"; break; + case (ECOLMIS): + p = "column syntax style mismatch"; + break; case (EATT): p = "expected valid AT&T symbol"; break; @@ -482,9 +486,6 @@ pwarn(struct mdoc *m, int line, int pos, enum mwarn ty case (WESCAPE): p = "invalid escape sequence"; break; - case (WDEPESC): - p = "deprecated special-character escape"; - break; case (WNOLINE): p = "suggested no line arguments"; break; @@ -548,19 +549,6 @@ err_count(struct mdoc *m, const char *k, } -static inline int -count_child(struct mdoc *mdoc) -{ - int i; - struct mdoc_node *n; - - for (i = 0, n = mdoc->last->child; n; n = n->next, i++) - /* Do nothing */ ; - - return(i); -} - - /* * Build these up with macros because they're basically the same check * for different inequalities. Yes, this could be done with functions, @@ -571,10 +559,9 @@ count_child(struct mdoc *mdoc) static int \ lvl##_child_##name(struct mdoc *mdoc, const char *p, int sz) \ { \ - int i; \ - if ((i = count_child(mdoc)) ineq sz) \ + if (mdoc->last->nchild ineq sz) \ return(1); \ - return(lvl##_count(mdoc, #ineq, sz, p, i)); \ + return(lvl##_count(mdoc, #ineq, sz, p, mdoc->last->nchild)); \ } #define CHECK_BODY_DEFN(name, lvl, func, num) \ @@ -722,9 +709,9 @@ check_argv(struct mdoc *m, const struct mdoc_node *n, static int check_text(struct mdoc *mdoc, int line, int pos, const char *p) { - size_t c; + int c; - for ( ; *p; p++) { + for ( ; *p; p++, pos++) { if ('\t' == *p) { if ( ! (MDOC_LITERAL & mdoc->flags)) if ( ! warn_print(mdoc, line, pos)) @@ -736,13 +723,10 @@ check_text(struct mdoc *mdoc, int line, int pos, const if ('\\' != *p) continue; - c = mdoc_isescape(p); + c = mandoc_special(p); if (c) { - /* See if form is deprecated. */ - if ('*' == p[1]) - if ( ! pwarn(mdoc, line, pos, WDEPESC)) - return(0); - p += (int)c - 1; + p += c - 1; + pos += c - 1; continue; } if ( ! (MDOC_IGN_ESCAPE & mdoc->pflags)) @@ -797,7 +781,7 @@ pre_display(PRE_ARGS) static int pre_bl(PRE_ARGS) { - int pos, col, type, width, offset; + int pos, type, width, offset; if (MDOC_BLOCK != n->type) return(1); @@ -806,7 +790,7 @@ pre_bl(PRE_ARGS) /* Make sure that only one type of list is specified. */ - type = offset = width = col = -1; + type = offset = width = -1; /* LINTED */ for (pos = 0; pos < (int)n->args->argc; pos++) @@ -835,7 +819,6 @@ pre_bl(PRE_ARGS) if (-1 != type) return(nerr(mdoc, n, EMULTILIST)); type = n->args->argv[pos].arg; - col = pos; break; case (MDOC_Width): if (-1 != width) @@ -879,22 +862,6 @@ pre_bl(PRE_ARGS) break; } - /* - * General validation of fields. - */ - - switch (type) { - case (MDOC_Column): - assert(col >= 0); - if (0 == n->args->argv[col].sz) - break; - if ( ! nwarn(mdoc, n, WDEPCOL)) - return(0); - break; - default: - break; - } - return(1); } @@ -1257,10 +1224,35 @@ post_it(POST_ARGS) static int +post_bl_head(POST_ARGS) +{ + int i; + const struct mdoc_node *n; + + n = mdoc->last->parent; + assert(n->args); + + for (i = 0; i < (int)n->args->argc; i++) + if (n->args->argv[i].arg == MDOC_Column) + break; + + if (i == (int)n->args->argc) + return(1); + + if (n->args->argv[i].sz && mdoc->last->child) + return(nerr(mdoc, n, ECOLMIS)); + + return(1); +} + + +static int post_bl(POST_ARGS) { struct mdoc_node *n; + if (MDOC_HEAD == mdoc->last->type) + return(post_bl_head(mdoc)); if (MDOC_BODY != mdoc->last->type) return(1); if (NULL == mdoc->last->child)