shithub: neatroff

Download patch

ref: 9d3c377d7153fd7172aaa005874ca5c7376430b1
parent: 2219823d7fa91cff01b26706c07a80ade53f408b
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon Mar 25 08:47:06 EDT 2013

reg: move environment support to reg.c

Now environment struct is defined locally in reg.c and builtin
macros are modified to use the new nreg(), which returns the
address of a number register.

--- a/cp.c
+++ b/cp.c
@@ -21,9 +21,9 @@
 
 static void cp_num(void)
 {
-	char buf[32];
-	sprintf(buf, "%d", num_get(regid()));
-	in_push(buf, NULL);
+	char *buf = num_get(regid());
+	if (buf)
+		in_push(buf, NULL);
 }
 
 static void cp_str(void)
--- a/reg.c
+++ b/reg.c
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
@@ -4,20 +5,45 @@
 #include "xroff.h"
 
 #define NREGS		(1 << 16)
+#define NENVS		(1 << 5)
 
-int nreg[NREGS];
-char *sreg[NREGS];
+struct env {
+	int eregs[NENVS];	/* environment-specific number registers */
+	struct adj *adj;	/* per environment line buffer */
+};
 
-int num_get(int id)
+static int nregs[NREGS];	/* global number registers */
+static char *sregs[NREGS];	/* global string registers */
+static struct env envs[3];	/* environments */
+static struct env *env;		/* current enviroment */
+static int eregs_idx[NREGS];	/* register environment index in eregs[] */
+
+static int eregs[] = {		/* environment-specific number registers */
+	REG('.', 'f'),
+	REG('.', 'i'),
+	REG('.', 'j'),
+	REG('.', 'l'),
+	REG('.', 's'),
+	REG('.', 'u'),
+	REG('.', 'v'),
+	REG(0, 'f'),
+	REG(0, 's'),
+};
+
+/* return the address of a number register */
+int *nreg(int id)
 {
-	return nreg[id];
+	if (eregs_idx[id])
+		return &env->eregs[eregs_idx[id]];
+	return &nregs[id];
 }
 
-int num_set(int id, int n)
+/* the contents of a number register (returns a static buffer) */
+char *num_get(int id)
 {
-	int o = nreg[id];
-	nreg[id] = n;
-	return o;
+	static char numbuf[128];
+	sprintf(numbuf, "%d", *nreg(id));
+	return numbuf;
 }
 
 void tr_nr(char **args)
@@ -26,43 +52,46 @@
 	if (!args[2])
 		return;
 	id = REG(args[1][0], args[1][1]);
-	nreg[id] = tr_int(args[2], nreg[id], 'u');
+	*nreg(id) = tr_int(args[2], *nreg(id), 'u');
 }
 
 void str_set(int id, char *s)
 {
 	int len = strlen(s) + 1;
-	if (sreg[id])
-		free(sreg[id]);
-	sreg[id] = malloc(len);
-	strcpy(sreg[id], s);
+	if (sregs[id])
+		free(sregs[id]);
+	sregs[id] = malloc(len);
+	strcpy(sregs[id], s);
 }
 
 char *str_get(int id)
 {
-	return sreg[id];
+	return sregs[id];
 }
 
-static struct env envs[3];
-struct env *env;
+static void env_set(int id)
+{
+	env = &envs[id];
+	if (!env->adj) {
+		env->adj = adj_alloc();
+		n_f = 1;
+		n_i = 0;
+		n_j = 1;
+		n_l = SC_IN * 65 / 10;
+		n_s = 10;
+		n_u = 1;
+		n_v = 12 * SC_PT;
+		n_s0 = n_s;
+		n_f0 = n_f;
+	}
+}
 
 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];
+	for (i = 0; i < LEN(eregs); i++)
+		eregs_idx[eregs[i]] = i + 1;
+	env_set(0);
 }
 
 void env_free(void)
@@ -69,10 +98,11 @@
 {
 	int i;
 	for (i = 0; i < LEN(envs); i++)
-		adj_free(envs[i].adj);
+		if (envs[i].adj)
+			adj_free(envs[i].adj);
 }
 
-static int oenv[NPREV];
+static int oenv[NPREV];		/* environment stack */
 static int nenv;
 
 void tr_ev(char **args)
@@ -84,5 +114,10 @@
 		return;
 	if (args[1] && env && nenv < NPREV)
 		oenv[nenv++] = env - envs;
-	env = &envs[id];
+	env_set(id);
+}
+
+struct adj *env_adj(void)
+{
+	return env->adj;
 }
--- a/ren.c
+++ b/ren.c
@@ -6,7 +6,7 @@
 
 #define ADJ_LL		(n_l - n_i)	/* effective line length */
 #define ADJ_MODE	(n_u ? n_j : ADJ_N)
-#define adj		env->adj	/* line buffer */
+#define adj		env_adj()	/* line buffer */
 
 /* diversion */
 struct div {
--- a/xroff.h
+++ b/xroff.h
@@ -22,9 +22,8 @@
 #define LEN(a)		(sizeof(a) / sizeof((a)[0]))
 
 /* number registers */
-extern int nreg[];
-int num_get(int id);
-int num_set(int id, int n);
+char *num_get(int id);
+int *nreg(int id);
 int tr_int(char *s, int orig, int unit);
 
 /* string registers */
@@ -32,14 +31,9 @@
 char *str_get(int id);
 
 /* 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);
+struct adj *env_adj(void);
 
 /* device related variables */
 extern int dev_res;
@@ -152,17 +146,17 @@
 
 /* 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 */
+#define n_d		(*nreg(REG('.', 'd')))
+#define n_f		(*nreg(REG('.', 'f')))
+#define n_i		(*nreg(REG('.', 'i')))
+#define n_j		(*nreg(REG('.', 'j')))
+#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 */