shithub: neatroff

Download patch

ref: b16fdb9ada11864270b266c4792710707741adea
parent: e61f5bacd5e58f10b6d597466937d92b09c18ed8
author: Ali Gholami Rudi <ali@rudi.ir>
date: Fri Jul 4 08:00:26 EDT 2014

ren: do not output completed lines unnecessarily in render_rec()

When formatting whole paragraphs, render_rec() should not fetch and
output completed lines from fmt.c, unless when asked explicitly.  This
is important especially when executing traps triggered in the middle
of a partial line.  Reported by peters@schwertfisch.de.

--- a/in.c
+++ b/in.c
@@ -14,7 +14,6 @@
 	int pos;
 	int len;
 	int lnum;		/* file line number */
-	int nl;			/* read \n, if the previous char was not */
 	struct inbuf *prev;
 };
 
@@ -45,12 +44,6 @@
 	buf->args = args ? args_init(args) : NULL;
 }
 
-void in_pushnl(char *s, char **args)
-{
-	in_push(s, args);
-	buf->nl = 1;
-}
-
 void in_so(char *path)
 {
 	FILE *fin = path && path[0] ? fopen(path, "r") : stdin;
@@ -119,8 +112,6 @@
 	while (buf || !in_nextfile()) {
 		if (buf->un)
 			return buf->unbuf[--buf->un];
-		if (buf->nl-- > 0 && in_last[0] != '\n')
-			return '\n';
 		if (buf->buf && buf->pos < buf->len)
 			break;
 		if (!buf->buf && (c = getc(buf->fin)) >= 0) {
--- a/ren.c
+++ b/ren.c
@@ -171,8 +171,10 @@
 	int partial = ren_partial;
 	if (str_get(reg)) {
 		sprintf(cmd, "%c%s %d\n", c_cc, TR_POPREN, ren_level);
-		in_pushnl(cmd, NULL);
-		in_pushnl(str_get(reg), NULL);
+		in_push(cmd, NULL);
+		in_push(str_get(reg), NULL);
+		if (partial)
+			in_push("\n", NULL);
 		render_rec(++ren_level);
 		/* executed the trap while in the middle of an input line */
 		if (partial)
@@ -929,6 +931,8 @@
 	ren_level = args[1] ? atoi(args[1]) : 0;
 }
 
+#define FMT_PAR()	(n_u && !n_na && !n_ce && (n_j & AD_P) == AD_P)
+
 /* read characters from tr.c and pass the rendered lines to out.c */
 static int render_rec(int level)
 {
@@ -966,15 +970,14 @@
 				if (c == '\n')
 					while (fmt_newline(cfmt))
 						ren_fmtpop(cfmt);
-				if (!(n_j & AD_P))
+				if (!FMT_PAR())
 					ren_fmtpopall(cfmt);
-				ren_fmtpop(cfmt);
 				if (c == ' ')
 					fmt_space(cfmt);
 			}
 		}
 		/* flush the line if necessary */
-		if (c == ' ' || c == '\n' || c < 0)
+		if ((!FMT_PAR() && (c == ' ' || c == '\n')) || c < 0)
 			ren_fmtpop(cfmt);
 		if (c == '\n' || ren_nl)	/* end or start of input line */
 			n_lb = f_hpos();
--- a/roff.h
+++ b/roff.h
@@ -218,7 +218,6 @@
 int tr_next(void);		/* troff layer */
 
 void in_push(char *s, char **args);
-void in_pushnl(char *s, char **args);
 void in_so(char *path);		/* .so request */
 void in_nx(char *path);		/* .nx request */
 void in_ex(void);		/* .ex request */