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