/* ----------------------------------------------------------------
 *   FILE
 *	lexdep.c
 *	
 *   DESCRIPTION
 *	dependencies of the lexical scanner: here lex
 *
 *   NOTES
 *	yytext: char yytext[]
 *	the lexer reads input via input()
 *	input data is pushed back via unput()
 *
 *   IDENTIFICATION
 *	???
 * ----------------------------------------------------------------
 */

#include <stdio.h>
#include "utils/log.h"
#include "dep.h"


/*
 * Default error handler for syntax errors.
 */
void
yyerror(message)
char    message[];
{
    elog(WARN, "parser: %s at or near \"%s\"\n", message, yytext);
}


/*
 *	Scanner error handler.
 */
void
serror(str)
char str[];
{
	elog(WARN, "*** scanner error: %s\n", str);
}


void
init_io()
{
    Ch = NULL;
}


int
scan_input()
{
    int c;

    if (StringInput) {
	if (Ch == NULL) {
	    Ch = TheString;
	    return(*Ch++);
	} else if (*Ch == '\0') {
	    return(0);
	} else {
	    return(*Ch++);
	}
    } else {
	c = getchar();
	if (c == EOF) {
	    return(0);
	} else {
	    return(c);
	}
    }
}


void
scan_unput(c)
char c;
{
    if (StringInput) {
	if (Ch == NULL) {
	    elog(FATAL, "Unput() failed.\n");
	    /* NOTREACHED */
	} else if (c != 0) {
	    *--Ch = c;
	}
    } else {
	ungetc(c, stdin);
    }
}


void
parser_cleanup()
{
}


/**********************************************************************
  SkipToFromList

  - employ lookahead to see if there is indeed a from_list
  ahead of us.  If so, skip to it and continue processing

 **********************************************************************/
  
static char *target_list_place;
static char *from_list_place;
  
void
SkipForwardToFromList()
{
        LispValue next_token;
        extern char *Ch;
        char *temp = Ch;

        while ((int)(next_token=(LispValue)yylex()) > 0 &&
	       (next_token != (LispValue) FROM &&
		/*
		 * Stop at the beginning of any statement that can have 
		 * a "from" clause (i.e., all optimizable statements --
		 * "execute" doesn't really exist).
		 */
		next_token != (LispValue) APPEND &&
		next_token != (LispValue) DELETE &&
		next_token != (LispValue) REPLACE &&
		next_token != (LispValue) RETRIEVE))
	     ; /* empty while */

        if (next_token == (LispValue) FROM ) {
                Ch -= 4;
                from_list_place = Ch;
                target_list_place = temp;
        } else {
		Ch = temp;
        }
}

LispValue
SkipBackToTlist()
{
	extern char yytext[];
	extern LispValue yychar;
	extern int yyleng;
        extern char *Ch;
	int i;

	/* need to put the token after the target_list back first */
	switch ((int) yychar) {
	/*
	 * by examination of gram.y, these seem to be the only clauses
	 * that can follow the "from_clause" non-terminal.  at least,
	 * someone else thought so.
	 */
	case WHERE:
	case SORT:
	/*
	 * these can also follow "from_clause" if we have multiple 
	 * queries, with some empty "from_clause"s.. 
	 */
	case APPEND:
	case DELETE:
	case REPLACE:
	case RETRIEVE:
		for (i = yyleng; i > -1 ; -- i ) {
			unput (yytext[i]);
		}
		break;
	}

	bcopy(Ch,from_list_place,strlen(Ch) + 1 );
	Ch = target_list_place;
	return(LispNil);
}



#include "tmp/acl.h"

void
dep_aclparse(aip, modechg)
        AclItem *aip;
	unsigned *modechg;
{
	Ch = aclparse(Ch, aip, modechg);
}
