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.

1528 lines
50 KiB

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. /*
  3. * state1.c - implements the state machine to track constructs
  4. */
  5. #include "gpdparse.h"
  6. // ---- functions defined in state1.c ---- //
  7. BOOL BInterpretTokens(
  8. PTKMAP ptkmap, // pointer to tokenmap
  9. BOOL bFirstPass, // is this the first or 2nd time around?
  10. PGLOBL pglobl
  11. ) ;
  12. BOOL BprocessSpecialKeyword(
  13. PTKMAP ptkmap, // pointer to tokenmap
  14. BOOL bFirstPass, // is this the first or 2nd time around?
  15. PGLOBL pglobl
  16. ) ;
  17. BOOL BprocessSymbolKeyword(
  18. PTKMAP ptkmap, // pointer to current entry in tokenmap
  19. PGLOBL pglobl
  20. ) ;
  21. VOID VinitAllowedTransitions(
  22. PGLOBL pglobl
  23. );
  24. BOOL BpushState(
  25. PTKMAP ptkmap, // pointer to current entry in tokenmap
  26. BOOL bFirstPass,
  27. PGLOBL pglobl
  28. ) ;
  29. BOOL BchangeState(
  30. PTKMAP ptkmap, // pointer to construct in tokenmap
  31. CONSTRUCT eConstruct, // this will induce a transition to NewState
  32. STATE stOldState,
  33. BOOL bSymbol, // should dwValue be saved as a SymbolID ?
  34. BOOL bFirstPass,
  35. PGLOBL pglobl
  36. ) ;
  37. DWORD DWregisterSymbol(
  38. PABSARRAYREF paarSymbol, // the symbol string to register
  39. CONSTRUCT eConstruct , // type of construct determines class of symbol.
  40. BOOL bCopy, // shall we copy paarSymbol to heap? May set
  41. DWORD dwFeatureID, // if you are registering an option symbol
  42. PGLOBL pglobl
  43. ) ;
  44. BOOL BaddAARtoHeap(
  45. PABSARRAYREF paarSrc,
  46. PARRAYREF parDest,
  47. DWORD dwAlign,
  48. PGLOBL pglobl) ;
  49. BOOL BwriteToHeap(
  50. OUT PDWORD pdwDestOff, // heap offset of dest string
  51. PBYTE pubSrc, // points to src string
  52. DWORD dwCnt, // num bytes to copy from src to dest.
  53. DWORD dwAlign,
  54. PGLOBL pglobl) ;
  55. DWORD DWsearchSymbolListForAAR(
  56. PABSARRAYREF paarSymbol,
  57. DWORD dwNodeIndex,
  58. PGLOBL pglobl) ;
  59. DWORD DWsearchSymbolListForID(
  60. DWORD dwSymbolID, // find node containing this ID.
  61. DWORD dwNodeIndex,
  62. PGLOBL pglobl
  63. ) ;
  64. BOOL BCmpAARtoAR(
  65. PABSARRAYREF paarStr1,
  66. PARRAYREF parStr2,
  67. PGLOBL pglobl
  68. ) ;
  69. BOOL BpopState(
  70. PGLOBL pglobl
  71. ) ;
  72. VOID VinitDictionaryIndex(
  73. PGLOBL pglobl
  74. ) ;
  75. VOID VcharSubstitution(
  76. PABSARRAYREF paarStr,
  77. BYTE ubTgt,
  78. BYTE ubReplcmnt,
  79. PGLOBL pglobl
  80. ) ;
  81. VOID VIgnoreBlock(
  82. PTKMAP ptkmap,
  83. BOOL bIgnoreBlock,
  84. PGLOBL pglobl
  85. ) ;
  86. // ---------------------------------------------------- //
  87. BOOL BInterpretTokens(
  88. PTKMAP ptkmap, // pointer to tokenmap
  89. BOOL bFirstPass, // is this the first or 2nd time around?
  90. PGLOBL pglobl
  91. )
  92. {
  93. DWORD dwKeywordID ;
  94. KEYWORD_TYPE eType;
  95. WORD wEntry ;
  96. BOOL bStatus = FALSE ;
  97. if(bFirstPass)
  98. {
  99. // This bit of code creates a synthesized inputslot
  100. // which the UI code will interpret as the UseFormToTrayTable
  101. // BUG_BUG!!!: should be replaced by preprocessing
  102. // shortcuts etc. Or by an option in stdnames.gpd
  103. ABSARRAYREF aarSymbol ;
  104. DWORD dwFeaID ;
  105. aarSymbol.pub = "InputBin" ; // no way to keep this in ssync
  106. // with the global table.
  107. aarSymbol.dw = strlen(aarSymbol.pub) ;
  108. dwFeaID = DWregisterSymbol(&aarSymbol, CONSTRUCT_FEATURE,
  109. TRUE, INVALID_SYMBOLID, pglobl) ;
  110. if(dwFeaID != INVALID_SYMBOLID)
  111. {
  112. aarSymbol.pub = "FORMSOURCE" ; // no way to keep this in ssync
  113. // with the global table.
  114. aarSymbol.dw = strlen(aarSymbol.pub) ;
  115. dwFeaID = DWregisterSymbol(&aarSymbol, CONSTRUCT_OPTION,
  116. TRUE, dwFeaID, pglobl) ;
  117. ASSERT(dwFeaID == 0); // this option must be first.
  118. }
  119. }
  120. else
  121. {
  122. ARRAYREF arStrValue ;
  123. BOOL bPrevsExists ;
  124. if(!BwriteToHeap(&arStrValue.loOffset, "\0\0", 2, 4, pglobl) )
  125. {
  126. bStatus = FALSE ; // heap overflow start over.
  127. }
  128. arStrValue.dwCount = 0 ; // create a NULL unicode string.
  129. BexchangeArbDataInFOATNode(
  130. 0 , // dwFea
  131. 0, // dwOption,
  132. offsetof(DFEATURE_OPTIONS, atrOptDisplayName ),
  133. sizeof(ARRAYREF),
  134. NULL, // previous contents of attribute node
  135. (PBYTE)&arStrValue, // new contents of attribute node.
  136. &bPrevsExists, // previous contents existed.
  137. FALSE, // access synthetic features
  138. pglobl
  139. ) ;
  140. }
  141. for(wEntry = 0 ; geErrorSev < ERRSEV_RESTART ; wEntry++)
  142. {
  143. // These ID's must be processed separately
  144. // because they do not index into the mainKeyword table.
  145. // The code for generic ID's will fail.
  146. dwKeywordID = ptkmap[wEntry].dwKeywordID ;
  147. if (dwKeywordID == gdwID_IgnoreBlock)
  148. {
  149. VIgnoreBlock(ptkmap + wEntry, TRUE, pglobl) ;
  150. continue ;
  151. }
  152. switch(dwKeywordID)
  153. {
  154. case (ID_EOF):
  155. {
  156. // BUG_BUG!!! Cleanup code here
  157. // integrity checking code:
  158. // check to see mdwCurStsPtr == 0
  159. // and any other loose ends are tied.
  160. bStatus = (mdwCurStsPtr) ? (FALSE) : (TRUE);
  161. return(bStatus) ;
  162. }
  163. case (ID_NULLENTRY):
  164. {
  165. continue ; // does this work?
  166. // should drop to bottom of FOREVER for loop.
  167. }
  168. case (ID_SYMBOL):
  169. {
  170. bStatus = BprocessSymbolKeyword(ptkmap + wEntry, pglobl) ;
  171. continue ; // uses TKMF_SYMBOL_REGISTERED to track passes
  172. }
  173. case (ID_UNRECOGNIZED):
  174. { // if identified on first pass, won't pass this way again!
  175. if(bStatus = BidentifyAttributeKeyword(ptkmap + wEntry, pglobl) )
  176. {
  177. dwKeywordID = ptkmap[wEntry].dwKeywordID ;
  178. break ; // fall out of switch statement
  179. // and into next switch.
  180. }
  181. if(bFirstPass)
  182. {
  183. vIdentifySource(ptkmap + wEntry, pglobl) ;
  184. ERR(("Warning, unrecognized keyword: %0.*s\n", \
  185. ptkmap[wEntry].aarKeyword.dw, \
  186. ptkmap[wEntry].aarKeyword.pub));
  187. VIgnoreBlock(ptkmap + wEntry, FALSE, pglobl) ;
  188. // if this keyword is immediately
  189. // followed by open brace, ignore all
  190. // statements from there until the matching closing
  191. // brace.
  192. }
  193. continue ;
  194. }
  195. default :
  196. break ;
  197. }
  198. eType = mMainKeywordTable[dwKeywordID].eType ;
  199. switch (eType)
  200. {
  201. case (TY_CONSTRUCT):
  202. {
  203. if( CONSTRUCT_CLOSEBRACE ==
  204. (CONSTRUCT)(mMainKeywordTable[dwKeywordID].dwSubType))
  205. {
  206. bStatus = BpopState(pglobl) ;
  207. if(!bStatus)
  208. {
  209. vIdentifySource(ptkmap + wEntry, pglobl) ;
  210. ERR(("Unmatched closing brace!\n"));
  211. }
  212. }
  213. else
  214. {
  215. bStatus = BpushState(ptkmap + wEntry, bFirstPass, pglobl) ;
  216. if(!bStatus)
  217. {
  218. vIdentifySource(ptkmap + wEntry, pglobl) ;
  219. // ERR(("Fatal error parsing construct.\n"));
  220. // stack is now invalid.
  221. // in the future make parser smarter -
  222. // eject contents between braces.
  223. // geErrorType = ERRTY_SYNTAX ;
  224. // geErrorSev = ERRSEV_FATAL ;
  225. }
  226. }
  227. break ;
  228. }
  229. case (TY_ATTRIBUTE) :
  230. {
  231. if(!bFirstPass) // must wait till all attribute
  232. { // buffers are allocated.
  233. bStatus = BprocessAttribute(ptkmap + wEntry, pglobl) ;
  234. if(!bStatus)
  235. {
  236. vIdentifySource(ptkmap + wEntry, pglobl) ;
  237. }
  238. }
  239. break ;
  240. }
  241. case (TY_SPECIAL) :
  242. {
  243. bStatus = BprocessSpecialKeyword(ptkmap + wEntry,
  244. bFirstPass, pglobl) ; // don't really know if 2 passes
  245. { // are needed.
  246. if(!bStatus)
  247. {
  248. vIdentifySource(ptkmap + wEntry, pglobl) ;
  249. }
  250. }
  251. break ;
  252. }
  253. default:
  254. {
  255. vIdentifySource(ptkmap + wEntry, pglobl) ;
  256. ERR(("Internal Error: unrecognized keyword type! %0.*s.\n",
  257. ptkmap[wEntry].aarKeyword.dw,
  258. ptkmap[wEntry].aarKeyword.pub));
  259. geErrorSev = ERRSEV_FATAL ;
  260. geErrorType = ERRTY_CODEBUG ;
  261. break ;
  262. }
  263. }
  264. }
  265. if(geErrorSev >= ERRSEV_RESTART)
  266. bStatus = FALSE ;
  267. return(bStatus) ;
  268. }
  269. BOOL BprocessSpecialKeyword(
  270. PTKMAP ptkmap, // pointer to tokenmap
  271. BOOL bFirstPass, // is this the first or 2nd time around?
  272. PGLOBL pglobl
  273. )
  274. {
  275. DWORD dwKeywordID, dwOffset ;
  276. CONSTRUCT eSubType ;
  277. BOOL bStatus = FALSE ;
  278. STATE stState ;
  279. dwKeywordID = ptkmap->dwKeywordID ;
  280. eSubType = (SPECIAL)(mMainKeywordTable[dwKeywordID].dwSubType) ;
  281. dwOffset = mMainKeywordTable[dwKeywordID].dwOffset ;
  282. if(mdwCurStsPtr)
  283. stState = mpstsStateStack[mdwCurStsPtr - 1].stState ;
  284. else
  285. stState = STATE_ROOT ;
  286. switch(eSubType)
  287. {
  288. // note: for the record I despise special casing these
  289. // shortcuts. Ideally I could preprocess them
  290. // to convert
  291. // *TTFS: "font name" : <fontID>
  292. // into
  293. // *TTFontSub: <unique value symbol>
  294. // {
  295. // *TTFontName: "font name"
  296. // *DevFontID: <fontID>
  297. // }
  298. // the only glitch with this is if the same font is listed
  299. // multiple times in the GPD file, it will appear
  300. // in the TTFontSubTable multiple times.
  301. #if 0
  302. case SPEC_FONTSUB :
  303. {
  304. ARRAYREF arFontname ;
  305. ABSARRAYREF aarFontname ;
  306. if(stState != STATE_ROOT)
  307. {
  308. vIdentifySource(ptkmap, pglobl) ;
  309. ERR(("The *TTFS keyword must reside at the root level.\n"));
  310. return(FALSE) ;
  311. }
  312. if(bFirstPass)
  313. {
  314. // parse string value and register as a symbol.
  315. if((ptkmap->dwFlags & TKMF_NOVALUE ) ||
  316. !BparseString(&ptkmap->aarValue, &arFontname) )
  317. {
  318. vIdentifySource(ptkmap, pglobl) ;
  319. ERR(("*TTFS fontname is not a valid string value.\n"));
  320. return(FALSE) ;
  321. }
  322. if(ptkmap->aarValue.pub[0] != ':')
  323. {
  324. ERR(("Colon delimiter expected after parsing fontname string for *TTFontSub.\n")) ;
  325. return(FALSE) ;
  326. }
  327. // a keyword with a composite value
  328. (VOID)BeatDelimiter(&ptkmap->aarValue, ":") ;
  329. // I know this will succeed!
  330. // paarValue should now contain the integer
  331. // fontID. Leave this for the 2nd pass.
  332. // convert arFontname to aar suitable for
  333. // Font registration.
  334. aarFontname.dw = arFontname.dwCount ;
  335. aarFontname.pub = arFontname.loOffset + mpubOffRef;
  336. // New version of DWregisterSymbol registers the entire
  337. // string - whitespaces and all.
  338. //
  339. // Note suppress copying symbol into Heap since
  340. // ParseString has already done that.
  341. ptkmap->dwValue = DWregisterSymbol(&aarFontname,
  342. CONSTRUCT_TTFONTSUBS, FALSE, pglobl ) ;
  343. if(ptkmap->dwValue != INVALID_SYMBOLID)
  344. {
  345. ptkmap->dwFlags |= TKMF_SYMBOL_REGISTERED ;
  346. }
  347. else
  348. {
  349. return(FALSE) ;
  350. }
  351. }
  352. else if(ptkmap->dwFlags & TKMF_SYMBOL_REGISTERED)
  353. // second pass, TTFONTSUBTABLE arrays allocated
  354. // for all successfully registered entrants.
  355. {
  356. PSYMBOLNODE psn ;
  357. DWORD dwDevFontID ;
  358. PTTFONTSUBTABLE pttft ;
  359. DWORD dwTTFontNameIndex ;
  360. psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
  361. pttft = (PTTFONTSUBTABLE)
  362. gMasterTable[MTI_TTFONTSUBTABLE].pubStruct;
  363. pttft += ptkmap->dwValue ; // index correct element.
  364. dwTTFontNameIndex = DWsearchSymbolListForID(ptkmap->dwValue,
  365. mdwTTFontSymbols, pglobl) ;
  366. ASSERT(dwTTFontNameIndex != INVALID_INDEX) ;
  367. pttft->arTTFontName = psn[dwTTFontNameIndex].arSymbolName ;
  368. // if structure assignment is supported.
  369. bStatus = BparseInteger(&ptkmap->aarValue, &dwDevFontID,
  370. VALUE_INTEGER) ;
  371. if(bStatus)
  372. pttft->dwDevFontID = dwDevFontID ;
  373. else
  374. {
  375. // BUG_BUG! : Error parsing TTFontSub table entry
  376. // syntax error in devID. Dead codepath who cares?
  377. pttft->dwDevFontID = 0 ; // is this a good fallback?
  378. }
  379. }
  380. break;
  381. }
  382. #endif
  383. case SPEC_INVALID_COMBO:
  384. {
  385. if(bFirstPass)
  386. {
  387. bStatus = TRUE ;
  388. break; // do nothing on the FirstPass
  389. }
  390. bStatus = BparseInvalidCombination(&ptkmap->aarValue, dwOffset, pglobl) ;
  391. break;
  392. }
  393. case SPEC_INVALID_INS_COMBO:
  394. {
  395. if(bFirstPass)
  396. {
  397. bStatus = TRUE ;
  398. break; // do nothing on the FirstPass
  399. }
  400. bStatus = BparseInvalidInstallableCombination1(&ptkmap->aarValue,
  401. dwOffset, pglobl) ;
  402. break;
  403. }
  404. case SPEC_MEM_CONFIG_KB: // should already be replaced
  405. case SPEC_MEM_CONFIG_MB: // at parseKeyword
  406. default:
  407. {
  408. break ;
  409. }
  410. }
  411. return(bStatus) ;
  412. }
  413. BOOL BprocessSymbolKeyword(
  414. PTKMAP ptkmap, // pointer to current entry in tokenmap
  415. PGLOBL pglobl
  416. )
  417. {
  418. // registering the TTFontNames as symbols allows
  419. // me to count the number of unique names and reserve
  420. // the proper amount of TTFONTSUBTABLE elements and
  421. // eliminates multiple instances of the same name.
  422. BOOL bStatus = FALSE ;
  423. STATE stState ;
  424. if(mdwCurStsPtr)
  425. stState = mpstsStateStack[mdwCurStsPtr - 1].stState ;
  426. else
  427. stState = STATE_ROOT ;
  428. switch (stState)
  429. {
  430. // note TTFontSubs now has its own keyword.
  431. // and is handled as a Special Keyword.
  432. default:
  433. {
  434. // assume its just VALUEMACRO state
  435. // or user-defined symbols from an undefined
  436. // keyword.
  437. // ignore these.
  438. bStatus = TRUE ;
  439. break ;
  440. }
  441. }
  442. return(bStatus);
  443. }
  444. VOID VinitAllowedTransitions(
  445. PGLOBL pglobl)
  446. {
  447. PSTATE pst ;
  448. PBOOL pb ;
  449. WORD wS, wC, wA ;
  450. // default initializer is STATE_INVALID
  451. for(wS = 0 ; wS < STATE_LAST ; wS++)
  452. {
  453. for(wC = 0 ; wC < CONSTRUCT_LAST ; wC++)
  454. gastAllowedTransitions[wS][wC] = STATE_INVALID ;
  455. }
  456. pst = gastAllowedTransitions[STATE_ROOT] ;
  457. pst[CONSTRUCT_UIGROUP] = STATE_UIGROUP;
  458. pst[CONSTRUCT_FEATURE] = STATE_FEATURE;
  459. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_ROOT;
  460. pst[CONSTRUCT_COMMAND] = STATE_COMMAND;
  461. pst[CONSTRUCT_FONTCART] = STATE_FONTCART;
  462. pst[CONSTRUCT_TTFONTSUBS] = STATE_TTFONTSUBS;
  463. pst[CONSTRUCT_OEM] = STATE_OEM;
  464. pst = gastAllowedTransitions[STATE_UIGROUP] ;
  465. pst[CONSTRUCT_UIGROUP] = STATE_UIGROUP;
  466. pst[CONSTRUCT_FEATURE] = STATE_FEATURE;
  467. pst = gastAllowedTransitions[STATE_FEATURE] ;
  468. pst[CONSTRUCT_OPTION] = STATE_OPTIONS;
  469. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_FEATURE;
  470. pst = gastAllowedTransitions[STATE_OPTIONS] ;
  471. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_OPTION;
  472. pst[CONSTRUCT_COMMAND] = STATE_COMMAND;
  473. pst[CONSTRUCT_OEM] = STATE_OEM;
  474. pst = gastAllowedTransitions[STATE_SWITCH_ROOT] ;
  475. pst[CONSTRUCT_CASE] = STATE_CASE_ROOT;
  476. pst[CONSTRUCT_DEFAULT] = STATE_DEFAULT_ROOT;
  477. pst = gastAllowedTransitions[STATE_SWITCH_FEATURE] ;
  478. pst[CONSTRUCT_CASE] = STATE_CASE_FEATURE;
  479. pst[CONSTRUCT_DEFAULT] = STATE_DEFAULT_FEATURE;
  480. pst = gastAllowedTransitions[STATE_SWITCH_OPTION] ;
  481. pst[CONSTRUCT_CASE] = STATE_CASE_OPTION;
  482. pst[CONSTRUCT_DEFAULT] = STATE_DEFAULT_OPTION;
  483. pst = gastAllowedTransitions[STATE_CASE_ROOT] ;
  484. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_ROOT;
  485. pst[CONSTRUCT_COMMAND] = STATE_COMMAND;
  486. pst[CONSTRUCT_OEM] = STATE_OEM;
  487. pst = gastAllowedTransitions[STATE_DEFAULT_ROOT] ;
  488. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_ROOT;
  489. pst[CONSTRUCT_COMMAND] = STATE_COMMAND;
  490. pst[CONSTRUCT_OEM] = STATE_OEM;
  491. pst = gastAllowedTransitions[STATE_CASE_FEATURE] ;
  492. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_FEATURE;
  493. pst[CONSTRUCT_COMMAND] = STATE_COMMAND;
  494. pst[CONSTRUCT_OEM] = STATE_OEM;
  495. pst = gastAllowedTransitions[STATE_DEFAULT_FEATURE] ;
  496. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_FEATURE;
  497. pst[CONSTRUCT_COMMAND] = STATE_COMMAND;
  498. pst[CONSTRUCT_OEM] = STATE_OEM;
  499. pst = gastAllowedTransitions[STATE_CASE_OPTION] ;
  500. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_OPTION;
  501. pst[CONSTRUCT_COMMAND] = STATE_COMMAND;
  502. pst[CONSTRUCT_OEM] = STATE_OEM;
  503. pst = gastAllowedTransitions[STATE_DEFAULT_OPTION] ;
  504. pst[CONSTRUCT_SWITCH] = STATE_SWITCH_OPTION;
  505. pst[CONSTRUCT_COMMAND] = STATE_COMMAND;
  506. pst[CONSTRUCT_OEM] = STATE_OEM;
  507. // ------------------------------------------------------ //
  508. // now initialize allowed attributes table:
  509. // which attributes are allowed in each state.
  510. // default initializer is FALSE -- No attributes are allowed
  511. // in any state.
  512. for(wS = 0 ; wS < STATE_LAST ; wS++)
  513. {
  514. for(wA = 0 ; wA < ATT_LAST ; wA++)
  515. {
  516. gabAllowedAttributes[wS][wA] = FALSE ;
  517. }
  518. }
  519. pb = gabAllowedAttributes[STATE_ROOT] ;
  520. pb[ATT_GLOBAL_ONLY] = TRUE ;
  521. pb[ATT_GLOBAL_FREEFLOAT] = TRUE ;
  522. pb = gabAllowedAttributes[STATE_CASE_ROOT] ;
  523. pb[ATT_GLOBAL_FREEFLOAT] = TRUE ;
  524. pb = gabAllowedAttributes[STATE_DEFAULT_ROOT] ;
  525. pb[ATT_GLOBAL_FREEFLOAT] = TRUE ;
  526. pb = gabAllowedAttributes[STATE_OPTIONS] ;
  527. pb[ATT_GLOBAL_FREEFLOAT] = TRUE ;
  528. pb[ATT_LOCAL_FEATURE_FF] = TRUE ;
  529. pb[ATT_LOCAL_OPTION_ONLY] = TRUE ;
  530. pb[ATT_LOCAL_OPTION_FF] = TRUE ;
  531. pb = gabAllowedAttributes[STATE_CASE_OPTION] ;
  532. pb[ATT_GLOBAL_FREEFLOAT] = TRUE ;
  533. pb[ATT_LOCAL_FEATURE_FF] = TRUE ;
  534. pb[ATT_LOCAL_OPTION_FF] = TRUE ;
  535. pb = gabAllowedAttributes[STATE_DEFAULT_OPTION] ;
  536. pb[ATT_GLOBAL_FREEFLOAT] = TRUE ;
  537. pb[ATT_LOCAL_FEATURE_FF] = TRUE ;
  538. pb[ATT_LOCAL_OPTION_FF] = TRUE ;
  539. pb = gabAllowedAttributes[STATE_FEATURE] ;
  540. pb[ATT_LOCAL_FEATURE_ONLY] = TRUE ;
  541. pb[ATT_LOCAL_FEATURE_FF] = TRUE ;
  542. pb = gabAllowedAttributes[STATE_CASE_FEATURE] ;
  543. pb[ATT_LOCAL_FEATURE_FF] = TRUE ;
  544. pb = gabAllowedAttributes[STATE_DEFAULT_FEATURE] ;
  545. pb[ATT_LOCAL_FEATURE_FF] = TRUE ;
  546. pb = gabAllowedAttributes[STATE_COMMAND] ;
  547. pb[ATT_LOCAL_COMMAND_ONLY] = TRUE ;
  548. pb = gabAllowedAttributes[STATE_FONTCART] ;
  549. pb[ATT_LOCAL_FONTCART_ONLY] = TRUE ;
  550. pb = gabAllowedAttributes[STATE_TTFONTSUBS] ;
  551. pb[ATT_LOCAL_TTFONTSUBS_ONLY] = TRUE ;
  552. pb = gabAllowedAttributes[STATE_OEM] ;
  553. pb[ATT_LOCAL_OEM_ONLY] = TRUE ;
  554. }
  555. BOOL BpushState(
  556. PTKMAP ptkmap, // pointer to current entry in tokenmap
  557. BOOL bFirstPass,
  558. PGLOBL pglobl
  559. )
  560. {
  561. // this function assumes (eType == TY_CONSTRUCT)
  562. DWORD dwKeywordID ;
  563. CONSTRUCT eSubType ;
  564. BOOL bStatus = FALSE ;
  565. STATE stOldState, stNewState ;
  566. if(mdwCurStsPtr >= mdwMaxStackDepth)
  567. {
  568. if(ERRSEV_RESTART > geErrorSev)
  569. {
  570. ERR(("Exceeded max state stack depth. Restarting\n"));
  571. geErrorSev = ERRSEV_RESTART ;
  572. geErrorType = ERRTY_MEMORY_ALLOCATION ;
  573. gdwMasterTabIndex = MTI_STSENTRY ;
  574. }
  575. return(FALSE);
  576. }
  577. dwKeywordID = ptkmap->dwKeywordID ;
  578. eSubType = (CONSTRUCT)(mMainKeywordTable[dwKeywordID].dwSubType) ;
  579. if(mdwCurStsPtr)
  580. stOldState = mpstsStateStack[mdwCurStsPtr - 1].stState ;
  581. else
  582. stOldState = STATE_ROOT ;
  583. switch (eSubType)
  584. {
  585. // note CONSTRUCT_CLOSEBRACE already processed
  586. // by PopState().
  587. case (CONSTRUCT_OPENBRACE):
  588. {
  589. vIdentifySource(ptkmap, pglobl) ;
  590. ERR(("OpenBrace encountered without accompanying construct keyword.\n"));
  591. geErrorType = ERRTY_SYNTAX ;
  592. geErrorSev = ERRSEV_FATAL ;
  593. break ;
  594. }
  595. case (CONSTRUCT_FEATURE):
  596. case (CONSTRUCT_OPTION):
  597. case (CONSTRUCT_SWITCH):
  598. case (CONSTRUCT_COMMAND): // commandID's already registered.
  599. case (CONSTRUCT_CASE):
  600. case (CONSTRUCT_FONTCART):
  601. case (CONSTRUCT_TTFONTSUBS):
  602. {
  603. bStatus = BchangeState(ptkmap, eSubType, stOldState, TRUE,
  604. bFirstPass, pglobl) ;
  605. break ;
  606. }
  607. case (CONSTRUCT_UIGROUP):
  608. {
  609. // BUG_BUG!!!!! incomplete. no reqest for this.
  610. }
  611. case (CONSTRUCT_DEFAULT):
  612. case (CONSTRUCT_OEM):
  613. {
  614. bStatus = BchangeState(ptkmap, eSubType, stOldState, FALSE,
  615. bFirstPass, pglobl) ;
  616. break ;
  617. }
  618. default:
  619. {
  620. bStatus = TRUE ; // its ok to ignore some keywords.
  621. break ;
  622. }
  623. }
  624. return(bStatus) ;
  625. }
  626. /*
  627. dead code.
  628. VOID VsetbTTFontSubs(
  629. IN PABSARRAYREF paarValue)
  630. {
  631. // BUG_BUG!!!!!:
  632. // exactly what is supposed to happen ? register
  633. // synthesized symbol ?
  634. gbTTFontSubs = FALSE ;
  635. if( BeatSurroundingWhiteSpaces(paarValue) )
  636. {
  637. if(paarValue->dw == 2 && ! strncmp(paarValue->pub, "ON", 2))
  638. gbTTFontSubs = TRUE ;
  639. else if(paarValue->dw != 3 || strncmp(paarValue->pub, "OFF", 3))
  640. {
  641. BUG_BUG!: value must be either "ON" or "OFF".
  642. }
  643. }
  644. }
  645. */
  646. BOOL BchangeState(
  647. PTKMAP ptkmap, // pointer to construct in tokenmap
  648. CONSTRUCT eConstruct, // this will induce a transition to NewState
  649. STATE stOldState,
  650. BOOL bSymbol, // should dwValue be saved as a SymbolID ?
  651. BOOL bFirstPass,
  652. PGLOBL pglobl
  653. )
  654. {
  655. BOOL bStatus = FALSE ;
  656. STATE stNewState ;
  657. // was checked in PushState, but never hurts to check
  658. // in the same function that consumes the resource.
  659. if(mdwCurStsPtr >= mdwMaxStackDepth)
  660. {
  661. if(ERRSEV_RESTART > geErrorSev)
  662. {
  663. geErrorSev = ERRSEV_RESTART ;
  664. geErrorType = ERRTY_MEMORY_ALLOCATION ;
  665. gdwMasterTabIndex = MTI_STSENTRY ;
  666. }
  667. return(FALSE);
  668. }
  669. stNewState = gastAllowedTransitions[stOldState][eConstruct] ;
  670. if(stNewState == STATE_INVALID)
  671. {
  672. vIdentifySource(ptkmap, pglobl) ;
  673. ERR(("the Construct %0.*s is not allowed within the state: %s\n",
  674. ptkmap->aarKeyword.dw, ptkmap->aarKeyword.pub,
  675. gpubStateNames[stOldState]));
  676. // (convert stOldState
  677. // and eConstruct to meaningful string)
  678. // This is a fatal error since parser cannot second
  679. // guess the problem. The parser's job is to report
  680. // as many legitemate problems as possible not to
  681. // create as useable binary in spite of all the syntax
  682. // errors.
  683. if(ERRSEV_FATAL > geErrorSev)
  684. {
  685. geErrorSev = ERRSEV_FATAL ;
  686. geErrorType = ERRTY_SYNTAX ;
  687. }
  688. return(FALSE);
  689. }
  690. else
  691. {
  692. if(bFirstPass)
  693. { // verify open brace follows construct and discard it.
  694. DWORD dwKeywordID ;
  695. PTKMAP ptkmapTmp = ptkmap + 1 ;
  696. dwKeywordID = ptkmapTmp->dwKeywordID ;
  697. while(dwKeywordID == ID_NULLENTRY) // skip nulls, comments etc.
  698. {
  699. dwKeywordID = (++ptkmapTmp)->dwKeywordID ;
  700. }
  701. if(dwKeywordID < ID_SPECIAL &&
  702. mMainKeywordTable[dwKeywordID].eType == TY_CONSTRUCT &&
  703. mMainKeywordTable[dwKeywordID].dwSubType ==
  704. CONSTRUCT_OPENBRACE )
  705. {
  706. ptkmapTmp->dwKeywordID = ID_NULLENTRY ;
  707. }
  708. else
  709. {
  710. vIdentifySource(ptkmap, pglobl) ;
  711. ERR(("open brace expected after construct: %0.*s but was not found\n",
  712. ptkmap->aarKeyword.dw , ptkmap->aarKeyword.pub )) ;
  713. geErrorType = ERRTY_SYNTAX ;
  714. geErrorSev = ERRSEV_FATAL ;
  715. return(FALSE);
  716. }
  717. }
  718. if(bSymbol)
  719. {
  720. // BUG_BUG: verify tokenmap.dwFlags set to SYMBOLID before
  721. // assuming dwValue is a symbol. An error here
  722. // is a parser bug.
  723. // dwValue is initialized when dwFlag is set.
  724. // further assert is pointless.
  725. // perform multiple passes. The first pass
  726. // registers symbols and counts number of arrays
  727. // to allocate, 2nd pass fills arrays. SymbolID
  728. // now serves as array index.
  729. if(!(ptkmap->dwFlags & TKMF_SYMBOL_REGISTERED))
  730. {
  731. if(!bFirstPass)
  732. {
  733. vIdentifySource(ptkmap, pglobl) ;
  734. ERR(("symbol registration failed twice for: *%0.*s.\n",
  735. ptkmap->aarValue.dw,
  736. ptkmap->aarValue.pub));
  737. return(FALSE) ; // retry
  738. }
  739. if((ptkmap->dwFlags & TKMF_NOVALUE ) ||
  740. ! BeatSurroundingWhiteSpaces(&ptkmap->aarValue) )
  741. {
  742. vIdentifySource(ptkmap, pglobl) ;
  743. ERR(("syntax error in symbol name.\n"));
  744. ptkmap->dwValue = INVALID_SYMBOLID ;
  745. return(FALSE) ;
  746. }
  747. ptkmap->dwValue = DWregisterSymbol(&ptkmap->aarValue,
  748. eConstruct, TRUE, INVALID_SYMBOLID, pglobl) ;
  749. if(ptkmap->dwValue != INVALID_SYMBOLID)
  750. {
  751. ptkmap->dwFlags |= TKMF_SYMBOL_REGISTERED ;
  752. }
  753. else
  754. {
  755. vIdentifySource(ptkmap, pglobl) ;
  756. ERR(("symbol registration failed: *%0.*s.\n",
  757. ptkmap->aarValue.dw,
  758. ptkmap->aarValue.pub));
  759. return(FALSE) ; // retry
  760. }
  761. }
  762. else // second pass, DFEATURE_OPTION arrays allocated.
  763. {
  764. if(eConstruct == CONSTRUCT_SWITCH)
  765. {
  766. PDFEATURE_OPTIONS pfo ;
  767. pfo = (PDFEATURE_OPTIONS)
  768. gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct ;
  769. pfo[ptkmap->dwValue].bReferenced = TRUE ;
  770. // this tells me this Feature is being referenced
  771. // by switch statement, hence the feature had better
  772. // be PICKONE. Sanity checks will later verify
  773. // this assumption.
  774. }
  775. if(eConstruct == CONSTRUCT_FEATURE ||
  776. eConstruct == CONSTRUCT_SWITCH)
  777. {
  778. // BUG_BUG!!!!!: (DCR 454049)
  779. // Note, the same Feature symbol cannot appear
  780. // twice in the stack for any reason.
  781. // A sanity check is needed.
  782. // if duplicate symbol found in stack,
  783. // "a Nested Switch Construct refers to the
  784. // same feature as an enclosing switch or Feature
  785. // construct. This makes no sense."
  786. }
  787. }
  788. bStatus = TRUE ;
  789. mpstsStateStack[mdwCurStsPtr].dwSymbolID = ptkmap->dwValue ;
  790. }
  791. else
  792. bStatus = TRUE ;
  793. if(bStatus)
  794. {
  795. mpstsStateStack[mdwCurStsPtr].stState = stNewState ;
  796. mdwCurStsPtr++ ;
  797. }
  798. }
  799. return(bStatus) ;
  800. }
  801. DWORD DWregisterSymbol(
  802. PABSARRAYREF paarSymbol, // the symbol string to register
  803. CONSTRUCT eConstruct , // type of construct determines class of symbol.
  804. BOOL bCopy, // shall we copy paarSymbol to heap? May set
  805. // to FALSE only if paarSymbol already points
  806. // to a heap object!
  807. DWORD dwFeatureID, // if you are registering an option symbol
  808. // and you already know the feature , pass it in
  809. // here. Otherwise set to INVALID_SYMBOLID
  810. PGLOBL pglobl
  811. )
  812. /* this function registers the entire string specified
  813. in paarSymbol. The caller must isolate the string.
  814. */
  815. {
  816. // returns SymbolID, a zero indexed ordinal
  817. // for extra speed we may hash string
  818. PSYMBOLNODE psn ;
  819. DWORD dwCurNode, dwSymbolID = INVALID_SYMBOLID;
  820. // bCopy = TRUE; //check. Force BUDs to be the same.
  821. if(!paarSymbol->dw)
  822. {
  823. ERR(("DWregisterSymbol: No symbol value supplied.\n"));
  824. return(INVALID_SYMBOLID); // report failure.
  825. }
  826. psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
  827. switch(eConstruct)
  828. {
  829. case CONSTRUCT_FEATURE : // since forward references are allowed
  830. case CONSTRUCT_SWITCH : // it cannot be assumed that references
  831. case CONSTRUCT_FONTCART: // will be to registered symbols .
  832. case CONSTRUCT_COMMAND:
  833. case CONSTRUCT_TTFONTSUBS:
  834. case CONSTRUCT_BLOCKMACRO:
  835. case CONSTRUCT_MACROS:
  836. case CONSTRUCT_PREPROCESSOR:
  837. {
  838. PDWORD pdwSymbolClass ;
  839. pdwSymbolClass = (PDWORD)gMasterTable[MTI_SYMBOLROOT].pubStruct ;
  840. if(eConstruct == CONSTRUCT_FONTCART)
  841. pdwSymbolClass += SCL_FONTCART ;
  842. else if(eConstruct == CONSTRUCT_TTFONTSUBS)
  843. pdwSymbolClass += SCL_TTFONTNAMES ;
  844. else if(eConstruct == CONSTRUCT_COMMAND)
  845. pdwSymbolClass += SCL_COMMANDNAMES ;
  846. else if(eConstruct == CONSTRUCT_BLOCKMACRO)
  847. pdwSymbolClass += SCL_BLOCKMACRO;
  848. else if(eConstruct == CONSTRUCT_MACROS)
  849. pdwSymbolClass += SCL_VALUEMACRO;
  850. else if(eConstruct == CONSTRUCT_PREPROCESSOR)
  851. pdwSymbolClass += SCL_PPDEFINES;
  852. else
  853. pdwSymbolClass += SCL_FEATURES ;
  854. if(*pdwSymbolClass == INVALID_INDEX)
  855. {
  856. // register this symbol now.
  857. if(!BallocElementFromMasterTable(MTI_SYMBOLTREE, &dwCurNode, pglobl))
  858. {
  859. // we have run out of symbol nodes!
  860. return(INVALID_SYMBOLID); // report failure.
  861. }
  862. if(bCopy)
  863. {
  864. if(!BaddAARtoHeap(paarSymbol,
  865. &(psn[dwCurNode].arSymbolName), 1, pglobl))
  866. return(INVALID_SYMBOLID); // report failure.
  867. }
  868. else
  869. {
  870. // derive one from the other.
  871. psn[dwCurNode].arSymbolName.dwCount = paarSymbol->dw ;
  872. psn[dwCurNode].arSymbolName.loOffset =
  873. (DWORD)(paarSymbol->pub - mpubOffRef);
  874. }
  875. dwSymbolID = psn[dwCurNode].dwSymbolID = 0 ; // first symbol
  876. // in list.
  877. psn[dwCurNode].dwNextSymbol = INVALID_INDEX ; // no previous
  878. // symbols exist.
  879. psn[dwCurNode].dwSubSpaceIndex = INVALID_INDEX ; // no
  880. // option symbols exist.
  881. *pdwSymbolClass = dwCurNode ; // now we have a registered
  882. // symbol
  883. }
  884. else
  885. {
  886. // search list for matching symbol.
  887. dwSymbolID = DWsearchSymbolListForAAR(paarSymbol, *pdwSymbolClass, pglobl) ;
  888. if(dwSymbolID != INVALID_SYMBOLID) // found
  889. ; // nothing else is needed, just return.
  890. else // not found, must register.
  891. {
  892. if(!BallocElementFromMasterTable(MTI_SYMBOLTREE,
  893. &dwCurNode, pglobl))
  894. {
  895. return(INVALID_SYMBOLID); // report failure.
  896. }
  897. // tack new symbol onto head of list.
  898. if(bCopy)
  899. {
  900. if(!BaddAARtoHeap(paarSymbol,
  901. &(psn[dwCurNode].arSymbolName), 1, pglobl) )
  902. return(INVALID_SYMBOLID); // report failure.
  903. }
  904. else
  905. {
  906. // derive one from the other.
  907. psn[dwCurNode].arSymbolName.dwCount = paarSymbol->dw ;
  908. psn[dwCurNode].arSymbolName.loOffset =
  909. (DWORD)(paarSymbol->pub - mpubOffRef);
  910. }
  911. dwSymbolID = psn[dwCurNode].dwSymbolID =
  912. psn[*pdwSymbolClass].dwSymbolID + 1;
  913. // increment last ID
  914. psn[dwCurNode].dwNextSymbol = *pdwSymbolClass ;
  915. // link to previous symbols.
  916. psn[dwCurNode].dwSubSpaceIndex = INVALID_INDEX ; // no
  917. // option symbols exist.
  918. *pdwSymbolClass = dwCurNode ; // points to most recent
  919. // symbol
  920. }
  921. }
  922. break;
  923. }
  924. case CONSTRUCT_OPTION :
  925. case CONSTRUCT_CASE :
  926. {
  927. DWORD
  928. dwFeatureIndex, // node containing this symbolID.
  929. dwRootOptions ; // root of option symbols.
  930. #if PARANOID
  931. if(mdwCurStsPtr)
  932. {
  933. // this safety check almost superfluous.
  934. stPrevsState = mpstsStateStack[mdwCurStsPtr - 1].State ;
  935. if(eConstruct == CONSTRUCT_OPTION &&
  936. stPrevsState != STATE_FEATURE)
  937. {
  938. ERR(("DWregisterSymbol: option or case construct is not enclosed within feature or switch !\n"));
  939. return(INVALID_SYMBOLID); // report failure.
  940. }
  941. if(eConstruct == CONSTRUCT_CASE &&
  942. (stPrevsState != STATE_SWITCH_ROOT ||
  943. (stPrevsState != STATE_SWITCH_FEATURE ||
  944. (stPrevsState != STATE_SWITCH_OPTION ) )
  945. {
  946. ERR(("DWregisterSymbol: case construct is not enclosed within switch !\n"));
  947. return(INVALID_SYMBOLID); // report failure.
  948. }
  949. #endif
  950. // Boldly assume top of stack contains a featureID.
  951. // see paranoid code for all assumptions made.
  952. if(dwFeatureID == INVALID_SYMBOLID)
  953. dwFeatureID = mpstsStateStack[mdwCurStsPtr - 1].dwSymbolID ;
  954. dwFeatureIndex = DWsearchSymbolListForID(dwFeatureID,
  955. mdwFeatureSymbols, pglobl) ;
  956. // PARANOID BUG_BUG: coding error if symbolID isn't found!
  957. ASSERT(dwFeatureIndex != INVALID_INDEX) ;
  958. dwRootOptions = psn[dwFeatureIndex].dwSubSpaceIndex ;
  959. // found root of option symbols!
  960. if(dwRootOptions == INVALID_INDEX)
  961. {
  962. if(!BallocElementFromMasterTable(MTI_SYMBOLTREE, &dwCurNode, pglobl))
  963. {
  964. return(INVALID_SYMBOLID); // report failure.
  965. }
  966. // register this symbol now.
  967. if(bCopy)
  968. {
  969. if(!BaddAARtoHeap(paarSymbol, &(psn[dwCurNode].arSymbolName), 1, pglobl) )
  970. return(INVALID_SYMBOLID); // report failure.
  971. }
  972. else
  973. {
  974. // derive one from the other.
  975. psn[dwCurNode].arSymbolName.dwCount = paarSymbol->dw ;
  976. psn[dwCurNode].arSymbolName.loOffset =
  977. (DWORD)(paarSymbol->pub - mpubOffRef);
  978. }
  979. dwSymbolID = psn[dwCurNode].dwSymbolID = 0 ;
  980. // first symbol in list.
  981. psn[dwCurNode].dwNextSymbol = INVALID_INDEX ;
  982. // no previous symbols exist.
  983. psn[dwCurNode].dwSubSpaceIndex = INVALID_INDEX ;
  984. // option symbols have no subspace.
  985. psn[dwFeatureIndex].dwSubSpaceIndex = dwRootOptions =
  986. dwCurNode ; // now we have a registered symbol
  987. }
  988. else
  989. {
  990. // search list for matching symbol.
  991. dwSymbolID = DWsearchSymbolListForAAR(paarSymbol,
  992. dwRootOptions, pglobl) ;
  993. if(dwSymbolID != INVALID_SYMBOLID) // found
  994. ; // nothing else is needed, just return.
  995. else // not found, must register.
  996. {
  997. if(!BallocElementFromMasterTable(MTI_SYMBOLTREE,
  998. &dwCurNode, pglobl))
  999. {
  1000. return(INVALID_SYMBOLID); // report failure.
  1001. }
  1002. // tack new symbol onto head of list.
  1003. if(bCopy)
  1004. {
  1005. if(!BaddAARtoHeap(paarSymbol,
  1006. &(psn[dwCurNode].arSymbolName), 1, pglobl) )
  1007. return(INVALID_SYMBOLID); // report failure.
  1008. }
  1009. else
  1010. {
  1011. // derive one from the other.
  1012. psn[dwCurNode].arSymbolName.dwCount =
  1013. paarSymbol->dw ;
  1014. psn[dwCurNode].arSymbolName.loOffset =
  1015. (DWORD)(paarSymbol->pub - mpubOffRef);
  1016. }
  1017. dwSymbolID = psn[dwCurNode].dwSymbolID =
  1018. psn[dwRootOptions].dwSymbolID + 1; // increment last ID
  1019. psn[dwCurNode].dwNextSymbol = dwRootOptions ;
  1020. // link to previous symbols.
  1021. psn[dwCurNode].dwSubSpaceIndex = INVALID_INDEX ;
  1022. // option symbols have no subspace.
  1023. psn[dwFeatureIndex].dwSubSpaceIndex = dwRootOptions =
  1024. dwCurNode ; // points to most recent symbol
  1025. }
  1026. }
  1027. #if PARANOID
  1028. }
  1029. else
  1030. {
  1031. // BUG_BUG:
  1032. ERR(("DWregisterSymbol: option or case construct is not enclosed within feature or switch !\n"));
  1033. return(INVALID_SYMBOLID); // report failure.
  1034. }
  1035. #endif
  1036. break;
  1037. }
  1038. default:
  1039. {
  1040. // PARANOID BUG_BUG:
  1041. ERR(("DWregisterSymbol: construct has no symbol class.\n"));
  1042. return(INVALID_SYMBOLID); // report failure.
  1043. }
  1044. }
  1045. return(dwSymbolID) ;
  1046. }
  1047. BOOL BaddAARtoHeap(
  1048. PABSARRAYREF paarSrc,
  1049. PARRAYREF parDest,
  1050. DWORD dwAlign, // write data to address that is a multiple of dwAlign
  1051. PGLOBL pglobl)
  1052. // this function copies a non NULL terminated string fragment
  1053. // referenced by an 'aar'
  1054. // into the communal STRINGHEAP and returns an 'ar'
  1055. // which describes the location of the copy.
  1056. {
  1057. PBYTE pubSrc, pubDest ;
  1058. DWORD dwCnt ; // num bytes to copy.
  1059. // legal values for dwAlign are 1 and 4.
  1060. mloCurHeap = (mloCurHeap + dwAlign - 1) / dwAlign ;
  1061. mloCurHeap *= dwAlign ;
  1062. pubSrc = paarSrc->pub ;
  1063. dwCnt = paarSrc->dw ;
  1064. pubDest = mpubOffRef + mloCurHeap ;
  1065. // is there enough room in the heap ?
  1066. // don't forget the NULL.
  1067. if(mloCurHeap + dwCnt + 1 > mdwMaxHeap)
  1068. {
  1069. // log error to debug output.
  1070. // register error so appropriate action is taken.
  1071. if(ERRSEV_RESTART > geErrorSev)
  1072. {
  1073. geErrorSev = ERRSEV_RESTART ;
  1074. geErrorType = ERRTY_MEMORY_ALLOCATION ;
  1075. gdwMasterTabIndex = MTI_STRINGHEAP ;
  1076. }
  1077. return(FALSE);
  1078. }
  1079. parDest->dwCount = dwCnt ;
  1080. parDest->loOffset = mloCurHeap; // offset only!
  1081. memcpy(pubDest, pubSrc, dwCnt);
  1082. // the copy may also fail for random reasons!
  1083. pubDest[dwCnt] = '\0' ; // Add Null termination.
  1084. mloCurHeap += (dwCnt + 1); // update heap ptr.
  1085. return(TRUE) ;
  1086. }
  1087. BOOL BwriteToHeap(
  1088. OUT PDWORD pdwDestOff, // heap offset of dest string
  1089. PBYTE pubSrc, // points to src string
  1090. DWORD dwCnt, // num bytes to copy from src to dest.
  1091. DWORD dwAlign, // write data to address that is a multiple of dwAlign
  1092. PGLOBL pglobl)
  1093. // this function copies dwCnt bytes from pubSrc to
  1094. // top of heap and writes the offset of the destination string
  1095. // to pdwDestOff. Nothing is changed if FAILS.
  1096. // Warning! No Null termination is added to string.
  1097. {
  1098. PBYTE pubDest ;
  1099. // legal values for dwAlign are 1 and 4.
  1100. mloCurHeap = (mloCurHeap + dwAlign - 1) / dwAlign ;
  1101. mloCurHeap *= dwAlign ;
  1102. pubDest = mpubOffRef + mloCurHeap ;
  1103. // is there enough room in the heap ?
  1104. if(mloCurHeap + dwCnt > mdwMaxHeap)
  1105. {
  1106. // log error to debug output.
  1107. // register error so appropriate action is taken.
  1108. ERR(("BwriteToHeap: out of heap - restarting.\n"));
  1109. if(ERRSEV_RESTART > geErrorSev)
  1110. {
  1111. geErrorSev = ERRSEV_RESTART ;
  1112. geErrorType = ERRTY_MEMORY_ALLOCATION ;
  1113. gdwMasterTabIndex = MTI_STRINGHEAP ;
  1114. }
  1115. return(FALSE);
  1116. }
  1117. memcpy(pubDest, pubSrc, dwCnt);
  1118. // the copy may also fail for random reasons!
  1119. *pdwDestOff = mloCurHeap ;
  1120. mloCurHeap += (dwCnt); // update heap ptr.
  1121. return(TRUE) ;
  1122. }
  1123. DWORD DWsearchSymbolListForAAR(
  1124. PABSARRAYREF paarSymbol,
  1125. DWORD dwNodeIndex,
  1126. PGLOBL pglobl)
  1127. // given a 'aar' to a string representing a symbol, search
  1128. // the SymbolList beginning at dwNodeIndex for this symbol.
  1129. // Return its symbolID if found, else return the INVALID_SYMBOLID.
  1130. {
  1131. PSYMBOLNODE psn ;
  1132. psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
  1133. for( ; dwNodeIndex != INVALID_INDEX ;
  1134. dwNodeIndex = psn[dwNodeIndex].dwNextSymbol)
  1135. {
  1136. if(BCmpAARtoAR(paarSymbol, &(psn[dwNodeIndex].arSymbolName), pglobl) )
  1137. return(psn[dwNodeIndex].dwSymbolID); // string matches !
  1138. }
  1139. return(INVALID_SYMBOLID);
  1140. }
  1141. DWORD DWsearchSymbolListForID(
  1142. DWORD dwSymbolID, // find node containing this ID.
  1143. DWORD dwNodeIndex, // start search here.
  1144. PGLOBL pglobl)
  1145. // given a symbolID, search the SymbolList beginning at dwNodeIndex
  1146. // for this symbol.
  1147. // If found return the node index which contains the requested symbolID,
  1148. // else return INVALID_INDEX.
  1149. {
  1150. PSYMBOLNODE psn ;
  1151. psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
  1152. for( ; dwNodeIndex != INVALID_INDEX ;
  1153. dwNodeIndex = psn[dwNodeIndex].dwNextSymbol)
  1154. {
  1155. if(psn[dwNodeIndex].dwSymbolID == dwSymbolID)
  1156. return(dwNodeIndex); // ID matches !
  1157. }
  1158. return(INVALID_INDEX);
  1159. }
  1160. BOOL BCmpAARtoAR(
  1161. PABSARRAYREF paarStr1,
  1162. PARRAYREF parStr2,
  1163. PGLOBL pglobl)
  1164. // Compares two strings, one referenced by 'aar' the other
  1165. // referenced by 'ar'. Returns TRUE if they match, FALSE
  1166. // otherwise.
  1167. {
  1168. if(paarStr1->dw != parStr2->dwCount)
  1169. return(FALSE) ; // Lengths don't even match!
  1170. if(strncmp(paarStr1->pub, mpubOffRef + parStr2->loOffset , paarStr1->dw))
  1171. return(FALSE) ;
  1172. return(TRUE) ;
  1173. }
  1174. BOOL BpopState(
  1175. PGLOBL pglobl)
  1176. {
  1177. if(mdwCurStsPtr)
  1178. {
  1179. mdwCurStsPtr-- ;
  1180. return(TRUE);
  1181. }
  1182. else
  1183. {
  1184. // ERR(("Unmatched closing brace!\n"));
  1185. // message moved to caller.
  1186. // in the future make parser smarter.
  1187. geErrorType = ERRTY_SYNTAX ;
  1188. geErrorSev = ERRSEV_FATAL ;
  1189. return(FALSE);
  1190. }
  1191. }
  1192. VOID VinitDictionaryIndex(
  1193. PGLOBL pglobl)
  1194. /*
  1195. MainKeywordTable[] is assumed to be divided into
  1196. a NonAttributes section and several Attributes sections
  1197. with pstrKeyword = NULL dividing the sections.
  1198. The end of the table is also terminated by a NULL entry.
  1199. This function initializes the grngDictionary[]
  1200. which serves as an index into the main keyword Table.
  1201. */
  1202. {
  1203. DWORD dwI, // keywordTable Index
  1204. dwSect ; // RNGDICTIONARY Index
  1205. PRANGE prng ;
  1206. prng = (PRANGE)(gMasterTable[MTI_RNGDICTIONARY].pubStruct) ;
  1207. for(dwI = dwSect = 0 ; dwSect < END_ATTR ; dwSect++, dwI++)
  1208. {
  1209. prng[dwSect].dwStart = dwI ;
  1210. for( ; mMainKeywordTable[dwI].pstrKeyword ; dwI++ )
  1211. ;
  1212. prng[dwSect].dwEnd = dwI ; // one past the last entry
  1213. }
  1214. }
  1215. VOID VcharSubstitution(
  1216. PABSARRAYREF paarStr,
  1217. BYTE ubTgt,
  1218. BYTE ubReplcmnt,
  1219. PGLOBL pglobl)
  1220. {
  1221. DWORD dwI ;
  1222. for(dwI = 0 ; dwI < paarStr->dw ; dwI++)
  1223. {
  1224. if(paarStr->pub[dwI] == ubTgt)
  1225. paarStr->pub[dwI] = ubReplcmnt ;
  1226. }
  1227. }
  1228. VOID VIgnoreBlock(
  1229. PTKMAP ptkmap,
  1230. BOOL bIgnoreBlock,
  1231. PGLOBL pglobl)
  1232. // This boolean determines the message that will be issued.
  1233. {
  1234. /* Should we ignore? check that first non-NULL entry
  1235. after wCurEntry is open brace if so
  1236. ignore all entries up to EOF or matching closing
  1237. brace. */
  1238. DWORD dwKeywordID, dwDepth ; // depth relative to *IgnoreBlock
  1239. ptkmap->dwKeywordID = ID_NULLENTRY ; // neutralize keyword regardless.
  1240. ptkmap++ ;
  1241. dwKeywordID = ptkmap->dwKeywordID ;
  1242. while(dwKeywordID == ID_NULLENTRY) // skip nulls, comments etc.
  1243. {
  1244. dwKeywordID = (++ptkmap)->dwKeywordID ;
  1245. }
  1246. if(dwKeywordID < ID_SPECIAL &&
  1247. mMainKeywordTable[dwKeywordID].eType == TY_CONSTRUCT &&
  1248. mMainKeywordTable[dwKeywordID].dwSubType ==
  1249. CONSTRUCT_OPENBRACE )
  1250. {
  1251. ptkmap->dwKeywordID = ID_NULLENTRY ;
  1252. dwDepth = 1 ;
  1253. ptkmap++ ;
  1254. if(bIgnoreBlock)
  1255. {
  1256. if(gdwVerbosity >= 4)
  1257. ERR(("Note: Ignoring block following *IgnoreBlock.\n"));
  1258. }
  1259. else
  1260. ERR(("Ignoring block following unrecognized keyword.\n"));
  1261. }
  1262. else
  1263. {
  1264. if(bIgnoreBlock && gdwVerbosity >= 2)
  1265. ERR(("Note: Brace delimited block not found after *IgnoreBlock.\n"));
  1266. return ; // do nothing.
  1267. }
  1268. while(dwDepth)
  1269. {
  1270. dwKeywordID = ptkmap->dwKeywordID ;
  1271. if(dwKeywordID == ID_EOF)
  1272. {
  1273. ERR(("Ignoring Block: EOF encountered before closing brace.\n"));
  1274. return ; // stop regardless!
  1275. }
  1276. if(dwKeywordID < ID_SPECIAL)
  1277. {
  1278. KEYWORD_TYPE eType;
  1279. CONSTRUCT eSubType ;
  1280. eType = mMainKeywordTable[dwKeywordID].eType ;
  1281. if(eType == TY_CONSTRUCT)
  1282. {
  1283. eSubType = (CONSTRUCT)(mMainKeywordTable[dwKeywordID].dwSubType) ;
  1284. if(eSubType == CONSTRUCT_OPENBRACE)
  1285. dwDepth++ ;
  1286. else if( eSubType == CONSTRUCT_CLOSEBRACE)
  1287. dwDepth-- ;
  1288. }
  1289. }
  1290. ptkmap->dwKeywordID = ID_NULLENTRY ;
  1291. ptkmap++ ;
  1292. }
  1293. return ;
  1294. }