source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Consolidated list processing to a single loop in
@ 2010-06-03 13:44 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2010-06-03 13:44 UTC (permalink / raw)
  To: source

Log Message:
-----------
Consolidated list processing to a single loop in mdoc_validate.c.  This
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.

Modified Files:
--------------
    mdocml:
        libmdoc.h
        main.c
        mandoc.h
        mdoc_action.c
        mdoc_html.c
        mdoc_validate.c

Revision Data
-------------
Index: mdoc_validate.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_validate.c,v
retrieving revision 1.90
retrieving revision 1.91
diff -Lmdoc_validate.c -Lmdoc_validate.c -u -p -r1.90 -r1.91
--- mdoc_validate.c
+++ mdoc_validate.c
@@ -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;
+	int		 i, width, offs, cmpt, dupl;
+	enum mdoc_list	 lt;
 
-	if (MDOC_BLOCK != n->type)
+	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;
 	}
Index: mdoc_html.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_html.c,v
retrieving revision 1.71
retrieving revision 1.72
diff -Lmdoc_html.c -Lmdoc_html.c -u -p -r1.71 -r1.72
--- mdoc_html.c
+++ mdoc_html.c
@@ -832,7 +832,6 @@ mdoc_it_block_pre(MDOC_ARGS, enum mdoc_l
 	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: mdoc_action.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_action.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -Lmdoc_action.c -Lmdoc_action.c -u -p -r1.64 -r1.65
--- mdoc_action.c
+++ mdoc_action.c
@@ -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: libmdoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libmdoc.h,v
retrieving revision 1.51
retrieving revision 1.52
diff -Llibmdoc.h -Llibmdoc.h -u -p -r1.51 -r1.52
--- libmdoc.h
+++ libmdoc.h
@@ -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 *);
Index: mandoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -Lmandoc.h -Lmandoc.h -u -p -r1.9 -r1.10
--- mandoc.h
+++ mandoc.h
@@ -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
@@ -82,8 +83,6 @@ enum	mandocerr {
 	MANDOCERR_FONTTYPE, /* missing font type */
 	/* 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 */
Index: main.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -Lmain.c -Lmain.c -u -p -r1.81 -r1.82
--- main.c
+++ main.c
@@ -141,12 +141,12 @@ static	const char * const	mandocerrs[MAN
 	"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",
--
 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-03 13:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-03 13:44 mdocml: Consolidated list processing to a single loop in 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).