Improve handling of next-line scope broken by end of file.
authorschwarze <schwarze@openbsd.org>
Fri, 8 Aug 2014 15:35:31 +0000 (15:35 +0000)
committerschwarze <schwarze@openbsd.org>
Fri, 8 Aug 2014 15:35:31 +0000 (15:35 +0000)
Detect the condition earlier, report in the error message
which block is broken, and delete the broken block.
Consequently, empty section headers can no longer happen.

usr.bin/mandoc/man_macro.c
usr.bin/mandoc/man_validate.c

index a183bc4..737aa0d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_macro.c,v 1.49 2014/08/08 15:32:17 schwarze Exp $ */
+/*     $Id: man_macro.c,v 1.50 2014/08/08 15:35:31 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
@@ -100,13 +100,35 @@ man_unscope(struct man *man, const struct man_node *to)
        to = to->parent;
        n = man->last;
        while (n != to) {
-               if (NULL == to &&
-                   MAN_BLOCK == n->type &&
-                   0 == (MAN_VALID & n->flags) &&
-                   MAN_EXPLICIT & man_macros[n->tok].flags)
-                       mandoc_msg(MANDOCERR_BLK_NOEND,
-                           man->parse, n->line, n->pos,
-                           man_macronames[n->tok]);
+
+               /* Reached the end of the document? */
+
+               if (to == NULL && ! (n->flags & MAN_VALID)) {
+                       if (man->flags & (MAN_BLINE | MAN_ELINE) &&
+                           man_macros[n->tok].flags & MAN_SCOPED) {
+                               mandoc_vmsg(MANDOCERR_BLK_LINE,
+                                   man->parse, n->line, n->pos,
+                                   "EOF breaks %s",
+                                   man_macronames[n->tok]);
+                               if (man->flags & MAN_ELINE)
+                                       man->flags &= ~MAN_ELINE;
+                               else {
+                                       assert(n->type == MAN_HEAD);
+                                       n = n->parent;
+                                       man->flags &= ~MAN_BLINE;
+                               }
+                               man->last = n;
+                               n = n->parent;
+                               man_node_delete(man, man->last);
+                               continue;
+                       }
+                       if (n->type == MAN_BLOCK &&
+                           man_macros[n->tok].flags & MAN_EXPLICIT)
+                               mandoc_msg(MANDOCERR_BLK_NOEND,
+                                   man->parse, n->line, n->pos,
+                                   man_macronames[n->tok]);
+               }
+
                /*
                 * We might delete the man->last node
                 * in the post-validation phase.
index b8fc608..3e5d4d1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_validate.c,v 1.72 2014/07/07 21:35:42 schwarze Exp $ */
+/*     $Id: man_validate.c,v 1.73 2014/08/08 15:35:31 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -58,7 +58,6 @@ static        int       post_vs(CHKARGS);
 static int       post_fi(CHKARGS);
 static int       post_ft(CHKARGS);
 static int       post_nf(CHKARGS);
-static int       post_sec(CHKARGS);
 static int       post_TH(CHKARGS);
 static int       post_UC(CHKARGS);
 static int       pre_sec(CHKARGS);
@@ -74,7 +73,6 @@ static        v_check   posts_le1[] = { check_le1, NULL };
 static v_check   posts_nf[] = { check_eq0, post_nf, NULL };
 static v_check   posts_par[] = { check_par, NULL };
 static v_check   posts_part[] = { check_part, NULL };
-static v_check   posts_sec[] = { post_sec, NULL };
 static v_check   posts_sp[] = { post_vs, check_le1, NULL };
 static v_check   posts_th[] = { check_ge2, check_le5, post_TH, NULL };
 static v_check   posts_uc[] = { post_UC, NULL };
@@ -84,8 +82,8 @@ static        v_check   pres_sec[] = { pre_sec, NULL };
 static const struct man_valid man_valids[MAN_MAX] = {
        { NULL, posts_br }, /* br */
        { NULL, posts_th }, /* TH */
-       { pres_sec, posts_sec }, /* SH */
-       { pres_sec, posts_sec }, /* SS */
+       { pres_sec, NULL }, /* SH */
+       { pres_sec, NULL }, /* SS */
        { NULL, NULL }, /* TP */
        { NULL, posts_par }, /* LP */
        { NULL, posts_par }, /* PP */
@@ -186,12 +184,7 @@ static int
 check_root(CHKARGS)
 {
 
-       if ((MAN_BLINE | MAN_ELINE) & man->flags)
-               mandoc_msg(MANDOCERR_BLK_LINE, man->parse,
-                   0, 0, "at end of file");
-
-       man->flags &= ~MAN_BLINE;
-       man->flags &= ~MAN_ELINE;
+       assert((man->flags & (MAN_BLINE | MAN_ELINE)) == 0);
 
        if (NULL == man->first->child)
                man_nmsg(man, n, MANDOCERR_DOC_EMPTY);
@@ -320,17 +313,6 @@ pre_sec(CHKARGS)
        return(1);
 }
 
-static int
-post_sec(CHKARGS)
-{
-
-       if ( ! (MAN_HEAD == n->type && 0 == n->nchild))
-               return(1);
-
-       man_nmsg(man, n, MANDOCERR_SYNTARGCOUNT);
-       return(0);
-}
-
 static int
 check_part(CHKARGS)
 {