# include # include "constants.h" # include "globals.h" # include SCCSID(@(#)getch.c 8.2 1/16/85) /* ** GETCH -- Get a character from the input stream ** ** Parameters: ** none ** ** Returns: ** the next character on the input stream, or ** the backed up character if there is one. ** EOF_TOK is returned on EOF. ** ** Side Effects: ** If a backed up character exists, unloads it. ** *Line_pos is returned if Line_pos != 0 ** and no backup character exists. Line_buf ** contains the line from which characters are being ** returned. A call with Line_pos == 0 forces ** reading of the next input line. Yyline is ** incremented when a newline is returned. ** If an EOF is in the middle of a line, ** then a newline will be appended. ** ** Compilation Flags: ** xDEBUG -- to test Chardebug for ** returning activity of getch() and backup(). */ /* initializes peek buffer to be empty */ int Peekc [2] = {-1, -1}; getch() { register char *cp; register char ch; static eoflag; extern int yyline; extern FILE *In_file; if (Peekc [0] >= 0) { /* have a backed up character */ ch = Peekc [0]; if (ch == '\n') yyline += 1; Peekc [0] = Peekc [1]; Peekc [1] = -1; } else { for ( ; ; ) { /* no lookahead character */ if (!Line_pos) { if (eoflag) { eoflag = 0; /* try to restore previous file */ if (!restoref()) return (0); # ifdef xDEBUG if (Chardebug || Lex_debug) printf("include file - pop\n"); # endif } for (cp = Line_buf; (*cp = getc(In_file)) != '\n' && *cp != EOF; cp++) { if (cp - Line_buf > sizeof Line_buf - 1) { yysemerr("WARNING : line too long, broken in two\n", 0); break; } } if (*cp == EOF) { eoflag++; if (cp == Line_buf) /* EOF after '\n' */ continue; /* EOF in middle of line */ *cp = '\n'; } Line_pos = Line_buf; /* test for a "#include" line */ if (tst_include()) { /* Force reloading Line_buf */ Line_pos = 0; eoflag = 0; # ifdef xDEBUG if (Chardebug || Lex_debug) printf("include file - push\n"); # endif continue; } } cp = Line_pos; if (*cp == '\n') { Line_pos = 0; yyline += 1; } else Line_pos++; ch = *cp; break; } } ch &= I1MASK; # ifdef xDEBUG if (Chardebug) printf("getch - returning '%c'.\n", ch); # endif return (ch); } /* ** BACKUP -- Back up a character on the input stream. ** Backs up a single character into Peekc. ** ** Parameters: ** ch - character to back up ** ** Returns: ** none ** ** Side Effects: ** pushes Peekc [0] to Peekc [1]. ** sets Peekc [0] to backed up character. */ backup(ch) char ch; { extern int yyline; # ifdef xDEBUG if (Chardebug) printf("backed up : '%c'\n", ch); # endif if (Peekc [1] >= 0) syserr("backup buffer overflow on line %d, \"%c%c%c\".", yyline, Peekc [0], Peekc [1], ch); Peekc [1] = Peekc [0]; if ((Peekc [0] = ch & I1MASK) == '\n') --yyline; }