shithub: neatroff

Download patch

ref: 2219823d7fa91cff01b26706c07a80ade53f408b
parent: 15c91dac1995fd5e93ed379b80d0ff7a7fd9fc72
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sun Mar 24 16:47:02 EDT 2013

basic environment support

--- a/adj.c
+++ b/adj.c
@@ -70,7 +70,7 @@
 	if (!n)
 		return;
 	lendiff = n < a->nwords ? a->words[n].beg : a->len;
-	memmove(a->buf, a->buf + lendiff, a->len - lendiff);
+	memmove(a->buf, a->buf + lendiff, a->len - lendiff + 1);
 	a->len -= lendiff;
 	a->nwords -= n;
 	memmove(a->words, a->words + n, a->nwords * sizeof(a->words[0]));
--- a/reg.c
+++ b/reg.c
@@ -42,3 +42,47 @@
 {
 	return sreg[id];
 }
+
+static struct env envs[3];
+struct env *env;
+
+void env_init(void)
+{
+	int i;
+	for (i = 0; i < LEN(envs); i++) {
+		struct env *e = &envs[i];
+		e->f = 1;
+		e->i = 0;
+		e->j = 1;
+		e->l = SC_IN * 65 / 10;
+		e->s = 10;
+		e->u = 1;
+		e->v = 12 * SC_PT;
+		e->s0 = e->s;
+		e->f0 = e->f;
+		e->adj = adj_alloc();
+	}
+	env = &envs[0];
+}
+
+void env_free(void)
+{
+	int i;
+	for (i = 0; i < LEN(envs); i++)
+		adj_free(envs[i].adj);
+}
+
+static int oenv[NPREV];
+static int nenv;
+
+void tr_ev(char **args)
+{
+	int id = args[1] ? atoi(args[1]) : -1;
+	if (id < 0 && nenv)
+		id = oenv[--nenv];
+	if (id >= LEN(envs) || id < 0)
+		return;
+	if (args[1] && env && nenv < NPREV)
+		oenv[nenv++] = env - envs;
+	env = &envs[id];
+}
--- a/ren.c
+++ b/ren.c
@@ -5,7 +5,8 @@
 #include "xroff.h"
 
 #define ADJ_LL		(n_l - n_i)	/* effective line length */
-#define ADJ_MODE	(n_u ? n_ad : ADJ_N)
+#define ADJ_MODE	(n_u ? n_j : ADJ_N)
+#define adj		env->adj	/* line buffer */
 
 /* diversion */
 struct div {
@@ -12,7 +13,6 @@
 	int f, s, f0, s0;		/* backup variables */
 };
 
-static struct adj *adj;			/* line buffer */
 static int ren_backed = -1;		/* pushed back character */
 static int ren_div;			/* current diversion */
 static struct sbuf out_div;		/* current diversion output */
@@ -162,7 +162,7 @@
 
 static void ren_ps(char *s)
 {
-	int ps = !*s || !strcmp("0", s) ? n_s0 : tr_int(s, n_s, '\0');
+	int ps = !s || !*s || !strcmp("0", s) ? n_s0 : tr_int(s, n_s, '\0');
 	n_s0 = n_s;
 	n_s = ps;
 }
@@ -169,8 +169,7 @@
 
 void tr_ps(char **args)
 {
-	if (args[1])
-		ren_ps(args[1]);
+	ren_ps(args[1]);
 }
 
 void tr_in(char **args)
@@ -254,7 +253,6 @@
 	int r_s = n_s;
 	int r_f = n_f;
 	int esc = 0;
-	adj = adj_alloc();
 	ren_br(0, 1);
 	while (nextchar(c) > 0) {
 		if (c[0] == ' ' || c[0] == '\n')
@@ -306,5 +304,4 @@
 		adj_put(adj, charwid(g ? g->wid : dev_spacewid(), n_s), arg);
 	}
 	ren_br(0, 1);
-	adj_free(adj);
 }
--- a/tr.c
+++ b/tr.c
@@ -147,7 +147,7 @@
 
 static void tr_na(char **args)
 {
-	n_ad = 0;
+	n_j = 0;
 }
 
 static char *arg_regname(char *s, int len)
@@ -267,6 +267,7 @@
 	{"de", tr_de, mkargs_reg1},
 	{"di", tr_di},
 	{"ds", tr_ds, mkargs_ds},
+	{"ev", tr_ev},
 	{"fp", tr_fp},
 	{"ft", tr_ft},
 	{"in", tr_in},
--- a/xroff.c
+++ b/xroff.c
@@ -11,17 +11,8 @@
 
 static void g_init(void)
 {
-	n_f = 1;
 	n_o = SC_IN;
 	n_p = SC_IN * 11;
-	n_l = SC_IN * 65 / 10;
-	n_i = 0;
-	n_s = 10;
-	n_u = 1;
-	n_v = 12 * SC_PT;
-	n_s0 = n_s;
-	n_f0 = n_f;
-	n_ad = 1;
 }
 
 static void compile(void)
@@ -44,8 +35,10 @@
 int main(void)
 {
 	dev_open("/root/troff/home/font/devutf");
+	env_init();
 	g_init();
 	compile();
+	env_free();
 	dev_close();
 	return 0;
 }
--- a/xroff.h
+++ b/xroff.h
@@ -13,6 +13,7 @@
 #define NWORDS		1000	/* number of words in line buffer */
 #define NARGS		9	/* number of macro arguments */
 #define RLEN		4	/* register/macro name */
+#define NPREV		16	/* environment stack depth */
 
 /* escape sequences */
 #define ESC_Q	"bCDhHlLNoSvwxX"	/* quoted escape sequences */
@@ -30,23 +31,16 @@
 void str_set(int id, char *s);
 char *str_get(int id);
 
-/* builtin number registers; n_X for .X register */
-#define REG(c1, c2)	((c1) * 256 + (c2))
-#define n_d		nreg[REG('.', 'd')]
-#define n_f		nreg[REG('.', 'f')]
-#define n_i		nreg[REG('.', 'i')]
-#define n_l		nreg[REG('.', 'l')]
-#define n_o		nreg[REG('.', 'o')]
-#define n_p		nreg[REG('.', 'p')]
-#define n_s		nreg[REG('.', 's')]
-#define n_u		nreg[REG('.', 'u')]
-#define n_v		nreg[REG('.', 'v')]
-#define n_nl		nreg[REG('n', 'l')]
-#define n_pg		nreg[REG('%', '\0')]	/* % */
-#define n_f0		nreg[REG('\0', 'f')]	/* last font */
-#define n_s0		nreg[REG('\0', 's')]	/* last size */
-#define n_ad		nreg[REG('\0', 'a')]	/* adjustment */
+/* enviroments */
+struct env {
+	int f, u, v, s, l, i, f0, s0, j;
+	struct adj *adj;
+};
 
+extern struct env *env;
+void env_init(void);
+void env_free(void);
+
 /* device related variables */
 extern int dev_res;
 extern int dev_uwid;
@@ -111,6 +105,7 @@
 void tr_bp(char **args);
 void tr_br(char **args);
 void tr_di(char **args);
+void tr_ev(char **args);
 void tr_fp(char **args);
 void tr_ft(char **args);
 void tr_in(char **args);
@@ -154,3 +149,20 @@
 void adj_swid(struct adj *adj, int swid);
 int adj_full(struct adj *adj, int mode, int linelen);
 int adj_empty(struct adj *adj, int mode);
+
+/* builtin number registers; n_X for .X register */
+#define REG(c1, c2)	((c1) * 256 + (c2))
+#define n_d		nreg[REG('.', 'd')]
+#define n_f		env->f
+#define n_i		env->i
+#define n_j		env->j
+#define n_l		env->l
+#define n_o		nreg[REG('.', 'o')]
+#define n_p		nreg[REG('.', 'p')]
+#define n_s		env->s
+#define n_u		env->u
+#define n_v		env->v
+#define n_nl		nreg[REG('n', 'l')]
+#define n_pg		nreg[REG('%', '\0')]	/* % */
+#define n_f0		env->f0			/* last font */
+#define n_s0		env->s0			/* last size */