=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.105 retrieving revision 1.114 diff -u -p -r1.105 -r1.114 --- mandoc/mdoc_validate.c 2010/07/02 12:54:33 1.105 +++ mandoc/mdoc_validate.c 2010/07/26 13:45:49 1.114 @@ -1,6 +1,6 @@ -/* $Id: mdoc_validate.c,v 1.105 2010/07/02 12:54:33 kristaps Exp $ */ +/* $Id: mdoc_validate.c,v 1.114 2010/07/26 13:45:49 kristaps Exp $ */ /* - * Copyright (c) 2008, 2009 Kristaps Dzonsons + * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -32,7 +32,6 @@ #include "libmandoc.h" /* FIXME: .Bl -diag can't have non-text children in HEAD. */ -/* TODO: ignoring Pp (it's superfluous in some invocations). */ #define PRE_ARGS struct mdoc *mdoc, struct mdoc_node *n #define POST_ARGS struct mdoc *mdoc @@ -146,7 +145,7 @@ static v_pre pres_ss[] = { pre_ss, NULL }; const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Ap */ - { pres_dd, posts_text }, /* Dd */ + { pres_dd, posts_wtext }, /* Dd */ { pres_dt, posts_dt }, /* Dt */ { pres_os, NULL }, /* Os */ { pres_sh, posts_sh }, /* Sh */ @@ -454,26 +453,29 @@ check_argv(struct mdoc *m, struct mdoc_node *n, struct static int -check_text(struct mdoc *mdoc, int line, int pos, char *p) +check_text(struct mdoc *m, int ln, int pos, char *p) { int c; + size_t sz; - /* - * FIXME: we absolutely cannot let \b get through or it will - * destroy some assumptions in terms of format. - */ - for ( ; *p; p++, pos++) { + sz = strcspn(p, "\t\\"); + p += (int)sz; + + if ('\0' == *p) + break; + + pos += (int)sz; + if ('\t' == *p) { - if ( ! (MDOC_LITERAL & mdoc->flags)) - if ( ! mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADCHAR)) - return(0); - } else if ( ! isprint((u_char)*p) && ASCII_HYPH != *p) - if ( ! mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADCHAR)) - return(0); + if (MDOC_LITERAL & m->flags) + continue; + if (mdoc_pmsg(m, ln, pos, MANDOCERR_BADTAB)) + continue; + return(0); + } - if ('\\' != *p) - continue; + /* Check the special character. */ c = mandoc_special(p); if (c) { @@ -482,8 +484,8 @@ check_text(struct mdoc *mdoc, int line, int pos, char continue; } - c = mdoc_pmsg(mdoc, line, pos, MANDOCERR_BADESCAPE); - if ( ! (MDOC_IGN_ESCAPE & mdoc->pflags) && ! c) + c = mdoc_pmsg(m, ln, pos, MANDOCERR_BADESCAPE); + if ( ! (MDOC_IGN_ESCAPE & m->pflags) && ! c) return(c); } @@ -491,8 +493,6 @@ check_text(struct mdoc *mdoc, int line, int pos, char } - - static int check_parent(PRE_ARGS, enum mdoct tok, enum mdoc_type t) { @@ -510,7 +510,6 @@ check_parent(PRE_ARGS, enum mdoct tok, enum mdoc_type } - static int pre_display(PRE_ARGS) { @@ -625,6 +624,8 @@ pre_bl(PRE_ARGS) if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV)) return(0); break; + default: + continue; } /* Check: duplicate auxiliary arguments. */ @@ -647,8 +648,16 @@ pre_bl(PRE_ARGS) /* Assign list type. */ - if (LIST__NONE != lt && n->data.Bl->type == LIST__NONE) + if (LIST__NONE != lt && n->data.Bl->type == LIST__NONE) { n->data.Bl->type = lt; + /* Set column information, too. */ + if (LIST_column == lt) { + n->data.Bl->ncols = + n->args->argv[i].sz; + n->data.Bl->cols = (const char **) + n->args->argv[i].value; + } + } /* The list type should come first. */ @@ -849,13 +858,20 @@ static int pre_an(PRE_ARGS) { - if (NULL == n->args || 1 == n->args->argc) + if (NULL == n->args) return(1); - mdoc_vmsg(mdoc, MANDOCERR_SYNTARGCOUNT, - n->line, n->pos, - "line arguments == 1 (have %d)", - n->args->argc); - return(0); + if (n->args->argc > 1) + if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGCOUNT)) + return(0); + + if (MDOC_Split == n->args->argv[0].arg) + n->data.An.auth = AUTH_split; + else if (MDOC_Nosplit == n->args->argv[0].arg) + n->data.An.auth = AUTH_nosplit; + else + abort(); + + return(1); } @@ -932,7 +948,7 @@ static int post_bf(POST_ARGS) { struct mdoc_node *np; - int arg; + enum mdocargt arg; /* * Unlike other data pointers, these are "housed" by the HEAD @@ -957,6 +973,8 @@ post_bf(POST_ARGS) } np = mdoc->last; + assert(MDOC_BLOCK == np->parent->type); + assert(MDOC_Bf == np->parent->tok); np->data.Bf = mandoc_calloc(1, sizeof(struct mdoc_bf)); /* @@ -964,16 +982,16 @@ post_bf(POST_ARGS) * If neither is specified, let it through with a warning. */ - if (np->args && np->child) { + if (np->parent->args && np->child) { mdoc_nmsg(mdoc, np, MANDOCERR_SYNTARGVCOUNT); return(0); - } else if (NULL == np->args && NULL == np->child) + } else if (NULL == np->parent->args && NULL == np->child) return(mdoc_nmsg(mdoc, np, MANDOCERR_FONTTYPE)); /* Extract argument into data. */ - if (np->args) { - arg = np->args->argv[0].arg; + if (np->parent->args) { + arg = np->parent->args->argv[0].arg; if (MDOC_Emphasis == arg) np->data.Bf->font = FONT_Em; else if (MDOC_Literal == arg) @@ -1074,16 +1092,14 @@ post_at(POST_ARGS) static int post_an(POST_ARGS) { + struct mdoc_node *np; - if (mdoc->last->args) { - if (NULL == mdoc->last->child) - return(1); - return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGCOUNT)); - } - - if (mdoc->last->child) + np = mdoc->last; + if (AUTH__NONE != np->data.An.auth && np->child) + return(mdoc_nmsg(mdoc, np, MANDOCERR_ARGCOUNT)); + if (AUTH__NONE != np->data.An.auth || np->child) return(1); - return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS)); + return(mdoc_nmsg(mdoc, np, MANDOCERR_NOARGS)); } @@ -1125,9 +1141,6 @@ post_it(POST_ARGS) if (NULL == mdoc->last->head->child) if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS)) return(0); - if (NULL == mdoc->last->body->child) - if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY)) - return(0); break; case (LIST_bullet): /* FALLTHROUGH */ @@ -1136,24 +1149,18 @@ post_it(POST_ARGS) case (LIST_enum): /* FALLTHROUGH */ case (LIST_hyphen): + if (NULL == mdoc->last->body->child) + if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY)) + return(0); /* FALLTHROUGH */ case (LIST_item): if (mdoc->last->head->child) if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGSLOST)) return(0); - if (NULL == mdoc->last->body->child) - if ( ! mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOBODY)) - return(0); break; case (LIST_column): - cols = -1; - for (i = 0; i < (int)n->args->argc; i++) - if (MDOC_Column == n->args->argv[i].arg) { - cols = (int)n->args->argv[i].sz; - break; - } + cols = (int)n->data.Bl->ncols; - assert(-1 != cols); assert(NULL == mdoc->last->head->child); if (NULL == mdoc->last->body->child) @@ -1193,12 +1200,7 @@ post_bl_head(POST_ARGS) n = mdoc->last->parent; if (LIST_column == n->data.Bl->type) { - for (i = 0; i < (int)n->args->argc; i++) - if (MDOC_Column == n->args->argv[i].arg) - break; - assert(i < (int)n->args->argc); - - if (n->args->argv[i].sz && mdoc->last->nchild) { + if (n->data.Bl->ncols && mdoc->last->nchild) { mdoc_nmsg(mdoc, n, MANDOCERR_COLUMNS); return(0); }