source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Get rid of all calls to rew_sub() in blk_exp_close(); only ten
@ 2015-02-02  4:27 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2015-02-02  4:27 UTC (permalink / raw)
  To: source

Log Message:
-----------
Get rid of all calls to rew_sub() in blk_exp_close(); only ten calls
remain in other functions.  As a bonus, this fixes an assertion failure
jsg@ found some time ago with afl (test case 982) and improves minor
details in error reporting.

Modified Files:
--------------
    mdocml:
        libmdoc.h
        mdoc.c
        mdoc_macro.c

Revision Data
-------------
Index: mdoc_macro.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/mdoc_macro.c,v
retrieving revision 1.165
retrieving revision 1.166
diff -Lmdoc_macro.c -Lmdoc_macro.c -u -p -r1.165 -r1.166
--- mdoc_macro.c
+++ mdoc_macro.c
@@ -65,6 +65,7 @@ static	enum rew	rew_dohalt(enum mdoct, e
 				const struct mdoc_node *);
 static	void		rew_elem(struct mdoc *, enum mdoct);
 static	void		rew_last(struct mdoc *, const struct mdoc_node *);
+static	void		rew_pending(struct mdoc *, const struct mdoc_node *);
 static	void		rew_sub(enum mdoc_type, struct mdoc *,
 				enum mdoct, int, int);
 
@@ -263,6 +264,9 @@ lookup(struct mdoc *mdoc, enum mdoct fro
 	return(MDOC_MAX);
 }
 
+/*
+ * Rewind up to and including a specific node.
+ */
 static void
 rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
 {
@@ -271,6 +275,9 @@ rew_last(struct mdoc *mdoc, const struct
 	assert(to);
 	mdoc->next = MDOC_NEXT_SIBLING;
 	while (mdoc->last != to) {
+		if ( ! (mdoc->last->flags & MDOC_VALID))
+			mdoc->last->lastline = to->lastline -
+			    (mdoc->flags & MDOC_NEWLINE ? 1 : 0);
 		/*
 		 * Save the parent here, because we may delete the
 		 * mdoc->last node in the post-validation phase and reset
@@ -288,6 +295,25 @@ rew_last(struct mdoc *mdoc, const struct
 }
 
 /*
+ * Rewind up to a specific block, including all blocks that broke it.
+ */
+static void
+rew_pending(struct mdoc *mdoc, const struct mdoc_node *n)
+{
+
+	rew_last(mdoc, n);
+
+	if (n->type != MDOC_BLOCK)
+		return;
+
+	while ((n = n->pending) != NULL) {
+		rew_last(mdoc, n);
+		if (n->type == MDOC_HEAD)
+			mdoc_body_alloc(mdoc, n->line, n->pos, n->tok);
+	}
+}
+
+/*
  * For a block closing macro, return the corresponding opening one.
  * Otherwise, return the macro itself.
  */
@@ -533,6 +559,8 @@ make_pending(struct mdoc_node *broken, e
 		 */
 		broken->pending = breaker;
 		breaker->flags |= MDOC_BREAK;
+		if (breaker->body != NULL)
+			breaker->body->flags |= MDOC_BREAK;
 		mandoc_vmsg(MANDOCERR_BLK_NEST, mdoc->parse, line, ppos,
 		    "%s breaks %s", mdoc_macronames[tok],
 		    mdoc_macronames[broken->tok]);
@@ -592,17 +620,7 @@ rew_sub(enum mdoc_type t, struct mdoc *m
 		break;
 	}
 	assert(n);
-	rew_last(mdoc, n);
-
-	/*
-	 * The current block extends an enclosing block.
-	 * Now that the current block ends, close the enclosing block, too.
-	 */
-	while ((n = n->pending) != NULL) {
-		rew_last(mdoc, n);
-		if (n->type == MDOC_HEAD)
-			mdoc_body_alloc(mdoc, n->line, n->pos, n->tok);
-	}
+	rew_pending(mdoc, n);
 }
 
 /*
@@ -716,9 +734,9 @@ blk_exp_close(MACRO_PROT_ARGS)
 	struct mdoc_node *body;		/* Our own body. */
 	struct mdoc_node *endbody;	/* Our own end marker. */
 	struct mdoc_node *later;	/* A sub-block starting later. */
-	struct mdoc_node *n;		/* For searching backwards. */
+	struct mdoc_node *n;		/* Search back to our block. */
 
-	int		 flushed, have_it, j, lastarg, maxargs, nl;
+	int		 have_it, j, lastarg, maxargs, nl;
 	enum margserr	 ac;
 	enum mdoct	 atok, ntok;
 	char		*p;
@@ -752,8 +770,10 @@ blk_exp_close(MACRO_PROT_ARGS)
 		/* Remember the start of our own body. */
 
 		if (n->type == MDOC_BODY && atok == n->tok) {
-			if (n->end == ENDBODY_NOT)
+			if (n->end == ENDBODY_NOT) {
 				body = n;
+				n->lastline = line;
+			}
 			continue;
 		}
 
@@ -766,6 +786,7 @@ blk_exp_close(MACRO_PROT_ARGS)
 		}
 
 		if (atok == n->tok) {
+			n->lastline = line;
 			assert(body);
 
 			/*
@@ -791,20 +812,17 @@ blk_exp_close(MACRO_PROT_ARGS)
 			 * the scope - of the current block ends.
 			 */
 
-			mdoc_endbody_alloc(mdoc, line, ppos,
+			endbody = mdoc_endbody_alloc(mdoc, line, ppos,
 			    atok, body, ENDBODY_SPACE);
 
 			/*
 			 * If a block closing macro taking arguments
 			 * breaks another block, put the arguments
-			 * into the end marker and remeber the
-			 * end marker in order to close it out.
+			 * into the end marker.
 			 */
 
-			if (maxargs) {
-				endbody = mdoc->last;
+			if (maxargs)
 				mdoc->next = MDOC_NEXT_CHILD;
-			}
 			break;
 		}
 
@@ -818,7 +836,23 @@ blk_exp_close(MACRO_PROT_ARGS)
 		    ! (mdoc_macros[later->tok].flags & MDOC_EXPLICIT))
 			later = n;
 	}
-	rew_sub(MDOC_BODY, mdoc, tok, line, ppos);
+
+	if (body == NULL) {
+		mandoc_msg(MANDOCERR_BLK_NOTOPEN, mdoc->parse,
+		    line, ppos, mdoc_macronames[tok]);
+		if (maxargs && endbody == NULL) {
+			/*
+			 * Stray .Ec without previous .Eo:
+			 * Break the output line, keep the arguments.
+			 */
+			mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);
+			rew_elem(mdoc, MDOC_br);
+		}
+	} else if (endbody == NULL) {
+		rew_last(mdoc, body);
+		if (maxargs)
+			mdoc_tail_alloc(mdoc, line, ppos, atok);
+	}
 
 	if ( ! (mdoc_macros[tok].flags & MDOC_PARSED)) {
 		if (buf[*pos] != '\0')
@@ -830,28 +864,14 @@ blk_exp_close(MACRO_PROT_ARGS)
 		return;
 	}
 
-	if (maxargs && endbody == NULL) {
-		if (n == NULL) {
-			/*
-			 * Stray .Ec without previous .Eo:
-			 * Break the output line, ignore any arguments.
-			 */
-			mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);
-			rew_elem(mdoc, MDOC_br);
-		} else
-			mdoc_tail_alloc(mdoc, line, ppos, atok);
-	}
-
-	flushed = n == NULL;
+	if (endbody != NULL)
+		n = endbody;
 	for (j = 0; ; j++) {
 		lastarg = *pos;
 
-		if (j == maxargs && ! flushed) {
-			if (endbody == NULL)
-				rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos);
-			else
-				rew_last(mdoc, endbody);
-			flushed = 1;
+		if (j == maxargs && n != NULL) {
+			rew_pending(mdoc, n);
+			n = NULL;
 		}
 
 		ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
@@ -867,24 +887,17 @@ blk_exp_close(MACRO_PROT_ARGS)
 			continue;
 		}
 
-		if ( ! flushed) {
-			if (endbody == NULL)
-				rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos);
-			else
-				rew_last(mdoc, endbody);
-			flushed = 1;
+		if (n != NULL) {
+			rew_pending(mdoc, n);
+			n = NULL;
 		}
 		mdoc->flags &= ~MDOC_NEWLINE;
 		mdoc_macro(mdoc, ntok, line, lastarg, pos, buf);
 		break;
 	}
 
-	if ( ! flushed) {
-		if (endbody == NULL)
-			rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos);
-		else
-			rew_last(mdoc, endbody);
-	}
+	if (n != NULL)
+		rew_pending(mdoc, n);
 	if (nl)
 		append_delims(mdoc, line, pos, buf);
 }
@@ -1327,18 +1340,7 @@ blk_part_imp(MACRO_PROT_ARGS)
 	rew_last(mdoc, body);
 	if (nl)
 		append_delims(mdoc, line, pos, buf);
-	rew_last(mdoc, blk);
-
-	/*
-	 * The current block extends an enclosing block.
-	 * Now that the current block ends, close the enclosing block, too.
-	 */
-
-	while ((blk = blk->pending) != NULL) {
-		rew_last(mdoc, blk);
-		if (blk->type == MDOC_HEAD)
-			mdoc_body_alloc(mdoc, blk->line, blk->pos, blk->tok);
-	}
+	rew_pending(mdoc, blk);
 
 	/* Move trailing .Ns out of scope. */
 
Index: mdoc.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/mdoc.c,v
retrieving revision 1.234
retrieving revision 1.235
diff -Lmdoc.c -Lmdoc.c -u -p -r1.234 -r1.235
--- mdoc.c
+++ mdoc.c
@@ -414,7 +414,7 @@ mdoc_body_alloc(struct mdoc *mdoc, int l
 	return(p);
 }
 
-void
+struct mdoc_node *
 mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok,
 		struct mdoc_node *body, enum mdoc_endbody end)
 {
@@ -426,6 +426,7 @@ mdoc_endbody_alloc(struct mdoc *mdoc, in
 	p->end = end;
 	node_append(mdoc, p);
 	mdoc->next = MDOC_NEXT_SIBLING;
+	return(p);
 }
 
 struct mdoc_node *
Index: libmdoc.h
===================================================================
RCS file: /home/cvs/mdocml/mdocml/libmdoc.h,v
retrieving revision 1.96
retrieving revision 1.97
diff -Llibmdoc.h -Llibmdoc.h -u -p -r1.96 -r1.97
--- libmdoc.h
+++ libmdoc.h
@@ -106,7 +106,7 @@ struct mdoc_node *mdoc_block_alloc(struc
 struct mdoc_node *mdoc_head_alloc(struct mdoc *, int, int, enum mdoct);
 void		  mdoc_tail_alloc(struct mdoc *, int, int, enum mdoct);
 struct mdoc_node *mdoc_body_alloc(struct mdoc *, int, int, enum mdoct);
-void		  mdoc_endbody_alloc(struct mdoc *, int, int, enum mdoct,
+struct mdoc_node *mdoc_endbody_alloc(struct mdoc *, int, int, enum mdoct,
 			struct mdoc_node *, enum mdoc_endbody);
 void		  mdoc_node_delete(struct mdoc *, struct mdoc_node *);
 void		  mdoc_node_relink(struct mdoc *, struct mdoc_node *);
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-02-02  4:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-02  4:27 mdocml: Get rid of all calls to rew_sub() in blk_exp_close(); only ten schwarze

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).