|
|
BSD 4.3
# include <stdio.h>
# include "constants.h"
# include "globals.h"
# include <sccs.h>
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;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.