ref: fa227033810da058e4b76ed18ccf36a9c04fa9d5
parent: 72b10b4403a811e2e95c9b7dbbc5098af022f669
author: Ali Gholami Rudi <ali@rudi.ir>
date: Wed Apr 24 15:02:40 EDT 2013
ren: execute the 0 trap just after the initial troff requests Now cp.c and tr.c are stateless and unread characters are saved in in.c.
--- a/cp.c
+++ b/cp.c
@@ -4,8 +4,6 @@
#define CPBUF 4
-static int cp_buf[CPBUF]; /* pushed character stack */
-static int cp_backed; /* number of pushed characters */
static int cp_nblk; /* input block depth (text in \{ and \}) */
static int cp_sblk[NIES]; /* skip \} escape at this depth, if set */
static int cp_widreq = 1; /* inline \w requests */
@@ -63,8 +61,8 @@
static int cp_raw(void)
{
int c;
- if (cp_backed)
- return cp_buf[--cp_backed];
+ if (in_top() >= 0)
+ return in_next();
c = in_next();
if (c == '\\') {
c = in_next();
@@ -86,8 +84,8 @@
int cp_next(void)
{
int c;
- if (cp_backed)
- return cp_buf[--cp_backed];
+ if (in_top() >= 0)
+ return in_next();
c = cp_raw();
if (c == '\\') {
c = cp_raw();
@@ -114,17 +112,6 @@
return c;
}
-void cp_back(int c)
-{
- if (cp_backed < CPBUF)
- cp_buf[cp_backed++] = c;
-}
-
-static int cp_top(void)
-{
- return cp_backed ? cp_buf[cp_backed - 1] : -1;
-}
-
void cp_blk(int skip)
{
int c;
@@ -132,7 +119,7 @@
do {
c = cp_raw();
} while (c == ' ' || c == '\t');
- if (c == '\\' && cp_top() == '{') { /* a troff \{ \} block */
+ if (c == '\\' && in_top() == '{') { /* a troff \{ \} block */
if (skip) {
while (skip && cp_nblk > nblk && c >= 0)
c = cp_raw();
--- a/in.c
+++ b/in.c
@@ -8,9 +8,10 @@
FILE *fin;
char *buf; /* for string buffers */
char **args;
+ int unbuf[8]; /* unread characters */
+ int un; /* number of unread characters */
int pos;
int len;
- int backed;
int nl; /* read \n, if the previous char was not */
struct inbuf *prev;
};
@@ -19,7 +20,7 @@
static char files[NFILES][PATHLEN];
static int nfiles;
static int cfile;
-static int in_last;
+static int in_last[2]; /* the last chars returned from in_next() */
static char **args_init(char **args);
static void args_free(char **args);
@@ -28,7 +29,6 @@
{
struct inbuf *next = malloc(sizeof(*next));
memset(next, 0, sizeof(*next));
- next->backed = -1;
next->prev = buf;
buf = next;
}
@@ -89,7 +89,9 @@
{
int c;
while (buf || !in_nextfile()) {
- if (buf->nl-- > 0 && in_last != '\n')
+ if (buf->un)
+ return buf->unbuf[--buf->un];
+ if (buf->nl-- > 0 && in_last[0] != '\n')
return '\n';
if (buf->buf && buf->pos < buf->len)
break;
@@ -107,22 +109,21 @@
int in_next(void)
{
- int c;
- if (!buf && in_nextfile())
- return -1;
- c = buf->backed;
- if (c >= 0)
- buf->backed = -1;
- else
- c = in_read();
- in_last = c;
- return c;
+ in_last[1] = in_last[0];
+ in_last[0] = in_read();
+ return in_last[0];
}
void in_back(int c)
{
+ in_last[0] = in_last[1];
if (buf)
- buf->backed = c;
+ buf->unbuf[buf->un++] = c;
+}
+
+int in_top(void)
+{
+ return buf && buf->un ? buf->unbuf[buf->un - 1] : -1;
}
char *in_arg(int i)
--- a/ren.c
+++ b/ren.c
@@ -605,6 +605,8 @@
{
int c;
n_nl = -1;
+ tr_first();
+ ren_first(); /* transition to the first page */
c = ren_next();
while (c >= 0) {
if (c == ' ' || c == '\n') {
--- a/tr.c
+++ b/tr.c
@@ -534,3 +534,8 @@
for (i = 0; i < LEN(cmds); i++)
str_dset(REG(cmds[i].id[0], cmds[i].id[1]), &cmds[i]);
}
+
+void tr_first(void)
+{
+ cp_back(tr_next());
+}
--- a/xroff.h
+++ b/xroff.h
@@ -106,20 +106,21 @@
char *in_arg(int i); /* look up argument */
int in_nargs(void); /* number of arguments */
void in_back(int c); /* push back input character */
+int in_top(void); /* the first pushed-back character */
char *in_filename(void); /* current filename */
-void cp_back(int c); /* push back copy-mode character */
void cp_blk(int skip); /* skip or read the next line or block */
void cp_wid(int enable); /* control inlining \w requests */
+void tr_first(void); /* read until the first non-command line */
+#define cp_back in_back /* cp.c is stateless */
/* rendering */
-void render(void); /* read from in.c and print the output */
+void render(void); /* read from in.c and print the output */
int ren_wid(int (*next)(void), void (*back)(int));
-void out_line(char *s); /* output the given rendered line */
+void out_line(char *s); /* output the given rendered line */
int out_draw(char *s, char *cc);
-void out(char *s, ...); /* output troff cmd */
-/* drawing lines */
-void ren_hline(struct adj *adj, char *arg);
-void ren_vline(struct adj *adj, char *arg);
+void out(char *s, ...); /* output troff cmd */
+void ren_hline(struct adj *adj, char *arg); /* horizontal line */
+void ren_vline(struct adj *adj, char *arg); /* vertical line */
/* troff commands */
void tr_bp(char **args);