source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Finally delete the kitchensink functions rew_sub() and
@ 2015-02-03  1:14 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2015-02-03  1:14 UTC (permalink / raw)
  To: source

Log Message:
-----------
Finally delete the kitchensink functions rew_sub() and rew_dohalt().
They were a maintenance and auditing nightmare because if you changed
one bit in there, stuff tended to break at seemingly unrelated places.
No functional change except getting rid of one bogus error message,
but minus 80 lines of code.

Modified Files:
--------------
    mdocml:
        mdoc_macro.c

Revision Data
-------------
Index: mdoc_macro.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/mdoc_macro.c,v
retrieving revision 1.170
retrieving revision 1.171
diff -Lmdoc_macro.c -Lmdoc_macro.c -u -p -r1.170 -r1.171
--- mdoc_macro.c
+++ mdoc_macro.c
@@ -31,13 +31,6 @@
 #include "libmdoc.h"
 #include "libmandoc.h"
 
-enum	rew {	/* see rew_dohalt() */
-	REWIND_NONE,
-	REWIND_THIS,
-	REWIND_MORE,
-	REWIND_FORCE
-};
-
 static	void		blk_full(MACRO_PROT_ARGS);
 static	void		blk_exp_close(MACRO_PROT_ARGS);
 static	void		blk_part_exp(MACRO_PROT_ARGS);
@@ -59,13 +52,9 @@ static	void		make_pending(struct mdoc *,
 static	int		parse_rest(struct mdoc *, enum mdoct,
 				int, int *, char *);
 static	enum mdoct	rew_alt(enum mdoct);
-static	enum rew	rew_dohalt(enum mdoct, enum mdoc_type,
-				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);
 
 const	struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
 	{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ap */
@@ -357,95 +346,6 @@ rew_alt(enum mdoct tok)
 	/* NOTREACHED */
 }
 
-/*
- * Rewinding to tok, how do we have to handle *p?
- * REWIND_NONE: *p would delimit tok, but no tok scope is open
- *   inside *p, so there is no need to rewind anything at all.
- * REWIND_THIS: *p matches tok, so rewind *p and nothing else.
- * REWIND_MORE: *p is implicit, rewind it and keep searching for tok.
- * REWIND_FORCE: *p is explicit, but tok is full, force rewinding *p.
- */
-static enum rew
-rew_dohalt(enum mdoct tok, enum mdoc_type type,
-		const struct mdoc_node *p)
-{
-
-	/*
-	 * No matching token, no delimiting block, no broken block.
-	 * This can happen when full implicit macros are called for
-	 * the first time but try to rewind their previous
-	 * instance anyway.
-	 */
-	if (MDOC_ROOT == p->type)
-		return(REWIND_NONE);
-
-	/*
-	 * When starting to rewind, skip plain text
-	 * and nodes that have already been rewound.
-	 */
-	if (p->type == MDOC_TEXT || p->flags & (MDOC_VALID | MDOC_BREAK))
-		return(REWIND_MORE);
-
-	/*
-	 * The easiest case:  Found a matching token.
-	 * This applies to both blocks and elements.
-	 */
-	tok = rew_alt(tok);
-	if (tok == p->tok)
-		return(type == p->type ? REWIND_THIS : REWIND_MORE);
-
-	/*
-	 * While elements do require rewinding for themselves,
-	 * they never affect rewinding of other nodes.
-	 */
-	if (MDOC_ELEM == p->type)
-		return(REWIND_MORE);
-
-	/*
-	 * Blocks delimited by our target token get REWIND_MORE.
-	 * Blocks delimiting our target token get REWIND_NONE.
-	 */
-	switch (tok) {
-	case MDOC_It:
-		if (MDOC_BODY == p->type && MDOC_Bl == p->tok)
-			return(REWIND_NONE);
-		break;
-	case MDOC_Nm:
-		return(REWIND_NONE);
-	case MDOC_Nd:
-		/* FALLTHROUGH */
-	case MDOC_Ss:
-		if (MDOC_BODY == p->type && MDOC_Sh == p->tok)
-			return(REWIND_NONE);
-		/* FALLTHROUGH */
-	case MDOC_Sh:
-		if (MDOC_ROOT == p->parent->type)
-			return(REWIND_THIS);
-		if (MDOC_Nd == p->tok || MDOC_Ss == p->tok ||
-		    MDOC_Sh == p->tok)
-			return(REWIND_MORE);
-		break;
-	default:
-		break;
-	}
-
-	/*
-	 * Default block rewinding rules.
-	 * In particular, let all blocks rewind Nm children.
-	 * Do not warn again when closing a block,
-	 * since closing the body already warned.
-	 */
-	if (MDOC_Nm == p->tok ||
-	    MDOC_BLOCK == type || MDOC_BLOCK == p->type)
-		return(REWIND_MORE);
-
-	/*
-	 * By default, closing out full blocks
-	 * forces closing of broken explicit blocks.
-	 */
-	return (REWIND_FORCE);
-}
-
 static void
 rew_elem(struct mdoc *mdoc, enum mdoct tok)
 {
@@ -531,45 +431,6 @@ make_pending(struct mdoc *mdoc, struct m
 		breaker->body->flags |= MDOC_BREAK;
 }
 
-static void
-rew_sub(enum mdoc_type t, struct mdoc *mdoc,
-		enum mdoct tok, int line, int ppos)
-{
-	struct mdoc_node *n, *to;
-
-	to = NULL;
-	n = mdoc->last;
-	while (n) {
-		switch (rew_dohalt(tok, t, n)) {
-		case REWIND_NONE:
-			if (to == NULL)
-				return;
-			n = to;
-			break;
-		case REWIND_THIS:
-			n->lastline = line -
-			    (mdoc->flags & MDOC_NEWLINE &&
-			     ! (mdoc_macros[tok].flags & MDOC_EXPLICIT));
-			break;
-		case REWIND_FORCE:
-			mandoc_vmsg(MANDOCERR_BLK_BROKEN, mdoc->parse,
-			    line, ppos, "%s breaks %s",
-			    mdoc_macronames[tok],
-			    mdoc_macronames[n->tok]);
-			/* FALLTHROUGH */
-		case REWIND_MORE:
-			n->lastline = line -
-			    (mdoc->flags & MDOC_NEWLINE ? 1 : 0);
-			to = n;
-			n = n->parent;
-			continue;
-		}
-		break;
-	}
-	assert(n);
-	rew_pending(mdoc, n);
-}
-
 /*
  * Allocate a word and check whether it's punctuation or not.
  * Punctuation consists of those tokens found in mdoc_isdelim().
@@ -680,10 +541,11 @@ blk_exp_close(MACRO_PROT_ARGS)
 {
 	struct mdoc_node *body;		/* Our own body. */
 	struct mdoc_node *endbody;	/* Our own end marker. */
+	struct mdoc_node *itblk;	/* An It block starting later. */
 	struct mdoc_node *later;	/* A sub-block starting later. */
 	struct mdoc_node *n;		/* Search back to our block. */
 
-	int		 have_it, j, lastarg, maxargs, nl;
+	int		 j, lastarg, maxargs, nl;
 	enum margserr	 ac;
 	enum mdoct	 atok, ntok;
 	char		*p;
@@ -707,9 +569,8 @@ blk_exp_close(MACRO_PROT_ARGS)
 	 * both of our own and of pending sub-blocks.
 	 */
 
-	have_it = 0;
 	atok = rew_alt(tok);
-	body = endbody = later = NULL;
+	body = endbody = itblk = later = NULL;
 	for (n = mdoc->last; n; n = n->parent) {
 		if (n->flags & (MDOC_VALID | MDOC_BREAK))
 			continue;
@@ -728,7 +589,7 @@ blk_exp_close(MACRO_PROT_ARGS)
 			continue;
 
 		if (n->tok == MDOC_It) {
-			have_it = 1;
+			itblk = n;
 			continue;
 		}
 
@@ -743,7 +604,7 @@ blk_exp_close(MACRO_PROT_ARGS)
 			 */
 
 			if (later == NULL ||
-			    (tok == MDOC_El && !have_it))
+			    (tok == MDOC_El && itblk == NULL))
 				break;
 
 			/*
@@ -753,6 +614,8 @@ blk_exp_close(MACRO_PROT_ARGS)
 			 */
 
 			make_pending(mdoc, n, later, line, ppos);
+			if (tok == MDOC_El)
+				itblk->flags |= MDOC_BREAK;
 
 			/*
 			 * Mark the place where the formatting - but not
@@ -807,7 +670,7 @@ blk_exp_close(MACRO_PROT_ARGS)
 			    mdoc->parse, line, ppos,
 			    "%s %s", mdoc_macronames[tok],
 			    buf + *pos);
-		if (endbody == NULL)
+		if (endbody == NULL && n != NULL)
 			rew_pending(mdoc, n);
 		return;
 	}
@@ -1038,7 +901,7 @@ blk_full(MACRO_PROT_ARGS)
 {
 	int		  la, nl, parsed;
 	struct mdoc_arg	 *arg;
-	struct mdoc_node *blk; /* Our own block. */
+	struct mdoc_node *blk; /* Our own or a broken block. */
 	struct mdoc_node *head; /* Our own head. */
 	struct mdoc_node *body; /* Our own body. */
 	struct mdoc_node *n;
@@ -1047,27 +910,79 @@ blk_full(MACRO_PROT_ARGS)
 
 	nl = MDOC_NEWLINE & mdoc->flags;
 
-	/* Skip items outside lists. */
+	if ( ! (mdoc_macros[tok].flags & MDOC_EXPLICIT)) {
+
+		/* Here, tok is one of Sh Ss Nm Nd It. */
+
+		blk = NULL;
+		for (n = mdoc->last; n != NULL; n = n->parent) {
+			if (n->flags & (MDOC_VALID | MDOC_BREAK) ||
+			    n->type != MDOC_BLOCK)
+				continue;
+			if (tok == MDOC_It && n->tok == MDOC_Bl) {
+				if (blk != NULL) {
+					mandoc_vmsg(MANDOCERR_BLK_BROKEN,
+					    mdoc->parse, line, ppos,
+					    "It breaks %s",
+					    mdoc_macronames[blk->tok]);
+					rew_pending(mdoc, blk);
+				}
+				break;
+			}
+
+			if (mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
+				switch (tok) {
+				case MDOC_Sh:
+					/* FALLTHROUGH */
+				case MDOC_Ss:
+					mandoc_vmsg(MANDOCERR_BLK_BROKEN,
+					    mdoc->parse, line, ppos,
+					    "%s breaks %s",
+					    mdoc_macronames[tok],
+					    mdoc_macronames[n->tok]);
+					rew_pending(mdoc, n);
+					continue;
+				case MDOC_It:
+					/* Delay in case it's astray. */
+					blk = n;
+					continue;
+				default:
+					break;
+				}
+				break;
+			}
+
+			/* Here, n is one of Sh Ss Nm Nd It. */
 
-	if (tok == MDOC_It) {
-		for (n = mdoc->last; n; n = n->parent)
-			if (n->tok == MDOC_Bl && n->type == MDOC_BLOCK &&
-			    ! (n->flags & (MDOC_VALID | MDOC_BREAK)))
+			if (tok != MDOC_Sh && (n->tok == MDOC_Sh ||
+			    (tok != MDOC_Ss && (n->tok == MDOC_Ss ||
+			     (tok != MDOC_It && n->tok == MDOC_It)))))
 				break;
-		if (n == NULL) {
+
+			/* Item breaking an explicit block. */
+
+			if (blk != NULL) {
+				mandoc_vmsg(MANDOCERR_BLK_BROKEN,
+				    mdoc->parse, line, ppos,
+				    "It breaks %s",
+				    mdoc_macronames[blk->tok]);
+				rew_pending(mdoc, blk);
+			}
+
+			/* Close out prior implicit scopes. */
+
+			rew_last(mdoc, n);
+		}
+
+		/* Skip items outside lists. */
+
+		if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) {
 			mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,
 			    line, ppos, "It %s", buf + *pos);
 			mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);
 			rew_elem(mdoc, MDOC_br);
 			return;
 		}
-	}
-
-	/* Close out prior implicit scope. */
-
-	if ( ! (mdoc_macros[tok].flags & MDOC_EXPLICIT)) {
-		rew_sub(MDOC_BODY, mdoc, tok, line, ppos);
-		rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos);
 	}
 
 	/*
--
 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-03  1:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-03  1:14 mdocml: Finally delete the kitchensink functions rew_sub() and 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).