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