shithub: neatroff

Download patch

ref: 8b5a245c4fef714fbf538223d6b9ee415b6a2c79
parent: 9c7a7f0f1eede61731fa24c7ed7f4bd3cd21a16e
author: Ali Gholami Rudi <ali@rudi.ir>
date: Thu Apr 25 08:33:42 EDT 2013

eval: add eval_re() for numbers relative to their previous values

--- a/eval.c
+++ b/eval.c
@@ -117,20 +117,26 @@
 }
 
 /* evaluate *s and update s to point to the last character read */
-int eval_up(char **s, int orig, int unit)
+int eval_up(char **s, int unit)
 {
-	int n;
-	int rel = 0;		/* n should be added to orig */
-	if (**s == '+' || **s == '-') {
-		rel = **s == '+' ? 1 : -1;
-		(*s)++;
-	}
 	defunit = unit;
 	if (unit == 'v')
 		abspos = -n_d;
 	if (unit == 'm')
 		abspos = n_lb - f_hpos();
-	n = evalexpr(s);
+	return evalexpr(s);
+}
+
+/* evaluate s relative to its previous value */
+int eval_re(char *s, int orig, int unit)
+{
+	int n;
+	int rel = 0;		/* n should be added to orig */
+	if (*s == '+' || *s == '-') {
+		rel = *s == '+' ? 1 : -1;
+		s++;
+	}
+	n = eval_up(&s, unit);
 	if (rel)
 		return rel > 0 ? orig + n : orig - n;
 	return n;
@@ -137,7 +143,7 @@
 }
 
 /* evaluate s */
-int eval(char *s, int orig, int unit)
+int eval(char *s, int unit)
 {
-	return eval_up(&s, orig, unit);
+	return eval_up(&s, unit);
 }
--- a/line.c
+++ b/line.c
@@ -34,7 +34,7 @@
 {
 	char *lc = "\\(ru";
 	int w, l, n, i, rem;
-	l = eval_up(&arg, 0, 'm');
+	l = eval_up(&arg, 'm');
 	if (!l)
 		return;
 	if (arg[0] == '\\' && arg[1] == '&')	/* \& can be used as a separator */
@@ -75,7 +75,7 @@
 {
 	char *lc = "\\(br";
 	int w, l, n, i, rem, hw, neg;
-	l = eval_up(&arg, 0, 'm');
+	l = eval_up(&arg, 'm');
 	if (!l)
 		return;
 	neg = l < 0;
@@ -184,7 +184,7 @@
 	int w = maxwid(arg);
 	while (*arg) {
 		arg = cutchar(c, arg);
-		a = (w - cwid(c)) / 2;
+		a = (w - cwid(c) + 1) / 2;
 		hmov(adj, a);
 		adj_put(adj, cwid(arg), c);
 		hmov(adj, -cwid(c) - a);
--- a/out.c
+++ b/out.c
@@ -124,7 +124,7 @@
 {
 	char tok[ILNLEN];
 	s = tok_str(tok, s);
-	*d = eval(tok, 0, scale);
+	*d = eval(tok, scale);
 	if (*cc)
 		*cc += sprintf(*cc, " %du", *d);
 	else
@@ -215,15 +215,15 @@
 					continue;
 				}
 				if (c[1] == 'h') {
-					outnn("h%d", eval(arg, 0, 'm'));
+					outnn("h%d", eval(arg, 'm'));
 					continue;
 				}
 				if (c[1] == 's') {
-					out_ps(eval(arg, o_s, '\0'));
+					out_ps(eval_re(arg, o_s, '\0'));
 					continue;
 				}
 				if (c[1] == 'v') {
-					outnn("v%d", eval(arg, 0, 'v'));
+					outnn("v%d", eval(arg, 'v'));
 					continue;
 				}
 				if (c[1] == 'X') {
--- a/ren.c
+++ b/ren.c
@@ -264,12 +264,12 @@
 	if (args[0][0] == '.')
 		traps = ren_br(1);
 	if (!n_ns && !traps)
-		down(args[1] ? eval(args[1], 0, 'v') : n_v);
+		down(args[1] ? eval(args[1], 'v') : n_v);
 }
 
 void tr_sv(char **args)
 {
-	int n = eval(args[1], 0, 'v');
+	int n = eval(args[1], 'v');
 	n_sv = 0;
 	if (n_d + n < f_nexttrap())
 		down(n);
@@ -304,7 +304,7 @@
 
 void tr_rt(char **args)
 {
-	int n = args[1] ? eval(args[1], n_d, 'v') : n_mk;
+	int n = args[1] ? eval_re(args[1], n_d, 'v') : n_mk;
 	if (n >= 0 && n < n_d)
 		ren_sp(n - n_d);
 }
@@ -311,7 +311,7 @@
 
 void tr_ne(char **args)
 {
-	int n = args[1] ? eval(args[1], 0, 'v') : n_v;
+	int n = args[1] ? eval(args[1], 'v') : n_v;
 	if (!ren_traps(n_d, n_d + n - 1, 1))
 		ren_pagelimit(n);
 }
@@ -325,7 +325,7 @@
 			in_pushnl(".br\n", NULL);
 		bp_force = 1;
 		if (args[1])
-			bp_next = eval(args[1], n_pg, 0);
+			bp_next = eval_re(args[1], n_pg, 0);
 	}
 }
 
@@ -332,12 +332,12 @@
 void tr_pn(char **args)
 {
 	if (args[1])
-		bp_next = eval(args[1], n_pg, 0);
+		bp_next = eval_re(args[1], n_pg, 0);
 }
 
 static void ren_ps(char *s)
 {
-	int ps = !s || !*s || !strcmp("0", s) ? n_s0 : eval(s, n_s, 0);
+	int ps = !s || !*s || !strcmp("0", s) ? n_s0 : eval_re(s, n_s, 0);
 	n_s0 = n_s;
 	n_s = MAX(1, ps);
 }
@@ -349,7 +349,7 @@
 
 void tr_ll(char **args)
 {
-	int ll = args[1] ? eval(args[1], n_l, 'm') : n_l0;
+	int ll = args[1] ? eval_re(args[1], n_l, 'm') : n_l0;
 	n_l0 = n_l;
 	n_l = MAX(0, ll);
 	adj_ll(cadj, n_l);
@@ -357,7 +357,7 @@
 
 void tr_in(char **args)
 {
-	int in = args[1] ? eval(args[1], n_i, 'm') : n_i0;
+	int in = args[1] ? eval_re(args[1], n_i, 'm') : n_i0;
 	if (args[0][0] == '.')
 		ren_br(1);
 	n_i0 = n_i;
@@ -370,7 +370,7 @@
 	if (args[0][0] == '.')
 		ren_br(1);
 	if (args[1])
-		adj_ti(cadj, eval(args[1], 0, 'm'));
+		adj_ti(cadj, eval(args[1], 'm'));
 }
 
 static void ren_ft(char *s)
@@ -479,13 +479,13 @@
 		adj_put(adj, w, "\\D'%s'", draw_arg);
 		break;
 	case 'd':
-		adj_put(adj, 0, "\\v'%du'", eval(".5m", 0, 0));
+		adj_put(adj, 0, "\\v'%du'", eval(".5m", 0));
 		break;
 	case 'f':
 		ren_ft(arg);
 		break;
 	case 'h':
-		n = eval(arg, 0, 'm');
+		n = eval(arg, 'm');
 		adj_put(adj, n, "\\h'%du'", n);
 		break;
 	case 'k':
@@ -501,22 +501,22 @@
 		ren_over(adj, arg);
 		break;
 	case 'r':
-		adj_put(adj, 0, "\\v'%du'", eval("-1m", 0, 0));
+		adj_put(adj, 0, "\\v'%du'", eval("-1m", 0));
 		break;
 	case 's':
 		ren_ps(arg);
 		break;
 	case 'u':
-		adj_put(adj, 0, "\\v'%du'", eval("-.5m", 0, 0));
+		adj_put(adj, 0, "\\v'%du'", eval("-.5m", 0));
 		break;
 	case 'v':
-		adj_put(adj, 0, "\\v'%du'", eval(arg, 0, 'v'));
+		adj_put(adj, 0, "\\v'%du'", eval(arg, 'v'));
 		break;
 	case 'X':
 		adj_put(adj, 0, "\\X'%s'", arg);
 		break;
 	case 'x':
-		adj_els(adj, eval(arg, 0, 'v'));
+		adj_els(adj, eval(arg, 'v'));
 		break;
 	case '0':
 		g = dev_glyph("0", n_f);
@@ -524,11 +524,11 @@
 		adj_put(adj, w, "\\h'%du'", w);
 		break;
 	case '|':
-		w = eval("1m/6", 0, 0);
+		w = eval("1m/6", 0);
 		adj_put(adj, w, "\\h'%du'", w);
 		break;
 	case '^':
-		w = eval("1m/12", 0, 0);
+		w = eval("1m/12", 0);
 		adj_put(adj, w, "\\h'%du'", w);
 		break;
 	case '{':
@@ -683,7 +683,7 @@
 
 static int tpos_parse(char *s)
 {
-	int pos = eval(s, 0, 'v');
+	int pos = eval(s, 'v');
 	return pos >= 0 ? pos : n_p + pos;
 }
 
@@ -725,7 +725,7 @@
 	if (!cdiv)
 		return;
 	if (args[2]) {
-		cdiv->tpos = eval(args[1], 0, 'v');
+		cdiv->tpos = eval(args[1], 'v');
 		cdiv->treg = REG(args[2][0], args[2][1]);
 	} else {
 		cdiv->treg = -1;
--- a/tr.c
+++ b/tr.c
@@ -16,7 +16,7 @@
 
 static void tr_vs(char **args)
 {
-	int vs = args[1] ? eval(args[1], n_v, 'p') : n_v0;
+	int vs = args[1] ? eval_re(args[1], n_v, 'p') : n_v0;
 	n_v0 = n_v;
 	n_v = MAX(0, vs);
 }
@@ -23,7 +23,7 @@
 
 static void tr_ls(char **args)
 {
-	int ls = args[1] ? eval(args[1], n_L, 'v') : n_L0;
+	int ls = args[1] ? eval_re(args[1], n_L, 'v') : n_L0;
 	n_L0 = n_L;
 	n_L = MAX(1, ls);
 }
@@ -30,7 +30,7 @@
 
 static void tr_pl(char **args)
 {
-	int n = eval(args[1] ? args[1] : "11i", n_p, 'v');
+	int n = eval_re(args[1] ? args[1] : "11i", n_p, 'v');
 	n_p = MAX(0, n);
 }
 
@@ -40,8 +40,8 @@
 	if (!args[2])
 		return;
 	id = REG(args[1][0], args[1][1]);
-	num_set(id, eval(args[2], num_get(id, 0), 'u'));
-	num_inc(id, args[3] ? eval(args[3], 0, 'u') : 0);
+	num_set(id, eval_re(args[2], num_get(id, 0), 'u'));
+	num_inc(id, args[3] ? eval(args[3], 'u') : 0);
 }
 
 static void tr_rr(char **args)
@@ -92,7 +92,7 @@
 
 static void tr_po(char **args)
 {
-	int po = args[1] ? eval(args[1], n_o, 'm') : n_o0;
+	int po = args[1] ? eval_re(args[1], n_o, 'm') : n_o0;
 	n_o0 = n_o;
 	n_o = MAX(0, po);
 }
@@ -200,7 +200,7 @@
 	else if (s[0] == 'n' && s[1] == '\0')
 		ret = 0;
 	else
-		ret = eval(s, 0, '\0') > 0;
+		ret = eval(s, '\0') > 0;
 	sbuf_done(&sbuf);
 	return ret;
 }
--- a/xroff.h
+++ b/xroff.h
@@ -35,8 +35,9 @@
 void num_del(int id);
 char *num_str(int id);
 int *nreg(int id);
-int eval(char *s, int orig, int unit);
-int eval_up(char **s, int orig, int unit);
+int eval(char *s, int unit);
+int eval_up(char **s, int unit);
+int eval_re(char *s, int orig, int unit);
 
 /* string registers */
 void str_set(int id, char *s);