170 lines
4 KiB
C
170 lines
4 KiB
C
|
/*** line.c - Line stream related functions
|
||
|
*
|
||
|
* Copyright (c) 1996,1997 Microsoft Corporation
|
||
|
* Author: Michael Tsang (MikeTs)
|
||
|
* Created: 09/04/96
|
||
|
*
|
||
|
* This module implements the line stream layer so that it can
|
||
|
* keep track of the information such as line number and line
|
||
|
* position. This information is necessary for the scanner or
|
||
|
* even the parser to accurately pin point the error location
|
||
|
* in case of syntax or semantic errors.
|
||
|
*
|
||
|
* MODIFICATION HISTORY
|
||
|
*/
|
||
|
|
||
|
#include "pch.h"
|
||
|
|
||
|
/***EP OpenLine - allocate and initialize line structure
|
||
|
*
|
||
|
* ENTRY
|
||
|
* pfileSrc -> source file
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns the pointer to the allocated line structure.
|
||
|
* EXIT-FAILURE
|
||
|
* returns NULL.
|
||
|
*/
|
||
|
|
||
|
PLINE EXPORT OpenLine(FILE *pfileSrc)
|
||
|
{
|
||
|
PLINE pline;
|
||
|
|
||
|
ENTER((5, "OpenLine(pfileSrc=%p)\n", pfileSrc));
|
||
|
|
||
|
if ((pline = malloc(sizeof(LINE))) == NULL)
|
||
|
MSG(("OpenLine: failed to allocate line structure"))
|
||
|
else
|
||
|
{
|
||
|
memset(pline, 0, sizeof(LINE));
|
||
|
pline->pfileSrc = pfileSrc;
|
||
|
}
|
||
|
|
||
|
EXIT((5, "OpenLine=%p\n", pline));
|
||
|
return pline;
|
||
|
} //OpenLine
|
||
|
|
||
|
/***EP CloseLine - free line structure
|
||
|
*
|
||
|
* ENTRY
|
||
|
* pline->line structure
|
||
|
*
|
||
|
* EXIT
|
||
|
* None
|
||
|
*/
|
||
|
|
||
|
VOID EXPORT CloseLine(PLINE pline)
|
||
|
{
|
||
|
ENTER((5, "CloseLine(pline=%p)\n", pline));
|
||
|
|
||
|
free(pline);
|
||
|
|
||
|
EXIT((5, "CloseLine!\n"));
|
||
|
} //CloseLine
|
||
|
|
||
|
/***EP LineGetC - get a character from the line stream
|
||
|
*
|
||
|
* This is equivalent to fgetc() except that it has the line
|
||
|
* stream layer below it instead of directly from the file. It
|
||
|
* is done this way to preserve the line number and line position
|
||
|
* information for accurately pin pointing the error location
|
||
|
* if necessary.
|
||
|
*
|
||
|
* ENTRY
|
||
|
* pline -> line structure
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns the character
|
||
|
* EXIT-FAILURE
|
||
|
* returns error code - EOF (end-of-file)
|
||
|
*/
|
||
|
|
||
|
int EXPORT LineGetC(PLINE pline)
|
||
|
{
|
||
|
int ch = 0;
|
||
|
|
||
|
ENTER((5, "LineGetC(pline=%p)\n", pline));
|
||
|
|
||
|
if (pline->wLinePos >= pline->wLineLen)
|
||
|
{
|
||
|
//
|
||
|
// EOL is encountered
|
||
|
//
|
||
|
if (fgets(pline->szLineBuff, sizeof(pline->szLineBuff), pline->pfileSrc)
|
||
|
!= NULL)
|
||
|
{
|
||
|
pline->wLinePos = 0;
|
||
|
if (!(pline->wfLine & LINEF_LONGLINE))
|
||
|
pline->wLineNum++;
|
||
|
|
||
|
pline->wLineLen = (WORD)strlen(pline->szLineBuff);
|
||
|
|
||
|
if (pline->szLineBuff[pline->wLineLen - 1] == '\n')
|
||
|
pline->wfLine &= ~LINEF_LONGLINE;
|
||
|
else
|
||
|
pline->wfLine |= LINEF_LONGLINE;
|
||
|
}
|
||
|
else
|
||
|
ch = EOF;
|
||
|
}
|
||
|
|
||
|
if (ch == 0)
|
||
|
ch = (int)pline->szLineBuff[pline->wLinePos++];
|
||
|
|
||
|
EXIT((5, "LineGetC=%x (ch=%c,Line=%u,NextPos=%u,LineLen=%u)\n",
|
||
|
ch, ch, pline->wLineNum, pline->wLinePos, pline->wLineLen));
|
||
|
return ch;
|
||
|
} //LineGetC
|
||
|
|
||
|
/***EP LineUnGetC - push a character back to the line stream
|
||
|
*
|
||
|
* This is equivalent to fungetc() except that it's source is
|
||
|
* the line stream not the file stream. Refer to LineGetC for
|
||
|
* explanation on this implementation.
|
||
|
*
|
||
|
* ENTRY
|
||
|
* ch - character being pushed back
|
||
|
* pline -> line structure
|
||
|
*
|
||
|
* EXIT-SUCCESS
|
||
|
* returns the character being pushed
|
||
|
* EXIT-FAILURE
|
||
|
* returns -1
|
||
|
*/
|
||
|
|
||
|
int EXPORT LineUnGetC(int ch, PLINE pline)
|
||
|
{
|
||
|
ENTER((5, "LineUnGetC(ch=%c,pline=%p)\n", ch, pline));
|
||
|
|
||
|
ASSERT(pline->wLinePos != 0);
|
||
|
if (ch != EOF)
|
||
|
{
|
||
|
pline->wLinePos--;
|
||
|
ASSERT((int)pline->szLineBuff[pline->wLinePos] == ch);
|
||
|
}
|
||
|
|
||
|
EXIT((5, "LineUnGetC=%x (ch=%c)\n", ch, ch));
|
||
|
return ch;
|
||
|
} //LineUnGetC
|
||
|
|
||
|
/***EP LineFlush - flush a line
|
||
|
*
|
||
|
* The scanner may want to discard the rest of the line when it
|
||
|
* detects an in-line comment symbol, for example.
|
||
|
*
|
||
|
* ENTRY
|
||
|
* pline -> line structure
|
||
|
*
|
||
|
* EXIT
|
||
|
* none
|
||
|
*/
|
||
|
|
||
|
VOID EXPORT LineFlush(PLINE pline)
|
||
|
{
|
||
|
ENTER((5, "LineFlush(pline=%p)\n", pline));
|
||
|
|
||
|
pline->wLinePos = pline->wLineLen;
|
||
|
|
||
|
EXIT((5, "LineFlush!\n"));
|
||
|
} //LineFlush
|