emrule.h
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 54k
Category:

Windows Kernel

Development Platform:

Visual C++

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