Source code of Windows XP (NT5)
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.

1422 lines
53 KiB

  1. /*****************************************************************************
  2. emrule.h
  3. Owner: DaleG
  4. Copyright (c) 1992-1997 Microsoft Corporation
  5. General Rule-Network Propagation Engine functions and prototypes
  6. ----------------------------------------------------------------------------
  7. NOTE:
  8. 1. BAD CODE, but it works: FIsDelayFactor(),LpruldependFromCDelay() and
  9. CDelayFromLpruldepend() rely upon the fact (?) that pointers
  10. on the machines we support are never (?) small integers. But if
  11. this should ever prove false, it would be bad. We should rewrite
  12. this to either have a RULDEP structure (as does the rule compiler),
  13. or make the list of dependencies indexes to rules, rather than
  14. pointers.
  15. *****************************************************************************/
  16. #ifndef EMRULE_H
  17. #include "msodbglg.h"
  18. #include "emkwd.h"
  19. #include "emrulini.h"
  20. #include "emrultk.h"
  21. MSOEXTERN_C_BEGIN // ***************** Begin extern "C" ********************
  22. // REVIEW: configure this in makefile, so emtest (for example) can build
  23. // debug without dynamic rules
  24. #ifdef DEBUG
  25. #ifndef YY_NODYNRULES
  26. #define DYN_RULES 1
  27. #endif
  28. #endif
  29. /*----------------------------------------------------------------------------
  30. System limits
  31. ----------------------------------------------------------------------------*/
  32. #define wDelayMax 100 // Maximum delay poss
  33. #define irultkRuleMax 256 // Max events cached
  34. #define iruldepAllocMax 256 // Max ruldeps alloced
  35. #define ichRulNameMax 128 // Max trace name len
  36. #define ichRulNameAllocMax 1024 // Max name alloc
  37. /*************************************************************************
  38. Types:
  39. irul Rule node ID.
  40. ruldep Rule node dependency link.
  41. ruldepblk Rule node dependency link allocation structure.
  42. sv Split Value structure.
  43. rul Rule node structure.
  44. ruls Rule state structure.
  45. *************************************************************************/
  46. /* I R U L */
  47. /*----------------------------------------------------------------------------
  48. %%Structure: IRUL
  49. %%Contact: daleg
  50. Rule Index definition
  51. ----------------------------------------------------------------------------*/
  52. typedef short IRUL;
  53. #define IrulFromTk(tk) ((IRUL) (tk))
  54. #define TkFromIrul(irul) (irul)
  55. // Lexer tokens: hard-coded rule node IDs
  56. #define irulERROR tkERROR
  57. #ifdef tkNil
  58. #define irulNil tkNil
  59. #else /* !tkNil */
  60. #define irulNil 0
  61. #endif /* tkNil */
  62. // Is rule ID valid (not irulNil and not irulERROR)
  63. #define FValidIrul(irul) \
  64. ((irul) > 0)
  65. /* R U L D E P */
  66. /*----------------------------------------------------------------------------
  67. %%Structure: RULDEP
  68. %%Contact: daleg
  69. Rule node dependency structure.
  70. This structure holds the dependency information that links a rule node
  71. to its dependents.
  72. ----------------------------------------------------------------------------*/
  73. typedef struct _RULDEP
  74. {
  75. struct _MSORUL *prul; // Node referenced
  76. struct _RULDEP *pruldepNext; // Next dependency
  77. // int cDelay; // Delay in eval
  78. } RULDEP;
  79. MSOAPI_(RULDEP *) _MsoPruldepNew( // Alloc blk of deps
  80. int cruldep,
  81. int fOnFreeList
  82. );
  83. // Return a new ruldep record from the free list (requires local var pruldep)
  84. // Operates in either sequential mode (vlpruls->lpruldepNextFree) or free list
  85. #define LpruldepNew() \
  86. (vlpruls->lpruldepNextFree != NULL \
  87. ? (vlpruls->fSeqentialFreeRuldeps \
  88. ? vlpruls->lpruldepNextFree++ \
  89. : (pruldep = vlpruls->lpruldepNextFree, \
  90. vlpruls->lpruldepNextFree \
  91. = pruldep->pruldepNext, \
  92. pruldep->pruldepNext = NULL, \
  93. pruldep)) \
  94. : _MsoPruldepNew(iruldepAllocMax, TRUE))
  95. // Push a ruldep record onto the free list
  96. #define PushLpruldepOnFreeList(pruldep) \
  97. ((pruldep)->pruldepNext = vlpruls->lpruldepNextFree, \
  98. vlpruls->lpruldepNextFree = (pruldep))
  99. /* R U L D E P B L K */
  100. /*----------------------------------------------------------------------------
  101. %%Structure: RULDEPBLK
  102. %%Contact: daleg
  103. Rule node dependency allocation block structure.
  104. This structure allows us to batch-allocate RULDEP records.
  105. ----------------------------------------------------------------------------*/
  106. typedef struct _RULDEPBLK
  107. {
  108. struct _RULDEPBLK *lpruldepblkNext; // Next block
  109. RULDEP rgruldep[1]; // Array of ruldeps
  110. } RULDEPBLK;
  111. /* R U L C X T */
  112. /*----------------------------------------------------------------------------
  113. %%Structure: RULCXT
  114. %%Contact: daleg
  115. (Rul)e (C)onte(x)t-group (T)able structure.
  116. This structure allows the rule engine to support cheap sparse dependents
  117. lists for special contexts.
  118. The callback function allows us to perform any desired side effects
  119. during the propagation, as well as offering the chance to optimize
  120. the lookup algorithm.
  121. ----------------------------------------------------------------------------*/
  122. typedef struct _RULCXT
  123. {
  124. struct _RULCXT *lprulcxtNext; // Next context
  125. LPFNRULCXT lpfnrulcxt; // Callback fn
  126. int iruldepMax; // Size of array
  127. struct _RULCXL *rglprulcxl[1]; // Hash table
  128. } RULCXT;
  129. /* R U L C X L */
  130. /*----------------------------------------------------------------------------
  131. %%Structure: RULCXL
  132. %%Contact: daleg
  133. (Rul)e (C)onte(x)t-group (L)ist item structure.
  134. This is the item used in the hash table of the RULCXT above.
  135. ----------------------------------------------------------------------------*/
  136. typedef struct _RULCXL
  137. {
  138. IRUL irul; // Rule ID
  139. struct _RULDEP *pruldep; // Dependent list
  140. struct _RULCXL *lprulcxlNext; // Next in hash chain
  141. } RULCXL;
  142. #ifdef DEBUG
  143. /* R U L N B L K */
  144. /*----------------------------------------------------------------------------
  145. %%Structure: RULNBLK
  146. %%Contact: daleg
  147. (Rul)e (N)ame block
  148. Store dynamically constructed rule names.
  149. ----------------------------------------------------------------------------*/
  150. typedef struct _RULNBLK
  151. {
  152. struct _RULNBLK *lprulnblkNext; // Next block
  153. char rgch[1]; // Block of text
  154. } RULNBLK;
  155. char *LszGenNameForLprul( // Gen dyn rule name
  156. struct _MSORUL *prul,
  157. int irulAssert
  158. );
  159. char *SzSaveRulName(char *szName); // Save node name sz
  160. char *LpchRulNameNew(int dichNeeded); // Get new name lpch
  161. #endif /* DEBUG */
  162. /* M S O R U L */
  163. /*----------------------------------------------------------------------------
  164. %%Structure: MSORUL
  165. %%Contact: daleg
  166. Rule node structure.
  167. This structure holds the state information for a rule within the
  168. propagation network.
  169. ASSUMPTIONS:
  170. 1. The wDelayMask field only applies to rules, but it is (currently)
  171. faster to not have to test for whether a node is a rule, by
  172. merely leaving the field empty for values.
  173. ----------------------------------------------------------------------------*/
  174. typedef long RULV;
  175. typedef struct _MSORUL *MSOPRUL;
  176. #pragma pack(2)
  177. typedef struct _MSORUL
  178. {
  179. IRUL irul; // Rule ID
  180. char rultType; // Type: rule/event
  181. char ipfnrulscSeqCheck; // Fn to ensure contig
  182. short rulevl; // Evaluation level
  183. short birulDependsOn; // Depends on: nodes
  184. SVL svl; // 32-bit storage area
  185. #ifdef DEBUG
  186. char const *lpchName; // Name or rule text
  187. #endif /* DEBUG */
  188. IRUL irulNextChanged; // Next changed value
  189. union
  190. {
  191. short ipociiInstrs; // Interp instrs
  192. short USEME_IN_EVENTS; // Unsed slot
  193. };
  194. short wIntervalCount; // Ensure contig seqs
  195. short wDelayMask; // Delays as bit pos's
  196. struct _MSORUL *prulNext; // Next node in queue
  197. #ifdef DEBUG
  198. IRUL irulNextTrace; // Next traced rule
  199. short wDebugFlags; // Random debug flags
  200. #endif /* DEBUG */
  201. } MSORUL;
  202. #pragma pack()
  203. // Allocate new nodes
  204. MSOAPI_(MSORUL *) MsoPrulNew(void); // Allocate new node
  205. MSOAPI_(int) MsoFEnsureIrulAllocated(int irulMax); // Pre-allocated nodes
  206. // Discard an existing rul node
  207. #define DiscardIrul(irul) \
  208. (vlpruls->irulLim--)
  209. #define msoprulNil ((MSORUL *) -1) // NIL value for MSORUL
  210. #define msoprulInactive ((MSORUL *) -2) // Node is deactivated
  211. #define wRulTrue 1000
  212. #define wRulFalse 0
  213. // Rule node type flags: shared with emrulini.h and rulc.h
  214. #define rultNil 0
  215. #define rultRule 0x00 // Rule
  216. #define rultEvent 0x01 // Event/Variable
  217. #define rultPrimaryRule 0x02 // Rule auto-scheduled
  218. #define rultImmediateRule 0x04 // Rule executes immed
  219. #define rultPersistentRule 0x20 // Rule not cleared
  220. #define rultAlwaysPersist 0x40 // Rule never cleared
  221. #define rultSpecialKwd 0x80 // Node is generic type
  222. // Debug check that rule is not marked as both NonTerminal and Seq
  223. #define rultRuleMask 0x19
  224. #ifdef NEVER
  225. #define FRultRuleIs(rult, rultExpected) \
  226. (((rult) & rultRuleMask) == ((rultExpected)))
  227. #endif /* NEVER */
  228. #ifdef DEBUG
  229. #define rultDynActionRule 0x04 // Dyn DEBUG only
  230. #define rultNonTermRule 0x08 // Dyn DEBUG only
  231. #define rultSeqRule 0x10 // Dyn DEBUG only
  232. #endif /* DEBUG */
  233. /* R U L S */
  234. /*----------------------------------------------------------------------------
  235. %%Structure: RULS
  236. %%Contact: daleg
  237. Rule state structure.
  238. This structure holds the state information for the rule engine.
  239. ----------------------------------------------------------------------------*/
  240. typedef int (WIN_CALLBACK *LPFNRul)(IRUL irul); // Rule Eval function
  241. typedef short (WIN_CALLBACK *PFNRULSC)(void); // Interval seq chk fn
  242. typedef int (*PFNRULVT)(IRUL irul); // Rule V-Table
  243. typedef struct _RULS
  244. {
  245. // Rule base limits
  246. RULLIMS rullims; // Rule base limits
  247. int irulMax; // Num nodes allocated
  248. int irulLim; // Num nodes used
  249. // Rule base state information
  250. RULDEP ***rgrgpruldepDependents; // List of Dep lists
  251. RULDEP **rgpruldepDependents; // Active Dep lists
  252. MSORUL **lrglprulBlk; // Array of node arrays
  253. int ilprulNodesLim; // #arrays of arrays
  254. #ifdef DEBUG
  255. MSORUL **rgprulNodes; // Debug node array
  256. #endif /* DEBUG */
  257. const short *prulgAppendTo; // Group linkages
  258. const short *prulgAppendedFrom; // Group linkages
  259. short const *rgrulevlRulevt; // Event_type eval lvls
  260. int *rgrulevlRulevtLast; // Highest Q of rulevts
  261. MSORUL **rgprulActiveQueues; // Active eval queues
  262. MSORUL **rgprulDelayedQueues; // Delayed eval queues
  263. MSORUL *lprulQPersistent; // Temp Q: persistent
  264. int *rgirulRulevtChanged; // Nodes changed in evt
  265. int *rgrulevtEval; // Pending rulevt eval
  266. MSORULTKH *prultkhRulevtHistory; // Ev history for type
  267. long *rgdtkiRulevt; // #times enter rulevt
  268. const int *rgrulevtFromRulevl; // Trans lvls to evts
  269. const short *lpgrpirulDependBack; // Back dependencies
  270. LPFNRul lpfnEvalRule; // Evaluate rule code
  271. PFNRULSC const *rgpfnrulscSeqCheck; // Interval seq chk fns
  272. MSOKWTB **rgpkwtbKeyTables; // Keyword tables
  273. // Allocation information
  274. WORD fDynamicInit : 1; // Structs alloced?
  275. WORD fDynAlloced : 1; // vlpruls alloced?
  276. WORD fDependBackDynAlloced : 1; // Back deps alloced?
  277. WORD fRgDependDynAlloced : 1; // Dep lists alloced?
  278. WORD fDynRulesAlloced : 1; // Dyn rulebase alloc?
  279. WORD fRgrulevlRulevtAlloced : 1; // Last lvl tbl alloc?
  280. WORD fRgprulQueuesAlloced : 1; // Eval queues alloc?
  281. WORD fRgrulevtFromRulevlAlloced : 1; // Lvl-evt tbl alloc?
  282. WORD fRgprulNodesAlloced : 1; // DEBUG nd arr alloc?
  283. int rulgCurr; // Current rule group
  284. IRUL irulSelf; // irulSelf under eval
  285. MSORUL *prulEvent; // Event causing eval
  286. IRUL irulPrimaryEvent; // Primary ev of intvl
  287. RULDEP *lpruldepNextFree; // Next free dep rec
  288. RULDEPBLK *lpruldepblkDependBlocks; // List of dep blocks
  289. RULCXT *lprulcxtActive; // Active context list
  290. RULCXT **lrglprulcxtContexts; // List of cntx groups
  291. int rulevtCurr; // Current event_type
  292. int *prulevtEvalLim; // Num Ev types to eval
  293. MSORUL *lprulQueue; // Current queue
  294. int rulevlRultevtMin; // 1st eval lvl in evt
  295. int rulevlRulevtLast; // Last eval lvl in evt
  296. void *pociiDynRules; // Dyn-loaded rulebase
  297. #ifdef DEBUG
  298. char *lpchNames; // Name/string buf
  299. char const * const *rgpchDynNames; // Interp: node names
  300. int irulQTrace; // Backtrace list
  301. int dichNameFree; // Num chars avail
  302. char *lpchNameNextFree; // Next free name rgch
  303. RULNBLK *lprulnblkNames; // Dyn name list
  304. #endif /* DEBUG */
  305. // Run-time flags
  306. WORD fInited : 1; // Rule base inited?
  307. WORD fNew : 1; // Rule base new?
  308. WORD fSeqentialFreeRuldeps : 1; // Free ruldeps are seq
  309. WORD fEvaluatingDeferred : 1; // Evaling deferred nd?
  310. WORD fEvaluating: 1; // Eval recursion check
  311. // Multiple Rule base support
  312. struct _RULS *lprulsNext; // Next struct LIFO
  313. // Allocation info
  314. WORD fAllocedSpare1 : 1;
  315. WORD fAllocedSpare2 : 1;
  316. WORD fAllocedSpare3 : 1;
  317. WORD fAllocedSpare4 : 1;
  318. WORD fAllocedSpare5 : 1;
  319. WORD fAllocedSpare6 : 1;
  320. WORD fAllocedSpare7 : 1;
  321. WORD fAllocedSpare8 : 1;
  322. WORD fAllocedSpare9 : 1;
  323. WORD fAllocedSpare10 : 1;
  324. WORD fAllocedSpare11 : 1;
  325. int ilprulNodesAllocFirstLim; // Start alloc'd nds +1
  326. long lReturn; // Return value
  327. LPV lpvSpare3;
  328. LPV lpvSpare4;
  329. LPV lpvSpare5;
  330. LPV lpvSpare6;
  331. LPV lpvSpare7;
  332. LPV lpvSpare8;
  333. LPV lpvSpare9;
  334. LPV lpvSpare10;
  335. LPV lpvSpare11;
  336. // Debug logging
  337. #ifdef DEBUG
  338. unsigned int grfDebugLogFilter; // DEBUG: how to log
  339. #endif /* DEBUG */
  340. #ifdef DYN_RULES
  341. // Dynamically-loaded rulebase support
  342. struct _MSOOCIS *pocis; // Op-Code Interp State
  343. short irulRuleInterpLim; // #Interpreted rules
  344. short irulRuleInterpMac; // #Alloced inter ptrs
  345. void **rgpociiRules; // Rule instructions
  346. #endif /* DYN_RULES */
  347. } RULS;
  348. extern RULS *vlpruls; // Global rule state
  349. //----------------------------------------------------
  350. // If using debugger, an rulebase node's value is given by:
  351. // rulv_<irul> == vlpruls->rgprulNodes[irul]->svl.lValue
  352. //
  353. // Or if the rulebase is statically initialized, and
  354. // DEBUG_RULE_POINTERS is #defined then
  355. // event FOO can be accessed as *prulFOO and
  356. // rule 126 can be accessed as *prul126
  357. //----------------------------------------------------
  358. // Return the number of rules in rule base
  359. #define IrulMax() (vlpruls->irulMax)
  360. // Return the number of compiled rules in rule base
  361. #define IrulCompiledMax() (vlpruls->rullims.irulRulesMax)
  362. // Return the number of event_types in rule base
  363. #define RulevtMax() RulevtMaxPruls(vlpruls)
  364. // Return the number of event_types in rule base
  365. #define RulevtMaxPruls(pruls) \
  366. ((pruls)->rullims.rulevtMax)
  367. // Return the number of evaluation levels in rule base
  368. #define RulevlMax() RulevlMaxPruls(vlpruls)
  369. // Return the number of evaluation levels in rule base
  370. #define RulevlMaxPruls(pruls) \
  371. ((pruls)->rullims.rulevlMax)
  372. #define irulMaxAlloc 128 // Max nodes/array
  373. #define cbfIrulShift 7 // #bits irulMaxAlloc
  374. #define wIrulMask 0x7F // Mask: irulMaxAlloc
  375. #define ilprulMaxAlloc 256L // Max arrays of arrys
  376. ///#define irulMaxAlloc 2048 // Max nodes/array
  377. ///#define cbfIrulShift 11 // #bits irulMaxAlloc
  378. ///#define wIrulMask 0x7FF // Mask: irulMaxAlloc
  379. ///#define ilprulMaxAlloc 100L // Max arrays of arrys
  380. ///#define irulMaxAlloc 1024 // Max nodes/array
  381. ///#define cbfIrulShift 10 // #bits irulMaxAlloc
  382. ///#define wIrulMask 0x3FF // Mask: irulMaxAlloc
  383. ///#define ilprulMaxAlloc 100L // Max arrays of arrys
  384. // Return the rule node structure pointer for the rule ID
  385. #define LprulFromIrul(irul) \
  386. (&vlpruls->lrglprulBlk \
  387. [(irul) >> cbfIrulShift] [(irul) & wIrulMask])
  388. // Return the rule ID of the rule node structure pointer
  389. #define IrulFromLprul(prul) \
  390. ((prul)->irul)
  391. // Return the Lim irul value for iruls that are contiguous with the irul
  392. #define IrulLimContig(irul) \
  393. ((((irul) >> cbfIrulShift) << cbfIrulShift) + irulMaxAlloc)
  394. // Return whether rule node is a primary rule
  395. #define FPrimaryRule(prul) ((prul)->rultType & rultPrimaryRule)
  396. #ifdef NEVER
  397. // Return whether rule node is a action rule
  398. #define FActionRule(prul) ((prul)->wDebugFlags & rultActionRule)
  399. #endif /* NEVER */
  400. #ifdef DEBUG
  401. // Return whether rule node is a non-terminal rule (then)
  402. #define FNonTermRule(prul) ((prul)->wDebugFlags & rultNonTermRule)
  403. // Return whether rule node is a sequence rule (...)
  404. #define FSeqRule(prul) ((prul)->wDebugFlags & rultSeqRule)
  405. #endif /* DEBUG */
  406. // Return whether the node ID refers to an event node
  407. #define FIsEventIrul(irul) FIsEventPrul(LprulFromIrul(irul))
  408. // Return whether the node is an event node
  409. #define FIsEventPrul(prul) ((prul)->rultType & rultEvent)
  410. // Return whether the node is a rule node
  411. #define FIsRulePrul(prul) (!FIsEventPrul(prul))
  412. #define IMMEDIATE_RULES
  413. #ifdef IMMEDIATE_RULES
  414. // Return whether rule node is a sequence rule (...)
  415. #define FImmediateRulePrul(prul) ((prul)->rultType & rultImmediateRule)
  416. #endif /* IMMEDIATE_RULES */
  417. // Return whether the node is an *undefined* event
  418. #define FSpecialKwdIrul(irul) \
  419. FSpecialKwdLprul(LprulFromIrul(irul))
  420. // Return whether the node is an *undefined* event
  421. #define SetFSpecialKwdIrul(irul) \
  422. SetFSpecialKwdLprul(LprulFromIrul(irul))
  423. // Return whether the node is an *undefined* event
  424. #define FSpecialKwdLprul(prul) ((prul)->rultType & rultSpecialKwd)
  425. // Return whether the node is an *undefined* event
  426. #define SetFSpecialKwdLprul(prul) \
  427. ((prul)->rultType |= rultSpecialKwd)
  428. // Return whether rule node can persist in delayed queue in soft resets
  429. #define FPersistentLprul(prul) \
  430. ((prul)->rultType & rultPersistentRule)
  431. // Mark that rule node can persist in delayed queue in soft resets
  432. #define SetFPersistentIrul(irul) \
  433. SetFPersistentLprul(LprulFromIrul(irul))
  434. // Mark that rule node can persist in delayed queue in soft resets
  435. #define SetFPersistentLprul(prul) \
  436. ((prul)->rultType |= rultPersistentRule)
  437. // Return whether rule node can persist in delayed queue in all resets
  438. #define FAlwaysPersistLprul(prul) \
  439. ((prul)->rultType & rultAlwaysPersist)
  440. // Mark that rule node can persist in delayed queue in all resets
  441. #define SetFAlwaysPersistIrul(irul) \
  442. SetFAlwaysPersistLprul(LprulFromIrul(irul))
  443. // Mark that rule node can persist in delayed queue in all resets
  444. #define SetFAlwaysPersistLprul(prul) \
  445. ((prul)->rultType |= rultAlwaysPersist)
  446. // Return whether rule node can persist in delayed queue
  447. #define FPersistLprulGrf(prul, grf) \
  448. ((prul)->rultType & (grf))
  449. // Return the value for the current rule
  450. #define RulvSelf() \
  451. RulvOfIrul(irulSelf)
  452. // Set the value for the current rule
  453. #define SetRulvSelf(rulv) \
  454. SetRulvOfIrul(irulSelf, (rulv))
  455. // Increment the value for the current rule
  456. #define IncrRulvSelf(drulv) \
  457. IncrRulvOfIrul(irulSelf, (drulv))
  458. // Return the value1 for the current rule
  459. #define Rulv1Self() \
  460. Rulv1OfIrul(irulSelf)
  461. // Set the value1 for the current rule
  462. #define SetRulv1Self(rulv) \
  463. SetRulv1OfIrul(irulSelf, (rulv))
  464. // Increment the value1 for the current rule
  465. #define IncrRulv1Self(drulv) \
  466. IncrRulv1OfIrul(irulSelf, (drulv))
  467. // Return the value2 for the current rule
  468. #define Rulv2Self() \
  469. Rulv2OfIrul(irulSelf)
  470. // Set the value2 for the current rule
  471. #define SetRulv2Self(rulv) \
  472. SetRulv2OfIrul(irulSelf, (rulv))
  473. // Increment the value2 for the current rule
  474. #define IncrRulv2Self(drulv) \
  475. IncrRulv2OfIrul(irulSelf, (drulv))
  476. // Return the value for the rule ID
  477. #define RulvOfIrul(irul) \
  478. (LprulFromIrul(irul)->svl.lValue)
  479. // Set the value for the rule ID
  480. #define SetRulvOfIrul(irul, rulv) \
  481. (LprulFromIrul(irul)->svl.lValue = (rulv))
  482. // Increment the value1 field for the rule ID
  483. #define IncrRulvOfIrul(irul, drulv) \
  484. IncrRulvOfLprul(LprulFromIrul(irul), (drulv))
  485. // Return the lValue field for a rule node
  486. #define RulvOfLprul(prul) ((prul)->svl.lValue)
  487. // Set the lValue field for a rule node
  488. #define SetRulvOfLprul(prul, w) ((prul)->svl.lValue = (w))
  489. // Increment the value1 field for a rule node
  490. #define IncrRulvOfLprul(prul, drulv) ((prul)->svl.lValue += (drulv))
  491. // Set the value for the rule ID
  492. #define PlValueOfIrul(irul) \
  493. (&LprulFromIrul(irul)->svl.lValue)
  494. // Return the value1 field for the rule ID
  495. #define Rulv1OfIrul(irul) \
  496. Rulv1OfLprul(LprulFromIrul(irul))
  497. // Set the value1 field for the rule ID
  498. #define SetRulv1OfIrul(irul, rulv) \
  499. SetRulv1OfLprul(LprulFromIrul(irul), (rulv))
  500. // Increment the value1 field for the rule ID
  501. #define IncrRulv1OfIrul(irul, drulv) \
  502. IncrRulv1OfLprul(LprulFromIrul(irul), (drulv))
  503. // Return the value2 field for the rule ID
  504. #define Rulv2OfIrul(irul) \
  505. Rulv2OfLprul(LprulFromIrul(irul))
  506. // Set the value2 field for the rule ID
  507. #define SetRulv2OfIrul(irul, rulv) \
  508. SetRulv2OfLprul(LprulFromIrul(irul), (rulv))
  509. // Increment the value2 field for the rule ID
  510. #define IncrRulv2OfIrul(irul, drulv) \
  511. IncrRulv2OfLprul(LprulFromIrul(irul), (drulv))
  512. // Return the value1 field for a rule node
  513. #define Rulv1OfLprul(prul) W1OfPsv(PsvOfLprul(prul))
  514. // Set the value1 field for a rule node
  515. #define SetRulv1OfLprul(prul, w) SetW1OfPsv(PsvOfLprul(prul), (w))
  516. // Increment the value1 field for a rule node
  517. #define IncrRulv1OfLprul(prul, dw) IncrW1OfPsv(PsvOfLprul(prul), (dw))
  518. // Return the value2 field for a rule node
  519. #define Rulv2OfLprul(prul) W2OfPsv(PsvOfLprul(prul))
  520. // Set the value2 field for a rule node
  521. #define SetRulv2OfLprul(prul, w) SetW2OfPsv(PsvOfLprul(prul), (w))
  522. // Increment the value2 field for a rule node
  523. #define IncrRulv2OfLprul(prul, dw) IncrW2OfPsv(PsvOfLprul(prul), (dw))
  524. // Return the Split Value pointer of a node
  525. #define PsvOfLprul(prul) (&(prul)->svl.sv)
  526. // Return the value1 field for an rule node
  527. #define Rulv1(rulv) W1OfPsv((SV *) &(rulv))
  528. // Set the value1 field for a node
  529. #define SetRulv1(rulv, w) SetW1OfPsv(((SV *) &(rulv)), (w))
  530. // Return the value2 field
  531. #define Rulv2(rulv) W2OfPsv((SV *) &(rulv))
  532. // Set the value2 field for a node
  533. #define SetRulv2(rulv, w) SetW2OfPsv(((SV *) &(rulv)), (w))
  534. // Return the confidence value of a node node
  535. #define WConfidence(prul) Rulv1OfLprul(prul)
  536. // Set the confidence value of a node node
  537. #define SetConfidence(prul, wValue) SetRulv1OfLprul((prul), (wValue))
  538. // Return the doubt value of a node node
  539. #define WDoubt(prul) Rulv2OfLprul(prul)
  540. // Set the doubt value of a node node
  541. #define SetDoubt(prul, wValue) SetRulv2OfLprul((prul), (wValue))
  542. // OBSOLETE FORMS OF MACROS
  543. #define WValueOfIrul(irul) RulvOfIrul(irul)
  544. #define SetWValueOfIrul(irul, rulv) SetRulvOfIrul(irul, rulv)
  545. #define WRulValue1(prul) Rulv1OfLprul(prul)
  546. #define SetWRulValue1(prul, w) SetRulv1OfLprul((prul), (w))
  547. #define WRulValue2(prul) Rulv2OfLprul(prul)
  548. #define SetWRulValue2(prul, w) SetRulv2OfLprul((prul), (w))
  549. // Return the rule node for the rule value
  550. #define LprulOfWValue(lplValue) \
  551. ((MSORUL *) \
  552. (((char *) lplValue) - CchStructOffset(MSORUL, svl.lValue)))
  553. #ifdef DEBUG
  554. // Return the value name or rule text of the rule node structure pointer
  555. #define LpchRulName(prul) ((prul)->lpchName)
  556. // Return the value name or rule text of the rule node structure pointer
  557. #define LpchIrulName(irul) LpchRulName(LprulFromIrul(irul))
  558. // Return debug rule name for dynamic rule
  559. #define PszNameDynLprul(prul) \
  560. (vlpruls->rgpchDynNames[(prul)->irul - IrulCompiledMax()])
  561. #endif /* DEBUG */
  562. // Return the node evaluation level for the node
  563. #define RulevlOfPrul(prul) \
  564. (prul->rulevl)
  565. // Return the event_type for the node
  566. #define RulevtOfLprul(prul) \
  567. RulevtOfRulevl(RulevlOfPrul(prul))
  568. // Return the event_type for the evaluation level
  569. #define RulevtOfRulevl(rulevl) \
  570. (vlpruls->rgrulevtFromRulevl[rulevl])
  571. // Return the rule queue of the rule level
  572. #define LplprulQueueOf(rulevl) (&vlpruls->rgprulActiveQueues[rulevl])
  573. // Return the delayed-evaluation rule queue of the event_type
  574. #define LplprulDelayedQueueOf(rulevt) \
  575. (&vlpruls->rgprulDelayedQueues[rulevt])
  576. // Return the minimum evaluation level of the event_type
  577. #define RulevlMinOfRulevt(rulevt) \
  578. (vlpruls->rgrulevlRulevt[(rulevt)])
  579. // Return the maximum evaluation level of the event_type
  580. #define RulevlMaxOfRulevt(rulevt) \
  581. (vlpruls->rgrulevlRulevt[(rulevt) + 1])
  582. // Return the list of dependent node references of node ID
  583. #define LpruldepFromIrul(irul) \
  584. (vlpruls->rgpruldepDependents[irul])
  585. // Return the list of dependent node references of node
  586. #define LpruldepGetDependents(prul) \
  587. LpruldepFromIrul(IrulFromLprul(prul))
  588. // Set the list of dependent node references of node ID
  589. #define SetLpruldepFromIrul(irul, pruldep) \
  590. (vlpruls->rgpruldepDependents[irul] = (pruldep))
  591. // Set the list of dependent node references of node
  592. #define LpruldepSetDependents(prul, pruldep) \
  593. SetLpruldepFromIrul(IrulFromLprul(prul), (pruldep))
  594. // Return the list of dependent node references of node ID for specific group
  595. #define LpruldepFromRulgIrul(rulg, irul) \
  596. (*LplpruldepForRulgIrul(rulg, irul))
  597. // Set the list of dependent node references of node ID for specific group
  598. #define SetLpruldepFromRulgIrul(rulg, irul, pruldep) \
  599. (*LplpruldepForRulgIrul(rulg, irul) = (pruldep))
  600. // Return the address of the start of a ruldep list for the irul and group
  601. #define LplpruldepForRulgIrul(rulg, irul) \
  602. (&(vlpruls->rgrgpruldepDependents[rulg][irul]))
  603. // Return whether a dependent reference is in fact a delay specfication
  604. #define FIsDelayFactor(lprulDepend) \
  605. ((unsigned long) (lprulDepend) < wDelayMax)
  606. // Return the delay value associated with the dependency record
  607. #define CDelayFromLpruldepend(lprulDepend) \
  608. ((int) ((unsigned long) lprulDepend))
  609. // Return a dependency record to represent the delay factor
  610. #define LpruldependFromCDelay(cDelay) \
  611. ((MSORUL *) (cDelay))
  612. // Add a delay to the delay field of a delayed rule
  613. #define AddCDelayToLprul(prul, cDelay) \
  614. ((prul)->wDelayMask |= (cDelay))
  615. // Return whether a rule has any delay factor
  616. #define FHaveCDelay(prul) \
  617. ((prul)->wDelayMask)
  618. // Return whether a rule has a specific delay factor
  619. #define FHaveCDelayOf(prul, cDelay) \
  620. ((prul)->wDelayMask & (cDelay))
  621. // Decrement the node's delay counts (by shifting right)
  622. #define DecrementCDelaysOfLprul(prul) \
  623. ((prul)->wDelayMask >>= 1)
  624. // Return whether the (event) node is marked for history recording
  625. #define FHistoryRecordLprul(prul) \
  626. (TRUE) // First version
  627. // ((prul)->fRecordHistory) // Correct version
  628. // Return whether node must check interval counts to detect seq discontinuities
  629. #define FIntervalsSeqCheckedPrul(prul) \
  630. ((prul)->ipfnrulscSeqCheck)
  631. // Return interval counts associated with node that has sequence checking
  632. #define WIntervalsSeqCheckedPrul(prul) \
  633. ((*vlpruls->rgpfnrulscSeqCheck[(prul)->ipfnrulscSeqCheck])())
  634. // Return whether the rule base is initialized
  635. #define FRulesInited(lpruls) (lpruls != NULL && lpruls->fInited)
  636. // Return the op-code instructions for an interpreted rule ID
  637. #define PociiForIrul(irul) \
  638. PociiForPrul(LprulFromIrul(irul))
  639. // Return the op-code instructions for an interpreted rule
  640. #define PociiForPrul(prul) \
  641. ((MSOOCII *) vlpruls->rgpociiRules[((prul)->ipociiInstrs)])
  642. // Return any group(s) that append(s) the current group
  643. #define RulgAppendedFrom(rulg) \
  644. (vlpruls->prulgAppendedFrom[rulg])
  645. // Return the list of groups that append from other groups
  646. #define PrulgAppendedFrom() \
  647. (vlpruls->prulgAppendedFrom)
  648. // Return the group (if any) that the current group appends to
  649. #define RulgAppendTo(rulg) \
  650. (vlpruls->prulgAppendTo[rulg])
  651. // Return the list of groups that append to other groups
  652. #define PrulgAppendTo() \
  653. (vlpruls->prulgAppendTo)
  654. #define rulgNil (-1) // "No" rule group
  655. #define rulevtNil (-1) // "No" event type
  656. #ifdef DEBUG
  657. // Return whether node is marked for automatic backtracing */
  658. #define FTraceLprul(prul) \
  659. ((prul)->irulNextTrace != 0)
  660. #endif /* DEBUG */
  661. // Return the list of nodes that current node depends upon
  662. #define LpirulGetDependsOn(prul) \
  663. (&vlpruls->lpgrpirulDependBack[(prul)->birulDependsOn])
  664. /*************************************************************************
  665. Prototypes and macros for rule.c
  666. *************************************************************************/
  667. #ifndef max
  668. #define max(a,b) ((a) > (b) ? (a) : (b))
  669. #endif /* !max */
  670. #ifndef min
  671. #define min(a,b) ((a) < (b) ? (a) : (b))
  672. #endif /* !max */
  673. // Push the node onto the queue
  674. #define PushLprul(prul, lplprulQ) \
  675. ((prul)->prulNext = *(lplprulQ), \
  676. *(lplprulQ) = (prul))
  677. // Pop the node from the queue into the variable
  678. #define PopLprul(lplprul, lplprulQ) \
  679. (*lplprul = *lplprulQ, \
  680. *lplprulQ = (*lplprul)->prulNext, \
  681. (*lplprul)->prulNext = 0)
  682. // Push event node into Auto-Clear (Changed) list
  683. #define PushLpRulChanged(prul) \
  684. if ((prul)->irulNextChanged == 0) \
  685. { \
  686. int rulevt = RulevtOfLprul(prul); \
  687. \
  688. (prul)->irulNextChanged \
  689. = vlpruls->rgirulRulevtChanged[rulevt]; \
  690. vlpruls->rgirulRulevtChanged[rulevt] = IrulFromLprul(prul); \
  691. }
  692. // Mark event as never Auto-Clearing
  693. #define SetNoAutoClearRulv(rulv) \
  694. (LprulFromRulv(rulv)->irulNextChanged = irulNoAutoClear)
  695. #define SetNoAutoClearLprul(prul) \
  696. ((prul)->irulNextChanged = irulNoAutoClear)
  697. #define irulChangedNil -1
  698. #define irulNoAutoClear -2
  699. // Return the offset of a field from the start of its typedef'd structure
  700. // NOTE: THIS IS TRICKY CODE, BUT COMPLETELY LEGAL C!!
  701. // To understand it, remember that 0 is a valid pointer for ALL types!
  702. #define CchStructOffset(type, field) \
  703. (((char *) (&((type *) 0)->field)) - ((char *) 0))
  704. // Call Rule Evaluation function provided by Application
  705. #define FEvalRule(irul) \
  706. (*vlpruls->lpfnEvalRule)(irul)
  707. #ifndef STATIC_LINK_EM
  708. MSOAPI_(RULS **) MsoPvlprulsMirror(RULS **pvlprulsApp); // Exchange &vlpruls
  709. #else /* STATIC_LINK_EM */
  710. #define MsoPvlprulsMirror(pvlprulsApp) pvlprulsApp
  711. #endif /* !STATIC_LINK_EM */
  712. MSOAPI_(int) MsoFInitRules( // Init rule base
  713. LPFNRulinit lpfnRulInit,
  714. RULS *lpruls
  715. );
  716. IRUL IrulDefineEvent(int rulevt, char *szName); // Define simple event
  717. MSOAPI_(MSOKWD *) MsoFDefineStringKwdEvent( // Define str kwd event
  718. int rulevt,
  719. char *szName,
  720. XCHAR *pxch,
  721. int cch,
  722. int ikwtb
  723. );
  724. MSOAPI_(MSOKWDLH *) MsoFDefineIntegerKwdEvent( // Define int kwd event
  725. int rulevt,
  726. char *szName,
  727. long lValue,
  728. int ikwtb
  729. );
  730. MSOAPI_(void) MsoClearRules(void); // Clear nodes & state
  731. MSOAPI_(void) MsoClearEventsForRulevts( // Clr rg of ev types
  732. int rulevtFirst,
  733. int drulevtCount,
  734. int fSavePersistentDelayed,
  735. int fClearChanged,
  736. int fClearIntervalCounts
  737. );
  738. MSOAPI_(void) MsoRestorePersistentDelayedRules(void); // Restore delayed Q
  739. MSOAPI_(int) MsoFAddPruldepDependent( // Add dependent link
  740. IRUL irul,
  741. MSORUL *prulDependent,
  742. int cDelay,
  743. int rulg
  744. );
  745. MSOAPI_(void) MsoFixUpPruldeps( // Fix up after insert
  746. IRUL irul,
  747. int rulg,
  748. int rulgBase,
  749. RULDEP *lpruldepOldList,
  750. RULDEP *lpruldepNewList
  751. );
  752. MSOAPI_(int) MsoFDelPruldepDependent( // Del dependent link
  753. IRUL irul,
  754. MSORUL *prulDependent,
  755. int rulg,
  756. int fDiscard
  757. );
  758. MSOAPI_(void) MsoSetActiveRuls(RULS *pruls); // Set curr vlpruls
  759. MSOAPI_(void) MsoFreeRuleMem(RULS *pruls); // Free rule memory
  760. #ifdef OFFICE_BUILD
  761. MSOAPI_(void) MsoMarkRuleMem(RULS *pruls); // Mark rule mem used
  762. #endif /* OFFICE_BUILD */
  763. MSOAPI_(void) MsoSetEventTypeRulevt(int rulevt); // Change event_types
  764. MSOAPI_(void) MsoClearChangedEventsForRulevt(int rulevt);// Clr event_type vals
  765. void RemoveLprulChanged(MSORUL *prul); // Un-auto-clear event
  766. MSOAPI_(int) MsoEvaluateEvents(int rulevt); // Event evaluation
  767. MSOAPI_(int) MsoFEvalIrul(IRUL irul); // Eval single node
  768. MSOAPI_(void) MsoDelaySignalIrul( // Signal node w/delay
  769. IRUL irul,
  770. long lValue,
  771. int cDelay
  772. );
  773. MSOAPI_(void) MsoDelaySignalIrulFrom( // Signal node w/delay
  774. IRUL irul,
  775. IRUL irulFrom,
  776. int cDelay
  777. );
  778. MSOAPI_(void) MsoSignalIrul(IRUL irul, long lValue); // Cond schedule irul
  779. #define PushIrulToEval(irul, lValue) \
  780. MsoSignalIrul(irul, lValue)
  781. MSOAPI_(void) MsoScheduleIrul(IRUL irul, long lValue); // Schedule rule to run
  782. #ifdef DEBUG
  783. MSOAPI_(void) MsoScheduleIrulDebug(IRUL irul, long lValue);// Log and schedule
  784. MSOAPI_(void) MsoScheduleIrulDebugMso(IRUL irul, long lValue);//Log &sched MSO
  785. #else
  786. #define MsoScheduleIrulDebug MsoScheduleIrul
  787. #define MsoScheduleIrulDebugMso MsoScheduleIrul
  788. #endif /* DEBUG */
  789. MSOAPI_(void) MsoDelayScheduleIrul( // Schedule after delay
  790. IRUL irul,
  791. long lValue,
  792. int cDelay
  793. );
  794. #ifdef DEBUG
  795. MSOAPI_(void) MsoDelayScheduleIrulDebug( // Log and schedule
  796. IRUL irul,
  797. long lValue,
  798. int cDelay
  799. );
  800. #else
  801. #define MsoDelayScheduleIrulDebug MsoDelayScheduleIrul
  802. #endif /* DEBUG */
  803. MSOAPI_(void) MsoDelayScheduleIrulFrom( // Sched, pass value
  804. IRUL irul,
  805. IRUL irulFrom,
  806. int cDelay
  807. );
  808. MSOAPI_(int) MsoFEvalIrulImmediately( // Eval irul now
  809. IRUL irul,
  810. long lValue
  811. );
  812. MSOAPI_(void) MsoPushLprulDependents(MSORUL *prul); // Push dependents
  813. MSOAPI_(void) MsoPushDelayedEvalForRulevt(int rulevt); // Push delayed nodes
  814. MSOAPI_(void) MsoAutoClearIrul(IRUL irul); // Mark node for clear
  815. MSOAPI_(int) MsoFAliasPrulPrul( // Ret if 2 are aliases
  816. MSORUL *prul,
  817. MSORUL *prulTarget
  818. );
  819. void RecordLprulHistory(MSORUL *prul); // Push ev into hist
  820. #ifdef NEVER
  821. MSOAPI_(int) MsoFIrulHistoryValueWas( // Look 4 event in hist
  822. int dirultkBackwards,
  823. long *lpwVar
  824. );
  825. #endif // NEVER
  826. #ifdef NEED_AS_FUNCTION
  827. void SetCurrRulg(int rulgGroup); // Set rule group
  828. #endif /* NEED_AS_FUNCTION */
  829. MSOAPI_(void) MsoSignalEventIrul(IRUL irul, long lValue);// Signal an event
  830. MSOAPI_(void) MsoSignalEventIrulFrom( // Signal ev from node
  831. IRUL irul,
  832. IRUL irulFrom
  833. );
  834. #ifdef NEVER
  835. MSOAPI_(void) MsoSetRuleConfid(IRUL irul, int wFactor); // Set confidence val
  836. #endif // NEVER
  837. // Schedule a node for deferred evaluation, based upon a decision rule
  838. // This macro gets invoked twice. See _MsoFDeferIrul() for details.
  839. #define FDeferIrul(irul) \
  840. (vlpruls->fEvaluatingDeferred || _MsoFDeferIrul(irul))
  841. #define FDeferIrulExpr(irul, lExpr) \
  842. (vlpruls->fEvaluatingDeferred \
  843. || (((int) lExpr) && _MsoFDeferIrul(irul)))
  844. #define FDeferIrulExprL(irul, lExpr, lValue) \
  845. (vlpruls->fEvaluatingDeferred \
  846. || (((int) lExpr) && _MsoFDeferIrulL((irul), (lValue))))
  847. #define IrulPickDeferred(irulDecision) \
  848. MsoIrulPickDeferred(irulDecision)
  849. MSOAPI_(int) _MsoFDeferIrul(IRUL irul); // Add to defer list
  850. MSOAPI_(int) _MsoFDeferIrulL(IRUL irul, long lValue); // Add to defer w/value
  851. MSOAPI_(IRUL) MsoIrulPickDeferred(IRUL irulDecision); // Pick from defer list
  852. MSOAPI_(void) MsoSetRulNotify( // Set up notification
  853. long lExprValue, // Really an int
  854. IRUL irulDecision,
  855. IRUL irulNotify
  856. );
  857. MSOAPI_(int) MsoFRulNotify(long wNotify); // Notify on next eval
  858. MSOAPI_(int) MsoFRulNotifyImmediately(long wNotify); // Notify immediately
  859. MSOAPI_(long) MsoRulvElement(IRUL irulArray, IRUL iirul);// Get value of array
  860. MSOAPI_(void) MsoSetElementRulv( // Set value of array
  861. IRUL irulArray,
  862. IRUL iirul,
  863. long lValue
  864. );
  865. MSOAPI_(void) MsoSetAllElementsToRulv( // Set all vals of arr
  866. IRUL irulArray,
  867. IRUL cirul,
  868. long lValue
  869. );
  870. /* M S O F A C T I V A T E I R U L */
  871. /*----------------------------------------------------------------------------
  872. %%Function: MsoFActivateIrul
  873. %%Contact: daleg
  874. Activate a node in the rulebase
  875. ----------------------------------------------------------------------------*/
  876. _inline int MsoFActivateIrul(IRUL irul) // Activate a node
  877. {
  878. MSOPRUL prul = LprulFromIrul(irul);
  879. if (prul->prulNext == msoprulInactive)
  880. {
  881. prul->prulNext = (MSOPRUL) NULL;
  882. return TRUE;
  883. }
  884. else
  885. return FALSE;
  886. }
  887. /* M S O F D E A C T I V A T E I R U L */
  888. /*----------------------------------------------------------------------------
  889. %%Function: MsoFDeactivateIrul
  890. %%Contact: daleg
  891. Deactivate a node in the rulebase
  892. ----------------------------------------------------------------------------*/
  893. MSOAPI_(int) _MsoFDeactivateIrul(IRUL irul); // Deactivate a node
  894. _inline int MsoFDeactivateIrul(IRUL irul)
  895. {
  896. MSOPRUL prul = LprulFromIrul(irul);
  897. if (prul->prulNext == NULL)
  898. {
  899. prul->prulNext = msoprulInactive;
  900. return TRUE;
  901. }
  902. else
  903. return _MsoFDeactivateIrul(irul);
  904. }
  905. MSOAPI_(int) MsoFDeleteIrul(IRUL irul, int rulg); // Delete a node
  906. /*************************************************************************
  907. Prototypes and macros for rultest.c and rulconcl.c.
  908. These prototypes "Hungarianize" the rule code so that the rule
  909. authors do not have to know Hungarian, but it is preserved within
  910. the application code.
  911. *************************************************************************/
  912. // Return the current interval number for the event_type
  913. #define CIntervalsRulevt(rulevt) \
  914. (vlpruls->rgdtkiRulevt[rulevt])
  915. // OBSOLETE: Return the current interval number for the event_type
  916. #define CIntervalsRsct(rulevt) CIntervalsRulevt(rulevt)
  917. // Increment the current interval number for the event_type
  918. #define IncrIntervalsRsct(rulevt, dc) \
  919. (vlpruls->rgdtkiRulevt[rulevt] += (dc))
  920. #ifdef NEVER
  921. // Set long value of a node and force propagation
  922. #define SetValue(wVar, lValue) \
  923. SignalEvent(wVar, lValue)
  924. #endif /* NEVER */
  925. // Convert a "variable" event reference to an node address
  926. #define LprulFromRulv(rulvVar) \
  927. LprulOfWValue(&(rulvVar))
  928. // Notify a node, on its next evaluation pass
  929. #define FNotify(rgwVar) \
  930. MsoFRulNotify(rgwVar)
  931. // Notify an action rule, immediately
  932. #define FNotifyImmediately(rgwVar) \
  933. MsoFRulNotifyImmediately(rgwVar)
  934. // Indicate the next event_type to enter when current event_type is exited
  935. #define SetNextEventType(rulevt) \
  936. if (vlpruls->prulevtEvalLim \
  937. < vlpruls->rgrulevtEval + RulevtMax()) \
  938. (*vlpruls->prulevtEvalLim++ = (rulevt)); \
  939. else \
  940. AssertSz0(FALSE, "Exceeded max number of rulevts to eval");
  941. // Force delayed evaluation of rule of given ID: GENERATED BY RULE COMPILER
  942. #define DelayEvalIrul(irul, cDelay) \
  943. MsoDelayScheduleIrulFrom((irul), (irul), (cDelay))
  944. // Return whether the dirultkBackwards'th previous value was the given event
  945. #define ValueWas(dirultkBackwards, wVar) \
  946. MsoFIrulHistoryValueWas(dirultkBackwards, &(wVar))
  947. // Find the given value in its event_type history, and return the (neg) offset
  948. #define FindPrevValueFrom(dirultkBackwards, wVar) \
  949. DirultkFindPrevValueFrom(dirultkBackwards, &(wVar))
  950. // Mark event/rule for automatic clearing on event_type exit
  951. #define AutoClear(irul) \
  952. MsoAutoClearIrul(irul)
  953. // Mark expression as exempt from dependency linkage in rule if
  954. #define Value(expr) (expr)
  955. // Push all dependents of node of ID onto their evaluation queues
  956. #define Propagate(irul) \
  957. MsoPushLprulDependents(LprulFromIrul((int) irul))
  958. // Evaluate the rule at normal time
  959. #define GoToRule(irul) \
  960. MsoDelayScheduleIrul((irul), TRUE, 0 /* cDelay */)
  961. // Evaluate the rule at normal time
  962. #define GoToIrul(irul) \
  963. MsoDelayScheduleIrulFrom((IRUL) (irul), (irulSelf), 0 /* cDelay */)
  964. // Evaluate the rule after delay of 1, incrementing value
  965. #define GoToIrulNoValue(irul) \
  966. MsoDelayScheduleIrulFrom \
  967. ((IRUL) (irul), (IRUL) (irul), 1 /* cDelay */)
  968. // Evaluate the rule at normal time
  969. #define GoToDirul(dirul) \
  970. MsoDelayScheduleIrulFrom \
  971. ((IRUL) (irulSelf) + (dirul), (irulSelf), 0 /* cDelay */)
  972. // Evaluate the rule after delay of 1
  973. #define DelayGoToRule(irul) \
  974. DelayGoToIrulNoValue(irul)
  975. // Signal the event with the given value
  976. #define SignalIrul(irul, lValue) \
  977. MsoSignalIrul(irul, lValue)
  978. // Signal the event with the given value
  979. #define SignalEvent(wVar, lValue) \
  980. MsoSignalEventIrul(IrulFromLprul(LprulFromRulv(wVar)), (lValue))
  981. // Signal the event with the given value
  982. #define SignalEventIrul(irul, lValue) \
  983. MsoSignalEventIrul(irul, lValue)
  984. // Signal the node with the value from the current rule
  985. // REVIEW: THIS IS WRONG, NOT CONDITIONALLY SCHEDULING IF EVENT
  986. #define SignalIrulSelf(irul) \
  987. MsoDelayScheduleIrulFrom((IRUL) (irul), (irulSelf), 0)
  988. // Signal the event with the value from the current rule
  989. #define SignalEventIrulSelf(irul) \
  990. MsoSignalEventIrulFrom((IRUL) (irul), (irulSelf))
  991. // Evaluate the event after delay of 1
  992. #define DelaySignalEventIrul(irul, lValue) \
  993. MsoDelayScheduleIrul((irul), (lValue), 1 /* cDelay */)
  994. // Evaluate the event after specified delay
  995. #define DelaySignalEventIrulAfter(irul, lValue, cDelay) \
  996. MsoDelayScheduleIrul((irul), (lValue), 1 << ((cDelay) - 1))
  997. // Evaluate the node after delay of 1, getting value from rule
  998. #define DelaySignalIrulSelf(irul) \
  999. MsoDelayScheduleIrulFrom((irul), (irulSelf), 1 /* cDelay */)
  1000. // Evaluate the event after delay of 1, getting value from rule
  1001. #define DelaySignalEventIrulSelf(irul) \
  1002. MsoDelayScheduleIrulFrom((irul), (irulSelf), 1 /* cDelay */)
  1003. // Evaluate the event after delay of 1
  1004. // REVIEW daleg: OBSOLETE: USE DelaySignalEventIrul or "then ... (<event>)"
  1005. #define DelaySignalIrul(irul) \
  1006. MsoDelayScheduleIrul((irul), TRUE, 1 /* cDelay */)
  1007. // Evaluate the event after delay of 1
  1008. #define DelaySignal(rulvVar) \
  1009. DelaySignalRulv((rulvVar), TRUE)
  1010. // Evaluate the event after delay of 1
  1011. #define DelaySignalRulv(rulvVar, lValue) \
  1012. CDelaySignalRulv((rulvVar), (lValue), 1 /* cDelay */)
  1013. // Evaluate the event after delay of 1
  1014. #define CDelaySignalRulv(rulvVar, lValue, cDelay) \
  1015. MsoDelayScheduleIrul(LprulFromRulv(rulvVar)->irul, (lValue), \
  1016. (cDelay))
  1017. // Evaluate the rule after delay of 1 passing TRUE as the value
  1018. #define DelayGoToIrul1(irul) \
  1019. MsoDelayScheduleIrul((irul), TRUE, 1 /* cDelay */)
  1020. // Evaluate the rule after specified delay
  1021. #define DelayGoToIrulAfter(irul, cDelay) \
  1022. MsoDelayScheduleIrul((irul), TRUE, 1 << ((cDelay) - 1))
  1023. // Evaluate the rule with value after specified delay
  1024. #define DelayGoToIrulWithRulvAfter(irul, lValue, cDelay) \
  1025. MsoDelayScheduleIrul((irul), (lValue) - (cDelay) + 1, \
  1026. 1 << ((cDelay) - 1))
  1027. // Evaluate the rule after specified delay
  1028. #define DelayGoToDirulAfter(dirul, cDelay) \
  1029. MsoDelayScheduleIrulFrom((IRUL) (irulSelf + (dirul)), (irulSelf), \
  1030. 1 << ((cDelay) - 1))
  1031. // Evaluate the rule after delay of 1, incrementing value
  1032. #define DelayGoToIrulNoValue(irul) \
  1033. MsoDelayScheduleIrulFrom \
  1034. ((IRUL) (irul), (IRUL) (irul), 1 /* cDelay */)
  1035. // Evaluate the rule after delay of 1, passing the value of the current node
  1036. #define DelayGoToIrul(irul) \
  1037. MsoDelayScheduleIrulFrom((IRUL) (irul), (irulSelf), 1 /* cDelay */)
  1038. // Evaluate the rule (via relative offset) after delay of 1
  1039. #define DelayGoToDirul(dirul) \
  1040. MsoDelayScheduleIrulFrom \
  1041. ((IRUL) (irulSelf + (dirul)), (irulSelf), 1)
  1042. // Evaluate the rule (via relative offset) after delay of 1
  1043. #define DelayGoToDirulNoValue(dirul) \
  1044. MsoDelayScheduleIrulFrom((IRUL) (irulSelf + (dirul)), \
  1045. (IRUL) (irulSelf + (dirul)), 1)
  1046. // Evaluate the rule (via relative offset) after delay of 1, with value rulv
  1047. #define DelayGoToDirulWithRulv(dirul, rulv) \
  1048. (SetRulvOfIrul(irulSelf + (dirul), (rulv)), \
  1049. DelayGoToDirulNoValue(dirul))
  1050. // Evaluate the rule (via relative offset) after delay of 1, with value rulv2
  1051. #define DelayGoToDirulWithRulv2(dirul, rulv2) \
  1052. (SetRulv2OfIrul(irulSelf + (dirul), (short) (rulv2)), \
  1053. DelayGoToDirulNoValue(dirul))
  1054. // Evaluate the rule (via relative offset) after delay of 1, with value rulv2
  1055. #define DelayGoToDirulWithRulv1(dirul, rulv1) \
  1056. (SetRulv1OfIrul(irulSelf + (dirul), (short) (rulv1)), \
  1057. DelayGoToDirulNoValue(dirul))
  1058. // Evaluate the rule (via relative offset) after delay of 1, with values
  1059. #define DelayGoToDirulWithRulvs(dirul, rulv1, rulv2) \
  1060. (SetRulv1OfIrul(irulSelf + (dirul), (short) (rulv1)), \
  1061. SetRulv2OfIrul(irulSelf + (dirul), (short) (rulv2)), \
  1062. DelayGoToDirulNoValue(dirul))
  1063. // Deactivate curr rule if the fTest value is FALSE: used in rule test clause
  1064. #define FAutoDeactivateSelf(fTest) \
  1065. FAutoDeactivateIrul(irulSelf, (fTest))
  1066. // Deactivate the rule if the fTest value is FALSE: used in rule test clause
  1067. #define FAutoDeactivateIrul(irul, fTest) \
  1068. ((fTest) ? FALSE : (_MsoFDeactivateIrul(irul), TRUE))
  1069. // Set the Rule Propagation Group to the given value
  1070. #define SetCurrRulg(rulgGroup) \
  1071. (vlpruls->rgpruldepDependents \
  1072. = vlpruls->rgrgpruldepDependents[vlpruls->rulgCurr \
  1073. = rulgGroup])
  1074. // Return the current main Rule Propagation Group
  1075. #define FCurrRulg(rulg) \
  1076. (vlpruls->rulgCurr == (rulg))
  1077. /*************************************************************************
  1078. Prototypes and macros for Debugging and Error Handling
  1079. *************************************************************************/
  1080. #ifdef DEBUG
  1081. MSOAPI_(int) MsoFTraceIrul(IRUL irul, int fTraceOn); // Trace a node
  1082. char *SzFromFixed3(long lValue, char *pchBuf); // Fixed to sz conv
  1083. #define DebugDumpQueues(wTraceLvl, sz, lValue, wToLevel) \
  1084. { \
  1085. static const unsigned char _szDump[] = sz; \
  1086. \
  1087. _DumpQueues(wTraceLvl, _szDump, lValue, wToLevel); \
  1088. }
  1089. #define DebugDumpQueue(wTraceLvl, rulevl) \
  1090. _DumpQueue(wTraceLvl, rulevl, LplprulQueueOf(rulevl))
  1091. #else /* !DEBUG */
  1092. #define DebugDumpQueues(wTraceLvl, sz, lValue, wToLevel)
  1093. #define DebugDumpQueue(wTraceLvl, rulevl)
  1094. #endif /* DEBUG */
  1095. MSOEXTERN_C_END // ****************** End extern "C" *********************
  1096. #define EMRULE_H
  1097. #if !(defined(OFFICE_BUILD) || defined(XL))
  1098. #ifdef DYN_RULES
  1099. int FLoadDynEmRules(void); // Load dyn rulebase
  1100. #include "emruloci.h"
  1101. #endif /* DYN_RULES */
  1102. #endif /* !OFFICE_BUILD */
  1103. #endif /* !EMRULE_H */