source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Cache all of `Bd's resolved arguments into mdoc_bd, which is
@ 2010-06-12 11:21 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2010-06-12 11:21 UTC (permalink / raw)
  To: source

Log Message:
-----------
Cache all of `Bd's resolved arguments into mdoc_bd, which is stashed in
the "data" union in mdoc_node.  Allows me to remove some ugly loops in
the front-end and duplicate tests in mdoc_action.c.  Add a regression
test to make sure we're not doing anything bad (more to come).

Modified Files:
--------------
    mdocml:
        mdoc.h
        mdoc_action.c
        mdoc_html.c
        mdoc_term.c
        mdoc_validate.c

Added Files:
-----------
    mdocml/regress/mdoc/Bd:
        bd0.in

Revision Data
-------------
Index: mdoc_validate.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_validate.c,v
retrieving revision 1.93
retrieving revision 1.94
diff -Lmdoc_validate.c -Lmdoc_validate.c -u -p -r1.93 -r1.94
--- mdoc_validate.c
+++ mdoc_validate.c
@@ -683,23 +683,28 @@ pre_bl(PRE_ARGS)
 static int
 pre_bd(PRE_ARGS)
 {
-	int		 i;
+	int		 i, dup, comp;
 	enum mdoc_disp 	 dt;
+	const char	*offs;
 
 	if (MDOC_BLOCK != n->type) {
 		assert(n->parent);
 		assert(MDOC_BLOCK == n->parent->type);
 		assert(MDOC_Bd == n->parent->tok);
-		assert(DISP__NONE != n->parent->data.disp);
-		n->data.disp = n->parent->data.disp;
+		assert(DISP__NONE != n->parent->data.Bd.type);
+		memcpy(&n->data.Bd, &n->parent->data.Bd, 
+				sizeof(struct mdoc_bd));
 		return(1);
 	}
 
-	assert(DISP__NONE == n->data.disp);
+	assert(DISP__NONE == n->data.Bd.type);
 
 	/* LINTED */
 	for (i = 0; n->args && i < (int)n->args->argc; i++) {
 		dt = DISP__NONE;
+		dup = comp = 0;
+		offs = NULL;
+
 		switch (n->args->argv[i].arg) {
 		case (MDOC_Centred):
 			dt = DISP_centred;
@@ -720,25 +725,67 @@ pre_bd(PRE_ARGS)
 			mdoc_nmsg(mdoc, n, MANDOCERR_BADDISP);
 			return(0);
 		case (MDOC_Offset):
-			/* FALLTHROUGH */
+			/* NB: this can be empty! */
+			if (n->args->argv[i].sz) {
+				offs = n->args->argv[i].value[0];
+				dup = (NULL != n->data.Bd.offs);
+				break;
+			}
+			/*
+			 * If empty, assign it to a sane default, which
+			 * groff stipulates is about 8n.
+			 */
+			/*
+			 * FIXME: remove this.
+			 *
+			 * Where the hell did I get the idea that this
+			 * happens?
+			 */
+			assert(1 == n->args->refcnt);
+			n->args->argv[i].sz++;
+			n->args->argv[i].value = 
+				mandoc_malloc(sizeof(char *));
+			n->args->argv[i].value[0] = 
+				mandoc_strdup("8n");
+			offs = n->args->argv[i].value[0];
+			break;
 		case (MDOC_Compact):
-			/* FALLTHROUGH */
-		default:
+			comp = 1;
+			dup = n->data.Bd.comp;
 			break;
+		default:
+			abort();
+			/* NOTREACHED */
 		}
 
-		if (DISP__NONE != dt && n->data.disp != DISP__NONE)
+		/* Check whether we have duplicates. */
+
+		if (dup && ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGVREP))
+			return(0);
+
+		/* Make our auxiliary assignments. */
+
+		if (offs && ! dup)
+			n->data.Bd.offs = offs;
+		if (comp && ! dup)
+			n->data.Bd.comp = comp;
+
+		/* Check whether a type has already been assigned. */
+
+		if (DISP__NONE != dt && n->data.Bd.type != DISP__NONE)
 			if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPREP))
 				return(0);
 
-		if (DISP__NONE != dt && n->data.disp == DISP__NONE)
-			n->data.disp = dt;
+		/* Make our type assignment. */
+
+		if (DISP__NONE != dt && n->data.Bd.type == DISP__NONE)
+			n->data.Bd.type = dt;
 	}
 
-	if (DISP__NONE == n->data.disp) {
+	if (DISP__NONE == n->data.Bd.type) {
 		if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE))
 			return(0);
-		n->data.disp = DISP_ragged;
+		n->data.Bd.type = DISP_ragged;
 	}
 
 	return(1);
Index: mdoc_html.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_html.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -Lmdoc_html.c -Lmdoc_html.c -u -p -r1.79 -r1.80
--- mdoc_html.c
+++ mdoc_html.c
@@ -1353,31 +1353,19 @@ static int
 mdoc_bd_pre(MDOC_ARGS)
 {
 	struct htmlpair	 	 tag[2];
-	int		 	 comp, i;
-	const struct mdoc_node	*bl, *nn;
+	int		 	 comp;
+	const struct mdoc_node	*nn;
 	struct roffsu		 su;
 
-	if (MDOC_BLOCK == n->type)
-		bl = n;
-	else if (MDOC_HEAD == n->type)
+	if (MDOC_HEAD == n->type)
 		return(0);
-	else
-		bl = n->parent;
 
 	SCALE_VS_INIT(&su, 0);
 
-	comp = 0;
-	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);
-			break;
-		case (MDOC_Compact):
-			comp = 1;
-			break;
-		default:
-			break;
-		}
+	if (n->data.Bd.offs)
+		a2offs(n->data.Bd.offs, &su);
+
+	comp = n->data.Bd.comp;
 
 	/* FIXME: -centered, etc. formatting. */
 	/* FIXME: does not respect -offset ??? */
@@ -1404,8 +1392,8 @@ mdoc_bd_pre(MDOC_ARGS)
 		return(1);
 	}
 
-	if (DISP_unfilled != n->data.disp && 
-			DISP_literal != n->data.disp)
+	if (DISP_unfilled != n->data.Bd.type && 
+			DISP_literal != n->data.Bd.type)
 		return(1);
 
 	PAIR_CLASS_INIT(&tag[0], "lit");
Index: mdoc_action.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_action.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -Lmdoc_action.c -Lmdoc_action.c -u -p -r1.66 -r1.67
--- mdoc_action.c
+++ mdoc_action.c
@@ -979,14 +979,12 @@ static int
 pre_bd(PRE_ARGS)
 {
 
-	if (MDOC_BLOCK == n->type)
-		return(pre_offset(m, n));
 	if (MDOC_BODY != n->type)
 		return(1);
 
-	if (DISP_literal == n->data.disp)
+	if (DISP_literal == n->data.Bd.type)
 		m->flags |= MDOC_LITERAL;
-	if (DISP_unfilled == n->data.disp)
+	if (DISP_unfilled == n->data.Bd.type)
 		m->flags |= MDOC_LITERAL;
 
 	return(1);
Index: mdoc_term.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_term.c,v
retrieving revision 1.147
retrieving revision 1.148
diff -Lmdoc_term.c -Lmdoc_term.c -u -p -r1.147 -r1.148
--- mdoc_term.c
+++ mdoc_term.c
@@ -54,7 +54,7 @@ struct	termact {
 
 static	size_t	  a2width(const struct mdoc_argv *, int);
 static	size_t	  a2height(const struct mdoc_node *);
-static	size_t	  a2offs(const struct mdoc_argv *);
+static	size_t	  a2offs(const char *);
 
 static	int	  arg_hasattr(int, const struct mdoc_node *);
 static	int	  arg_getattrs(const int *, int *, size_t,
@@ -489,20 +489,20 @@ a2width(const struct mdoc_argv *arg, int
 
 
 static size_t
-a2offs(const struct mdoc_argv *arg)
+a2offs(const char *v)
 {
 	struct roffsu	 su;
 
-	if ('\0' == arg->value[0][0])
+	if ('\0' == *v)
 		return(0);
-	else if (0 == strcmp(arg->value[0], "left"))
+	else if (0 == strcmp(v, "left"))
 		return(0);
-	else if (0 == strcmp(arg->value[0], "indent"))
+	else if (0 == strcmp(v, "indent"))
 		return(INDENT + 1);
-	else if (0 == strcmp(arg->value[0], "indent-two"))
+	else if (0 == strcmp(v, "indent-two"))
 		return((INDENT + 1) * 2);
-	else if ( ! a2roffsu(arg->value[0], &su, SCALE_MAX))
-		SCALE_HS_INIT(&su, strlen(arg->value[0]));
+	else if ( ! a2roffsu(v, &su, SCALE_MAX))
+		SCALE_HS_INIT(&su, strlen(v));
 
 	return(term_hspan(&su));
 }
@@ -672,7 +672,7 @@ termp_it_pre(DECL_ARGS)
 	width = offset = 0;
 
 	if (vals[1] >= 0) 
-		offset = a2offs(&bl->args->argv[vals[1]]);
+		offset = a2offs(bl->args->argv[vals[1]].value[0]);
 
 	switch (type) {
 	case (LIST_column):
@@ -1602,7 +1602,6 @@ static int
 termp_bd_pre(DECL_ARGS)
 {
 	size_t			 tabwidth;
-	int	         	 i;
 	size_t			 rm, rmax;
 	const struct mdoc_node	*nn;
 
@@ -1612,10 +1611,8 @@ termp_bd_pre(DECL_ARGS)
 	} else if (MDOC_HEAD == n->type)
 		return(0);
 
-	nn = n->parent;
-
-	if (-1 != (i = arg_getattr(MDOC_Offset, nn)))
-		p->offset += a2offs(&nn->args->argv[i]);
+	if (n->data.Bd.offs)
+		p->offset += a2offs(n->data.Bd.offs);
 
 	/*
 	 * If -ragged or -filled are specified, the block does nothing
@@ -1625,8 +1622,8 @@ termp_bd_pre(DECL_ARGS)
 	 * lines are allowed.
 	 */
 	
-	if (DISP_literal != n->data.disp && 
-			DISP_unfilled != n->data.disp)
+	if (DISP_literal != n->data.Bd.type && 
+			DISP_unfilled != n->data.Bd.type)
 		return(1);
 
 	tabwidth = p->tabwidth;
@@ -1663,8 +1660,8 @@ termp_bd_post(DECL_ARGS)
 	rm = p->rmargin;
 	rmax = p->maxrmargin;
 
-	if (DISP_literal == n->data.disp || 
-			DISP_unfilled == n->data.disp)
+	if (DISP_literal == n->data.Bd.type || 
+			DISP_unfilled == n->data.Bd.type)
 		p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
 
 	p->flags |= TERMP_NOSPACE;
Index: mdoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc.h,v
retrieving revision 1.84
retrieving revision 1.85
diff -Lmdoc.h -Lmdoc.h -u -p -r1.84 -r1.85
--- mdoc.h
+++ mdoc.h
@@ -272,6 +272,12 @@ enum	mdoc_disp {
 	DISP_literal
 };
 
+struct	mdoc_bd {
+	const char	 *offs;
+	enum mdoc_disp	  type;
+	int		  comp;
+};
+
 /* Node in AST. */
 struct	mdoc_node {
 	struct mdoc_node *parent; /* parent AST node */
@@ -300,7 +306,7 @@ struct	mdoc_node {
 
 	union {
 		enum mdoc_list list; /* `Bl' nodes */
-		enum mdoc_disp disp; /* `Bd' nodes */
+		struct mdoc_bd Bd;
 	} data;
 };
 
--- /dev/null
+++ regress/mdoc/Bd/bd0.in
@@ -0,0 +1,28 @@
+.Dd $Mdocdate: June 12 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+1
+.Em who are you?
+.Bd -ragged
+a b
+c d
+.Ed
+2
+.Bd -unfilled
+a b
+c d
+.Ed
+3
+.Bd -filled
+a b
+c d
+.Ed
+4
+.Bd -literal
+a b
+c d
+.Ed
--
 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:[~2010-06-12 11:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-12 11:21 mdocml: Cache all of `Bd's resolved arguments into mdoc_bd, which is kristaps

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).