shithub: neatroff

Download patch

ref: 995cc6df26f779886104d2b76efeeaa6f2a02511
parent: 970847e76c14ed3d07e82d4e28f1443bee6ee948
author: Ali Gholami Rudi <[email protected]>
date: Mon Nov 19 15:07:20 EST 2012

cp: expand \nx and \n(xy

--- a/cp.c
+++ b/cp.c
@@ -1,12 +1,37 @@
+#include <stdio.h>
 #include "xroff.h"
 
 static int cp_backed = -1;
 
+static void cp_num(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)));
+	in_push(buf);
+}
+
 int cp_next(void)
 {
-	int ret = cp_backed >= 0 ? cp_backed : in_next();
+	int c = cp_backed >= 0 ? cp_backed : in_next();
 	cp_backed = -1;
-	return ret;
+	if (c == '\\') {
+		c = in_next();
+		if (c == 'n') {
+			cp_num();
+			c = in_next();
+		} else {
+			in_back(c);
+			c = '\\';
+		}
+	}
+	return c;
 }
 
 void cp_back(int c)
--- a/in.c
+++ b/in.c
@@ -1,6 +1,54 @@
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "xroff.h"
 
+struct inbuf {
+	char *buf;
+	int pos;
+	int len;
+	int backed;
+	struct inbuf *prev;
+};
+
+static struct inbuf in_main = {.backed = -1};
+static struct inbuf *buf = &in_main;
+
+void in_push(char *s)
+{
+	struct inbuf *next = malloc(sizeof(*buf));
+	int len = strlen(s);
+	next->buf = malloc(len + 1);
+	strcpy(next->buf, s);
+	next->pos = 0;
+	next->len = len;
+	next->backed = -1;
+	next->prev = buf;
+	buf = next;
+}
+
+static void in_pop(void)
+{
+	struct inbuf *old = buf;
+	buf = buf->prev;
+	free(old->buf);
+	free(old);
+}
+
 int in_next(void)
 {
-	return getchar();
+	int c = buf->backed;
+	buf->backed = -1;
+	if (c >= 0)
+		return c;
+	while (buf->pos == buf->len && buf->prev)
+		in_pop();
+	if (!buf->buf)
+		return getchar();
+	return buf->pos < buf->len ? buf->buf[buf->pos++] : -1;
+}
+
+void in_back(int c)
+{
+	buf->backed = c;
 }
--- a/xroff.h
+++ b/xroff.h
@@ -67,6 +67,8 @@
 int in_next(void);
 int cp_next(void);
 int tr_next(void);
+void in_push(char *s);
+void in_back(int c);
 void cp_back(int c);
 
 /* rendering */