shithub: neatroff

Download patch

ref: 9d68d6260e5b04097d8e1e6bca795da4a0192d78
parent: bf62c957f310d3d127093f472d98ed1e3bf94490
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Nov 24 14:59:54 EST 2012

expand macro arguments

--- a/cp.c
+++ b/cp.c
@@ -1,8 +1,12 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include "xroff.h"
 
-static int cp_backed = -1;
+#define CPBUF		4
 
+static int cp_backed = 0;
+static int cp_buf[CPBUF];
+
 static int regid(void)
 {
 	int c1;
@@ -19,7 +23,7 @@
 {
 	char buf[32];
 	sprintf(buf, "%d", num_get(regid()));
-	in_push(buf);
+	in_push(buf, NULL);
 }
 
 static void cp_str(void)
@@ -26,13 +30,26 @@
 {
 	char *buf = str_get(regid());
 	if (buf)
-		in_push(buf);
+		in_push(buf, NULL);
 }
 
+static void cp_arg(void)
+{
+	int c;
+	char *arg;
+	c = cp_next();
+	if (c >= '1' && c <= '9')
+		arg = in_arg(c - '0');
+	if (arg)
+		in_push(arg, NULL);
+}
+
 int cp_next(void)
 {
-	int c = cp_backed >= 0 ? cp_backed : in_next();
-	cp_backed = -1;
+	int c;
+	if (cp_backed)
+		return cp_buf[--cp_backed];
+	c = in_next();
 	if (c == '\\') {
 		c = in_next();
 		if (c == 'n') {
@@ -39,10 +56,13 @@
 			cp_num();
 			c = in_next();
 		} else if (c == '*') {
-			cp_str();;
+			cp_str();
 			c = in_next();
+		} else if (c == '$') {
+			cp_arg();
+			c = in_next();
 		} else {
-			in_back(c);
+			cp_back(c);
 			c = '\\';
 		}
 	}
@@ -51,5 +71,6 @@
 
 void cp_back(int c)
 {
-	cp_backed = c;
+	if (cp_backed < CPBUF)
+		cp_buf[cp_backed++] = c;
 }
--- a/in.c
+++ b/in.c
@@ -5,6 +5,7 @@
 
 struct inbuf {
 	char *buf;
+	char **args;
 	int pos;
 	int len;
 	int backed;
@@ -14,7 +15,10 @@
 static struct inbuf in_main = {.backed = -1};
 static struct inbuf *buf = &in_main;
 
-void in_push(char *s)
+static char **args_init(char **args);
+static void args_free(char **args);
+
+void in_push(char *s, char **args)
 {
 	struct inbuf *next = malloc(sizeof(*buf));
 	int len = strlen(s);
@@ -24,6 +28,7 @@
 	next->len = len;
 	next->backed = -1;
 	next->prev = buf;
+	next->args = args ? args_init(args) : NULL;
 	buf = next;
 }
 
@@ -31,6 +36,8 @@
 {
 	struct inbuf *old = buf;
 	buf = buf->prev;
+	if (old->args)
+		args_free(old->args);
 	free(old->buf);
 	free(old);
 }
@@ -45,10 +52,47 @@
 		in_pop();
 	if (!buf->buf)
 		return getchar();
-	return buf->pos < buf->len ? buf->buf[buf->pos++] : -1;
+	if (buf->pos >= buf->len)
+		return -1;
+	/* replacing \\ with \ only for buffers inserted via in_push() */
+	if (buf->buf[buf->pos] == '\\' && buf->buf[buf->pos + 1] == '\\')
+		buf->pos++;
+	return buf->buf[buf->pos++];
 }
 
 void in_back(int c)
 {
 	buf->backed = c;
+}
+
+char *in_arg(int i)
+{
+	struct inbuf *cur = buf;
+	while (cur->prev && !cur->prev)
+		cur = cur->prev;
+	return cur->args && cur->args[i - 1] ? cur->args[i - 1] : "";
+}
+
+static char **args_init(char **args)
+{
+	char **out = malloc(NARGS * sizeof(*out));
+	int i;
+	for (i = 0; i < NARGS; i++) {
+		out[i] = NULL;
+		if (args[i]) {
+			int len = strlen(args[i]) + 1;
+			out[i] = malloc(len);
+			memcpy(out[i], args[i], len);
+		}
+	}
+	return out;
+}
+
+static void args_free(char **args)
+{
+	int i;
+	for (i = 0; i < NARGS; i++)
+		if (args[i])
+			free(args[i]);
+	free(args);
 }
--- a/tr.c
+++ b/tr.c
@@ -4,7 +4,6 @@
 #include <string.h>
 #include "xroff.h"
 
-#define NARGS		10
 #define LINEL		1024
 #define LEN(a)		(sizeof(a) / sizeof((a)[0]))
 
@@ -283,7 +282,7 @@
 {
 	int c = cp_next();
 	int nl = c == '\n';
-	char *args[NARGS];
+	char *args[NARGS + 1] = {NULL};
 	char buf[LINEL];
 	char cmd[LINEL];
 	struct cmd *req = NULL;
@@ -299,12 +298,14 @@
 				req = &cmds[i];
 		if (req) {
 			if (req->args)
-				argc = req->args(args + 1, NARGS - 1, buf, LINEL);
+				argc = req->args(args + 1, NARGS, buf, LINEL);
 			else
-				argc = mkargs(args + 1, NARGS - 1, buf, LINEL);
+				argc = mkargs(args + 1, NARGS, buf, LINEL);
 			req->f(argc + 1, args);
 		} else {
-			jmp_eol();
+			argc = mkargs(args + 1, NARGS, buf, LINEL);
+			if (str_get(REG(cmd[1], cmd[2])))
+				in_push(str_get(REG(cmd[1], cmd[2])), args + 1);
 		}
 		c = cp_next();
 	}
--- a/xroff.h
+++ b/xroff.h
@@ -6,8 +6,8 @@
 #define FNNAME		32
 #define LLEN		128
 #define LINELEN		1024
+#define NARGS		9
 
-
 /* number registers */
 extern int nreg[];
 int num_get(int id);
@@ -77,7 +77,8 @@
 int in_next(void);
 int cp_next(void);
 int tr_next(void);
-void in_push(char *s);
+void in_push(char *s, char **args);
+char *in_arg(int i);
 void in_back(int c);
 void cp_back(int c);