Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

867 lines
29 KiB

// Copyright (c) 1996-1999 Microsoft Corporation
/*
* preproc1.c - syntax generic preprocessor for parser
*/
#include "gpdparse.h"
//check. static ABSARRAYREF gaarPPPrefix = {"*", 1} ;
// set preprocessor prefix to '*'
// Now moved to GLOBL structure.
// ---- functions defined in preproc1.c ---- //
BOOL DefineSymbol(PBYTE symbol, PGLOBL pglobl) ;
BOOL SetPPPrefix(PABSARRAYREF parrPrefix, PGLOBL pglobl) ;
BOOL BPreProcess(PGLOBL pglobl) ; // from current file position, use file macros to access.
enum DIRECTIVE ParseDirective(
PABSARRAYREF paarCurPos,
PABSARRAYREF parrSymbol,
PGLOBL pglobl) ;
BOOL bSkipAnyWhite(PABSARRAYREF paarCurPos) ;
BOOL bSkipWhiteSpace(PABSARRAYREF paarCurPos) ;
BOOL bmatch(PABSARRAYREF paarCurPos, ABSARRAYREF aarReference) ;
BOOL extractSymbol(PABSARRAYREF paarSymbol, PABSARRAYREF paarCurPos) ;
BOOL strmatch(PABSARRAYREF paarCurPos, PCHAR pref ) ;
BOOL ExtractColon(PABSARRAYREF paarCurPos) ;
enum DIRECTIVE IsThisPPDirective(
IN OUT PABSARRAYREF paarFile , // current pos in GPD file
PABSARRAYREF paarSymbol, // return reference to heap copy of directive symbol
PGLOBL pglobl);
void deleteToEOL(PABSARRAYREF paarCurPos) ;
int BytesToEOL(PABSARRAYREF paarCurPos) ;
BOOL SymbolTableAdd(
PABSARRAYREF parrSymbol,
PGLOBL pglobl) ;
BOOL SymbolTableRemove(
PABSARRAYREF parrSymbol,
PGLOBL pglobl) ;
BOOL SymbolTableExists(
PABSARRAYREF parrSymbol,
PGLOBL pglobl) ;
// ---------------------------------------------------- //
// ERR(("%*s\n", BytesToEOL(paarCurPos), paarCurPos->pub ));
BOOL DefineSymbol(
PBYTE symbol,
PGLOBL pglobl)
{
ABSARRAYREF aarSymbol ;
ARRAYREF arSymbolName ;
aarSymbol.pub = symbol ;
aarSymbol.dw = strlen(symbol);
#if 0
this is not needed because SymbolTableAdd now always
makes a copy of the aarSymbol.
if(!BaddAARtoHeap(&aarSymbol, &arSymbolName, 1, pglobl))
{
ERR(("Internal error, unable to define %s!\n", symbol));
return FALSE ;
}
aarSymbol.pub = arSymbolName.loOffset + mpubOffRef ;
aarSymbol.dw = arSymbolName.dwCount ;
#endif
if(! SymbolTableAdd(&aarSymbol, pglobl) )
{
ERR(("Internal error, unable to define %s!\n", symbol));
return FALSE ;
}
return TRUE ;
}
BOOL SetPPPrefix(
PABSARRAYREF parrPrefix,
PGLOBL pglobl)
{
if(!parrPrefix->dw)
{
ERR(("#SetPPPrefix: syntax error - preprocessor prefix cannot be NULL !\n"));
// optional: report filename and line number
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_FATAL ;
return FALSE ;
}
gaarPPPrefix = *parrPrefix ;
return TRUE ;
}
// GPD preprocessor: implements the following preprocessor directives:
// #Define: symbol
// #Undefine: symbol
// #Include: filename Note: this uses the exact syntax used by
// The GPD *Include: keyword except * is replaced by #
// #Ifdef: symbol
// #Elseifdef: symbol
// #Else:
// #Endif:
// #SetPPPrefix: symbol
//
// notes: when #Include: is found, just replace prefix with '*'.
// instead of compressing file when #ifdefs are processed, just 'erase' unwanted
// sections with space chars. (leaving \n and \r unchanged to preserve line #'s)
// Need to store some global state information. like how many nesting levels
// what are we currently doing, what symbols are defined etc.
// Definitions:
// Section: these directives act as section delimiters:
// #Ifdef: symbol
// #Elseifdef: symbol
// #Else:
// #Endif:
// Nesting level: the number of unmatched #ifdefs at the current position
// determines the nesting level at that position.
// Note in these source code comments '#' represents the current preprocessor prefix.
// This is set to '*' by default, but is changed using the #SetPPPrefix: directive.
BOOL BPreProcess(
PGLOBL pglobl)
// from current file position, use file macros to access.
{
BOOL bStatus = FALSE ;
ABSARRAYREF arrSymbol , // holds symbol portion of directive.
aarCurPos ; // holds current position in source file buffer.
enum DIRECTIVE directive ;
enum IFSTATE prevsIFState ;
enum PERMSTATE prevsPermState ;
aarCurPos.pub = mpubSrcRef + mdwSrcInd ;
aarCurPos.dw = mdwSrcMax - mdwSrcInd ;
while((directive = ParseDirective(&aarCurPos, &arrSymbol, pglobl)) != DIRECTIVE_EOF)
{
switch(directive)
{
case DIRECTIVE_DEFINE:
if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
{
if(!SymbolTableAdd(&arrSymbol, pglobl) )
return(FALSE); // error!
}
break;
case DIRECTIVE_UNDEFINE:
if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
{
if(!SymbolTableRemove(&arrSymbol, pglobl) )
{
if(geErrorSev != ERRSEV_FATAL )
{
ERR(("syntax error - attempting to undefine a symbol that isn't defined !\n"));
ERR(("%.*s\n", BytesToEOL(&arrSymbol), arrSymbol.pub ));
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_FATAL ;
goto PREPROCESS_FAILURE;
}
}
}
break;
case DIRECTIVE_INCLUDE:
if(mppStack[mdwNestingLevel].permState != PERM_ALLOW)
{
deleteToEOL(&aarCurPos) ;
break; // it never happened.
}
goto PREPROCESS_SUCCESS ;
break;
case DIRECTIVE_SETPPPREFIX :
if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
SetPPPrefix(&arrSymbol, pglobl);
break;
case DIRECTIVE_IFDEF:
// state-invariant behavior
prevsPermState = mppStack[mdwNestingLevel].permState ;
mdwNestingLevel++ ;
if(mdwNestingLevel >= mMaxNestingLevel)
{
if(ERRSEV_RESTART > geErrorSev)
{
geErrorType = ERRTY_MEMORY_ALLOCATION ;
geErrorSev = ERRSEV_RESTART ;
gdwMasterTabIndex = MTI_PREPROCSTATE ;
}
goto PREPROCESS_FAILURE;
}
if(SymbolTableExists(&arrSymbol, pglobl))
mppStack[mdwNestingLevel].permState = PERM_ALLOW ;
else
mppStack[mdwNestingLevel].permState = PERM_DENY ;
if(prevsPermState != PERM_ALLOW)
mppStack[mdwNestingLevel].permState = PERM_LATCHED ;
mppStack[mdwNestingLevel].ifState = IFS_CONDITIONAL;
break;
case DIRECTIVE_ELSEIFDEF:
if(mppStack[mdwNestingLevel].ifState == IFS_ROOT)
{
ERR(("syntax error - #Elseifdef directive must be preceeded by #Ifdef !\n"));
// optional: report filename and line number
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_FATAL ;
goto PREPROCESS_FAILURE;
}
if(mppStack[mdwNestingLevel].ifState == IFS_LAST_CONDITIONAL)
{
ERR(("syntax error - #Elseifdef directive cannot follow #Else !\n"));
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_FATAL ;
goto PREPROCESS_FAILURE;
}
if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
mppStack[mdwNestingLevel].permState = PERM_LATCHED ;
else if(mppStack[mdwNestingLevel].permState == PERM_DENY)
{
if(SymbolTableExists(&arrSymbol, pglobl))
mppStack[mdwNestingLevel].permState = PERM_ALLOW ;
}
break;
case DIRECTIVE_ELSE :
if(mppStack[mdwNestingLevel].ifState == IFS_ROOT)
{
ERR(("syntax error - #Else directive must be preceeded by #Ifdef or #Elseifdef !\n"));
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_FATAL ;
goto PREPROCESS_FAILURE;
}
if(mppStack[mdwNestingLevel].ifState == IFS_LAST_CONDITIONAL)
{
ERR(("syntax error - #Else directive cannot follow #Else !\n"));
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_FATAL ;
goto PREPROCESS_FAILURE;
}
mppStack[mdwNestingLevel].ifState = IFS_LAST_CONDITIONAL ;
if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
mppStack[mdwNestingLevel].permState = PERM_LATCHED ;
else if(mppStack[mdwNestingLevel].permState == PERM_DENY)
{
mppStack[mdwNestingLevel].permState = PERM_ALLOW ;
}
break;
case DIRECTIVE_ENDIF :
if(mppStack[mdwNestingLevel].ifState == IFS_ROOT)
{
ERR(("syntax error - #Endif directive must be preceeded by #Ifdef or #Elseifdef or #Else !\n"));
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_FATAL ;
goto PREPROCESS_FAILURE;
}
mdwNestingLevel-- ; // restore previous nesting level.
break;
default:
ERR(("internal consistency error - no such preprocessor directive!\n"));
ERR(("%.*s\n", BytesToEOL(&aarCurPos), aarCurPos.pub ));
geErrorType = ERRTY_CODEBUG ;
geErrorSev = ERRSEV_FATAL ;
goto PREPROCESS_FAILURE;
break;
}
}
PREPROCESS_SUCCESS:
return TRUE ;
PREPROCESS_FAILURE:
return FALSE ;
}
enum DIRECTIVE ParseDirective(PABSARRAYREF paarCurPos,
PABSARRAYREF parrSymbol,
PGLOBL pglobl)
{
// this function parses from the 'current' position: mdwSrcInd
// for any recognized directive and returns that directive.
// if (mppStack[mdwNestingLevel].permState != PERM_ALLOW)
// all characters != \n or \r encountered while looking for the directive
// will be replaced by space characters.
//
// the entire line containing the directive is replaced by spaces.
// (except for the Include directive - only the prefix is replaced by '*'
// with leftpadded spaces if needed.)
// cur pos is set to the line following the one containing the directive.
// before the directive is destroyed, a copy is made of the symbol argument
// and a reference parrSymbol is initialized to point to this copy.
// this copy is stored on the heap so it's lifetime is effectively 'forever'.
// syntax of directive:
// a directive token must be immediately preceeded by the current preprocessor
// prefix. The prefix must be preceeded by a line delimiter (unless its the
// first line in the file). Optional whitespace characters (space or tab) may reside between
// the line delimiter and the prefix.
// the actual DIRECTIVE Token may be followed by Optional whitespace, then must
// be followed by the Colon delimiter, the next non-whitespace token is interpreted
// as the symbol. Any characters following the symbol token to the line delimiter
// will be ignored. A Directive cannot occupy more than one line.
// this function assumes cur pos points to start of line when it is called.
enum DIRECTIVE directive ;
BOOL bStartOfNewLine = TRUE ;
BYTE ubSrc ;
while( paarCurPos->dw ) // EOF detector
{
if(bStartOfNewLine && // directives must start at newline or
// have only whitespace intervening
(directive = IsThisPPDirective( paarCurPos, parrSymbol, pglobl)) != NOT_A_DIRECTIVE )
{
return directive;
}
ubSrc = *paarCurPos->pub ;
//extract current character
if(ubSrc != '\n' && ubSrc != '\r')
{
bStartOfNewLine = FALSE ;
if(mppStack[mdwNestingLevel].permState != PERM_ALLOW)
{
*paarCurPos->pub = ' ' ; // replace with harmless space.
}
}
else
bStartOfNewLine = TRUE ;
(paarCurPos->pub)++ ; // advance to next character.
(paarCurPos->dw)-- ;
}
return DIRECTIVE_EOF ;
}
BOOL bSkipAnyWhite(PABSARRAYREF paarCurPos)
// checks for EOF
{
while( paarCurPos->dw ) // EOF detector
{
BYTE ubSrc = *paarCurPos->pub ;
//extract current character
if(ubSrc != ' ' && ubSrc != '\t' && ubSrc != '\n' && ubSrc != '\r')
{
return TRUE ; // Non-white char encountered
}
(paarCurPos->pub)++ ; // advance to next character.
(paarCurPos->dw)-- ;
}
return FALSE ; // reached eof
}
BOOL bSkipWhiteSpace(PABSARRAYREF paarCurPos)
{
// checks for EOF
while( paarCurPos->dw ) // EOF detector
{
BYTE ubSrc = *paarCurPos->pub ;
//extract current character
if(ubSrc != ' ' && ubSrc != '\t' )
{
return TRUE ; // Non-white char encountered
}
(paarCurPos->pub)++ ; // advance to next character.
(paarCurPos->dw)-- ;
}
return FALSE ; // reached eof
}
BOOL bmatch(PABSARRAYREF paarCurPos, ABSARRAYREF aarReference)
// checks for EOF
{
if(!paarCurPos->dw)
return FALSE ; // reached eof
if(paarCurPos->dw < aarReference.dw)
return FALSE ; // not enough chars in buffer to match reference.
if(strncmp(paarCurPos->pub, aarReference.pub, aarReference.dw))
return FALSE ;
paarCurPos->pub += aarReference.dw ; // otherwise we match the reference!!
paarCurPos->dw -= aarReference.dw ; // advance pointer past matching substring
return TRUE ;
}
BOOL extractSymbol(PABSARRAYREF paarSymbol, PABSARRAYREF paarCurPos)
// checks for EOF
{
paarSymbol->pub = paarCurPos->pub ;
for(paarSymbol->dw = 0 ; paarCurPos->dw ; paarSymbol->dw++,
(paarCurPos->pub)++ , paarCurPos->dw--)
{
BYTE ubSrc = *paarCurPos->pub ;
//extract current character
if(ubSrc == ' ' || ubSrc == '\t' || ubSrc == '\n' || ubSrc == '\r')
{
break;
}
}
if(!paarSymbol->dw)
return FALSE ; // nothing?
return TRUE ; // this is our preprocessor symbol.
}
BOOL strmatch(PABSARRAYREF paarCurPos, PCHAR pref )
// checks for EOF - means dw cannot go neg.
{
DWORD dwRefLen ;
if(!paarCurPos->dw)
return FALSE ; // reached eof
dwRefLen = strlen(pref);
if(paarCurPos->dw < dwRefLen)
return FALSE ; // not enough chars in buffer to match reference.
if(strncmp(paarCurPos->pub, pref, dwRefLen))
return FALSE ; // no match
paarCurPos->pub += dwRefLen ; // otherwise we match the reference!!
paarCurPos->dw -= dwRefLen ; // advance pointer past matching substring
return TRUE ; // match!
}
BOOL ExtractColon(PABSARRAYREF paarCurPos)
// checks for EOF - means dw cannot go neg.
{
if(! bSkipWhiteSpace( paarCurPos) )
return FALSE ; // reached EOF
if(!strmatch(paarCurPos, ":" ) )
return FALSE ; // no match
if(! bSkipWhiteSpace( paarCurPos) )
return FALSE ; // reached EOF
return TRUE ; // match!
}
enum DIRECTIVE IsThisPPDirective(
IN OUT PABSARRAYREF paarFile , // current pos in GPD file
PABSARRAYREF paarSymbol, // return reference to heap copy of directive symbol
PGLOBL pglobl)
// This function only processes the current line and determines if
// the current line is a valid preprocessor directive.
// This function assumes paarFile initially points to start of the line
// if this is a directive, advances paarFile->pub to EOL and replaces the
// line with spaces.
// if not a directive, advances paarFile->pub past initial whitespace padding.
// to reduce repeat processing.
{
ABSARRAYREF aarPrefix, // points to first non-white char found
aarDirective; // points right after prefix.
enum DIRECTIVE directive ;
// PBYTE pBuff = paarFile->pub ;
// there can only be whitespace padding or linebreaks preceeding prefix:
if(!bSkipAnyWhite(paarFile )) // skip any combination of spaces , tabs and linebreaks
return DIRECTIVE_EOF ;
// EOF overflow has occured or some bizzare failure!
aarPrefix = *paarFile; // remember location of the prefix or first non-white char
if(!bmatch(paarFile, gaarPPPrefix)) // advances paarFile
{
*paarFile = aarPrefix ; // restore to just beyond white padding
return NOT_A_DIRECTIVE ;
}
aarDirective = *paarFile ;
if(strmatch(paarFile, "Define") )
directive = DIRECTIVE_DEFINE;
else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Undefine") )
directive = DIRECTIVE_UNDEFINE;
else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Include") )
directive = DIRECTIVE_INCLUDE;
else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Ifdef") )
directive = DIRECTIVE_IFDEF;
else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Elseifdef") )
directive = DIRECTIVE_ELSEIFDEF;
else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Else") )
directive = DIRECTIVE_ELSE;
else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Endif") )
directive = DIRECTIVE_ENDIF;
else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "SetPPPrefix") )
directive = DIRECTIVE_SETPPPREFIX ;
else
{ // (directive == NOT_A_DIRECTIVE)
*paarFile = aarPrefix ; // restore to just beyond white padding
return NOT_A_DIRECTIVE ;
}
if(directive == DIRECTIVE_INCLUDE)
{
// replace prefix with leftpadded '*' ;
DWORD dwI ;
for(dwI = 0 ; dwI < gaarPPPrefix.dw ; dwI++)
(aarPrefix.pub)[dwI] = ' ' ; // replace prefix with all spaces
(aarPrefix.pub)[ gaarPPPrefix.dw - 1] = '*' ; // last char becomes '*'.
*paarFile = aarPrefix ; // this allows *Include: entry to be deleted if != PERM_ALLOW
return directive;
}
if(!ExtractColon(paarFile)) // parse surrounding spaces also.
{
ERR(("syntax error - colon delimiter required after preprocessor directive !\n"));
ERR(("%.*s\n", BytesToEOL(&aarPrefix), aarPrefix.pub ));
if(geErrorSev < ERRSEV_CONTINUE)
{
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_CONTINUE ;
}
*paarFile = aarPrefix ; // restore to just beyond white padding
return NOT_A_DIRECTIVE ;
}
if(directive == DIRECTIVE_SETPPPREFIX ||
directive == DIRECTIVE_ELSEIFDEF ||
directive == DIRECTIVE_IFDEF ||
directive == DIRECTIVE_UNDEFINE ||
directive == DIRECTIVE_DEFINE)
{
ARRAYREF arSymbolName ;
if(!extractSymbol(paarSymbol, paarFile)) // identifies substring of paarFile
{
ERR(("syntax error - symbol required after this preprocessor directive !\n"));
ERR(("%.*s\n", BytesToEOL(&aarPrefix), aarPrefix.pub ));
if(geErrorSev < ERRSEV_CONTINUE)
{
geErrorType = ERRTY_SYNTAX ;
geErrorSev = ERRSEV_CONTINUE ;
}
*paarFile = aarPrefix ; // restore to just beyond white padding
return NOT_A_DIRECTIVE ;
}
/* I would use
BOOL BcopyToTmpHeap() (token1.c)
except this will confuse the
heck out of Register symbol, which is expecting all strings to
be stored in the regular heap! */
if(!BaddAARtoHeap(paarSymbol, &arSymbolName, 1, pglobl))
return(DIRECTIVE_EOF ); // cause a swift abort
paarSymbol->pub = arSymbolName.loOffset + mpubOffRef ;
paarSymbol->dw = arSymbolName.dwCount ;
// permanent location of symbol in Heap.
}
// replace all non-white chars on the line to EOL or EOF with spaces ;
*paarFile = aarPrefix ;
deleteToEOL(paarFile) ;
return directive;
}
void deleteToEOL(PABSARRAYREF paarCurPos)
// actually replace with space chars
{
for( ; paarCurPos->dw ; paarCurPos->pub++, paarCurPos->dw--)
{
BYTE ubSrc = *(paarCurPos->pub) ;
if(ubSrc != '\n' && ubSrc != '\r')
*(paarCurPos->pub) = ' ' ; // replace with harmless space.
else
break; // reached EOL. paarFile points to EOL.
}
}
int BytesToEOL(PABSARRAYREF paarCurPos)
{
int iCount ;
for(iCount = 0 ; paarCurPos->dw > (DWORD)iCount ; iCount++)
{
BYTE ubSrc = paarCurPos->pub[iCount] ;
if(ubSrc == '\n' || ubSrc == '\r')
break; // reached EOL.
}
return(iCount) ;
}
BOOL SymbolTableAdd(
PABSARRAYREF paarSymbol,
PGLOBL pglobl)
{
DWORD dwSymbolID ;
dwSymbolID = DWregisterSymbol(paarSymbol, CONSTRUCT_PREPROCESSOR,
TRUE, INVALID_SYMBOLID, pglobl) ;
if(dwSymbolID == INVALID_SYMBOLID)
{
return(FALSE );
}
return TRUE ;
}
BOOL SymbolTableRemove(
PABSARRAYREF paarSymbol,
PGLOBL pglobl)
{
DWORD dwSymbolID , dwCurNode;
PSYMBOLNODE psn ;
dwSymbolID = DWsearchSymbolListForAAR(paarSymbol, mdwPreProcDefinesSymbols, pglobl) ;
if(dwSymbolID == INVALID_SYMBOLID)
{
return(FALSE );
}
dwCurNode = DWsearchSymbolListForID(dwSymbolID,
mdwPreProcDefinesSymbols, pglobl) ;
if(dwCurNode == INVALID_INDEX)
{
ERR(("Parser error - can't find symbol node !\n"));
geErrorType = ERRTY_CODEBUG ;
geErrorSev = ERRSEV_FATAL ;
return(FALSE ); // cause a swift abort
}
psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
// how do you remove this node from the symbol tree?
psn[dwCurNode].arSymbolName.dwCount = 0 ;
// can't navigate backwards along tree so just truncate string!
return TRUE ;
}
BOOL SymbolTableExists(
PABSARRAYREF paarSymbol,
PGLOBL pglobl)
{
DWORD dwSymbolID ;
dwSymbolID = DWsearchSymbolListForAAR(paarSymbol, mdwPreProcDefinesSymbols, pglobl) ;
if(dwSymbolID == INVALID_SYMBOLID)
{
return(FALSE );
}
return TRUE ;
}
#if 0
>>>>
DWORD dwCurNode, dwSymbolID ;
PSYMBOLNODE psn ;
dwSymbolID = DWregisterSymbol(paarSymbol, CONSTRUCT_PREPROCESSOR,
FALSE, INVALID_SYMBOLID) ;
if(dwSymbolID == INVALID_SYMBOLID)
{
return(DIRECTIVE_EOF ); // cause a swift abort
}
dwCurNode = DWsearchSymbolListForID(dwSymbolID,
mdwPreProcDefinesSymbols) ;
if(dwCurNode == INVALID_INDEX);
{
ERR(("Parser error - can't find symbol node !\n"));
geErrorType = ERRTY_CODEBUG ;
geErrorSev = ERRSEV_FATAL ;
return(DIRECTIVE_EOF ); // cause a swift abort
}
psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
paarSymbol->pub = psn[dwCurNode].arSymbolName.loOffset + mpubOffRef ;
paarSymbol->dw = psn[dwCurNode].arSymbolName.dwCount ;
SymbolTableAdd(&aarSymbol);
may use from state1.c
DWORD DWregisterSymbol(
PABSARRAYREF paarSymbol, // the symbol string to register
CONSTRUCT eConstruct , // type of construct determines class of symbol.
BOOL bCopy, // shall we copy paarSymbol to heap? May set
DWORD dwFeatureID // if you are registering an option symbol
// and you already know the feature , pass it in
// here. Otherwise set to INVALID_SYMBOLID
)
/* this function registers the entire string specified
in paarSymbol. The caller must isolate the string.
*/
{
// returns SymbolID, a zero indexed ordinal
// for extra speed we may hash string
but what do we define for symbol class?
if(eConstruct == CONSTRUCT_FONTCART)
pdwSymbolClass += SCL_FONTCART ;
else if(eConstruct == CONSTRUCT_TTFONTSUBS)
pdwSymbolClass += SCL_TTFONTNAMES ;
else if(eConstruct == CONSTRUCT_COMMAND)
pdwSymbolClass += SCL_COMMANDNAMES ;
else if(eConstruct == CONSTRUCT_BLOCKMACRO)
pdwSymbolClass += SCL_BLOCKMACRO;
else if(eConstruct == CONSTRUCT_MACROS)
pdwSymbolClass += SCL_VALUEMACRO;
else if(eConstruct == CONSTRUCT_PREPROCESSOR)
pdwSymbolClass += SCL_PPDEFINES;
else
pdwSymbolClass += SCL_FEATURES ;
DWORD DWsearchSymbolListForAAR(
PABSARRAYREF paarSymbol,
DWORD dwNodeIndex) ;
// given a 'aar' to a string representing a symbol, search
// the SymbolList beginning at dwNodeIndex for this symbol.
// Return its symbolID if found, else return the INVALID_SYMBOLID.
{
PSYMBOLNODE psn ;
psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
for( ; dwNodeIndex != INVALID_INDEX ;
dwNodeIndex = psn[dwNodeIndex].dwNextSymbol)
{
if(BCmpAARtoAR(paarSymbol, &(psn[dwNodeIndex].arSymbolName)) )
return(psn[dwNodeIndex].dwSymbolID); // string matches !
}
return(INVALID_SYMBOLID);
}
fragments for future use:
from framwrk1.c:
VOID VinitGlobals()
gMasterTable[MTI_SYMBOLROOT].dwArraySize = SCL_NUMSYMCLASSES ;
gMasterTable[MTI_SYMBOLROOT].dwMaxArraySize = SCL_NUMSYMCLASSES ;
gMasterTable[MTI_SYMBOLROOT].dwElementSiz = sizeof(DWORD) ;
gMasterTable[MTI_STSENTRY].dwArraySize = 20 ;
gMasterTable[MTI_STSENTRY].dwMaxArraySize = 60 ;
gMasterTable[MTI_STSENTRY].dwElementSiz = sizeof(STSENTRY) ;
modify to serve as the preprocessor state Stack
need also macros to access the stack.
// ----- Preprocessor Section ---- // from gpdparse.h
enum IFSTATE {IFS_ROOT, IFS_CONDITIONAL , IFS_LAST_CONDITIONAL } ;
// tracks correct syntatical use of #ifdef, #elseifdef, #else and #endif directives.
enum PERMSTATE {PERM_ALLOW, PERM_DENY , PERM_LATCHED } ;
// tracks current state of preprocessing,
// PERM_ALLOW: all statements in this section are passed to body gpdparser
// PERM_DENY: statements in this section are discarded
// PERM_LATCHED: all statements until the end of this nesting level are discarded.
enum DIRECTIVE {NOT_A_DIRECTIVE, DIRECTIVE_EOF, DIRECTIVE_DEFINE , DIRECTIVE_UNDEFINE ,
DIRECTIVE_INCLUDE , DIRECTIVE_SETPPPREFIX , DIRECTIVE_IFDEF ,
DIRECTIVE_ELSEIFDEF , DIRECTIVE_ELSE , DIRECTIVE_ENDIF }
typedef struct
{
enum IFSTATE ifState ;
enum PERMSTATE permState ;
} PPSTATESTACK, * PPPSTATESTACK ;
// the tagname is 'ppss'
MTI_PREPROCSTATE, // array of PPSTATESTACK structures
// which hold state of preprocessor.
gMasterTable[MTI_PREPROCSTATE].dwArraySize = 20 ;
gMasterTable[MTI_PREPROCSTATE].dwMaxArraySize = 100 ;
gMasterTable[MTI_PREPROCSTATE].dwElementSiz = sizeof(PPSTATESTACK) ;
#define mppStack ((PPPSTATESTACK)(gMasterTable \
[MTI_PREPROCSTATE].pubStruct))
// location of first SOURCEBUFFER element in array
#define mdwNestingLevel (gMasterTable[MTI_PREPROCSTATE].dwCurIndex)
// current preprocessor directive nesting level
#define mMaxNestingLevel (gMasterTable[MTI_PREPROCSTATE].dwArraySize)
// max preprocessor directive nesting depth
// init preprocessor state stack
mdwNestingLevel = 0 ;
mppStack[mdwNestingLevel].permState = PERM_ALLOW ;
mppStack[mdwNestingLevel].ifState = IFS_ROOT;
#endif
// ---- End Of Preprocessor Section ---- //