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

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. /*
  3. * preproc1.c - syntax generic preprocessor for parser
  4. */
  5. #include "gpdparse.h"
  6. //check. static ABSARRAYREF gaarPPPrefix = {"*", 1} ;
  7. // set preprocessor prefix to '*'
  8. // Now moved to GLOBL structure.
  9. // ---- functions defined in preproc1.c ---- //
  10. BOOL DefineSymbol(PBYTE symbol, PGLOBL pglobl) ;
  11. BOOL SetPPPrefix(PABSARRAYREF parrPrefix, PGLOBL pglobl) ;
  12. BOOL BPreProcess(PGLOBL pglobl) ; // from current file position, use file macros to access.
  13. enum DIRECTIVE ParseDirective(
  14. PABSARRAYREF paarCurPos,
  15. PABSARRAYREF parrSymbol,
  16. PGLOBL pglobl) ;
  17. BOOL bSkipAnyWhite(PABSARRAYREF paarCurPos) ;
  18. BOOL bSkipWhiteSpace(PABSARRAYREF paarCurPos) ;
  19. BOOL bmatch(PABSARRAYREF paarCurPos, ABSARRAYREF aarReference) ;
  20. BOOL extractSymbol(PABSARRAYREF paarSymbol, PABSARRAYREF paarCurPos) ;
  21. BOOL strmatch(PABSARRAYREF paarCurPos, PCHAR pref ) ;
  22. BOOL ExtractColon(PABSARRAYREF paarCurPos) ;
  23. enum DIRECTIVE IsThisPPDirective(
  24. IN OUT PABSARRAYREF paarFile , // current pos in GPD file
  25. PABSARRAYREF paarSymbol, // return reference to heap copy of directive symbol
  26. PGLOBL pglobl);
  27. void deleteToEOL(PABSARRAYREF paarCurPos) ;
  28. int BytesToEOL(PABSARRAYREF paarCurPos) ;
  29. BOOL SymbolTableAdd(
  30. PABSARRAYREF parrSymbol,
  31. PGLOBL pglobl) ;
  32. BOOL SymbolTableRemove(
  33. PABSARRAYREF parrSymbol,
  34. PGLOBL pglobl) ;
  35. BOOL SymbolTableExists(
  36. PABSARRAYREF parrSymbol,
  37. PGLOBL pglobl) ;
  38. // ---------------------------------------------------- //
  39. // ERR(("%*s\n", BytesToEOL(paarCurPos), paarCurPos->pub ));
  40. BOOL DefineSymbol(
  41. PBYTE symbol,
  42. PGLOBL pglobl)
  43. {
  44. ABSARRAYREF aarSymbol ;
  45. ARRAYREF arSymbolName ;
  46. aarSymbol.pub = symbol ;
  47. aarSymbol.dw = strlen(symbol);
  48. #if 0
  49. this is not needed because SymbolTableAdd now always
  50. makes a copy of the aarSymbol.
  51. if(!BaddAARtoHeap(&aarSymbol, &arSymbolName, 1, pglobl))
  52. {
  53. ERR(("Internal error, unable to define %s!\n", symbol));
  54. return FALSE ;
  55. }
  56. aarSymbol.pub = arSymbolName.loOffset + mpubOffRef ;
  57. aarSymbol.dw = arSymbolName.dwCount ;
  58. #endif
  59. if(! SymbolTableAdd(&aarSymbol, pglobl) )
  60. {
  61. ERR(("Internal error, unable to define %s!\n", symbol));
  62. return FALSE ;
  63. }
  64. return TRUE ;
  65. }
  66. BOOL SetPPPrefix(
  67. PABSARRAYREF parrPrefix,
  68. PGLOBL pglobl)
  69. {
  70. if(!parrPrefix->dw)
  71. {
  72. ERR(("#SetPPPrefix: syntax error - preprocessor prefix cannot be NULL !\n"));
  73. // optional: report filename and line number
  74. geErrorType = ERRTY_SYNTAX ;
  75. geErrorSev = ERRSEV_FATAL ;
  76. return FALSE ;
  77. }
  78. gaarPPPrefix = *parrPrefix ;
  79. return TRUE ;
  80. }
  81. // GPD preprocessor: implements the following preprocessor directives:
  82. // #Define: symbol
  83. // #Undefine: symbol
  84. // #Include: filename Note: this uses the exact syntax used by
  85. // The GPD *Include: keyword except * is replaced by #
  86. // #Ifdef: symbol
  87. // #Elseifdef: symbol
  88. // #Else:
  89. // #Endif:
  90. // #SetPPPrefix: symbol
  91. //
  92. // notes: when #Include: is found, just replace prefix with '*'.
  93. // instead of compressing file when #ifdefs are processed, just 'erase' unwanted
  94. // sections with space chars. (leaving \n and \r unchanged to preserve line #'s)
  95. // Need to store some global state information. like how many nesting levels
  96. // what are we currently doing, what symbols are defined etc.
  97. // Definitions:
  98. // Section: these directives act as section delimiters:
  99. // #Ifdef: symbol
  100. // #Elseifdef: symbol
  101. // #Else:
  102. // #Endif:
  103. // Nesting level: the number of unmatched #ifdefs at the current position
  104. // determines the nesting level at that position.
  105. // Note in these source code comments '#' represents the current preprocessor prefix.
  106. // This is set to '*' by default, but is changed using the #SetPPPrefix: directive.
  107. BOOL BPreProcess(
  108. PGLOBL pglobl)
  109. // from current file position, use file macros to access.
  110. {
  111. BOOL bStatus = FALSE ;
  112. ABSARRAYREF arrSymbol , // holds symbol portion of directive.
  113. aarCurPos ; // holds current position in source file buffer.
  114. enum DIRECTIVE directive ;
  115. enum IFSTATE prevsIFState ;
  116. enum PERMSTATE prevsPermState ;
  117. aarCurPos.pub = mpubSrcRef + mdwSrcInd ;
  118. aarCurPos.dw = mdwSrcMax - mdwSrcInd ;
  119. while((directive = ParseDirective(&aarCurPos, &arrSymbol, pglobl)) != DIRECTIVE_EOF)
  120. {
  121. switch(directive)
  122. {
  123. case DIRECTIVE_DEFINE:
  124. if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
  125. {
  126. if(!SymbolTableAdd(&arrSymbol, pglobl) )
  127. return(FALSE); // error!
  128. }
  129. break;
  130. case DIRECTIVE_UNDEFINE:
  131. if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
  132. {
  133. if(!SymbolTableRemove(&arrSymbol, pglobl) )
  134. {
  135. if(geErrorSev != ERRSEV_FATAL )
  136. {
  137. ERR(("syntax error - attempting to undefine a symbol that isn't defined !\n"));
  138. ERR(("%.*s\n", BytesToEOL(&arrSymbol), arrSymbol.pub ));
  139. geErrorType = ERRTY_SYNTAX ;
  140. geErrorSev = ERRSEV_FATAL ;
  141. goto PREPROCESS_FAILURE;
  142. }
  143. }
  144. }
  145. break;
  146. case DIRECTIVE_INCLUDE:
  147. if(mppStack[mdwNestingLevel].permState != PERM_ALLOW)
  148. {
  149. deleteToEOL(&aarCurPos) ;
  150. break; // it never happened.
  151. }
  152. goto PREPROCESS_SUCCESS ;
  153. break;
  154. case DIRECTIVE_SETPPPREFIX :
  155. if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
  156. SetPPPrefix(&arrSymbol, pglobl);
  157. break;
  158. case DIRECTIVE_IFDEF:
  159. // state-invariant behavior
  160. prevsPermState = mppStack[mdwNestingLevel].permState ;
  161. mdwNestingLevel++ ;
  162. if(mdwNestingLevel >= mMaxNestingLevel)
  163. {
  164. if(ERRSEV_RESTART > geErrorSev)
  165. {
  166. geErrorType = ERRTY_MEMORY_ALLOCATION ;
  167. geErrorSev = ERRSEV_RESTART ;
  168. gdwMasterTabIndex = MTI_PREPROCSTATE ;
  169. }
  170. goto PREPROCESS_FAILURE;
  171. }
  172. if(SymbolTableExists(&arrSymbol, pglobl))
  173. mppStack[mdwNestingLevel].permState = PERM_ALLOW ;
  174. else
  175. mppStack[mdwNestingLevel].permState = PERM_DENY ;
  176. if(prevsPermState != PERM_ALLOW)
  177. mppStack[mdwNestingLevel].permState = PERM_LATCHED ;
  178. mppStack[mdwNestingLevel].ifState = IFS_CONDITIONAL;
  179. break;
  180. case DIRECTIVE_ELSEIFDEF:
  181. if(mppStack[mdwNestingLevel].ifState == IFS_ROOT)
  182. {
  183. ERR(("syntax error - #Elseifdef directive must be preceeded by #Ifdef !\n"));
  184. // optional: report filename and line number
  185. geErrorType = ERRTY_SYNTAX ;
  186. geErrorSev = ERRSEV_FATAL ;
  187. goto PREPROCESS_FAILURE;
  188. }
  189. if(mppStack[mdwNestingLevel].ifState == IFS_LAST_CONDITIONAL)
  190. {
  191. ERR(("syntax error - #Elseifdef directive cannot follow #Else !\n"));
  192. geErrorType = ERRTY_SYNTAX ;
  193. geErrorSev = ERRSEV_FATAL ;
  194. goto PREPROCESS_FAILURE;
  195. }
  196. if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
  197. mppStack[mdwNestingLevel].permState = PERM_LATCHED ;
  198. else if(mppStack[mdwNestingLevel].permState == PERM_DENY)
  199. {
  200. if(SymbolTableExists(&arrSymbol, pglobl))
  201. mppStack[mdwNestingLevel].permState = PERM_ALLOW ;
  202. }
  203. break;
  204. case DIRECTIVE_ELSE :
  205. if(mppStack[mdwNestingLevel].ifState == IFS_ROOT)
  206. {
  207. ERR(("syntax error - #Else directive must be preceeded by #Ifdef or #Elseifdef !\n"));
  208. geErrorType = ERRTY_SYNTAX ;
  209. geErrorSev = ERRSEV_FATAL ;
  210. goto PREPROCESS_FAILURE;
  211. }
  212. if(mppStack[mdwNestingLevel].ifState == IFS_LAST_CONDITIONAL)
  213. {
  214. ERR(("syntax error - #Else directive cannot follow #Else !\n"));
  215. geErrorType = ERRTY_SYNTAX ;
  216. geErrorSev = ERRSEV_FATAL ;
  217. goto PREPROCESS_FAILURE;
  218. }
  219. mppStack[mdwNestingLevel].ifState = IFS_LAST_CONDITIONAL ;
  220. if(mppStack[mdwNestingLevel].permState == PERM_ALLOW)
  221. mppStack[mdwNestingLevel].permState = PERM_LATCHED ;
  222. else if(mppStack[mdwNestingLevel].permState == PERM_DENY)
  223. {
  224. mppStack[mdwNestingLevel].permState = PERM_ALLOW ;
  225. }
  226. break;
  227. case DIRECTIVE_ENDIF :
  228. if(mppStack[mdwNestingLevel].ifState == IFS_ROOT)
  229. {
  230. ERR(("syntax error - #Endif directive must be preceeded by #Ifdef or #Elseifdef or #Else !\n"));
  231. geErrorType = ERRTY_SYNTAX ;
  232. geErrorSev = ERRSEV_FATAL ;
  233. goto PREPROCESS_FAILURE;
  234. }
  235. mdwNestingLevel-- ; // restore previous nesting level.
  236. break;
  237. default:
  238. ERR(("internal consistency error - no such preprocessor directive!\n"));
  239. ERR(("%.*s\n", BytesToEOL(&aarCurPos), aarCurPos.pub ));
  240. geErrorType = ERRTY_CODEBUG ;
  241. geErrorSev = ERRSEV_FATAL ;
  242. goto PREPROCESS_FAILURE;
  243. break;
  244. }
  245. }
  246. PREPROCESS_SUCCESS:
  247. return TRUE ;
  248. PREPROCESS_FAILURE:
  249. return FALSE ;
  250. }
  251. enum DIRECTIVE ParseDirective(PABSARRAYREF paarCurPos,
  252. PABSARRAYREF parrSymbol,
  253. PGLOBL pglobl)
  254. {
  255. // this function parses from the 'current' position: mdwSrcInd
  256. // for any recognized directive and returns that directive.
  257. // if (mppStack[mdwNestingLevel].permState != PERM_ALLOW)
  258. // all characters != \n or \r encountered while looking for the directive
  259. // will be replaced by space characters.
  260. //
  261. // the entire line containing the directive is replaced by spaces.
  262. // (except for the Include directive - only the prefix is replaced by '*'
  263. // with leftpadded spaces if needed.)
  264. // cur pos is set to the line following the one containing the directive.
  265. // before the directive is destroyed, a copy is made of the symbol argument
  266. // and a reference parrSymbol is initialized to point to this copy.
  267. // this copy is stored on the heap so it's lifetime is effectively 'forever'.
  268. // syntax of directive:
  269. // a directive token must be immediately preceeded by the current preprocessor
  270. // prefix. The prefix must be preceeded by a line delimiter (unless its the
  271. // first line in the file). Optional whitespace characters (space or tab) may reside between
  272. // the line delimiter and the prefix.
  273. // the actual DIRECTIVE Token may be followed by Optional whitespace, then must
  274. // be followed by the Colon delimiter, the next non-whitespace token is interpreted
  275. // as the symbol. Any characters following the symbol token to the line delimiter
  276. // will be ignored. A Directive cannot occupy more than one line.
  277. // this function assumes cur pos points to start of line when it is called.
  278. enum DIRECTIVE directive ;
  279. BOOL bStartOfNewLine = TRUE ;
  280. BYTE ubSrc ;
  281. while( paarCurPos->dw ) // EOF detector
  282. {
  283. if(bStartOfNewLine && // directives must start at newline or
  284. // have only whitespace intervening
  285. (directive = IsThisPPDirective( paarCurPos, parrSymbol, pglobl)) != NOT_A_DIRECTIVE )
  286. {
  287. return directive;
  288. }
  289. ubSrc = *paarCurPos->pub ;
  290. //extract current character
  291. if(ubSrc != '\n' && ubSrc != '\r')
  292. {
  293. bStartOfNewLine = FALSE ;
  294. if(mppStack[mdwNestingLevel].permState != PERM_ALLOW)
  295. {
  296. *paarCurPos->pub = ' ' ; // replace with harmless space.
  297. }
  298. }
  299. else
  300. bStartOfNewLine = TRUE ;
  301. (paarCurPos->pub)++ ; // advance to next character.
  302. (paarCurPos->dw)-- ;
  303. }
  304. return DIRECTIVE_EOF ;
  305. }
  306. BOOL bSkipAnyWhite(PABSARRAYREF paarCurPos)
  307. // checks for EOF
  308. {
  309. while( paarCurPos->dw ) // EOF detector
  310. {
  311. BYTE ubSrc = *paarCurPos->pub ;
  312. //extract current character
  313. if(ubSrc != ' ' && ubSrc != '\t' && ubSrc != '\n' && ubSrc != '\r')
  314. {
  315. return TRUE ; // Non-white char encountered
  316. }
  317. (paarCurPos->pub)++ ; // advance to next character.
  318. (paarCurPos->dw)-- ;
  319. }
  320. return FALSE ; // reached eof
  321. }
  322. BOOL bSkipWhiteSpace(PABSARRAYREF paarCurPos)
  323. {
  324. // checks for EOF
  325. while( paarCurPos->dw ) // EOF detector
  326. {
  327. BYTE ubSrc = *paarCurPos->pub ;
  328. //extract current character
  329. if(ubSrc != ' ' && ubSrc != '\t' )
  330. {
  331. return TRUE ; // Non-white char encountered
  332. }
  333. (paarCurPos->pub)++ ; // advance to next character.
  334. (paarCurPos->dw)-- ;
  335. }
  336. return FALSE ; // reached eof
  337. }
  338. BOOL bmatch(PABSARRAYREF paarCurPos, ABSARRAYREF aarReference)
  339. // checks for EOF
  340. {
  341. if(!paarCurPos->dw)
  342. return FALSE ; // reached eof
  343. if(paarCurPos->dw < aarReference.dw)
  344. return FALSE ; // not enough chars in buffer to match reference.
  345. if(strncmp(paarCurPos->pub, aarReference.pub, aarReference.dw))
  346. return FALSE ;
  347. paarCurPos->pub += aarReference.dw ; // otherwise we match the reference!!
  348. paarCurPos->dw -= aarReference.dw ; // advance pointer past matching substring
  349. return TRUE ;
  350. }
  351. BOOL extractSymbol(PABSARRAYREF paarSymbol, PABSARRAYREF paarCurPos)
  352. // checks for EOF
  353. {
  354. paarSymbol->pub = paarCurPos->pub ;
  355. for(paarSymbol->dw = 0 ; paarCurPos->dw ; paarSymbol->dw++,
  356. (paarCurPos->pub)++ , paarCurPos->dw--)
  357. {
  358. BYTE ubSrc = *paarCurPos->pub ;
  359. //extract current character
  360. if(ubSrc == ' ' || ubSrc == '\t' || ubSrc == '\n' || ubSrc == '\r')
  361. {
  362. break;
  363. }
  364. }
  365. if(!paarSymbol->dw)
  366. return FALSE ; // nothing?
  367. return TRUE ; // this is our preprocessor symbol.
  368. }
  369. BOOL strmatch(PABSARRAYREF paarCurPos, PCHAR pref )
  370. // checks for EOF - means dw cannot go neg.
  371. {
  372. DWORD dwRefLen ;
  373. if(!paarCurPos->dw)
  374. return FALSE ; // reached eof
  375. dwRefLen = strlen(pref);
  376. if(paarCurPos->dw < dwRefLen)
  377. return FALSE ; // not enough chars in buffer to match reference.
  378. if(strncmp(paarCurPos->pub, pref, dwRefLen))
  379. return FALSE ; // no match
  380. paarCurPos->pub += dwRefLen ; // otherwise we match the reference!!
  381. paarCurPos->dw -= dwRefLen ; // advance pointer past matching substring
  382. return TRUE ; // match!
  383. }
  384. BOOL ExtractColon(PABSARRAYREF paarCurPos)
  385. // checks for EOF - means dw cannot go neg.
  386. {
  387. if(! bSkipWhiteSpace( paarCurPos) )
  388. return FALSE ; // reached EOF
  389. if(!strmatch(paarCurPos, ":" ) )
  390. return FALSE ; // no match
  391. if(! bSkipWhiteSpace( paarCurPos) )
  392. return FALSE ; // reached EOF
  393. return TRUE ; // match!
  394. }
  395. enum DIRECTIVE IsThisPPDirective(
  396. IN OUT PABSARRAYREF paarFile , // current pos in GPD file
  397. PABSARRAYREF paarSymbol, // return reference to heap copy of directive symbol
  398. PGLOBL pglobl)
  399. // This function only processes the current line and determines if
  400. // the current line is a valid preprocessor directive.
  401. // This function assumes paarFile initially points to start of the line
  402. // if this is a directive, advances paarFile->pub to EOL and replaces the
  403. // line with spaces.
  404. // if not a directive, advances paarFile->pub past initial whitespace padding.
  405. // to reduce repeat processing.
  406. {
  407. ABSARRAYREF aarPrefix, // points to first non-white char found
  408. aarDirective; // points right after prefix.
  409. enum DIRECTIVE directive ;
  410. // PBYTE pBuff = paarFile->pub ;
  411. // there can only be whitespace padding or linebreaks preceeding prefix:
  412. if(!bSkipAnyWhite(paarFile )) // skip any combination of spaces , tabs and linebreaks
  413. return DIRECTIVE_EOF ;
  414. // EOF overflow has occured or some bizzare failure!
  415. aarPrefix = *paarFile; // remember location of the prefix or first non-white char
  416. if(!bmatch(paarFile, gaarPPPrefix)) // advances paarFile
  417. {
  418. *paarFile = aarPrefix ; // restore to just beyond white padding
  419. return NOT_A_DIRECTIVE ;
  420. }
  421. aarDirective = *paarFile ;
  422. if(strmatch(paarFile, "Define") )
  423. directive = DIRECTIVE_DEFINE;
  424. else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Undefine") )
  425. directive = DIRECTIVE_UNDEFINE;
  426. else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Include") )
  427. directive = DIRECTIVE_INCLUDE;
  428. else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Ifdef") )
  429. directive = DIRECTIVE_IFDEF;
  430. else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Elseifdef") )
  431. directive = DIRECTIVE_ELSEIFDEF;
  432. else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Else") )
  433. directive = DIRECTIVE_ELSE;
  434. else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "Endif") )
  435. directive = DIRECTIVE_ENDIF;
  436. else if((*paarFile = aarDirective, 1) && strmatch(paarFile, "SetPPPrefix") )
  437. directive = DIRECTIVE_SETPPPREFIX ;
  438. else
  439. { // (directive == NOT_A_DIRECTIVE)
  440. *paarFile = aarPrefix ; // restore to just beyond white padding
  441. return NOT_A_DIRECTIVE ;
  442. }
  443. if(directive == DIRECTIVE_INCLUDE)
  444. {
  445. // replace prefix with leftpadded '*' ;
  446. DWORD dwI ;
  447. for(dwI = 0 ; dwI < gaarPPPrefix.dw ; dwI++)
  448. (aarPrefix.pub)[dwI] = ' ' ; // replace prefix with all spaces
  449. (aarPrefix.pub)[ gaarPPPrefix.dw - 1] = '*' ; // last char becomes '*'.
  450. *paarFile = aarPrefix ; // this allows *Include: entry to be deleted if != PERM_ALLOW
  451. return directive;
  452. }
  453. if(!ExtractColon(paarFile)) // parse surrounding spaces also.
  454. {
  455. ERR(("syntax error - colon delimiter required after preprocessor directive !\n"));
  456. ERR(("%.*s\n", BytesToEOL(&aarPrefix), aarPrefix.pub ));
  457. if(geErrorSev < ERRSEV_CONTINUE)
  458. {
  459. geErrorType = ERRTY_SYNTAX ;
  460. geErrorSev = ERRSEV_CONTINUE ;
  461. }
  462. *paarFile = aarPrefix ; // restore to just beyond white padding
  463. return NOT_A_DIRECTIVE ;
  464. }
  465. if(directive == DIRECTIVE_SETPPPREFIX ||
  466. directive == DIRECTIVE_ELSEIFDEF ||
  467. directive == DIRECTIVE_IFDEF ||
  468. directive == DIRECTIVE_UNDEFINE ||
  469. directive == DIRECTIVE_DEFINE)
  470. {
  471. ARRAYREF arSymbolName ;
  472. if(!extractSymbol(paarSymbol, paarFile)) // identifies substring of paarFile
  473. {
  474. ERR(("syntax error - symbol required after this preprocessor directive !\n"));
  475. ERR(("%.*s\n", BytesToEOL(&aarPrefix), aarPrefix.pub ));
  476. if(geErrorSev < ERRSEV_CONTINUE)
  477. {
  478. geErrorType = ERRTY_SYNTAX ;
  479. geErrorSev = ERRSEV_CONTINUE ;
  480. }
  481. *paarFile = aarPrefix ; // restore to just beyond white padding
  482. return NOT_A_DIRECTIVE ;
  483. }
  484. /* I would use
  485. BOOL BcopyToTmpHeap() (token1.c)
  486. except this will confuse the
  487. heck out of Register symbol, which is expecting all strings to
  488. be stored in the regular heap! */
  489. if(!BaddAARtoHeap(paarSymbol, &arSymbolName, 1, pglobl))
  490. return(DIRECTIVE_EOF ); // cause a swift abort
  491. paarSymbol->pub = arSymbolName.loOffset + mpubOffRef ;
  492. paarSymbol->dw = arSymbolName.dwCount ;
  493. // permanent location of symbol in Heap.
  494. }
  495. // replace all non-white chars on the line to EOL or EOF with spaces ;
  496. *paarFile = aarPrefix ;
  497. deleteToEOL(paarFile) ;
  498. return directive;
  499. }
  500. void deleteToEOL(PABSARRAYREF paarCurPos)
  501. // actually replace with space chars
  502. {
  503. for( ; paarCurPos->dw ; paarCurPos->pub++, paarCurPos->dw--)
  504. {
  505. BYTE ubSrc = *(paarCurPos->pub) ;
  506. if(ubSrc != '\n' && ubSrc != '\r')
  507. *(paarCurPos->pub) = ' ' ; // replace with harmless space.
  508. else
  509. break; // reached EOL. paarFile points to EOL.
  510. }
  511. }
  512. int BytesToEOL(PABSARRAYREF paarCurPos)
  513. {
  514. int iCount ;
  515. for(iCount = 0 ; paarCurPos->dw > (DWORD)iCount ; iCount++)
  516. {
  517. BYTE ubSrc = paarCurPos->pub[iCount] ;
  518. if(ubSrc == '\n' || ubSrc == '\r')
  519. break; // reached EOL.
  520. }
  521. return(iCount) ;
  522. }
  523. BOOL SymbolTableAdd(
  524. PABSARRAYREF paarSymbol,
  525. PGLOBL pglobl)
  526. {
  527. DWORD dwSymbolID ;
  528. dwSymbolID = DWregisterSymbol(paarSymbol, CONSTRUCT_PREPROCESSOR,
  529. TRUE, INVALID_SYMBOLID, pglobl) ;
  530. if(dwSymbolID == INVALID_SYMBOLID)
  531. {
  532. return(FALSE );
  533. }
  534. return TRUE ;
  535. }
  536. BOOL SymbolTableRemove(
  537. PABSARRAYREF paarSymbol,
  538. PGLOBL pglobl)
  539. {
  540. DWORD dwSymbolID , dwCurNode;
  541. PSYMBOLNODE psn ;
  542. dwSymbolID = DWsearchSymbolListForAAR(paarSymbol, mdwPreProcDefinesSymbols, pglobl) ;
  543. if(dwSymbolID == INVALID_SYMBOLID)
  544. {
  545. return(FALSE );
  546. }
  547. dwCurNode = DWsearchSymbolListForID(dwSymbolID,
  548. mdwPreProcDefinesSymbols, pglobl) ;
  549. if(dwCurNode == INVALID_INDEX)
  550. {
  551. ERR(("Parser error - can't find symbol node !\n"));
  552. geErrorType = ERRTY_CODEBUG ;
  553. geErrorSev = ERRSEV_FATAL ;
  554. return(FALSE ); // cause a swift abort
  555. }
  556. psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
  557. // how do you remove this node from the symbol tree?
  558. psn[dwCurNode].arSymbolName.dwCount = 0 ;
  559. // can't navigate backwards along tree so just truncate string!
  560. return TRUE ;
  561. }
  562. BOOL SymbolTableExists(
  563. PABSARRAYREF paarSymbol,
  564. PGLOBL pglobl)
  565. {
  566. DWORD dwSymbolID ;
  567. dwSymbolID = DWsearchSymbolListForAAR(paarSymbol, mdwPreProcDefinesSymbols, pglobl) ;
  568. if(dwSymbolID == INVALID_SYMBOLID)
  569. {
  570. return(FALSE );
  571. }
  572. return TRUE ;
  573. }
  574. #if 0
  575. >>>>
  576. DWORD dwCurNode, dwSymbolID ;
  577. PSYMBOLNODE psn ;
  578. dwSymbolID = DWregisterSymbol(paarSymbol, CONSTRUCT_PREPROCESSOR,
  579. FALSE, INVALID_SYMBOLID) ;
  580. if(dwSymbolID == INVALID_SYMBOLID)
  581. {
  582. return(DIRECTIVE_EOF ); // cause a swift abort
  583. }
  584. dwCurNode = DWsearchSymbolListForID(dwSymbolID,
  585. mdwPreProcDefinesSymbols) ;
  586. if(dwCurNode == INVALID_INDEX);
  587. {
  588. ERR(("Parser error - can't find symbol node !\n"));
  589. geErrorType = ERRTY_CODEBUG ;
  590. geErrorSev = ERRSEV_FATAL ;
  591. return(DIRECTIVE_EOF ); // cause a swift abort
  592. }
  593. psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
  594. paarSymbol->pub = psn[dwCurNode].arSymbolName.loOffset + mpubOffRef ;
  595. paarSymbol->dw = psn[dwCurNode].arSymbolName.dwCount ;
  596. SymbolTableAdd(&aarSymbol);
  597. may use from state1.c
  598. DWORD DWregisterSymbol(
  599. PABSARRAYREF paarSymbol, // the symbol string to register
  600. CONSTRUCT eConstruct , // type of construct determines class of symbol.
  601. BOOL bCopy, // shall we copy paarSymbol to heap? May set
  602. DWORD dwFeatureID // if you are registering an option symbol
  603. // and you already know the feature , pass it in
  604. // here. Otherwise set to INVALID_SYMBOLID
  605. )
  606. /* this function registers the entire string specified
  607. in paarSymbol. The caller must isolate the string.
  608. */
  609. {
  610. // returns SymbolID, a zero indexed ordinal
  611. // for extra speed we may hash string
  612. but what do we define for symbol class?
  613. if(eConstruct == CONSTRUCT_FONTCART)
  614. pdwSymbolClass += SCL_FONTCART ;
  615. else if(eConstruct == CONSTRUCT_TTFONTSUBS)
  616. pdwSymbolClass += SCL_TTFONTNAMES ;
  617. else if(eConstruct == CONSTRUCT_COMMAND)
  618. pdwSymbolClass += SCL_COMMANDNAMES ;
  619. else if(eConstruct == CONSTRUCT_BLOCKMACRO)
  620. pdwSymbolClass += SCL_BLOCKMACRO;
  621. else if(eConstruct == CONSTRUCT_MACROS)
  622. pdwSymbolClass += SCL_VALUEMACRO;
  623. else if(eConstruct == CONSTRUCT_PREPROCESSOR)
  624. pdwSymbolClass += SCL_PPDEFINES;
  625. else
  626. pdwSymbolClass += SCL_FEATURES ;
  627. DWORD DWsearchSymbolListForAAR(
  628. PABSARRAYREF paarSymbol,
  629. DWORD dwNodeIndex) ;
  630. // given a 'aar' to a string representing a symbol, search
  631. // the SymbolList beginning at dwNodeIndex for this symbol.
  632. // Return its symbolID if found, else return the INVALID_SYMBOLID.
  633. {
  634. PSYMBOLNODE psn ;
  635. psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
  636. for( ; dwNodeIndex != INVALID_INDEX ;
  637. dwNodeIndex = psn[dwNodeIndex].dwNextSymbol)
  638. {
  639. if(BCmpAARtoAR(paarSymbol, &(psn[dwNodeIndex].arSymbolName)) )
  640. return(psn[dwNodeIndex].dwSymbolID); // string matches !
  641. }
  642. return(INVALID_SYMBOLID);
  643. }
  644. fragments for future use:
  645. from framwrk1.c:
  646. VOID VinitGlobals()
  647. gMasterTable[MTI_SYMBOLROOT].dwArraySize = SCL_NUMSYMCLASSES ;
  648. gMasterTable[MTI_SYMBOLROOT].dwMaxArraySize = SCL_NUMSYMCLASSES ;
  649. gMasterTable[MTI_SYMBOLROOT].dwElementSiz = sizeof(DWORD) ;
  650. gMasterTable[MTI_STSENTRY].dwArraySize = 20 ;
  651. gMasterTable[MTI_STSENTRY].dwMaxArraySize = 60 ;
  652. gMasterTable[MTI_STSENTRY].dwElementSiz = sizeof(STSENTRY) ;
  653. modify to serve as the preprocessor state Stack
  654. need also macros to access the stack.
  655. // ----- Preprocessor Section ---- // from gpdparse.h
  656. enum IFSTATE {IFS_ROOT, IFS_CONDITIONAL , IFS_LAST_CONDITIONAL } ;
  657. // tracks correct syntatical use of #ifdef, #elseifdef, #else and #endif directives.
  658. enum PERMSTATE {PERM_ALLOW, PERM_DENY , PERM_LATCHED } ;
  659. // tracks current state of preprocessing,
  660. // PERM_ALLOW: all statements in this section are passed to body gpdparser
  661. // PERM_DENY: statements in this section are discarded
  662. // PERM_LATCHED: all statements until the end of this nesting level are discarded.
  663. enum DIRECTIVE {NOT_A_DIRECTIVE, DIRECTIVE_EOF, DIRECTIVE_DEFINE , DIRECTIVE_UNDEFINE ,
  664. DIRECTIVE_INCLUDE , DIRECTIVE_SETPPPREFIX , DIRECTIVE_IFDEF ,
  665. DIRECTIVE_ELSEIFDEF , DIRECTIVE_ELSE , DIRECTIVE_ENDIF }
  666. typedef struct
  667. {
  668. enum IFSTATE ifState ;
  669. enum PERMSTATE permState ;
  670. } PPSTATESTACK, * PPPSTATESTACK ;
  671. // the tagname is 'ppss'
  672. MTI_PREPROCSTATE, // array of PPSTATESTACK structures
  673. // which hold state of preprocessor.
  674. gMasterTable[MTI_PREPROCSTATE].dwArraySize = 20 ;
  675. gMasterTable[MTI_PREPROCSTATE].dwMaxArraySize = 100 ;
  676. gMasterTable[MTI_PREPROCSTATE].dwElementSiz = sizeof(PPSTATESTACK) ;
  677. #define mppStack ((PPPSTATESTACK)(gMasterTable \
  678. [MTI_PREPROCSTATE].pubStruct))
  679. // location of first SOURCEBUFFER element in array
  680. #define mdwNestingLevel (gMasterTable[MTI_PREPROCSTATE].dwCurIndex)
  681. // current preprocessor directive nesting level
  682. #define mMaxNestingLevel (gMasterTable[MTI_PREPROCSTATE].dwArraySize)
  683. // max preprocessor directive nesting depth
  684. // init preprocessor state stack
  685. mdwNestingLevel = 0 ;
  686. mppStack[mdwNestingLevel].permState = PERM_ALLOW ;
  687. mppStack[mdwNestingLevel].ifState = IFS_ROOT;
  688. #endif
  689. // ---- End Of Preprocessor Section ---- //