/*** 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