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