ref: 74e88bbb0eb0e98021f64a16f04a316d9a9b5021
parent: 57cbedc36926da8a101bbb7bd3a6dd119c3ebc17
author: Ali Gholami Rudi <ali@rudi.ir>
date: Thu Nov 22 14:14:39 EST 2012
cp: .ds and \*x for string register
--- a/cp.c
+++ b/cp.c
@@ -3,20 +3,32 @@
static int cp_backed = -1;
-static void cp_num(void)
+static int regid(void)
{
int c1;
int c2 = 0;
- char buf[32];
c1 = cp_next();
if (c1 == '(') {
c1 = cp_next();
c2 = cp_next();
}
- sprintf(buf, "%d", num_get(N_ID(c1, c2)));
+ return N_ID(c1, c2);
+}
+
+static void cp_num(void)
+{
+ char buf[32];
+ sprintf(buf, "%d", num_get(regid()));
in_push(buf);
}
+static void cp_str(void)
+{
+ char *buf = str_get(regid());
+ if (buf)
+ in_push(buf);
+}
+
int cp_next(void)
{
int c = cp_backed >= 0 ? cp_backed : in_next();
@@ -25,6 +37,9 @@
c = in_next();
if (c == 'n') {
cp_num();
+ c = in_next();
+ } else if (c == '*') {
+ cp_str();;
c = in_next();
} else {
in_back(c);
--- a/reg.c
+++ b/reg.c
@@ -1,9 +1,12 @@
#include <stdlib.h>
+#include <stdlib.h>
+#include <string.h>
#include "xroff.h"
#define NREGS (1 << 16)
int nreg[NREGS];
+char *sreg[NREGS];
int num_get(int id)
{
@@ -24,4 +27,18 @@
return;
id = N_ID(args[1][0], args[1][1]);
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);
+}
+
+char *str_get(int id)
+{
+ return sreg[id];
}
--- a/tr.c
+++ b/tr.c
@@ -88,6 +88,13 @@
n_v = tr_int(args[1], n_v, 'p');
}
+static void tr_ds(int argc, char **args)
+{
+ if (argc < 3)
+ return;
+ str_set(N_ID(args[1][0], args[1][1]), args[2]);
+}
+
static void tr_in(int argc, char **args)
{
if (argc >= 2)
@@ -114,8 +121,18 @@
cp_back(c);
}
-static int tr_readargs(char **args, int maxargs, char *buf, int len)
+/* skip everything until the end of line */
+static void jmp_eol(void)
{
+ int c;
+ do {
+ c = cp_next();
+ } while (c >= 0 && c != '\n');
+}
+
+/* read macro arguments */
+static int tr_args(char **args, int maxargs, char *buf, int len)
+{
char *s = buf;
char *e = buf + len - 1;
int c;
@@ -132,16 +149,47 @@
while (c == ' ')
c = cp_next();
}
- if (c != '\n')
- cp_back(c);
+ if (c >= 0 && c != '\n')
+ jmp_eol();
return n;
}
+/* read arguments for .ds */
+static int tr_args_ds(char **args, int maxargs, char *buf, int len)
+{
+ char *s = buf;
+ char *e = buf + len - 1;
+ int c;
+ while ((c = cp_next()) == ' ')
+ ;
+ if (c == '\n' || c < 0)
+ return 0;
+ args[0] = s;
+ *s++ = c;
+ c = cp_next();
+ if (c >= 0 && c != '\n' && c != ' ')
+ *s++ = c;
+ *s++ = '\0';
+ while ((c = cp_next()) == ' ')
+ ;
+ if (c == '"')
+ c = cp_next();
+ args[1] = s;
+ while (s < e && c > 0 && c != '\n') {
+ *s++ = c;
+ c = cp_next();
+ }
+ *s = '\0';
+ return 2;
+}
+
static struct cmd {
char *id;
void (*f)(int argc, char **args);
+ int (*args)(char **args, int maxargs, char *buf, int len);
} cmds[] = {
{"br", tr_br},
+ {"ds", tr_ds, tr_args_ds},
{"fp", tr_fp},
{"ft", tr_ft},
{"in", tr_in},
@@ -160,6 +208,7 @@
char *args[NARGS];
char buf[LINEL];
char cmd[LINEL];
+ struct cmd *req = NULL;
int argc;
int i;
while (tr_nl && (c == '.' || c == '\'')) {
@@ -167,10 +216,18 @@
args[0] = cmd;
cmd[0] = c;
tr_readcmd(cmd + 1);
- argc = tr_readargs(args + 1, NARGS - 1, buf, LINEL);
for (i = 0; i < LEN(cmds); i++)
if (!strcmp(cmd + 1, cmds[i].id))
- cmds[i].f(argc + 1, args);
+ req = &cmds[i];
+ if (req) {
+ if (req->args)
+ argc = req->args(args + 1, NARGS - 1, buf, LINEL);
+ else
+ argc = tr_args(args + 1, NARGS - 1, buf, LINEL);
+ req->f(argc + 1, args);
+ } else {
+ jmp_eol();
+ }
c = cp_next();
}
tr_nl = nl;
--- a/xroff.h
+++ b/xroff.h
@@ -14,6 +14,10 @@
int num_set(int id, int n);
int tr_int(char *s, int orig, int unit);
+/* string registers */
+void str_set(int id, char *s);
+char *str_get(int id);
+
/* builtin number registers; n_X for .X register */
#define N_ID(c1, c2) ((c1) * 256 + (c2))
#define n_f nreg[N_ID('.', 'f')]