]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_validate.c
discard .Rs head arguments and improve .Rs diagnostics
[mandoc.git] / mdoc_validate.c
index 726960417daa1401ee7dd45ac75d10f860233058..417e21615c43f22f66b3c852507e885e3fda974e 100644 (file)
@@ -1,7 +1,7 @@
-/*     $Id: mdoc_validate.c,v 1.261 2014/11/28 18:09:01 schwarze Exp $ */
+/*     $Id: mdoc_validate.c,v 1.268 2015/02/04 18:03:47 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -48,11 +48,6 @@ enum check_ineq {
        CHECK_EQ
 };
 
-enum   check_lvl {
-       CHECK_WARN,
-       CHECK_ERROR,
-};
-
 typedef        void    (*v_pre)(PRE_ARGS);
 typedef        void    (*v_post)(POST_ARGS);
 
@@ -62,7 +57,7 @@ struct        valids {
 };
 
 static void     check_count(struct mdoc *, enum mdoc_type,
-                       enum check_lvl, enum check_ineq, int);
+                       enum check_ineq, int);
 static void     check_text(struct mdoc *, int, int, char *);
 static void     check_argv(struct mdoc *,
                        struct mdoc_node *, struct mdoc_argv *);
@@ -210,7 +205,7 @@ static      const struct valids mdoc_valids[MDOC_MAX] = {
        { NULL, NULL },                         /* Nx */
        { NULL, NULL },                         /* Ox */
        { NULL, NULL },                         /* Pc */
-       { NULL, ewarn_eq1 },                    /* Pf */
+       { NULL, NULL },                         /* Pf */
        { NULL, NULL },                         /* Po */
        { NULL, NULL },                         /* Pq */
        { NULL, NULL },                         /* Qc */
@@ -374,10 +369,9 @@ mdoc_valid_post(struct mdoc *mdoc)
 
 static void
 check_count(struct mdoc *mdoc, enum mdoc_type type,
-               enum check_lvl lvl, enum check_ineq ineq, int val)
+       enum check_ineq ineq, int val)
 {
        const char      *p;
-       enum mandocerr   t;
 
        if (mdoc->last->type != type)
                return;
@@ -403,8 +397,7 @@ check_count(struct mdoc *mdoc, enum mdoc_type type,
                /* NOTREACHED */
        }
 
-       t = lvl == CHECK_WARN ? MANDOCERR_ARGCWARN : MANDOCERR_ARGCOUNT;
-       mandoc_vmsg(t, mdoc->parse, mdoc->last->line,
+       mandoc_vmsg(MANDOCERR_ARGCWARN, mdoc->parse, mdoc->last->line,
            mdoc->last->pos, "want %s%d children (have %d)",
            p, val, mdoc->last->nchild);
 }
@@ -412,25 +405,25 @@ check_count(struct mdoc *mdoc, enum mdoc_type type,
 static void
 bwarn_ge1(POST_ARGS)
 {
-       check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0);
+       check_count(mdoc, MDOC_BODY, CHECK_GT, 0);
 }
 
 static void
 ewarn_eq1(POST_ARGS)
 {
-       check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1);
+       check_count(mdoc, MDOC_ELEM, CHECK_EQ, 1);
 }
 
 static void
 ewarn_ge1(POST_ARGS)
 {
-       check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_GT, 0);
+       check_count(mdoc, MDOC_ELEM, CHECK_GT, 0);
 }
 
 static void
 hwarn_eq0(POST_ARGS)
 {
-       check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0);
+       check_count(mdoc, MDOC_HEAD, CHECK_EQ, 0);
 }
 
 static void
@@ -941,7 +934,7 @@ post_lb(POST_ARGS)
        const char              *stdlibname;
        char                    *libname;
 
-       check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 1);
+       check_count(mdoc, MDOC_ELEM, CHECK_EQ, 1);
        n = mdoc->last->child;
        assert(MDOC_TEXT == n->type);
 
@@ -995,7 +988,7 @@ static void
 post_fo(POST_ARGS)
 {
 
-       check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 1);
+       check_count(mdoc, MDOC_HEAD, CHECK_EQ, 1);
        bwarn_ge1(mdoc);
        if (mdoc->last->type == MDOC_HEAD && mdoc->last->nchild)
                post_fname(mdoc);
@@ -1047,22 +1040,39 @@ post_vt(POST_ARGS)
 static void
 post_nm(POST_ARGS)
 {
+       struct mdoc_node        *n;
+
+       n = mdoc->last;
+
+       if (n->last != NULL &&
+           (n->last->tok == MDOC_Pp ||
+            n->last->tok == MDOC_Lp))
+               mdoc_node_relink(mdoc, n->last);
 
        if (NULL != mdoc->meta.name)
                return;
 
-       mdoc_deroff(&mdoc->meta.name, mdoc->last);
+       mdoc_deroff(&mdoc->meta.name, n);
 
        if (NULL == mdoc->meta.name)
                mandoc_msg(MANDOCERR_NM_NONAME, mdoc->parse,
-                   mdoc->last->line, mdoc->last->pos, "Nm");
+                   n->line, n->pos, "Nm");
 }
 
 static void
 post_nd(POST_ARGS)
 {
+       struct mdoc_node        *n;
+
+       n = mdoc->last;
+
+       if (n->type != MDOC_BODY)
+               return;
+
+       if (n->child == NULL)
+               mandoc_msg(MANDOCERR_ND_EMPTY, mdoc->parse,
+                   n->line, n->pos, "Nd");
 
-       check_count(mdoc, MDOC_BODY, CHECK_ERROR, CHECK_GT, 0);
        post_hyph(mdoc);
 }
 
@@ -1169,9 +1179,9 @@ post_an(POST_ARGS)
        np = mdoc->last;
        if (AUTH__NONE == np->norm->An.auth) {
                if (0 == np->child)
-                       check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_GT, 0);
+                       check_count(mdoc, MDOC_ELEM, CHECK_GT, 0);
        } else if (np->child)
-               check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 0);
+               check_count(mdoc, MDOC_ELEM, CHECK_EQ, 0);
 }
 
 static void
@@ -1197,7 +1207,7 @@ post_it(POST_ARGS)
        struct mdoc_node *nbl, *nit, *nch;
 
        nit = mdoc->last;
-       if (MDOC_BLOCK != nit->type)
+       if (nit->type != MDOC_BLOCK)
                return;
 
        nbl = nit->parent->parent;
@@ -1213,7 +1223,7 @@ post_it(POST_ARGS)
        case LIST_inset:
                /* FALLTHROUGH */
        case LIST_diag:
-               if (NULL == nit->head->child)
+               if (nit->head->child == NULL)
                        mandoc_vmsg(MANDOCERR_IT_NOHEAD,
                            mdoc->parse, nit->line, nit->pos,
                            "Bl -%s It",
@@ -1226,14 +1236,14 @@ post_it(POST_ARGS)
        case LIST_enum:
                /* FALLTHROUGH */
        case LIST_hyphen:
-               if (NULL == nit->body->child)
+               if (nit->body == NULL || nit->body->child == NULL)
                        mandoc_vmsg(MANDOCERR_IT_NOBODY,
                            mdoc->parse, nit->line, nit->pos,
                            "Bl -%s It",
                            mdoc_argnames[nbl->args->argv[0].arg]);
                /* FALLTHROUGH */
        case LIST_item:
-               if (NULL != nit->head->child)
+               if (nit->head->child != NULL)
                        mandoc_vmsg(MANDOCERR_ARG_SKIP,
                            mdoc->parse, nit->line, nit->pos,
                            "It %s", nit->head->child->string);
@@ -1241,10 +1251,10 @@ post_it(POST_ARGS)
        case LIST_column:
                cols = (int)nbl->norm->Bl.ncols;
 
-               assert(NULL == nit->head->child);
+               assert(nit->head->child == NULL);
 
                for (i = 0, nch = nit->child; nch; nch = nch->next)
-                       if (MDOC_BODY == nch->type)
+                       if (nch->type == MDOC_BODY)
                                i++;
 
                if (i < cols || i > cols + 1)
@@ -1484,7 +1494,10 @@ post_bl(POST_ARGS)
 
        nchild = nbody->child;
        while (NULL != nchild) {
-               if (MDOC_It == nchild->tok || MDOC_Sm == nchild->tok) {
+               if (nchild->tok == MDOC_It ||
+                   (nchild->tok == MDOC_Sm &&
+                    nchild->next != NULL &&
+                    nchild->next->tok == MDOC_It)) {
                        nchild = nchild->next;
                        continue;
                }
@@ -1645,19 +1658,17 @@ post_st(POST_ARGS)
 static void
 post_rs(POST_ARGS)
 {
-       struct mdoc_node *nn, *next, *prev;
+       struct mdoc_node *np, *nch, *next, *prev;
        int               i, j;
 
-       switch (mdoc->last->type) {
-       case MDOC_HEAD:
-               check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_EQ, 0);
-               return;
-       case MDOC_BODY:
-               if (mdoc->last->child)
-                       break;
-               check_count(mdoc, MDOC_BODY, CHECK_WARN, CHECK_GT, 0);
+       np = mdoc->last;
+
+       if (np->type != MDOC_BODY)
                return;
-       default:
+
+       if (np->child == NULL) {
+               mandoc_msg(MANDOCERR_RS_EMPTY, mdoc->parse,
+                   np->line, np->pos, "Rs");
                return;
        }
 
@@ -1668,38 +1679,38 @@ post_rs(POST_ARGS)
         */
 
        next = NULL;
-       for (nn = mdoc->last->child->next; nn; nn = next) {
-               /* Determine order of `nn'. */
+       for (nch = np->child->next; nch != NULL; nch = next) {
+               /* Determine order number of this child. */
                for (i = 0; i < RSORD_MAX; i++)
-                       if (rsord[i] == nn->tok)
+                       if (rsord[i] == nch->tok)
                                break;
 
                if (i == RSORD_MAX) {
                        mandoc_msg(MANDOCERR_RS_BAD,
-                           mdoc->parse, nn->line, nn->pos,
-                           mdoc_macronames[nn->tok]);
+                           mdoc->parse, nch->line, nch->pos,
+                           mdoc_macronames[nch->tok]);
                        i = -1;
-               } else if (MDOC__J == nn->tok || MDOC__B == nn->tok)
-                       mdoc->last->norm->Rs.quote_T++;
+               } else if (nch->tok == MDOC__J || nch->tok == MDOC__B)
+                       np->norm->Rs.quote_T++;
 
                /*
-                * Remove `nn' from the chain.  This somewhat
+                * Remove this child from the chain.  This somewhat
                 * repeats mdoc_node_unlink(), but since we're
                 * just re-ordering, there's no need for the
                 * full unlink process.
                 */
 
-               if (NULL != (next = nn->next))
-                       next->prev = nn->prev;
+               if ((next = nch->next) != NULL)
+                       next->prev = nch->prev;
 
-               if (NULL != (prev = nn->prev))
-                       prev->next = nn->next;
+               if ((prev = nch->prev) != NULL)
+                       prev->next = nch->next;
 
-               nn->prev = nn->next = NULL;
+               nch->prev = nch->next = NULL;
 
                /*
                 * Scan back until we reach a node that's
-                * ordered before `nn'.
+                * to be ordered before this child.
                 */
 
                for ( ; prev ; prev = prev->prev) {
@@ -1715,21 +1726,21 @@ post_rs(POST_ARGS)
                }
 
                /*
-                * Set `nn' back into its correct place in front
-                * of the `prev' node.
+                * Set this child back into its correct place
+                * in front of the `prev' node.
                 */
 
-               nn->prev = prev;
+               nch->prev = prev;
 
-               if (prev) {
-                       if (prev->next)
-                               prev->next->prev = nn;
-                       nn->next = prev->next;
-                       prev->next = nn;
+               if (prev == NULL) {
+                       np->child->prev = nch;
+                       nch->next = np->child;
+                       np->child = nch;
                } else {
-                       mdoc->last->child->prev = nn;
-                       nn->next = mdoc->last->child;
-                       mdoc->last->child = nn;
+                       if (prev->next)
+                               prev->next->prev = nch;
+                       nch->next = prev->next;
+                       prev->next = nch;
                }
        }
 }
@@ -2061,7 +2072,7 @@ post_ignpar(POST_ARGS)
 {
        struct mdoc_node *np;
 
-       check_count(mdoc, MDOC_HEAD, CHECK_WARN, CHECK_GT, 0);
+       check_count(mdoc, MDOC_HEAD, CHECK_GT, 0);
        post_hyph(mdoc);
 
        if (MDOC_BODY != mdoc->last->type)
@@ -2124,9 +2135,9 @@ post_par(POST_ARGS)
        struct mdoc_node *np;
 
        if (mdoc->last->tok == MDOC_sp)
-               check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_LT, 2);
+               check_count(mdoc, MDOC_ELEM, CHECK_LT, 2);
        else
-               check_count(mdoc, MDOC_ELEM, CHECK_WARN, CHECK_EQ, 0);
+               check_count(mdoc, MDOC_ELEM, CHECK_EQ, 0);
 
        if (MDOC_ELEM != mdoc->last->type &&
            MDOC_BLOCK != mdoc->last->type)
@@ -2280,19 +2291,9 @@ post_dt(POST_ARGS)
                mdoc->meta.msec = mandoc_strdup(nn->string);
        }
 
-       if (NULL == (nn = nn->next))
-               goto out;
-
-       /*
-        * If the third argument is a volume name, format is,
-        * otherwise assume it's an architecture.
-        */
+       /* Handle an optional architecture */
 
-       cp = mdoc_a2vol(nn->string);
-       if (cp) {
-               free(mdoc->meta.vol);
-               mdoc->meta.vol = mandoc_strdup(cp);
-       } else {
+       if ((nn = nn->next) != NULL) {
                for (p = nn->string; *p; p++)
                        *p = tolower((unsigned char)*p);
                mdoc->meta.arch = mandoc_strdup(nn->string);