source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: The `ig' now supports `ig end-macro'.
@ 2010-05-15 21:53 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2010-05-15 21:53 UTC (permalink / raw)
  To: source

Log Message:
-----------
The `ig' now supports `ig end-macro'.
Initial warning/error messages in place (still experimental).

Modified Files:
--------------
    mdocml:
        main.c
        mandoc.h
        roff.c

Revision Data
-------------
Index: mandoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lmandoc.h -Lmandoc.h -u -p -r1.1 -r1.2
--- mandoc.h
+++ mandoc.h
@@ -25,6 +25,9 @@ enum	mandocerr {
 	MANDOCERR_NOSCOPE, /* request scope close w/none open */
 #define	MANDOCERR_WARNING	MANDOCERR_SCOPEEXIT
 
+	MANDOCERR_ARGSLOST, /* line arguments will be lost */
+#define	MANDOCERR_ERROR		MANDOCERR_ARGSLOST
+
 	MANDOCERR_MEM, /* memory exhausted */
 #define	MANDOCERR_FATAL		MANDOCERR_MEM
 
Index: roff.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -Lroff.c -Lroff.c -u -p -r1.70 -r1.71
--- roff.c
+++ roff.c
@@ -44,6 +44,7 @@ struct	roff {
 struct	roffnode {
 	enum rofft	 tok; /* type of node */
 	struct roffnode	*parent; /* up one in stack */
+	char		*end; /* custom end-token */
 	int		 line; /* parse line */
 	int		 col; /* parse col */
 };
@@ -267,21 +268,52 @@ roff_ignore(ROFF_ARGS)
 static enum rofferr
 roff_sub_ig(ROFF_ARGS)
 {
-	enum rofft	 t;
-	int		 pos;
+	int		 i, j;
 
 	/* Ignore free-text lines. */
 
 	if ('.' != (*bufp)[ppos])
 		return(ROFF_IGN);
 
-	/* Ignore macros unless it's a closing macro. */
-
-	t = roff_parse(*bufp, &pos);
-	if (ROFF_close != t)
+	if (r->last->end) {
+		/*
+		 * Allow a macro to break us, if we've defined a special
+		 * one for the case.  Old groff didn't allow spaces to
+		 * buffer the macro, but new groff does.  Whee!
+		 */
+		i = ppos + 1;
+		while ((*bufp)[i] && ' ' == (*bufp)[i])
+			i++;
+
+		if ('\0' == (*bufp)[i])
+			return(ROFF_IGN);
+
+		for (j = 0; r->last->end[j]; i++, j++)
+			if ((*bufp)[i] != r->last->end[j])
+				return(ROFF_IGN);
+
+		if (r->last->end[j])
+			return(ROFF_IGN);
+		if ((*bufp)[i] && ' ' != (*bufp)[i])
+			return(ROFF_IGN);
+
+		while (' ' == (*bufp)[i])
+			i++;
+	} else if (ROFF_close != roff_parse(*bufp, &i))
 		return(ROFF_IGN);
 
+	/*
+	 * Pop off the ignoring context and warn if we're going to lose
+	 * any of our remaining arguments.
+	 */
+
 	roffnode_pop(r);
+
+	if ('\0' == (*bufp)[i])
+		return(ROFF_IGN);
+	if ( ! (*r->msg)(MANDOCERR_ARGSLOST, r->data, ln, i, NULL))
+		return(ROFF_ERR);
+
 	return(ROFF_IGN);
 }
 
@@ -303,9 +335,42 @@ roff_new_close(ROFF_ARGS)
 static enum rofferr
 roff_new_ig(ROFF_ARGS)
 {
+	int		 i;
 
-	return(roffnode_push(r, ROFF_ig, ln, ppos) ? 
-			ROFF_IGN : ROFF_ERR);
+	if ( ! roffnode_push(r, ROFF_ig, ln, ppos))
+		return(ROFF_ERR);
+
+	i = (int)ppos;
+	while ((*bufp)[i] && ' ' != (*bufp)[i])
+		i++;
+
+	if (i == (int)ppos)
+		return(ROFF_IGN);
+	if ((*bufp)[i])
+		if ( ! (*r->msg)(MANDOCERR_ARGSLOST, r->data, ln, i, NULL))
+			return(ROFF_ERR);
+
+	/*
+	 * If `.ig' has arguments, the first argument (up to the next
+	 * whitespace) is interpreted as an argument marking the macro
+	 * close.  Thus, `.ig foo' will close at `.foo'.
+	 *
+	 * NOTE: the closing macro `.foo' in the above case is not
+	 * allowed to have leading spaces with old groff!  Thus `.foo'
+	 * != `. foo'.  Oh yeah, everything after the `.foo' is lost.
+	 * Merry fucking Christmas.
+	 */
+
+	r->last->end = malloc((size_t)i - ppos + 1);
+	if (NULL == r->last->end) {
+		(*r->msg)(MANDOCERR_MEM, r->data, ln, ppos, NULL);
+		return(ROFF_ERR);
+	}
+
+	memcpy(r->last->end, &(*bufp)[ppos], (size_t)i - ppos);
+	r->last->end[(size_t)i - ppos] = '\0';
+
+	return(ROFF_IGN);
 }
 
 
Index: main.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/main.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -Lmain.c -Lmain.c -u -p -r1.72 -r1.73
--- main.c
+++ main.c
@@ -773,6 +773,14 @@ mwarn(void *arg, int line, int col, cons
 	return(1);
 }
 
+static	const char * const	mandocerrs[MANDOCERR_MAX] = {
+	"ok",
+	"multi-line scope open on exit",
+	"request for scope closure when no matching scope is open",
+	"line arguments will be lost",
+	"memory exhausted"
+};
+
 /*
  * XXX: this is experimental code that will eventually become the
  * generic means of covering all warnings and errors!
@@ -785,7 +793,12 @@ mmsg(enum mandocerr t, void *arg, int ln
 
 	cp = (struct curparse *)arg;
 
-	/*fprintf(stderr, "%s:%d:%d: %s\n", cp->file, ln, col + 1, msg);*/
+	fprintf(stderr, "%s:%d:%d: %s", cp->file, 
+			ln, col + 1, mandocerrs[t]);
+
+	if (msg)
+		fprintf(stderr, ": %s", msg);
 
+	fputc('\n', stderr);
 	return(1);
 }
--
 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-05-15 21:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-15 21:53 mdocml: The `ig' now supports `ig end-macro' 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).