source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Rudimentary implementation of the .it request (input line trap).
@ 2013-07-13 12:52 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2013-07-13 12:52 UTC (permalink / raw)
  To: source

Log Message:
-----------
Rudimentary implementation of the .it request (input line trap).
As with any low-level roff request involving subtle interactions
with macro internals, this implementation is not exact, but it
does handle the simplest cases.

This request occurs in man(7) code generated from DocBook,
for example mysql(1) and yasm_arch(7).
Thanks to brad@ for reporting the issue back in January 2011.

Modified Files:
--------------
    mdocml:
        TODO
        mandoc.h
        read.c
        roff.c

Revision Data
-------------
Index: TODO
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/TODO,v
retrieving revision 1.151
retrieving revision 1.152
diff -LTODO -LTODO -u -p -r1.151 -r1.152
--- TODO
+++ TODO
@@ -37,10 +37,6 @@ None known right now.
 - .fc (field control)
   found by naddy@ in xloadimage(1)
   
-- .it (line traps) occur in mysql(1), yasm_arch(7)
-  generated by DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
-  reported by brad@  Sat, 15 Jan 2011 15:48:18 -0500
-
 - .ns (no-space mode) occurs in xine-config(1)
   reported by brad@  Sat, 15 Jan 2011 15:45:23 -0500
 
Index: mandoc.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v
retrieving revision 1.107
retrieving revision 1.108
diff -Lmandoc.h -Lmandoc.h -u -p -r1.107 -r1.108
--- mandoc.h
+++ mandoc.h
@@ -1,7 +1,7 @@
 /*	$Id$ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -145,6 +145,7 @@ enum	mandocerr {
 	MANDOCERR_NOARGS, /* macro requires line argument(s) */
 	MANDOCERR_NOBODY, /* macro requires body argument(s) */
 	MANDOCERR_NOARGV, /* macro requires argument(s) */
+	MANDOCERR_NUMERIC, /* request requires a numeric argument */
 	MANDOCERR_LISTTYPE, /* missing list type */
 	MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
 	MANDOCERR_BODYLOST, /* body argument(s) will be lost */
Index: roff.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v
retrieving revision 1.177
retrieving revision 1.178
diff -Lroff.c -Lroff.c -u -p -r1.177 -r1.178
--- roff.c
+++ roff.c
@@ -21,6 +21,7 @@
 
 #include <assert.h>
 #include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -186,12 +187,13 @@ static	void		 roff_freestr(struct roffkv
 static	char		*roff_getname(struct roff *, char **, int, int);
 static	const char	*roff_getstrn(const struct roff *, 
 				const char *, size_t);
+static	enum rofferr	 roff_it(ROFF_ARGS);
 static	enum rofferr	 roff_line_ignore(ROFF_ARGS);
 static	enum rofferr	 roff_nr(ROFF_ARGS);
 static	void		 roff_openeqn(struct roff *, const char *,
 				int, int, const char *);
 static	enum rofft	 roff_parse(struct roff *, const char *, int *);
-static	enum rofferr	 roff_parsetext(char *);
+static	enum rofferr	 roff_parsetext(char **, size_t *, int, int *);
 static	enum rofferr	 roff_res(struct roff *, 
 				char **, size_t *, int, int);
 static	enum rofferr	 roff_rm(ROFF_ARGS);
@@ -233,7 +235,7 @@ static	struct roffmac	 roffs[ROFF_MAX] =
 	{ "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
 	{ "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
 	{ "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL },
-	{ "it", roff_line_ignore, NULL, NULL, 0, NULL },
+	{ "it", roff_it, NULL, NULL, 0, NULL },
 	{ "ne", roff_line_ignore, NULL, NULL, 0, NULL },
 	{ "nh", roff_line_ignore, NULL, NULL, 0, NULL },
 	{ "nr", roff_nr, NULL, NULL, 0, NULL },
@@ -295,6 +297,9 @@ static	const struct predef predefs[PREDE
 /* See roffhash_find() */
 #define	ROFF_HASH(p)	(p[0] - ASCII_LO)
 
+static	int	 roffit_lines;  /* number of lines to delay */
+static	char	*roffit_macro;  /* nil-terminated macro line */
+
 static void
 roffhash_init(void)
 {
@@ -596,16 +601,20 @@ again:
 }
 
 /*
- * Process text streams: convert all breakable hyphens into ASCII_HYPH.
+ * Process text streams:
+ * Convert all breakable hyphens into ASCII_HYPH.
+ * Decrement and spring input line trap.
  */
 static enum rofferr
-roff_parsetext(char *p)
+roff_parsetext(char **bufp, size_t *szp, int pos, int *offs)
 {
 	size_t		 sz;
 	const char	*start;
+	char		*p;
+	int		 isz;
 	enum mandoc_esc	 esc;
 
-	start = p;
+	start = p = *bufp + pos;
 
 	while ('\0' != *p) {
 		sz = strcspn(p, "-\\");
@@ -633,6 +642,22 @@ roff_parsetext(char *p)
 		p++;
 	}
 
+	/* Spring the input line trap. */
+	if (1 == roffit_lines) {
+		isz = asprintf(&p, "%s\n.%s", *bufp, roffit_macro);
+		if (-1 == isz) {
+			perror(NULL);
+			exit((int)MANDOCLEVEL_SYSERR);
+		}
+		free(*bufp);
+		*bufp = p;
+		*szp = isz + 1;
+		*offs = 0;
+		free(roffit_macro);
+		roffit_lines = 0;
+		return(ROFF_REPARSE);
+	} else if (1 < roffit_lines)
+		--roffit_lines;
 	return(ROFF_CONT);
 }
 
@@ -677,13 +702,13 @@ roff_parseln(struct roff *r, int ln, cha
 			return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
 		if (r->tbl)
 			return(tbl_read(r->tbl, ln, *bufp, pos));
-		return(roff_parsetext(*bufp + pos));
+		return(roff_parsetext(bufp, szp, pos, offs));
 	} else if ( ! ctl) {
 		if (r->eqn)
 			return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
 		if (r->tbl)
 			return(tbl_read(r->tbl, ln, *bufp, pos));
-		return(roff_parsetext(*bufp + pos));
+		return(roff_parsetext(bufp, szp, pos, offs));
 	} else if (r->eqn)
 		return(eqn_read(&r->eqn, ln, *bufp, ppos, offs));
 
@@ -1120,9 +1145,6 @@ static enum rofferr
 roff_line_ignore(ROFF_ARGS)
 {
 
-	if (ROFF_it == tok)
-		mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos, "it");
-
 	return(ROFF_IGN);
 }
 
@@ -1292,6 +1314,31 @@ roff_rm(ROFF_ARGS)
 		if ('\0' != *name)
 			roff_setstr(r, name, NULL, 0);
 	}
+	return(ROFF_IGN);
+}
+
+/* ARGSUSED */
+static enum rofferr
+roff_it(ROFF_ARGS)
+{
+	char		*cp;
+	size_t		 len;
+	int		 iv;
+
+	/* Parse the number of lines. */
+	cp = *bufp + pos;
+	len = strcspn(cp, " \t");
+	cp[len] = '\0';
+	if ((iv = mandoc_strntoi(cp, len, 10)) <= 0) {
+		mandoc_msg(MANDOCERR_NUMERIC, r->parse,
+				ln, ppos, *bufp + 1);
+		return(ROFF_IGN);
+	}
+	cp += len + 1;
+
+	/* Arm the input line trap. */
+	roffit_lines = iv;
+	roffit_macro = mandoc_strdup(cp);
 	return(ROFF_IGN);
 }
 
Index: read.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/read.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -Lread.c -Lread.c -u -p -r1.37 -r1.38
--- read.c
+++ read.c
@@ -185,6 +185,7 @@ static	const char * const	mandocerrs[MAN
 	"macro requires line argument(s)",
 	"macro requires body argument(s)",
 	"macro requires argument(s)",
+	"request requires a numeric argument",
 	"missing list type",
 	"line argument(s) will be lost",
 	"body argument(s) will be lost",
--
 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:[~2013-07-13 12:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-13 12:52 mdocml: Rudimentary implementation of the .it request (input line trap) 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).