diff options
Diffstat (limited to 'input.c')
| -rw-r--r-- | input.c | 84 |
1 files changed, 31 insertions, 53 deletions
@@ -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) { |