summaryrefslogtreecommitdiff
path: root/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'input.c')
-rw-r--r--input.c84
1 files changed, 31 insertions, 53 deletions
diff --git a/input.c b/input.c
index 24ca05f..5fef967 100644
--- a/input.c
+++ b/input.c
@@ -8,31 +8,28 @@
#include "input.h"
#include "jbwrap.h"
-/*
- NB: character unget is supported for up to two characters, but NOT
- in the case of EOF. Since EOF does not fit in a char, it is easiest
- to support only one unget of EOF.
-*/
+/* How many characters can we unget? */
+enum { UNGETSIZE = 2 };
typedef enum inputtype {
iFd, iString, iEdit
} inputtype;
typedef struct Input {
- bool saved, eofread;
+ bool saved;
inputtype t;
- int fd, index, read, lineno, last;
+ int fd, index, read, ungetcount, lineno, last;
char *ibuf;
void *cookie;
+ int ungetbuf[UNGETSIZE];
int (*gchar)(void);
- void (*ugchar)(int);
} Input;
#define BUFSIZE ((size_t) 256)
static char *inbuf;
static size_t istacksize, chars_out, chars_in;
-static bool eofread = FALSE, save_lineno = TRUE;
+static bool save_lineno = TRUE;
static Input *istack, *itop;
int lastchar;
@@ -40,24 +37,15 @@ int lastchar;
static char *prompt, *prompt2;
extern void ugchar(int c) {
- if (c == EOF)
- eofread = TRUE;
- else
- (*istack->ugchar)(c);
-}
-
-static void fdstringugchar(int c) {
- assert(chars_out);
- inbuf[--chars_out] = c;
+ assert(istack->ungetcount < UNGETSIZE);
+ istack->ungetbuf[istack->ungetcount++] = c;
}
extern int gchar() {
int c;
- if (eofread) {
- eofread = FALSE;
- return lastchar = EOF;
- }
+ if (istack->ungetcount)
+ return lastchar = istack->ungetbuf[--istack->ungetcount];
while ((c = (*istack->gchar)()) == '\0')
pr_error("warning: null character ignored", 0);
@@ -65,6 +53,7 @@ extern int gchar() {
return c;
}
+
/* get the next character from a string. */
static int stringgchar() {
@@ -82,7 +71,7 @@ static void history() {
return;
for (a = 0; a < chars_in; a++) {
- char c = inbuf[a+2];
+ char c = inbuf[a];
/* skip empty lines and comments */
if (c == '#' || c == '\n')
@@ -92,11 +81,10 @@ static void history() {
if (c != ' ' && c != '\t') {
char *name = hist->w;
int fd = rc_open(name, rAppend);
- if (fd < 0) {
+ if (fd < 0)
uerror(name);
- varrm(name, TRUE);
- } else {
- writeall(fd, inbuf + 2, chars_in);
+ else {
+ writeall(fd, inbuf, chars_in);
close(fd);
}
break;
@@ -104,13 +92,14 @@ static void history() {
}
}
+
/* read a character from a file descriptor */
static int fdgchar() {
- if (chars_out >= chars_in + 2) { /* replenish empty buffer */
+ if (chars_out >= chars_in) { /* replenish empty buffer */
ssize_t r;
do {
- r = rc_read(istack->fd, inbuf + 2, BUFSIZE);
+ r = rc_read(istack->fd, inbuf, BUFSIZE);
sigchk();
if (r == -1)
switch (errno) {
@@ -134,31 +123,18 @@ static int fdgchar() {
chars_in = (size_t) r;
if (chars_in == 0)
return lastchar = EOF;
- chars_out = 2;
+ chars_out = 0;
if (dashvee)
- writeall(2, inbuf + 2, chars_in);
+ writeall(2, inbuf, chars_in);
history();
}
return lastchar = inbuf[chars_out++];
}
-enum { UNGETSIZE = 2 };
-static int ungetbuf[UNGETSIZE];
-static int ungetcount = 0;
-
-static void editugchar(int c) {
- fprint(2, "in editugchar, with c = %d and ungetcount = %d\n", c, ungetcount);
- assert(ungetcount < UNGETSIZE);
- ungetbuf[ungetcount++] = c;
-}
-
/* read a character from a line-editing file descriptor */
static int editgchar() {
- if (ungetcount)
- return lastchar = ungetbuf[--ungetcount];
-
if (chars_out >= chars_in) { /* replenish empty buffer */
edit_free(istack->cookie);
inbuf = edit_alloc(istack->cookie, &chars_in);
@@ -182,11 +158,12 @@ void termchange(void) {
edit_reset(istack->cookie);
}
+
/* set up the input stack, and put a "dead" input at the bottom, so that yyparse will always read eof */
extern void initinput() {
istack = itop = ealloc(istacksize = 256 * sizeof (Input));
- istack->eofread = TRUE;
+ ugchar(EOF);
}
/* push an input source onto the stack. set up a new input buffer, and set gchar() */
@@ -199,15 +176,15 @@ static void pushcommon() {
istack->lineno = lineno;
istack->saved = save_lineno;
istack->last = lastchar;
- istack->eofread = eofread;
istack++;
idiff = istack - itop;
if (idiff >= istacksize / sizeof (Input)) {
itop = erealloc(itop, istacksize *= 2);
istack = itop + idiff;
}
- chars_out = 2;
+ chars_out = 0;
chars_in = 0;
+ istack->ungetcount = 0;
}
extern void pushfd(int fd) {
@@ -218,13 +195,11 @@ extern void pushfd(int fd) {
if (editing && interactive && isatty(fd)) {
istack->t = iEdit;
istack->gchar = editgchar;
- istack->ugchar = editugchar;
istack->cookie = edit_begin(fd);
} else {
istack->t = iFd;
istack->gchar = fdgchar;
- istack->ugchar = fdstringugchar;
- inbuf = ealloc(BUFSIZE + 2);
+ inbuf = ealloc(BUFSIZE);
}
}
@@ -232,15 +207,15 @@ extern void pushstring(char **a, bool save) {
pushcommon();
istack->t = iString;
save_lineno = save;
- inbuf = mprint("..%A", a);
+ inbuf = mprint("%A", a);
istack->gchar = stringgchar;
- istack->ugchar = fdstringugchar;
if (save_lineno)
lineno = 1;
else
--lineno;
}
+
/* remove an input source from the stack. restore associated variables etc. */
extern void popinput() {
@@ -251,7 +226,6 @@ extern void popinput() {
efree(inbuf);
--istack;
lastchar = istack->last;
- eofread = istack->eofread;
inbuf = istack->ibuf;
chars_out = istack->index;
chars_in = istack->read;
@@ -262,6 +236,7 @@ extern void popinput() {
save_lineno = istack->saved;
}
+
/* flush input characters upto newline. Used by scanerror() */
extern void skiptonl() {
@@ -274,6 +249,7 @@ extern void skiptonl() {
ugchar(c);
}
+
/* the wrapper loop in rc: prompt for commands until EOF, calling yyparse and walk() */
extern Node *doit(bool clobberexecit) {
@@ -367,6 +343,8 @@ extern void closefds() {
}
}
+/* print (or set) prompt(2) */
+
extern void nextline() {
lineno++;
if (interactive) {