]> git.cameronkatri.com Git - mandoc.git/commitdiff
Consolidated list processing to a single loop in mdoc_validate.c. This
authorKristaps Dzonsons <kristaps@bsd.lv>
Thu, 3 Jun 2010 13:44:36 +0000 (13:44 +0000)
committerKristaps Dzonsons <kristaps@bsd.lv>
Thu, 3 Jun 2010 13:44:36 +0000 (13:44 +0000)
relieves having to repeat running over the argument list in
mdoc_action.c and mdoc_validate.c.

Default to LIST_item for type-less lists (groff technically doesn't do
this: it just ignores the `It' lines altogether).

Make MANDOC_LISTTYPE be a recoverable error.

libmdoc.h
main.c
mandoc.h
mdoc_action.c
mdoc_html.c
mdoc_validate.c

index d383f7bae9c1942394656e4ba58390d5cb7c2151..b106b557a44baf176504e358ebff60fd25fe0b4d 100644 (file)
--- a/libmdoc.h
+++ b/libmdoc.h
@@ -1,4 +1,4 @@
-/*     $Id: libmdoc.h,v 1.51 2010/05/31 15:42:09 kristaps Exp $ */
+/*     $Id: libmdoc.h,v 1.52 2010/06/03 13:44:36 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -118,8 +118,7 @@ const char   *mdoc_a2st(const char *);
 const char      *mdoc_a2arch(const char *);
 const char      *mdoc_a2vol(const char *);
 const char      *mdoc_a2msec(const char *);
-int              mdoc_valid_pre(struct mdoc *, 
-                       const struct mdoc_node *);
+int              mdoc_valid_pre(struct mdoc *, struct mdoc_node *);
 int              mdoc_valid_post(struct mdoc *);
 int              mdoc_action_pre(struct mdoc *, 
                        struct mdoc_node *);
diff --git a/main.c b/main.c
index 78f0ddb0f885cea81f3f4aee04c4554a84f16aed..2a2bd386c84910bd4fa237db35ee9f65669d2731 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/*     $Id: main.c,v 1.81 2010/06/01 14:54:37 kristaps Exp $ */
+/*     $Id: main.c,v 1.82 2010/06/03 13:44:36 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -141,12 +141,12 @@ static    const char * const      mandocerrs[MANDOCERR_MAX] = {
        "macro requires body argument(s)",
        "macro requires argument(s)",
        "no title in document",
+       "missing list type",
        "line argument(s) will be lost",
        "body argument(s) will be lost",
        "column syntax is inconsistent",
        "missing font type",
        "missing display type",
-       "missing list type",
        "displays may not be nested",
        "no scope to rewind: syntax violated",
        "scope broken, syntax violated",
index e3666c2f0cdaee5442bb7025ae23b2e7e7a55ff7..ae9b2814745d7d0f80dbda4369812841d8e76e62 100644 (file)
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,4 +1,4 @@
-/*     $Id: mandoc.h,v 1.9 2010/06/01 14:54:37 kristaps Exp $ */
+/*     $Id: mandoc.h,v 1.10 2010/06/03 13:44:36 kristaps Exp $ */
 /*
  * Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -73,6 +73,7 @@ enum  mandocerr {
        MANDOCERR_NOBODY, /* macro requires body argument(s) */
        MANDOCERR_NOARGV, /* macro requires argument(s) */
        MANDOCERR_NOTITLE, /* no title in document */
+       MANDOCERR_LISTTYPE, /* missing list type */
        MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
        MANDOCERR_BODYLOST, /* body argument(s) will be lost */
 #define        MANDOCERR_ERROR         MANDOCERR_BODYLOST
@@ -83,8 +84,6 @@ enum  mandocerr {
        /* FIXME: this should be a MANDOCERR_ERROR */
        MANDOCERR_DISPTYPE, /* missing display type */
        /* FIXME: this should be a MANDOCERR_ERROR */
-       MANDOCERR_LISTTYPE, /* missing list type */
-       /* FIXME: this should be a MANDOCERR_ERROR */
        MANDOCERR_NESTEDDISP, /* displays may not be nested */
        MANDOCERR_SYNTNOSCOPE, /* request scope close w/none open */
        MANDOCERR_SYNTSCOPE, /* scope broken, syntax violated */
index ddb8b20198bed11c35aebe66534361ef908ca4ed..f27ef13b4b585cfe29c914440606b2d14574835f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_action.c,v 1.64 2010/05/31 10:28:04 kristaps Exp $ */
+/*     $Id: mdoc_action.c,v 1.65 2010/06/03 13:44:36 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -948,8 +948,7 @@ pre_offset(PRE_ARGS)
         * stipulated by mdoc.samples. 
         */
 
-       assert(n->args);
-       for (i = 0; i < (int)n->args->argc; i++) {
+       for (i = 0; n->args && i < (int)n->args->argc; i++) {
                if (MDOC_Offset != n->args->argv[i].arg) 
                        continue;
                if (n->args->argv[i].sz)
@@ -969,63 +968,10 @@ pre_offset(PRE_ARGS)
 static int
 pre_bl(PRE_ARGS)
 {
-       int              pos;
-
-       if (MDOC_BLOCK != n->type) {
-               assert(n->parent);
-               assert(MDOC_BLOCK == n->parent->type);
-               assert(MDOC_Bl == n->parent->tok);
-               assert(LIST__NONE != n->parent->data.list);
-               n->data.list = n->parent->data.list;
-               return(1);
-       }
-
-       assert(LIST__NONE == n->data.list);
-
-       for (pos = 0; pos < (int)n->args->argc; pos++) {
-               switch (n->args->argv[pos].arg) {
-               case (MDOC_Bullet):
-                       n->data.list = LIST_bullet;
-                       break;
-               case (MDOC_Dash):
-                       n->data.list = LIST_dash;
-                       break;
-               case (MDOC_Enum):
-                       n->data.list = LIST_enum;
-                       break;
-               case (MDOC_Hyphen):
-                       n->data.list = LIST_hyphen;
-                       break;
-               case (MDOC_Item):
-                       n->data.list = LIST_item;
-                       break;
-               case (MDOC_Tag):
-                       n->data.list = LIST_tag;
-                       break;
-               case (MDOC_Diag):
-                       n->data.list = LIST_diag;
-                       break;
-               case (MDOC_Hang):
-                       n->data.list = LIST_hang;
-                       break;
-               case (MDOC_Ohang):
-                       n->data.list = LIST_ohang;
-                       break;
-               case (MDOC_Inset):
-                       n->data.list = LIST_inset;
-                       break;
-               case (MDOC_Column):
-                       n->data.list = LIST_column;
-                       break;
-               default:
-                       break;
-               }
-               if (LIST__NONE != n->data.list)
-                       break;
-       }
 
-       assert(LIST__NONE != n->data.list);
-       return(pre_offset(m, n));
+       if (MDOC_BLOCK == n->type)
+               return(pre_offset(m, n));
+       return(1);
 }
 
 
index 894d605e7dfe258a121ef5f2b3f44ea296ca931f..76a7fe8c45981ab7673eec2ae3e28886a3247d7b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_html.c,v 1.71 2010/05/31 10:28:04 kristaps Exp $ */
+/*     $Id: mdoc_html.c,v 1.72 2010/06/03 13:44:36 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -832,7 +832,6 @@ mdoc_it_block_pre(MDOC_ARGS, enum mdoc_list type, int comp,
        struct roffsu            su;
 
        nn = n->parent->parent;
-       assert(nn->args);
 
        /* XXX: see notes in mdoc_it_pre(). */
 
@@ -1014,7 +1013,8 @@ mdoc_it_pre(MDOC_ARGS)
 
        /* Get width, offset, and compact arguments. */
 
-       for (wp = -1, comp = i = 0; i < (int)bl->args->argc; i++) 
+       wp = -1;
+       for (comp = i = 0; bl->args && i < (int)bl->args->argc; i++) 
                switch (bl->args->argv[i].arg) {
                case (MDOC_Column):
                        wp = i; /* Save for later. */
@@ -1322,7 +1322,7 @@ mdoc_bd_pre(MDOC_ARGS)
        SCALE_VS_INIT(&su, 0);
 
        type = comp = 0;
-       for (i = 0; i < (int)bl->args->argc; i++) 
+       for (i = 0; bl->args && i < (int)bl->args->argc; i++) 
                switch (bl->args->argv[i].arg) {
                case (MDOC_Offset):
                        a2offs(bl->args->argv[i].value[0], &su);
@@ -1997,8 +1997,7 @@ mdoc_bf_pre(MDOC_ARGS)
                else if ( ! strcmp("Li", n->head->child->string))
                        PAIR_CLASS_INIT(&tag[0], "lit");
        } else {
-               assert(n->args);
-               for (i = 0; i < (int)n->args->argc; i++) 
+               for (i = 0; n->args && i < (int)n->args->argc; i++) 
                        switch (n->args->argv[i].arg) {
                        case (MDOC_Symbolic):
                                PAIR_CLASS_INIT(&tag[0], "symb");
index 48e000c7ddb70b0f0e05bbd8497c5a8b2a11b7ad..85f6474381c743ade4a45d8567948303b39e1b54 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_validate.c,v 1.90 2010/05/31 23:40:25 kristaps Exp $ */
+/*     $Id: mdoc_validate.c,v 1.91 2010/06/03 13:44:36 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -34,7 +34,7 @@
 /* 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, const struct mdoc_node *n
+#define        PRE_ARGS  struct mdoc *mdoc, struct mdoc_node *n
 #define        POST_ARGS struct mdoc *mdoc
 
 typedef        int     (*v_pre)(PRE_ARGS);
@@ -273,7 +273,7 @@ const       struct valids mdoc_valids[MDOC_MAX] = {
 
 
 int
-mdoc_valid_pre(struct mdoc *mdoc, const struct mdoc_node *n)
+mdoc_valid_pre(struct mdoc *mdoc, struct mdoc_node *n)
 {
        v_pre           *p;
        int              line, pos;
@@ -535,79 +535,117 @@ pre_display(PRE_ARGS)
 static int
 pre_bl(PRE_ARGS)
 {
-       int              pos, type, width, offset;
-
-       if (MDOC_BLOCK != n->type)
+       int              i, width, offs, cmpt, dupl;
+       enum mdoc_list   lt;
+
+       if (MDOC_BLOCK != n->type) {
+               assert(n->parent);
+               assert(MDOC_BLOCK == n->parent->type);
+               assert(MDOC_Bl == n->parent->tok);
+               assert(LIST__NONE != n->parent->data.list);
+               n->data.list = n->parent->data.list;
                return(1);
-       if (NULL == n->args) {
-               mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE);
-               return(0);
        }
 
-       /* Make sure that only one type of list is specified.  */
+       /* 
+        * First figure out which kind of list to use: bind ourselves to
+        * the first mentioned list type and warn about any remaining
+        * ones.  If we find no list type, we default to LIST_item.
+        */
 
-       type = offset = width = -1;
+       assert(LIST__NONE == n->data.list);
+       offs = width = cmpt = -1;
 
        /* LINTED */
-       for (pos = 0; pos < (int)n->args->argc; pos++)
-               switch (n->args->argv[pos].arg) {
+       for (i = 0; n->args && i < (int)n->args->argc; i++) {
+               lt = LIST__NONE;
+               dupl = 0;
+               switch (n->args->argv[i].arg) {
+               /* Set list types. */
                case (MDOC_Bullet):
-                       /* FALLTHROUGH */
+                       lt = LIST_bullet;
+                       break;
                case (MDOC_Dash):
-                       /* FALLTHROUGH */
+                       lt = LIST_dash;
+                       break;
                case (MDOC_Enum):
-                       /* FALLTHROUGH */
+                       lt = LIST_enum;
+                       break;
                case (MDOC_Hyphen):
-                       /* FALLTHROUGH */
+                       lt = LIST_hyphen;
+                       break;
                case (MDOC_Item):
-                       /* FALLTHROUGH */
+                       lt = LIST_item;
+                       break;
                case (MDOC_Tag):
-                       /* FALLTHROUGH */
+                       lt = LIST_tag;
+                       break;
                case (MDOC_Diag):
-                       /* FALLTHROUGH */
+                       lt = LIST_diag;
+                       break;
                case (MDOC_Hang):
-                       /* FALLTHROUGH */
+                       lt = LIST_hang;
+                       break;
                case (MDOC_Ohang):
-                       /* FALLTHROUGH */
+                       lt = LIST_ohang;
+                       break;
                case (MDOC_Inset):
-                       /* FALLTHROUGH */
+                       lt = LIST_inset;
+                       break;
                case (MDOC_Column):
-                       if (type < 0) {
-                               type = n->args->argv[pos].arg;
-                               break;
-                       }
-                       if (mdoc_nmsg(mdoc, n, MANDOCERR_LISTREP))
-                               break;
-                       return(0);
+                       lt = LIST_column;
+                       break;
+               /* Set list arguments. */
                case (MDOC_Compact):
-                       if (type >= 0)
-                               break;
-                       if (mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
-                               break;
-                       return(0);
+                       if (cmpt >= 0) 
+                               dupl++;
+                       cmpt = i;
+                       break;
                case (MDOC_Width):
                        if (width >= 0)
-                               if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
-                                       return(0);
-                       if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
-                               return(0);
-                       width = n->args->argv[pos].arg;
+                               dupl++;
+                       width = i;
                        break;
                case (MDOC_Offset):
-                       if (offset >= 0)
-                               if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
-                                       return(0);
-                       if (type < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
-                               return(0);
-                       offset = n->args->argv[pos].arg;
-                       break;
-               default:
+                       if (offs >= 0)
+                               dupl++;
+                       offs = i;
                        break;
                }
 
-       if (type < 0) {
-               mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE);
-               return(0);
+               /* Check: duplicate auxiliary arguments. */
+
+               if (dupl)
+                       if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
+                               return(0);
+
+               /* Check: multiple list types. */
+
+               if (LIST__NONE != lt && n->data.list != LIST__NONE)
+                       if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTREP))
+                               return(0);
+
+               /* Assign list type. */
+
+               if (LIST__NONE != lt && n->data.list == LIST__NONE)
+                       n->data.list = lt;
+
+               /* The list type should come first. */
+
+               if (n->data.list == LIST__NONE)
+                       if (width >= 0 || offs >= 0 || cmpt >= 0)
+                               if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
+                                       return(0);
+
+               continue;
+       }
+
+       /* Allow lists to default to LIST_item. */
+
+       if (LIST__NONE == n->data.list) {
+               if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE))
+                       return(0);
+               n->data.list = LIST_item;
        }
 
        /* 
@@ -616,23 +654,27 @@ pre_bl(PRE_ARGS)
         * and must also be warned.
         */
 
-       switch (type) {
-       case (MDOC_Tag):
-               if (width < 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG))
-                       return(0);
-               break;
-       case (MDOC_Column):
+       switch (n->data.list) {
+       case (LIST_tag):
+               if (width >= 0)
+                       break;
+               if (mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG))
+                       break;
+               return(0);
+       case (LIST_column):
                /* FALLTHROUGH */
-       case (MDOC_Diag):
+       case (LIST_diag):
                /* FALLTHROUGH */
-       case (MDOC_Ohang):
+       case (LIST_ohang):
                /* FALLTHROUGH */
-       case (MDOC_Inset):
+       case (LIST_inset):
                /* FALLTHROUGH */
-       case (MDOC_Item):
-               if (width >= 0 && ! mdoc_nmsg(mdoc, n, MANDOCERR_WIDTHARG))
-                       return(0);
-               break;
+       case (LIST_item):
+               if (width < 0)
+                       break;
+               if (mdoc_nmsg(mdoc, n, MANDOCERR_WIDTHARG))
+                       break;
+               return(0);
        default:
                break;
        }