]> git.cameronkatri.com Git - mandoc.git/commitdiff
Migrate action for `Rs' into mdoc_validate.c.
authorKristaps Dzonsons <kristaps@bsd.lv>
Mon, 29 Nov 2010 12:22:28 +0000 (12:22 +0000)
committerKristaps Dzonsons <kristaps@bsd.lv>
Mon, 29 Nov 2010 12:22:28 +0000 (12:22 +0000)
Remove superfluous in-line order_rs function.
Merge `Rs' validations {BLOCK, BODY} -> {BODY}.
Make invalid children of `Rs' raise an error but otherwise be allowed.

mdoc_action.c
mdoc_validate.c

index 5bdc2fcd4f316779f526686d0f1e4f2dae146259..d0b6411e71b5d284453bb5f862001c898a26c16b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_action.c,v 1.78 2010/07/30 17:14:09 joerg Exp $ */
+/*     $Id: mdoc_action.c,v 1.79 2010/11/29 12:22:28 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -50,7 +50,6 @@ struct        actions {
 
 static int       concat(struct mdoc *, char *,
                        const struct mdoc_node *, size_t);
-static inline int order_rs(enum mdoct);
 
 static int       post_ar(POST_ARGS);
 static int       post_at(POST_ARGS);
@@ -67,7 +66,6 @@ static        int       post_nm(POST_ARGS);
 static int       post_os(POST_ARGS);
 static int       post_pa(POST_ARGS);
 static int       post_prol(POST_ARGS);
-static int       post_rs(POST_ARGS);
 static int       post_sh(POST_ARGS);
 static int       post_st(POST_ARGS);
 static int       post_std(POST_ARGS);
@@ -161,7 +159,7 @@ static      const struct actions mdoc_actions[MDOC_MAX] = {
        { NULL, NULL }, /* Qo */
        { NULL, NULL }, /* Qq */
        { NULL, NULL }, /* Re */
-       { NULL, post_rs }, /* Rs */
+       { NULL, NULL }, /* Rs */
        { NULL, NULL }, /* Sc */
        { NULL, NULL }, /* So */
        { NULL, NULL }, /* Sq */
@@ -986,67 +984,3 @@ post_display(POST_ARGS)
                m->flags &= ~MDOC_LITERAL;
        return(1);
 }
-
-
-static inline int
-order_rs(enum mdoct t)
-{
-       int             i;
-
-       for (i = 0; i < (int)RSORD_MAX; i++)
-               if (rsord[i] == t)
-                       return(i);
-
-       abort();
-       /* NOTREACHED */
-}
-
-
-/* ARGSUSED */
-static int
-post_rs(POST_ARGS)
-{
-       struct mdoc_node        *nn, *next, *prev;
-       int                      o;
-
-       if (MDOC_BLOCK != n->type)
-               return(1);
-
-       assert(n->body->child);
-       for (next = NULL, nn = n->body->child->next; nn; nn = next) {
-               o = order_rs(nn->tok);
-
-               /* Remove `nn' from the chain. */
-               next = nn->next;
-               if (next)
-                       next->prev = nn->prev;
-
-               prev = nn->prev;
-               if (prev)
-                       prev->next = nn->next;
-
-               nn->prev = nn->next = NULL;
-
-               /* 
-                * Scan back until we reach a node that's ordered before
-                * us, then set ourselves as being the next. 
-                */
-               for ( ; prev; prev = prev->prev)
-                       if (order_rs(prev->tok) <= o)
-                               break;
-
-               nn->prev = prev;
-               if (prev) {
-                       if (prev->next)
-                               prev->next->prev = nn;
-                       nn->next = prev->next;
-                       prev->next = nn;
-                       continue;
-               } 
-
-               n->body->child->prev = nn;
-               nn->next = n->body->child;
-               n->body->child = nn;
-       }
-       return(1);
-}
index 0553c0455e83f1ab3a09cc5f637c332767e8d36f..3acab0dc5b517b5f28c6898a9d2042db7230c28d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_validate.c,v 1.121 2010/10/11 15:46:19 kristaps Exp $ */
+/*     $Id: mdoc_validate.c,v 1.122 2010/11/29 12:22:28 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -275,6 +275,25 @@ const      struct valids mdoc_valids[MDOC_MAX] = {
        { NULL, NULL },                         /* Ta */
 };
 
+#define        RSORD_MAX 14 /* Number of `Rs' blocks. */
+
+static const enum mdoct rsord[RSORD_MAX] = {
+       MDOC__A,
+       MDOC__T,
+       MDOC__B,
+       MDOC__I,
+       MDOC__J,
+       MDOC__R,
+       MDOC__N,
+       MDOC__V,
+       MDOC__P,
+       MDOC__Q,
+       MDOC__D,
+       MDOC__O,
+       MDOC__C,
+       MDOC__U
+};
+
 
 int
 mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n)
@@ -1340,46 +1359,96 @@ post_st(POST_ARGS)
 static int
 post_rs(POST_ARGS)
 {
-       struct mdoc_node        *nn;
+       struct mdoc_node *nn, *next, *prev;
+       int               i, j;
 
        if (MDOC_BODY != mdoc->last->type)
                return(1);
 
-       for (nn = mdoc->last->child; nn; nn = nn->next)
-               switch (nn->tok) {
-               case(MDOC__U):
-                       /* FALLTHROUGH */
-               case(MDOC__Q):
-                       /* FALLTHROUGH */
-               case(MDOC__C):
-                       /* FALLTHROUGH */
-               case(MDOC__A):
-                       /* FALLTHROUGH */
-               case(MDOC__B):
-                       /* FALLTHROUGH */
-               case(MDOC__D):
-                       /* FALLTHROUGH */
-               case(MDOC__I):
-                       /* FALLTHROUGH */
-               case(MDOC__J):
-                       /* FALLTHROUGH */
-               case(MDOC__N):
-                       /* FALLTHROUGH */
-               case(MDOC__O):
-                       /* FALLTHROUGH */
-               case(MDOC__P):
-                       /* FALLTHROUGH */
-               case(MDOC__R):
-                       /* FALLTHROUGH */
-               case(MDOC__T):
-                       /* FALLTHROUGH */
-               case(MDOC__V):
-                       break;
-               default:
-                       mdoc_nmsg(mdoc, nn, MANDOCERR_SYNTCHILD);
-                       return(0);
+       /*
+        * Make sure only certain types of nodes are allowed within the
+        * the `Rs' body.  Delete offending nodes and raise a warning.
+        * Do this before re-ordering for the sake of clarity.
+        */
+
+       next = NULL;
+       for (nn = mdoc->last->child; nn; nn = next) {
+               for (i = 0; i < RSORD_MAX; i++)
+                       if (nn->tok == rsord[i])
+                               break;
+
+               if (i < RSORD_MAX) {
+                       next = nn->next;
+                       continue;
+               }
+
+               next = nn->next;
+               mdoc_nmsg(mdoc, nn, MANDOCERR_CHILD);
+               mdoc_node_delete(mdoc, nn);
+       }
+
+       /*
+        * The full `Rs' block needs special handling to order the
+        * sub-elements according to `rsord'.  Pick through each element
+        * and correctly order it.  This is a insertion sort.
+        */
+
+       next = NULL;
+       for (nn = mdoc->last->child->next; nn; nn = next) {
+               /* Determine order of `nn'. */
+               for (i = 0; i < RSORD_MAX; i++)
+                       if (rsord[i] == nn->tok)
+                               break;
+
+               /* 
+                * Remove `nn' 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 (NULL != (prev = nn->prev))
+                       prev->next = nn->next;
+
+               nn->prev = nn->next = NULL;
+
+               /* 
+                * Scan back until we reach a node that's
+                * ordered before `nn'.
+                */
+
+               for ( ; prev ; prev = prev->prev) {
+                       /* Determine order of `prev'. */
+                       for (j = 0; j < RSORD_MAX; j++)
+                               if (rsord[j] == prev->tok)
+                                       break;
+
+                       if (j <= i)
+                               break;
                }
 
+               /*
+                * Set `nn' back into its correct place in front
+                * of the `prev' node.
+                */
+
+               nn->prev = prev;
+
+               if (prev) {
+                       if (prev->next)
+                               prev->next->prev = nn;
+                       nn->next = prev->next;
+                       prev->next = nn;
+               } else {
+                       mdoc->last->child->prev = nn;
+                       nn->next = mdoc->last->child;
+                       mdoc->last->child = nn;
+               }
+       }
+
        return(1);
 }