ref: 7a5b33eb77e544f5a6c814c40c9a8ae2787b5c96
parent: fc70233e629c5a83b20e72086e6c5e4d038982bd
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon May 6 18:06:22 EDT 2013
ren: prevent invalid line breaks after traps
--- a/adj.c
+++ b/adj.c
@@ -151,6 +151,14 @@
adj->gap = 0;
}
+/* ignore the previous newline */
+void adj_nonl(struct adj *adj)
+{
+ if (adj->nls)
+ adj->gap += adj->swid;
+ adj->nls = 0;
+}
+
static void adj_word(struct adj *adj, struct wb *wb)
{
struct word *cur = &adj->words[adj->nwords++];
--- a/ren.c
+++ b/ren.c
@@ -24,6 +24,7 @@
static struct wb ren_wb; /* the main ren.c word buffer */
static int ren_nl; /* just after newline */
+static int ren_cnl; /* current char is a newline */
static int ren_unbuf[8]; /* ren_back() buffer */
static int ren_un;
@@ -158,11 +159,17 @@
in_pushnl(str_get(reg), NULL);
}
+static int detect_traps(int beg, int end)
+{
+ int pos = trap_pos(beg);
+ return pos >= 0 && (cdiv || pos < n_p) && pos <= end;
+}
+
/* return 1 if executed a trap */
static int ren_traps(int beg, int end, int dosp)
{
int pos = trap_pos(beg);
- if (pos >= 0 && (cdiv || pos < n_p) && pos <= end) {
+ if (detect_traps(beg, end)) {
if (dosp && pos > beg)
ren_sp(pos - beg);
trap_exec(trap_reg(beg));
@@ -171,10 +178,15 @@
return 0;
}
+static int detect_pagelimit(int ne)
+{
+ return !cdiv && n_nl + ne >= n_p;
+}
+
/* start a new page if needed */
static int ren_pagelimit(int ne)
{
- if (n_nl + ne >= n_p && !cdiv) {
+ if (detect_pagelimit(ne)) {
bp_force = 0;
ren_page(bp_next);
return 1;
@@ -228,9 +240,10 @@
/* return 1 if triggered a trap */
static int ren_bradj(struct adj *adj, int fill, int ad)
{
+ char cmd[16];
struct sbuf sbuf;
int ll, li, lt, els_neg, els_pos;
- int w, prev_d;
+ int w, prev_d, lspc;
ren_first();
if (!adj_empty(adj, fill)) {
sbuf_init(&sbuf);
@@ -248,16 +261,17 @@
if (els_pos)
ren_sp(els_pos);
n_a = els_pos;
- if (!ren_traps(prev_d, n_d, 0)) {
- if (n_L > 1 && (cdiv || n_d < n_p)) {
- down(n_L * n_v - n_v);
- } else {
- if (ren_pagelimit(0))
- return 1;
- }
- return 0;
+ lspc = MAX(1, n_L) * n_v - n_v;
+ if (detect_traps(prev_d, n_d) || detect_pagelimit(lspc)) {
+ sprintf(cmd, "%c&", c_ec);
+ if (!ren_cnl) /* prevent unwanted newlines */
+ in_push(cmd, NULL);
+ if (!ren_traps(prev_d, n_d, 0))
+ ren_pagelimit(lspc);
+ return 1;
}
- return 1;
+ if (lspc)
+ down(lspc);
}
return 0;
}
@@ -742,6 +756,7 @@
ren_first(); /* transition to the first page */
c = ren_next();
while (c >= 0) {
+ ren_cnl = c == '\n';
if (c == ' ' || c == '\n') {
adj_swid(cadj, charwid(dev_spacewid(), n_s));
adj_wb(cadj, wb);
@@ -761,6 +776,8 @@
if (c != ' ') {
ren_back(c);
ren_char(wb, ren_next, ren_back);
+ if (c != '\n' && wb_empty(wb))
+ adj_nonl(cadj);
}
ren_nl = c == '\n';
c = ren_next();
--- a/xroff.h
+++ b/xroff.h
@@ -201,6 +201,7 @@
void adj_wb(struct adj *adj, struct wb *wb);
void adj_nl(struct adj *adj);
void adj_sp(struct adj *adj);
+void adj_nonl(struct adj *adj);
/* rendering */
void render(void); /* read from in.c and print the output */