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 */