/* DLGLexerBase.c
 *
 * SOFTWARE RIGHTS
 *
 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
 * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
 * company may do whatever they wish with source code distributed with
 * PCCTS or the code generated by PCCTS, including the incorporation of
 * PCCTS, or its output, into commerical software.
 *
 * We encourage users to develop software with PCCTS.  However, we do ask
 * that credit is given to us for developing PCCTS.  By "credit",
 * we mean that if you incorporate our source code into one of your
 * programs (commercial product, research project, or otherwise) that you
 * acknowledge this fact somewhere in the documentation, research report,
 * etc...  If you like PCCTS and have developed a nice tool with the
 * output, please mention that you developed it using PCCTS.  In
 * addition, we ask that this header remain intact in our source code.
 * As long as these guidelines are kept, we expect to continue enhancing
 * this system and expect to make other tools available as they are
 * completed.
 *
 * ANTLR 1.33
 * Terence Parr
 * Parr Research Corporation
 * with Purdue University and AHPCRC, University of Minnesota
 * 1989-2000
 */

#include "pcctscfg.h"

#include "pccts_stdio.h"
#include "pccts_stdlib.h"

PCCTS_NAMESPACE_STD

/* I have to put this here due to C++ limitation
 * that you can't have a 'forward' decl for enums.
 * I hate C++!!!!!!!!!!!!!!!
 */

// MR1
// MR1  10-Apr-97  133MR1  Prevent use of varying sizes for the
// MR1  			ANTLRTokenType enum
// MR1

enum ANTLRTokenType { TER_HATES_CPP=0, ITS_UTTER_GARBAGE,		// MR1
					 WITH_SOME_GOOD_IDEAS=9999};	// MR1

#define ANTLR_SUPPORT_CODE

#include "pcctscfg.h"
#include DLEXERBASE_H
#include APARSER_H		// MR23

DLGLexerBase::
DLGLexerBase(DLGInputStream *in,
	     unsigned bufsize,
	     int _interactive,
	     int _track_columns)
{
	this->_bufsize = bufsize;
	this->_lextext = new DLGChar[_bufsize];
	if ( this->_lextext==NULL ) {
	    panic("text buffer is NULL");
	}
	this->_begexpr = this->_endexpr = NULL;
	this->ch = this->bufovf = 0;
	this->nextpos = NULL;
	this->cl = 0;
	this->add_erase = 0;
	this->input = in;
	this->_begcol = 0;
	this->_endcol = 0;
	this->_line = 1;
	this->charfull = 0;
	this->automaton = 0;
	this->token_to_fill = NULL;
	this->interactive = _interactive;
	this->track_columns = _track_columns;
	this->debugLexerFlag = 0;					// MR1
	this->parser = NULL;						// MR1
    this->lexErrCount=0;                        // MR11
}

// MR19  THM 

void DLGLexerBase::reset()
{
	this->charfull = 0;
	this->_begcol = 0;
	this->_endcol = 0;
	this->automaton = 0;
	this->_line=1;
	this->lexErrCount=0;
}

void DLGLexerBase::
setInputStream( DLGInputStream *in )
{
	this->input = in;
	_line = 1;
	charfull = 0;
}

/* saves dlg state, but not what feeds dlg (such as file position) */
void DLGLexerBase::
saveState(DLGState *state)
{
	state->input = input;
	state->interactive = interactive;
	state->track_columns = track_columns;
	state->auto_num = automaton;
	state->add_erase = add_erase;
	state->lookc = ch;
	state->char_full = charfull;
	state->begcol = _begcol;
	state->endcol = _endcol;
	state->line = _line;
	state->lextext = _lextext;
	state->begexpr = _begexpr;
	state->endexpr = _endexpr;
	state->bufsize = _bufsize;
	state->bufovf = bufovf;
	state->nextpos = nextpos;
	state->class_num = cl;
	state->debugLexerFlag = debugLexerFlag;				// MR1
	state->parser = parser;						// MR1
}

void DLGLexerBase::
restoreState(DLGState *state)
{
	input = state->input;
	interactive = state->interactive;
	track_columns = state->track_columns;
	automaton = state->auto_num;
	add_erase = state->add_erase;
	ch = state->lookc;
	charfull = state->char_full;
	_begcol = state->begcol;
	_endcol = state->endcol;
	_line = state->line;
	_lextext = state->lextext;
	_begexpr = state->begexpr;
	_endexpr = state->endexpr;
	_bufsize = state->bufsize;
	bufovf = state->bufovf;
	nextpos = state->nextpos;
	cl = state->class_num;
	debugLexerFlag = state->debugLexerFlag;				// MR1
	parser = state->parser;						// MR1
}

/* erase what is currently in the buffer, and get a new reg. expr */
void DLGLexerBase::
skip()
{
	add_erase = 1;
}

/* don't erase what is in the lextext buffer, add on to it */
void DLGLexerBase::
more()
{
	add_erase = 2;
}

/* substitute c for the reg. expr last matched and is in the buffer */
void DLGLexerBase::
replchar(DLGChar c)
{
	/* can't allow overwriting null at end of string */
	if (_begexpr < &_lextext[_bufsize-1]){
		*_begexpr = c;
		*(_begexpr+1) = '\0';
	}
	_endexpr = _begexpr;
	if (c != '\0') {
		nextpos = _begexpr + 1;
	}
	else {
		nextpos = _begexpr;	/* MR30 Zero terminates string. */
	}
}

/* replace the string s for the reg. expr last matched and in the buffer */

#ifdef _MSC_VER  // MR23
//Turn off "assignment within conditional expression" warning
#pragma warning(disable : 4706)
#endif
void DLGLexerBase::
replstr(const DLGChar *s) /* MR20 const */
{
	DLGChar *l= &_lextext[_bufsize -1];

	nextpos = _begexpr;
	if (s){
		while ((nextpos <= l) && (*(nextpos++) = *(s++))){
			/* empty */
		}
		/* correct for NULL at end of string */
		nextpos--;
	}
	if ((nextpos <= l) && (*(--s) == 0)){
		bufovf = 0;
	}else{
		bufovf = 1;
	}
	*(nextpos) = '\0';
	_endexpr = nextpos - 1;
}
#ifdef _MSC_VER  // MR23
#pragma warning(default: 4706)
#endif

void DLGLexerBase::
errstd(const char *s)                               /* MR20 const */
{
        lexErrCount++;                              /* MR11 */
        /* MR23 */ printMessage(stderr,
                "%s near line %d (text was '%s')\n",
                ((s == NULL) ? "Lexical error" : s),
                _line,_lextext);
}

int DLGLexerBase::
err_in()
{
	/* MR23 */ printMessage(stderr,"No input stream, function, or string\n");
	/* return eof to get out gracefully */
	return EOF;
}

ANTLRTokenType DLGLexerBase::
erraction()
{
	errstd("invalid token");
	advance();
	skip();
	return (ANTLRTokenType) 0;	// bogus, but satisfies compiler
}

_ANTLRTokenPtr DLGLexerBase::
getToken()
{
	if ( token_to_fill==NULL ) panic("NULL token_to_fill");
	ANTLRTokenType tt = nextTokenType();
	_ANTLRTokenPtr tk = token_to_fill->makeToken(tt, _lextext,_line);
	return tk;
}

void DLGLexerBase::
panic(const char *msg)      /* MR20 const */
{
	if (parser)				//MR23
		parser->panic(msg);	//MR23
	else					//MR23
	{
		/* MR23 */ printMessage(stderr, "DLG panic: %s\n", msg);
	//
	//  7-Apr-97 133MR1
	//
		exit(PCCTS_EXIT_FAILURE);					// MR1
	}
}

ANTLRParser * DLGLexerBase::						// MR1
setParser(ANTLRParser *p) {						// MR1
  ANTLRParser	*oldValue=parser;					// MR1
  parser=p;								// MR1
  return oldValue;							// MR1
}									// MR1
									// MR1
ANTLRParser * DLGLexerBase::						// MR1
getParser() {								// MR1
  return parser;							// MR1
}									// MR1
									// MR1
int DLGLexerBase::							// MR1
debugLexer(int newValue) {						// MR1
  int	oldValue=debugLexerFlag;					// MR1
  debugLexerFlag=newValue;						// MR1
  return oldValue;							// MR1
}									// MR1

//MR23
int DLGLexerBase::printMessage(FILE* pFile, const char* pFormat, ...)
{
	va_list marker;
	va_start( marker, pFormat );

	int iRet = 0;
	if (parser)
		parser->printMessageV(pFile, pFormat, marker);
	else
  		iRet = vfprintf(pFile, pFormat, marker);

	va_end( marker );
	return iRet;
}
