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