/*
 * yylex for lex tables
 */

/*
 * Bob Denny 28-Aug-82  Remove reference to stdio.h
 * Remove code to default lexin, change to call to
 * llstin(), generated by lex depending upon setting
 * of "-s" switch.  Eliminates hardwired dependency
 * on standard I/O library.  Moved declaration of
 * lexin to lexgetc().
 *
 * Bob Denny 31-Aug-82  Add call to lexswitch() in
 * the generated file, to switch to the table whose
 * name was given in the "-t" switch (or to "lextab"
 * if "-t" wasn't given).  Removed hardwired setting
 * of _tabp --> "lextab" here. Now handled automagically.
 *
 * Bob Denny 21-Oct-82  Add llinit() function to re-initialize
 * yylex(), making it serially reusable.
 *
 * Initialize _tabp to NULL so lexswitch() to real table happens
 * only once.
 *
 * Bob Denny 15-Apr-83 Move NBPW to LEX.H and make it 32 on VAX native,
 *                     else 16.
 */

#ifdef	vms
#include	"c:lex.h"
#else
#include	<lex.h>
#endif

/*)LIBRARY
*/

#define	ERROR	256	/* yacc's value */

/* check a bit table 'tab' indexed by 'c' to see if the bit is set */
tst__b(c, tab)
int c;
char tab[];
{
	return(tab[(c >> 3) & 0x1f] & (1 << (c & 0x7)) );
}

struct	lextab	*_tabp = 0;

extern char	*llsave[];	/* Right-context buffer			*/
char	llbuf[100];		/* work buffer				*/
char	*llp1	= &llbuf[0];	/* pointer to next avail. in token	*/
char	*llp2	= &llbuf[0];	/* pointer to end of lookahead		*/
char	*llend	= &llbuf[0];	/* pointer to end of token		*/
char	*llebuf = &llbuf[sizeof llbuf];
int	lleof;
int	yylval	= 0;
int	yyline	= 0;

yylex()
{
	int c, st;
	int final, l, llk, i;
	auto struct lextab *lp;
	char *cp;

	/*
	 * Call llstin() to default lexin to stdin
	 * and assign _tabp to "real" table.
	 */
	llstin();			/* Initialize yylex() variables */

loop:
	llk = 0;
	if (llset())
		return(0);		/* Prevent EOF loop	*/
	st = 0;
	final = -1;
	lp = _tabp;

	do {
#ifdef cptrace
		printf("yylex , state = %d\n",st);
		printf("yylex , lp->lllook = %d\n",lp->lllook);
#endif
		if (lp->lllook && (l = lp->lllook[st]))
			{
			for (c=0; c<NBPW; c++)
				if (l&(1<<c))
					llsave[c] = llp1;
			llk++;
			};

#ifdef cptrace
		printf("yylex, (*(lp->llfinal))[st] = %d\n",
			(*(lp->llfinal))[st]);
#endif
		if ((i = (*(lp->llfinal))[st]) != -1)
			{
			final = i;
			llend = llp1;
			};

		if ((c = llinp()) < 0)
			break;

#ifdef cptrace
		printf("yylex , c = %x.%c\n",c,c);
#endif
		if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp))
			{
			llp1--;

#ifdef cptrace
			printf("yylex , breaking out of while\n");
#endif
			break;
			}
	} while ((st = (*lp->llmove)(lp, c, st)) != -1);

	if (llp2 < llp1)
		llp2 = llp1;
	if (final == -1) {
		llend = llp1;
		if (st == 0 && c < 0)
			return(0);
		if ((cp = lp->llill) && tst__b(c, cp)) {
#ifdef vms
			lexerror("Illegal (out of range) input character");
#else
			lexerror("Illegal character: %c (%03o)", c, c);
#endif
			goto loop;
		}
		return(ERROR);
	}
	if (c = (final >> 11) & 037)
		llend = llsave[c-1];
	if ((c = (*lp->llactr)(final&03777)) >= 0)
		return(c);
	goto loop;
}

llinp()
{
	int c;
	auto struct lextab *lp;
	auto char *cp;

	lp = _tabp;
	cp = lp->llign;				/* Ignore class		*/
	for (;;) {
		/*
		 * Get the next character from the save buffer (if possible)
		 * If the save buffer's empty, then return EOF or the next
		 * input character.  Ignore the character if it's in the
		 * ignore class.
		 */
		c = (llp1 < llp2) ? *llp1 & 0377 : (lleof) ? EOF : lexgetc();
		if (c >= 0) {			/* Got a character?	*/
			if (cp && tst__b(c, cp))
				continue;	/* Ignore it		*/
			if (llp1 >= llebuf) {	/* No, is there room?	*/
				lexerror("Token buffer overflow");
				exit(1);
			}
			*llp1++ = c;		/* Store in token buff	*/
		} else
			lleof = 1;		/* Set EOF signal	*/
		return(c);
	}
}

llset()
/*
 * Return TRUE if EOF and nothing was moved in the look-ahead buffer
 */
{
	auto char *lp1, *lp2;

	for (lp1 = llbuf, lp2 = llend; lp2 < llp2;)
		*lp1++ = *lp2++;
	llend = llp1 = llbuf;
	llp2 = lp1;
	return(lleof && lp1 == llbuf);
}

/*
 * Re-initialize yylex() so that it can be re-used on
 * another file.
 */
llinit()
   {
   llp1 = llp2 = llend = llbuf;
   llebuf = llbuf + sizeof(llbuf);
   lleof = yylval = yyline = 0;
   }
                                                                                                                                                                                                                                    