shithub: neatroff

Download patch

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')]