1    /*******************************************************/
2    /*      "C" Language Integrated Production System      */
3    /*                                                     */
4    /*               CLIPS Version 6.30  08/16/14          */
5    /*                                                     */
6    /*    INFERENCE ENGINE OBJECT ACCESS ROUTINES MODULE   */
7    /*******************************************************/
8 
9 /*************************************************************/
10 /* Purpose: RETE Network Interface for Objects               */
11 /*                                                           */
12 /* Principal Programmer(s):                                  */
13 /*      Brian L. Dantes                                      */
14 /*                                                           */
15 /* Contributing Programmer(s):                               */
16 /*                                                           */
17 /* Revision History:                                         */
18 /*                                                           */
19 /*      6.23: Correction for FalseSymbol/TrueSymbol. DR0859  */
20 /*                                                           */
21 /*      6.24: Converted INSTANCE_PATTERN_MATCHING to         */
22 /*            DEFRULE_CONSTRUCT.                             */
23 /*                                                           */
24 /*            Renamed BOOLEAN macro type to intBool.         */
25 /*                                                           */
26 /*      6.30: Support for long long integers.                */
27 /*                                                           */
28 /*            Removed conditional code for unsupported       */
29 /*            compilers/operating systems (IBM_MCW,          */
30 /*            MAC_MCW, and IBM_TBC).                         */
31 /*                                                           */
32 /*            Added support for hashed alpha memories.       */
33 /*                                                           */
34 /*            Added const qualifiers to remove C++           */
35 /*            deprecation warnings.                          */
36 /*                                                           */
37 /*************************************************************/
38 /* =========================================
39    *****************************************
40                EXTERNAL DEFINITIONS
41    =========================================
42    ***************************************** */
43 #include "setup.h"
44 
45 #if DEFRULE_CONSTRUCT && OBJECT_SYSTEM
46 
47 #include <stdio.h>
48 #define _STDIO_INCLUDED_
49 #include <string.h>
50 
51 #include "classcom.h"
52 #include "classfun.h"
53 
54 #if DEVELOPER
55 #include "exprnops.h"
56 #endif
57 #if BLOAD || BLOAD_AND_BSAVE
58 #include "bload.h"
59 #endif
60 #include "constant.h"
61 #include "drive.h"
62 #include "engine.h"
63 #include "envrnmnt.h"
64 #include "memalloc.h"
65 #include "multifld.h"
66 #include "objrtmch.h"
67 #include "reteutil.h"
68 #include "router.h"
69 
70 #define _OBJRTFNX_SOURCE_
71 #include "objrtfnx.h"
72 
73 /* =========================================
74    *****************************************
75                  MACROS AND TYPES
76    =========================================
77    ***************************************** */
78 
79 #define GetInsSlot(ins,si) ins->slotAddresses[ins->cls->slotNameMap[si]-1]
80 
81 /* =========================================
82    *****************************************
83       INTERNALLY VISIBLE FUNCTION HEADERS
84    =========================================
85    ***************************************** */
86 
87 static void PrintObjectGetVarJN1(void *,const char *,void *);
88 static intBool ObjectGetVarJNFunction1(void *,void *,DATA_OBJECT *);
89 static void PrintObjectGetVarJN2(void *,const char *,void *);
90 static intBool ObjectGetVarJNFunction2(void *,void *,DATA_OBJECT *);
91 static void PrintObjectGetVarPN1(void *,const char *,void *);
92 static intBool ObjectGetVarPNFunction1(void *,void *,DATA_OBJECT *);
93 static void PrintObjectGetVarPN2(void *,const char *,void *);
94 static intBool ObjectGetVarPNFunction2(void *,void *,DATA_OBJECT *);
95 static void PrintObjectCmpConstant(void *,const char *,void *);
96 static void PrintSlotLengthTest(void *,const char *,void *);
97 static intBool SlotLengthTestFunction(void *,void *,DATA_OBJECT *);
98 static void PrintPNSimpleCompareFunction1(void *,const char *,void *);
99 static intBool PNSimpleCompareFunction1(void *,void *,DATA_OBJECT *);
100 static void PrintPNSimpleCompareFunction2(void *,const char *,void *);
101 static intBool PNSimpleCompareFunction2(void *,void *,DATA_OBJECT *);
102 static void PrintPNSimpleCompareFunction3(void *,const char *,void *);
103 static intBool PNSimpleCompareFunction3(void *,void *,DATA_OBJECT *);
104 static void PrintJNSimpleCompareFunction1(void *,const char *,void *);
105 static intBool JNSimpleCompareFunction1(void *,void *,DATA_OBJECT *);
106 static void PrintJNSimpleCompareFunction2(void *,const char *,void *);
107 static intBool JNSimpleCompareFunction2(void *,void *,DATA_OBJECT *);
108 static void PrintJNSimpleCompareFunction3(void *,const char *,void *);
109 static intBool JNSimpleCompareFunction3(void *,void *,DATA_OBJECT *);
110 static void GetPatternObjectAndMarks(void *,int,int,int,INSTANCE_TYPE **,struct multifieldMarker **);
111 static void GetObjectValueGeneral(void *,DATA_OBJECT *,INSTANCE_TYPE *,
112                                  struct multifieldMarker *,struct ObjectMatchVar1 *);
113 static void GetObjectValueSimple(void *,DATA_OBJECT *,INSTANCE_TYPE *,struct ObjectMatchVar2 *);
114 static long CalculateSlotField(struct multifieldMarker *,INSTANCE_SLOT *,long,long *); /* 6.04 Bug Fix */
115 static void GetInsMultiSlotField(FIELD *,INSTANCE_TYPE *,unsigned,unsigned,unsigned);
116 static void DeallocateObjectReteData(void *);
117 static void DestroyObjectPatternNetwork(void *,OBJECT_PATTERN_NODE *);
118 static void DestroyObjectAlphaNodes(void *,OBJECT_ALPHA_NODE *);
119 
120 /* =========================================
121    *****************************************
122           EXTERNALLY VISIBLE FUNCTIONS
123    =========================================
124    ***************************************** */
125 
126 /***************************************************
127   NAME         : InstallObjectPrimitives
128   DESCRIPTION  : Installs all the entity records
129                  associated with object pattern
130                  matching operations
131   INPUTS       : None
132   RETURNS      : Nothing useful
133   SIDE EFFECTS : Primitive operations installed
134   NOTES        : None
135  ***************************************************/
InstallObjectPrimitives(void * theEnv)136 globle void InstallObjectPrimitives(
137   void *theEnv)
138   {
139    struct entityRecord objectGVInfo1 = { "OBJ_GET_SLOT_JNVAR1", OBJ_GET_SLOT_JNVAR1,0,1,0,
140                                              PrintObjectGetVarJN1,
141                                              PrintObjectGetVarJN1,NULL,
142                                              ObjectGetVarJNFunction1,
143                                              NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
144 
145    struct entityRecord objectGVInfo2 = { "OBJ_GET_SLOT_JNVAR2", OBJ_GET_SLOT_JNVAR2,0,1,0,
146                                              PrintObjectGetVarJN2,
147                                              PrintObjectGetVarJN2,NULL,
148                                              ObjectGetVarJNFunction2,
149                                              NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
150 
151    struct entityRecord objectGVPNInfo1 = { "OBJ_GET_SLOT_PNVAR1", OBJ_GET_SLOT_PNVAR1,0,1,0,
152                                                PrintObjectGetVarPN1,
153                                                PrintObjectGetVarPN1,NULL,
154                                                ObjectGetVarPNFunction1,
155                                                NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
156 
157    struct entityRecord objectGVPNInfo2 = { "OBJ_GET_SLOT_PNVAR2", OBJ_GET_SLOT_PNVAR2,0,1,0,
158                                                PrintObjectGetVarPN2,
159                                                PrintObjectGetVarPN2,NULL,
160                                                ObjectGetVarPNFunction2,
161                                                NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
162 
163    struct entityRecord objectCmpConstantInfo = { "OBJ_PN_CONSTANT", OBJ_PN_CONSTANT,0,1,1,
164                                                      PrintObjectCmpConstant,
165                                                      PrintObjectCmpConstant,NULL,
166                                                      ObjectCmpConstantFunction,
167                                                      NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
168 
169    struct entityRecord lengthTestInfo = { "OBJ_SLOT_LENGTH", OBJ_SLOT_LENGTH,0,1,0,
170                                               PrintSlotLengthTest,
171                                               PrintSlotLengthTest,NULL,
172                                               SlotLengthTestFunction,
173                                               NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
174 
175    struct entityRecord pNSimpleCompareInfo1 = { "OBJ_PN_CMP1", OBJ_PN_CMP1,0,1,1,
176                                                     PrintPNSimpleCompareFunction1,
177                                                     PrintPNSimpleCompareFunction1,NULL,
178                                                     PNSimpleCompareFunction1,
179                                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
180 
181    struct entityRecord pNSimpleCompareInfo2 = { "OBJ_PN_CMP2", OBJ_PN_CMP2,0,1,1,
182                                                     PrintPNSimpleCompareFunction2,
183                                                     PrintPNSimpleCompareFunction2,NULL,
184                                                     PNSimpleCompareFunction2,
185                                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
186 
187    struct entityRecord pNSimpleCompareInfo3 = { "OBJ_PN_CMP3", OBJ_PN_CMP3,0,1,1,
188                                                     PrintPNSimpleCompareFunction3,
189                                                     PrintPNSimpleCompareFunction3,NULL,
190                                                     PNSimpleCompareFunction3,
191                                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
192 
193    struct entityRecord jNSimpleCompareInfo1 = { "OBJ_JN_CMP1", OBJ_JN_CMP1,0,1,1,
194                                                     PrintJNSimpleCompareFunction1,
195                                                     PrintJNSimpleCompareFunction1,NULL,
196                                                     JNSimpleCompareFunction1,
197                                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
198 
199    struct entityRecord jNSimpleCompareInfo2 = { "OBJ_JN_CMP2", OBJ_JN_CMP2,0,1,1,
200                                                     PrintJNSimpleCompareFunction2,
201                                                     PrintJNSimpleCompareFunction2,NULL,
202                                                     JNSimpleCompareFunction2,
203                                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
204 
205    struct entityRecord jNSimpleCompareInfo3 = { "OBJ_JN_CMP3", OBJ_JN_CMP3,0,1,1,
206                                                     PrintJNSimpleCompareFunction3,
207                                                     PrintJNSimpleCompareFunction3,NULL,
208                                                     JNSimpleCompareFunction3,
209                                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
210 
211    AllocateEnvironmentData(theEnv,OBJECT_RETE_DATA,sizeof(struct objectReteData),DeallocateObjectReteData);
212    ObjectReteData(theEnv)->CurrentObjectSlotLength = 1;
213 
214    memcpy(&ObjectReteData(theEnv)->ObjectGVInfo1,&objectGVInfo1,sizeof(struct entityRecord));
215    memcpy(&ObjectReteData(theEnv)->ObjectGVInfo2,&objectGVInfo2,sizeof(struct entityRecord));
216    memcpy(&ObjectReteData(theEnv)->ObjectGVPNInfo1,&objectGVPNInfo1,sizeof(struct entityRecord));
217    memcpy(&ObjectReteData(theEnv)->ObjectGVPNInfo2,&objectGVPNInfo2,sizeof(struct entityRecord));
218    memcpy(&ObjectReteData(theEnv)->ObjectCmpConstantInfo,&objectCmpConstantInfo,sizeof(struct entityRecord));
219    memcpy(&ObjectReteData(theEnv)->LengthTestInfo,&lengthTestInfo,sizeof(struct entityRecord));
220    memcpy(&ObjectReteData(theEnv)->PNSimpleCompareInfo1,&pNSimpleCompareInfo1,sizeof(struct entityRecord));
221    memcpy(&ObjectReteData(theEnv)->PNSimpleCompareInfo2,&pNSimpleCompareInfo2,sizeof(struct entityRecord));
222    memcpy(&ObjectReteData(theEnv)->PNSimpleCompareInfo3,&pNSimpleCompareInfo3,sizeof(struct entityRecord));
223    memcpy(&ObjectReteData(theEnv)->JNSimpleCompareInfo1,&jNSimpleCompareInfo1,sizeof(struct entityRecord));
224    memcpy(&ObjectReteData(theEnv)->JNSimpleCompareInfo2,&jNSimpleCompareInfo2,sizeof(struct entityRecord));
225    memcpy(&ObjectReteData(theEnv)->JNSimpleCompareInfo3,&jNSimpleCompareInfo3,sizeof(struct entityRecord));
226 
227    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->ObjectGVInfo1,OBJ_GET_SLOT_JNVAR1);
228    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->ObjectGVInfo2,OBJ_GET_SLOT_JNVAR2);
229    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->ObjectGVPNInfo1,OBJ_GET_SLOT_PNVAR1);
230    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->ObjectGVPNInfo2,OBJ_GET_SLOT_PNVAR2);
231    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->ObjectCmpConstantInfo,OBJ_PN_CONSTANT);
232    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->LengthTestInfo,OBJ_SLOT_LENGTH);
233    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->PNSimpleCompareInfo1,OBJ_PN_CMP1);
234    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->PNSimpleCompareInfo2,OBJ_PN_CMP2);
235    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->PNSimpleCompareInfo3,OBJ_PN_CMP3);
236    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->JNSimpleCompareInfo1,OBJ_JN_CMP1);
237    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->JNSimpleCompareInfo2,OBJ_JN_CMP2);
238    InstallPrimitive(theEnv,&ObjectReteData(theEnv)->JNSimpleCompareInfo3,OBJ_JN_CMP3);
239   }
240 
241 /*****************************************************/
242 /* DeallocateObjectReteData: Deallocates environment */
243 /*    data for the object rete network.              */
244 /*****************************************************/
DeallocateObjectReteData(void * theEnv)245 static void DeallocateObjectReteData(
246   void *theEnv)
247   {
248    OBJECT_PATTERN_NODE *theNetwork;
249 
250 #if BLOAD || BLOAD_AND_BSAVE
251    if (Bloaded(theEnv)) return;
252 #endif
253 
254    theNetwork = ObjectReteData(theEnv)->ObjectPatternNetworkPointer;
255    DestroyObjectPatternNetwork(theEnv,theNetwork);
256   }
257 
258 /****************************************************************/
259 /* DestroyObjectPatternNetwork: Deallocates the data structures */
260 /*   associated with the object pattern network.                */
261 /****************************************************************/
DestroyObjectPatternNetwork(void * theEnv,OBJECT_PATTERN_NODE * thePattern)262 static void DestroyObjectPatternNetwork(
263   void *theEnv,
264   OBJECT_PATTERN_NODE *thePattern)
265   {
266    OBJECT_PATTERN_NODE *patternPtr;
267 
268    if (thePattern == NULL) return;
269 
270    while (thePattern != NULL)
271      {
272       patternPtr = thePattern->rightNode;
273 
274       DestroyObjectPatternNetwork(theEnv,thePattern->nextLevel);
275       DestroyObjectAlphaNodes(theEnv,thePattern->alphaNode);
276 #if ! RUN_TIME
277       rtn_struct(theEnv,objectPatternNode,thePattern);
278 #endif
279       thePattern = patternPtr;
280      }
281   }
282 
283 /************************************************************/
284 /* DestroyObjectAlphaNodes: Deallocates the data structures */
285 /*   associated with the object alpha nodes.                */
286 /************************************************************/
DestroyObjectAlphaNodes(void * theEnv,OBJECT_ALPHA_NODE * theNode)287 static void DestroyObjectAlphaNodes(
288   void *theEnv,
289   OBJECT_ALPHA_NODE *theNode)
290   {
291    OBJECT_ALPHA_NODE *nodePtr;
292 
293    if (theNode == NULL) return;
294 
295    while (theNode != NULL)
296      {
297       nodePtr = theNode->nxtInGroup;
298 
299       DestroyAlphaMemory(theEnv,&theNode->header,FALSE);
300 
301 #if ! RUN_TIME
302       rtn_struct(theEnv,objectAlphaNode,theNode);
303 #endif
304 
305       theNode = nodePtr;
306      }
307   }
308 
309 /*****************************************************
310   NAME         : ObjectCmpConstantFunction
311   DESCRIPTION  : Used to compare object slot values
312                  against a constant
313   INPUTS       : 1) The constant test bitmap
314                  2) Data object buffer to hold result
315   RETURNS      : TRUE if test successful,
316                  FALSE otherwise
317   SIDE EFFECTS : Buffer set to symbol TRUE if test
318                  successful, FALSE otherwise
319   NOTES        : Called directly by
320                    EvaluatePatternExpression()
321  *****************************************************/
ObjectCmpConstantFunction(void * theEnv,void * theValue,DATA_OBJECT * theResult)322 globle intBool ObjectCmpConstantFunction(
323   void *theEnv,
324   void *theValue,
325   DATA_OBJECT *theResult)
326   {
327    struct ObjectCmpPNConstant *hack;
328    DATA_OBJECT theVar;
329    EXPRESSION *constantExp;
330    int rv;
331    SEGMENT *theSegment;
332 
333    hack = (struct ObjectCmpPNConstant *) ValueToBitMap(theValue);
334    if (hack->general)
335      {
336       EvaluateExpression(theEnv,GetFirstArgument(),&theVar);
337       constantExp = GetFirstArgument()->nextArg;
338      }
339    else
340      {
341       constantExp = GetFirstArgument();
342       if (ObjectReteData(theEnv)->CurrentPatternObjectSlot->type == MULTIFIELD)
343         {
344          theSegment = (struct multifield *) ObjectReteData(theEnv)->CurrentPatternObjectSlot->value;
345          if (hack->fromBeginning)
346            {
347             theVar.type = theSegment->theFields[hack->offset].type;
348             theVar.value = theSegment->theFields[hack->offset].value;
349            }
350          else
351            {
352             theVar.type = theSegment->theFields[theSegment->multifieldLength -
353                                       (hack->offset + 1)].type;
354             theVar.value = theSegment->theFields[theSegment->multifieldLength -
355                                       (hack->offset + 1)].value;
356            }
357         }
358       else
359         {
360          theVar.type = (unsigned short) ObjectReteData(theEnv)->CurrentPatternObjectSlot->type;
361          theVar.value = ObjectReteData(theEnv)->CurrentPatternObjectSlot->value;
362         }
363      }
364    if (theVar.type != constantExp->type)
365      rv = hack->fail;
366    else if (theVar.value != constantExp->value)
367      rv = hack->fail;
368    else
369      rv = hack->pass;
370    theResult->type = SYMBOL;
371    theResult->value = rv ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv);
372    return(rv);
373   }
374 
375 /* =========================================
376    *****************************************
377           INTERNALLY VISIBLE FUNCTIONS
378    =========================================
379    ***************************************** */
380 
PrintObjectGetVarJN1(void * theEnv,const char * logicalName,void * theValue)381 static void PrintObjectGetVarJN1(
382   void *theEnv,
383   const char *logicalName,
384   void *theValue)
385   {
386 #if DEVELOPER
387    struct ObjectMatchVar1 *hack;
388 
389    hack = (struct ObjectMatchVar1 *) ValueToBitMap(theValue);
390 
391    if (hack->objectAddress)
392      {
393       EnvPrintRouter(theEnv,logicalName,"(obj-ptr ");
394       PrintLongInteger(theEnv,logicalName,(long long) hack->whichPattern);
395      }
396    else if (hack->allFields)
397      {
398       EnvPrintRouter(theEnv,logicalName,"(obj-slot-contents ");
399       PrintLongInteger(theEnv,logicalName,(long long) hack->whichPattern);
400       EnvPrintRouter(theEnv,logicalName," ");
401       EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->whichSlot)));
402      }
403    else
404      {
405       EnvPrintRouter(theEnv,logicalName,"(obj-slot-var ");
406       PrintLongInteger(theEnv,logicalName,(long long) hack->whichPattern);
407       EnvPrintRouter(theEnv,logicalName," ");
408       EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->whichSlot)));
409       EnvPrintRouter(theEnv,logicalName," ");
410       PrintLongInteger(theEnv,logicalName,(long long) hack->whichField);
411      }
412    EnvPrintRouter(theEnv,logicalName,")");
413 #else
414 #if MAC_XCD
415 #pragma unused(theEnv)
416 #pragma unused(logicalName)
417 #pragma unused(theValue)
418 #endif
419 #endif
420   }
421 
ObjectGetVarJNFunction1(void * theEnv,void * theValue,DATA_OBJECT * theResult)422 static intBool ObjectGetVarJNFunction1(
423   void *theEnv,
424   void *theValue,
425   DATA_OBJECT *theResult)
426   {
427    struct ObjectMatchVar1 *hack;
428    INSTANCE_TYPE *theInstance;
429    struct multifieldMarker *theMarks;
430 
431    hack = (struct ObjectMatchVar1 *) ValueToBitMap(theValue);
432    GetPatternObjectAndMarks(theEnv,((int) hack->whichPattern),hack->lhs,hack->rhs,&theInstance,&theMarks);
433    GetObjectValueGeneral(theEnv,theResult,theInstance,theMarks,hack);
434    return(TRUE);
435   }
436 
PrintObjectGetVarJN2(void * theEnv,const char * logicalName,void * theValue)437 static void PrintObjectGetVarJN2(
438   void *theEnv,
439   const char *logicalName,
440   void *theValue)
441   {
442 #if DEVELOPER
443    struct ObjectMatchVar2 *hack;
444 
445    hack = (struct ObjectMatchVar2 *) ValueToBitMap(theValue);
446    EnvPrintRouter(theEnv,logicalName,"(obj-slot-quick-var ");
447    PrintLongInteger(theEnv,logicalName,(long long) hack->whichPattern);
448    EnvPrintRouter(theEnv,logicalName," ");
449    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->whichSlot)));
450    if (hack->fromBeginning)
451      {
452       EnvPrintRouter(theEnv,logicalName," B");
453       PrintLongInteger(theEnv,logicalName,(long long) (hack->beginningOffset + 1));
454      }
455    if (hack->fromEnd)
456      {
457       EnvPrintRouter(theEnv,logicalName," E");
458       PrintLongInteger(theEnv,logicalName,(long long) (hack->endOffset + 1));
459      }
460    EnvPrintRouter(theEnv,logicalName,")");
461 #else
462 #if MAC_XCD
463 #pragma unused(theEnv)
464 #pragma unused(logicalName)
465 #pragma unused(theValue)
466 #endif
467 #endif
468   }
469 
ObjectGetVarJNFunction2(void * theEnv,void * theValue,DATA_OBJECT * theResult)470 static intBool ObjectGetVarJNFunction2(
471   void *theEnv,
472   void *theValue,
473   DATA_OBJECT *theResult)
474   {
475    struct ObjectMatchVar2 *hack;
476    INSTANCE_TYPE *theInstance;
477    struct multifieldMarker *theMarks;
478 
479    hack = (struct ObjectMatchVar2 *) ValueToBitMap(theValue);
480    GetPatternObjectAndMarks(theEnv,((int) hack->whichPattern),hack->lhs,hack->rhs,&theInstance,&theMarks);
481    GetObjectValueSimple(theEnv,theResult,theInstance,hack);
482    return(TRUE);
483   }
484 
PrintObjectGetVarPN1(void * theEnv,const char * logicalName,void * theValue)485 static void PrintObjectGetVarPN1(
486   void *theEnv,
487   const char *logicalName,
488   void *theValue)
489   {
490 #if DEVELOPER
491    struct ObjectMatchVar1 *hack;
492 
493    hack = (struct ObjectMatchVar1 *) ValueToBitMap(theValue);
494 
495    if (hack->objectAddress)
496      EnvPrintRouter(theEnv,logicalName,"(ptn-obj-ptr ");
497    else if (hack->allFields)
498      {
499       EnvPrintRouter(theEnv,logicalName,"(ptn-obj-slot-contents ");
500       EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->whichSlot)));
501      }
502    else
503      {
504       EnvPrintRouter(theEnv,logicalName,"(ptn-obj-slot-var ");
505       EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->whichSlot)));
506       EnvPrintRouter(theEnv,logicalName," ");
507       PrintLongInteger(theEnv,logicalName,(long long) hack->whichField);
508      }
509    EnvPrintRouter(theEnv,logicalName,")");
510 #else
511 #if MAC_XCD
512 #pragma unused(theEnv)
513 #pragma unused(logicalName)
514 #pragma unused(theValue)
515 #endif
516 #endif
517   }
518 
ObjectGetVarPNFunction1(void * theEnv,void * theValue,DATA_OBJECT * theResult)519 static intBool ObjectGetVarPNFunction1(
520   void *theEnv,
521   void *theValue,
522   DATA_OBJECT *theResult)
523   {
524    struct ObjectMatchVar1 *hack;
525 
526    hack = (struct ObjectMatchVar1 *) ValueToBitMap(theValue);
527    GetObjectValueGeneral(theEnv,theResult,ObjectReteData(theEnv)->CurrentPatternObject,ObjectReteData(theEnv)->CurrentPatternObjectMarks,hack);
528    return(TRUE);
529   }
530 
PrintObjectGetVarPN2(void * theEnv,const char * logicalName,void * theValue)531 static void PrintObjectGetVarPN2(
532   void *theEnv,
533   const char *logicalName,
534   void *theValue)
535   {
536 #if DEVELOPER
537    struct ObjectMatchVar2 *hack;
538 
539    hack = (struct ObjectMatchVar2 *) ValueToBitMap(theValue);
540    EnvPrintRouter(theEnv,logicalName,"(ptn-obj-slot-quick-var ");
541    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->whichSlot)));
542    if (hack->fromBeginning)
543      {
544       EnvPrintRouter(theEnv,logicalName," B");
545       PrintLongInteger(theEnv,logicalName,(long long) (hack->beginningOffset + 1));
546      }
547    if (hack->fromEnd)
548      {
549       EnvPrintRouter(theEnv,logicalName," E");
550       PrintLongInteger(theEnv,logicalName,(long long) (hack->endOffset + 1));
551      }
552    EnvPrintRouter(theEnv,logicalName,")");
553 #else
554 #if MAC_XCD
555 #pragma unused(theEnv)
556 #pragma unused(logicalName)
557 #pragma unused(theValue)
558 #endif
559 #endif
560   }
561 
ObjectGetVarPNFunction2(void * theEnv,void * theValue,DATA_OBJECT * theResult)562 static intBool ObjectGetVarPNFunction2(
563   void *theEnv,
564   void *theValue,
565   DATA_OBJECT *theResult)
566   {
567    struct ObjectMatchVar2 *hack;
568 
569    hack = (struct ObjectMatchVar2 *) ValueToBitMap(theValue);
570    GetObjectValueSimple(theEnv,theResult,ObjectReteData(theEnv)->CurrentPatternObject,hack);
571    return(TRUE);
572   }
573 
PrintObjectCmpConstant(void * theEnv,const char * logicalName,void * theValue)574 static void PrintObjectCmpConstant(
575   void *theEnv,
576   const char *logicalName,
577   void *theValue)
578   {
579 #if DEVELOPER
580    struct ObjectCmpPNConstant *hack;
581 
582    hack = (struct ObjectCmpPNConstant *) ValueToBitMap(theValue);
583 
584    EnvPrintRouter(theEnv,logicalName,"(obj-const ");
585    EnvPrintRouter(theEnv,logicalName,hack->pass ? "p " : "n ");
586    if (hack->general)
587      PrintExpression(theEnv,logicalName,GetFirstArgument());
588    else
589      {
590       EnvPrintRouter(theEnv,logicalName,hack->fromBeginning ? "B" : "E");
591       PrintLongInteger(theEnv,logicalName,(long long) hack->offset);
592       EnvPrintRouter(theEnv,logicalName," ");
593       PrintExpression(theEnv,logicalName,GetFirstArgument());
594      }
595    EnvPrintRouter(theEnv,logicalName,")");
596 #else
597 #if MAC_XCD
598 #pragma unused(theEnv)
599 #pragma unused(logicalName)
600 #pragma unused(theValue)
601 #endif
602 #endif
603   }
604 
PrintSlotLengthTest(void * theEnv,const char * logicalName,void * theValue)605 static void PrintSlotLengthTest(
606   void *theEnv,
607   const char *logicalName,
608   void *theValue)
609   {
610 #if DEVELOPER
611    struct ObjectMatchLength *hack;
612 
613    hack = (struct ObjectMatchLength *) ValueToBitMap(theValue);
614 
615    EnvPrintRouter(theEnv,logicalName,"(obj-slot-len ");
616    if (hack->exactly)
617      EnvPrintRouter(theEnv,logicalName,"= ");
618    else
619      EnvPrintRouter(theEnv,logicalName,">= ");
620    PrintLongInteger(theEnv,logicalName,(long long) hack->minLength);
621    EnvPrintRouter(theEnv,logicalName,")");
622 #else
623 #if MAC_XCD
624 #pragma unused(theEnv)
625 #pragma unused(logicalName)
626 #pragma unused(theValue)
627 #endif
628 #endif
629   }
630 
SlotLengthTestFunction(void * theEnv,void * theValue,DATA_OBJECT * theResult)631 static intBool SlotLengthTestFunction(
632   void *theEnv,
633   void *theValue,
634   DATA_OBJECT *theResult)
635   {
636    struct ObjectMatchLength *hack;
637 
638    theResult->type = SYMBOL;
639    theResult->value = EnvFalseSymbol(theEnv);
640    hack = (struct ObjectMatchLength *) ValueToBitMap(theValue);
641    if (ObjectReteData(theEnv)->CurrentObjectSlotLength < hack->minLength)
642      return(FALSE);
643    if (hack->exactly && (ObjectReteData(theEnv)->CurrentObjectSlotLength > hack->minLength))
644      return(FALSE);
645    theResult->value = EnvTrueSymbol(theEnv);
646    return(TRUE);
647   }
648 
PrintPNSimpleCompareFunction1(void * theEnv,const char * logicalName,void * theValue)649 static void PrintPNSimpleCompareFunction1(
650   void *theEnv,
651   const char *logicalName,
652   void *theValue)
653   {
654 #if DEVELOPER
655    struct ObjectCmpPNSingleSlotVars1 *hack;
656 
657    hack = (struct ObjectCmpPNSingleSlotVars1 *) ValueToBitMap(theValue);
658 
659    EnvPrintRouter(theEnv,logicalName,"(pslot-cmp1 ");
660    EnvPrintRouter(theEnv,logicalName,hack->pass ? "p " : "n ");
661    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->firstSlot)));
662    EnvPrintRouter(theEnv,logicalName," ");
663    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->secondSlot)));
664    EnvPrintRouter(theEnv,logicalName,")");
665 #else
666 #if MAC_XCD
667 #pragma unused(theEnv)
668 #pragma unused(logicalName)
669 #pragma unused(theValue)
670 #endif
671 #endif
672   }
673 
PNSimpleCompareFunction1(void * theEnv,void * theValue,DATA_OBJECT * theResult)674 static intBool PNSimpleCompareFunction1(
675   void *theEnv,
676   void *theValue,
677   DATA_OBJECT *theResult)
678   {
679    struct ObjectCmpPNSingleSlotVars1 *hack;
680    INSTANCE_SLOT *is1,*is2;
681    int rv;
682 
683    hack = (struct ObjectCmpPNSingleSlotVars1 *) ValueToBitMap(theValue);
684    is1 = GetInsSlot(ObjectReteData(theEnv)->CurrentPatternObject,hack->firstSlot);
685    is2 = GetInsSlot(ObjectReteData(theEnv)->CurrentPatternObject,hack->secondSlot);
686    if (is1->type != is2->type)
687      rv = hack->fail;
688    else if (is1->value != is2->value)
689      rv = hack->fail;
690    else
691      rv = hack->pass;
692    theResult->type = SYMBOL;
693    theResult->value = rv ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv);
694    return(rv);
695   }
696 
PrintPNSimpleCompareFunction2(void * theEnv,const char * logicalName,void * theValue)697 static void PrintPNSimpleCompareFunction2(
698   void *theEnv,
699   const char *logicalName,
700   void *theValue)
701   {
702 #if DEVELOPER
703    struct ObjectCmpPNSingleSlotVars2 *hack;
704 
705    hack = (struct ObjectCmpPNSingleSlotVars2 *) ValueToBitMap(theValue);
706 
707    EnvPrintRouter(theEnv,logicalName,"(pslot-cmp2 ");
708    EnvPrintRouter(theEnv,logicalName,hack->pass ? "p " : "n ");
709    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->firstSlot)));
710    EnvPrintRouter(theEnv,logicalName,hack->fromBeginning ? " B" : " E");
711    PrintLongInteger(theEnv,logicalName,(long long) hack->offset);
712    EnvPrintRouter(theEnv,logicalName," ");
713    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->secondSlot)));
714    EnvPrintRouter(theEnv,logicalName,")");
715 #else
716 #if MAC_XCD
717 #pragma unused(theEnv)
718 #pragma unused(logicalName)
719 #pragma unused(theValue)
720 #endif
721 #endif
722   }
723 
PNSimpleCompareFunction2(void * theEnv,void * theValue,DATA_OBJECT * theResult)724 static intBool PNSimpleCompareFunction2(
725   void *theEnv,
726   void *theValue,
727   DATA_OBJECT *theResult)
728   {
729    struct ObjectCmpPNSingleSlotVars2 *hack;
730    int rv;
731    FIELD f1;
732    INSTANCE_SLOT *is2;
733 
734    hack = (struct ObjectCmpPNSingleSlotVars2 *) ValueToBitMap(theValue);
735    GetInsMultiSlotField(&f1,ObjectReteData(theEnv)->CurrentPatternObject,(unsigned) hack->firstSlot,
736                              (unsigned) hack->fromBeginning,(unsigned) hack->offset);
737    is2 = GetInsSlot(ObjectReteData(theEnv)->CurrentPatternObject,hack->secondSlot);
738    if (f1.type != is2->type)
739      rv = hack->fail;
740    else if (f1.value != is2->value)
741      rv = hack->fail;
742    else
743      rv = hack->pass;
744    theResult->type = SYMBOL;
745    theResult->value = rv ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv);
746    return(rv);
747   }
748 
PrintPNSimpleCompareFunction3(void * theEnv,const char * logicalName,void * theValue)749 static void PrintPNSimpleCompareFunction3(
750   void *theEnv,
751   const char *logicalName,
752   void *theValue)
753   {
754 #if DEVELOPER
755    struct ObjectCmpPNSingleSlotVars3 *hack;
756 
757    hack = (struct ObjectCmpPNSingleSlotVars3 *) ValueToBitMap(theValue);
758 
759    EnvPrintRouter(theEnv,logicalName,"(pslot-cmp3 ");
760    EnvPrintRouter(theEnv,logicalName,hack->pass ? "p " : "n ");
761    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->firstSlot)));
762    EnvPrintRouter(theEnv,logicalName,hack->firstFromBeginning ? " B" : " E");
763    PrintLongInteger(theEnv,logicalName,(long long) hack->firstOffset);
764    EnvPrintRouter(theEnv,logicalName," ");
765    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->secondSlot)));
766    EnvPrintRouter(theEnv,logicalName,hack->secondFromBeginning ? " B" : " E");
767    PrintLongInteger(theEnv,logicalName,(long long) hack->secondOffset);
768    EnvPrintRouter(theEnv,logicalName,")");
769 #else
770 #if MAC_XCD
771 #pragma unused(theEnv)
772 #pragma unused(logicalName)
773 #pragma unused(theValue)
774 #endif
775 #endif
776   }
777 
PNSimpleCompareFunction3(void * theEnv,void * theValue,DATA_OBJECT * theResult)778 static intBool PNSimpleCompareFunction3(
779   void *theEnv,
780   void *theValue,
781   DATA_OBJECT *theResult)
782   {
783    struct ObjectCmpPNSingleSlotVars3 *hack;
784    int rv;
785    FIELD f1,f2;
786 
787    hack = (struct ObjectCmpPNSingleSlotVars3 *) ValueToBitMap(theValue);
788    GetInsMultiSlotField(&f1,ObjectReteData(theEnv)->CurrentPatternObject,(unsigned) hack->firstSlot,
789                         (unsigned) hack->firstFromBeginning,(unsigned) hack->firstOffset);
790    GetInsMultiSlotField(&f2,ObjectReteData(theEnv)->CurrentPatternObject,(unsigned) hack->secondSlot,
791                         (unsigned) hack->secondFromBeginning,(unsigned) hack->secondOffset);
792    if (f1.type != f2.type)
793      rv = hack->fail;
794    else if (f1.value != f2.value)
795      rv = hack->fail;
796    else
797      rv = hack->pass;
798    theResult->type = SYMBOL;
799    theResult->value = rv ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv);
800    return(rv);
801   }
802 
PrintJNSimpleCompareFunction1(void * theEnv,const char * logicalName,void * theValue)803 static void PrintJNSimpleCompareFunction1(
804   void *theEnv,
805   const char *logicalName,
806   void *theValue)
807   {
808 #if DEVELOPER
809    struct ObjectCmpJoinSingleSlotVars1 *hack;
810 
811    hack = (struct ObjectCmpJoinSingleSlotVars1 *) ValueToBitMap(theValue);
812 
813    EnvPrintRouter(theEnv,logicalName,"(jslot-cmp1 ");
814    EnvPrintRouter(theEnv,logicalName,hack->pass ? "p " : "n ");
815    PrintLongInteger(theEnv,logicalName,(long long) hack->firstPattern);
816    EnvPrintRouter(theEnv,logicalName," ");
817    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->firstSlot)));
818    EnvPrintRouter(theEnv,logicalName," ");
819    PrintLongInteger(theEnv,logicalName,(long long) hack->secondPattern);
820    EnvPrintRouter(theEnv,logicalName," ");
821    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->secondSlot)));
822    EnvPrintRouter(theEnv,logicalName,")");
823 #else
824 #if MAC_XCD
825 #pragma unused(theEnv)
826 #pragma unused(logicalName)
827 #pragma unused(theValue)
828 #endif
829 #endif
830   }
831 
JNSimpleCompareFunction1(void * theEnv,void * theValue,DATA_OBJECT * theResult)832 static intBool JNSimpleCompareFunction1(
833   void *theEnv,
834   void *theValue,
835   DATA_OBJECT *theResult)
836   {
837    INSTANCE_TYPE *ins1,*ins2;
838    struct multifieldMarker *theMarks;
839    struct ObjectCmpJoinSingleSlotVars1 *hack;
840    int rv;
841    INSTANCE_SLOT *is1,*is2;
842 
843    hack = (struct ObjectCmpJoinSingleSlotVars1 *) ValueToBitMap(theValue);
844    GetPatternObjectAndMarks(theEnv,((int) hack->firstPattern),hack->firstPatternLHS,hack->firstPatternRHS,&ins1,&theMarks);
845    is1 = GetInsSlot(ins1,hack->firstSlot);
846    GetPatternObjectAndMarks(theEnv,((int) hack->secondPattern),hack->secondPatternLHS,hack->secondPatternRHS,&ins2,&theMarks);
847    is2 = GetInsSlot(ins2,hack->secondSlot);
848    if (is1->type != is2->type)
849      rv = hack->fail;
850    else if (is1->value != is2->value)
851      rv = hack->fail;
852    else
853      rv = hack->pass;
854    theResult->type = SYMBOL;
855    theResult->value = rv ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv);
856    return(rv);
857   }
858 
PrintJNSimpleCompareFunction2(void * theEnv,const char * logicalName,void * theValue)859 static void PrintJNSimpleCompareFunction2(
860   void *theEnv,
861   const char *logicalName,
862   void *theValue)
863   {
864 #if DEVELOPER
865    struct ObjectCmpJoinSingleSlotVars2 *hack;
866 
867    hack = (struct ObjectCmpJoinSingleSlotVars2 *) ValueToBitMap(theValue);
868 
869    EnvPrintRouter(theEnv,logicalName,"(jslot-cmp2 ");
870    EnvPrintRouter(theEnv,logicalName,hack->pass ? "p " : "n ");
871    PrintLongInteger(theEnv,logicalName,(long long) hack->firstPattern);
872    EnvPrintRouter(theEnv,logicalName," ");
873    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->firstSlot)));
874    EnvPrintRouter(theEnv,logicalName,hack->fromBeginning ? " B" : " E");
875    PrintLongInteger(theEnv,logicalName,(long long) hack->offset);
876    EnvPrintRouter(theEnv,logicalName," ");
877    PrintLongInteger(theEnv,logicalName,(long long) hack->secondPattern);
878    EnvPrintRouter(theEnv,logicalName," ");
879    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->secondSlot)));
880    EnvPrintRouter(theEnv,logicalName,")");
881 #else
882 #if MAC_XCD
883 #pragma unused(theEnv)
884 #pragma unused(logicalName)
885 #pragma unused(theValue)
886 #endif
887 #endif
888   }
889 
JNSimpleCompareFunction2(void * theEnv,void * theValue,DATA_OBJECT * theResult)890 static intBool JNSimpleCompareFunction2(
891   void *theEnv,
892   void *theValue,
893   DATA_OBJECT *theResult)
894   {
895    INSTANCE_TYPE *ins1,*ins2;
896    struct multifieldMarker *theMarks;
897    struct ObjectCmpJoinSingleSlotVars2 *hack;
898    int rv;
899    FIELD f1;
900    INSTANCE_SLOT *is2;
901 
902    hack = (struct ObjectCmpJoinSingleSlotVars2 *) ValueToBitMap(theValue);
903    GetPatternObjectAndMarks(theEnv,((int) hack->firstPattern),hack->firstPatternLHS,hack->firstPatternRHS,&ins1,&theMarks);
904    GetInsMultiSlotField(&f1,ins1,(unsigned) hack->firstSlot,
905                         (unsigned) hack->fromBeginning,(unsigned) hack->offset);
906    GetPatternObjectAndMarks(theEnv,((int) hack->secondPattern),hack->secondPatternLHS,hack->secondPatternRHS,&ins2,&theMarks);
907    is2 = GetInsSlot(ins2,hack->secondSlot);
908    if (f1.type != is2->type)
909      rv = hack->fail;
910    else if (f1.value != is2->value)
911      rv = hack->fail;
912    else
913      rv = hack->pass;
914    theResult->type = SYMBOL;
915    theResult->value = rv ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv);
916    return(rv);
917   }
918 
PrintJNSimpleCompareFunction3(void * theEnv,const char * logicalName,void * theValue)919 static void PrintJNSimpleCompareFunction3(
920   void *theEnv,
921   const char *logicalName,
922   void *theValue)
923   {
924 #if DEVELOPER
925    struct ObjectCmpJoinSingleSlotVars3 *hack;
926 
927    hack = (struct ObjectCmpJoinSingleSlotVars3 *) ValueToBitMap(theValue);
928 
929    EnvPrintRouter(theEnv,logicalName,"(jslot-cmp3 ");
930    EnvPrintRouter(theEnv,logicalName,hack->pass ? "p " : "n ");
931    PrintLongInteger(theEnv,logicalName,(long long) hack->firstPattern);
932    EnvPrintRouter(theEnv,logicalName," ");
933    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->firstSlot)));
934    EnvPrintRouter(theEnv,logicalName,hack->firstFromBeginning ? " B" : " E");
935    PrintLongInteger(theEnv,logicalName,(long long) hack->firstOffset);
936    EnvPrintRouter(theEnv,logicalName," ");
937    PrintLongInteger(theEnv,logicalName,(long long) hack->secondPattern);
938    EnvPrintRouter(theEnv,logicalName," ");
939    EnvPrintRouter(theEnv,logicalName,ValueToString(FindIDSlotName(theEnv,(unsigned) hack->secondSlot)));
940    EnvPrintRouter(theEnv,logicalName,hack->secondFromBeginning ? " B" : " E");
941    PrintLongInteger(theEnv,logicalName,(long long) hack->secondOffset);
942    EnvPrintRouter(theEnv,logicalName,")");
943 #else
944 #if MAC_XCD
945 #pragma unused(theEnv)
946 #pragma unused(logicalName)
947 #pragma unused(theValue)
948 #endif
949 #endif
950   }
951 
JNSimpleCompareFunction3(void * theEnv,void * theValue,DATA_OBJECT * theResult)952 static intBool JNSimpleCompareFunction3(
953   void *theEnv,
954   void *theValue,
955   DATA_OBJECT *theResult)
956   {
957    INSTANCE_TYPE *ins1,*ins2;
958    struct multifieldMarker *theMarks;
959    struct ObjectCmpJoinSingleSlotVars3 *hack;
960    int rv;
961    FIELD f1,f2;
962 
963    hack = (struct ObjectCmpJoinSingleSlotVars3 *) ValueToBitMap(theValue);
964    GetPatternObjectAndMarks(theEnv,((int) hack->firstPattern),hack->firstPatternLHS,hack->firstPatternRHS,&ins1,&theMarks);
965    GetInsMultiSlotField(&f1,ins1,(unsigned) hack->firstSlot,
966                         (unsigned) hack->firstFromBeginning,
967                         (unsigned) hack->firstOffset);
968    GetPatternObjectAndMarks(theEnv,((int) hack->secondPattern),hack->secondPatternLHS,hack->secondPatternRHS,&ins2,&theMarks);
969    GetInsMultiSlotField(&f2,ins2,(unsigned) hack->secondSlot,
970                         (unsigned) hack->secondFromBeginning,
971                         (unsigned) hack->secondOffset);
972    if (f1.type != f2.type)
973      rv = hack->fail;
974    else if (f1.value != f2.value)
975      rv = hack->fail;
976    else
977      rv = hack->pass;
978    theResult->type = SYMBOL;
979    theResult->value = rv ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv);
980    return(rv);
981   }
982 
983 /****************************************************
984   NAME         : GetPatternObjectAndMarks
985   DESCRIPTION  : Finds the instance and multfiield
986                  markers corresponding to a specified
987                  pattern in the join network
988   INPUTS       : 1) The index of the desired pattern
989                  2) A buffer to hold the instance
990                     address
991                  3) A buffer to hold the list of
992                     multifield markers
993   RETURNS      : Nothing useful
994   SIDE EFFECTS : Buffers set
995   NOTES        : None
996  ****************************************************/
GetPatternObjectAndMarks(void * theEnv,int pattern,int lhs,int rhs,INSTANCE_TYPE ** theInstance,struct multifieldMarker ** theMarkers)997 static void GetPatternObjectAndMarks(
998   void *theEnv,
999   int pattern,
1000   int lhs,
1001   int rhs,
1002   INSTANCE_TYPE **theInstance,
1003   struct multifieldMarker **theMarkers)
1004   {
1005    if (lhs)
1006      {
1007       *theInstance = (INSTANCE_TYPE *)
1008         get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->matchingItem;
1009       *theMarkers =
1010         get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->markers;
1011      }
1012    else if (rhs)
1013      {
1014       *theInstance = (INSTANCE_TYPE *)
1015         get_nth_pm_match(EngineData(theEnv)->GlobalRHSBinds,pattern)->matchingItem;
1016       *theMarkers =
1017         get_nth_pm_match(EngineData(theEnv)->GlobalRHSBinds,pattern)->markers;
1018      }
1019    else if (EngineData(theEnv)->GlobalRHSBinds == NULL)
1020      {
1021       *theInstance = (INSTANCE_TYPE *)
1022         get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->matchingItem;
1023       *theMarkers =
1024         get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->markers;
1025      }
1026    else if ((((int) EngineData(theEnv)->GlobalJoin->depth) - 1) == pattern)
1027      {
1028       *theInstance = (INSTANCE_TYPE *)
1029         get_nth_pm_match(EngineData(theEnv)->GlobalRHSBinds,0)->matchingItem;
1030       *theMarkers = get_nth_pm_match(EngineData(theEnv)->GlobalRHSBinds,0)->markers;
1031      }
1032    else
1033      {
1034       *theInstance = (INSTANCE_TYPE *)
1035         get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->matchingItem;
1036       *theMarkers =
1037         get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->markers;
1038      }
1039   }
1040 
1041 /***************************************************
1042   NAME         : GetObjectValueGeneral
1043   DESCRIPTION  : Access function for getting
1044                  pattern variable values within the
1045                  object pattern and join networks
1046   INPUTS       : 1) The result data object buffer
1047                  2) The instance to access
1048                  3) The list of multifield markers
1049                     for the pattern
1050                  4) Data for variable reference
1051   RETURNS      : Nothing useful
1052   SIDE EFFECTS : Data object is filled with the
1053                  values of the pattern variable
1054   NOTES        : None
1055  ***************************************************/
GetObjectValueGeneral(void * theEnv,DATA_OBJECT * result,INSTANCE_TYPE * theInstance,struct multifieldMarker * theMarks,struct ObjectMatchVar1 * matchVar)1056 static void GetObjectValueGeneral(
1057   void *theEnv,
1058   DATA_OBJECT *result,
1059   INSTANCE_TYPE *theInstance,
1060   struct multifieldMarker *theMarks,
1061   struct ObjectMatchVar1 *matchVar)
1062   {
1063    long field, extent; /* 6.04 Bug Fix */
1064    INSTANCE_SLOT **insSlot,*basisSlot;
1065 
1066    if (matchVar->objectAddress)
1067      {
1068       result->type = INSTANCE_ADDRESS;
1069       result->value = (void *) theInstance;
1070       return;
1071      }
1072    if (matchVar->whichSlot == ISA_ID)
1073      {
1074       result->type = SYMBOL;
1075       result->value = (void *) GetDefclassNamePointer((void *) theInstance->cls);
1076       return;
1077      }
1078    if (matchVar->whichSlot == NAME_ID)
1079      {
1080       result->type = INSTANCE_NAME;
1081       result->value = (void *) theInstance->name;
1082       return;
1083      }
1084    insSlot =
1085      &theInstance->slotAddresses
1086      [theInstance->cls->slotNameMap[matchVar->whichSlot] - 1];
1087 
1088    /* =========================================
1089       We need to reference the basis slots if
1090       the slot of this object has changed while
1091       the RHS was executing
1092 
1093       However, if the reference is being done
1094       by the LHS of a rule (as a consequence of
1095       an RHS action), give the pattern matcher
1096       the real value of the slot
1097       ========================================= */
1098    if ((theInstance->basisSlots != NULL) &&
1099        (! EngineData(theEnv)->JoinOperationInProgress))
1100      {
1101       basisSlot = theInstance->basisSlots + (insSlot - theInstance->slotAddresses);
1102       if (basisSlot->value != NULL)
1103         insSlot = &basisSlot;
1104      }
1105 
1106    /* ==================================================
1107       If we know we are accessing the entire slot,
1108       the don't bother with searching multifield markers
1109       or calculating offsets
1110       ================================================== */
1111    if (matchVar->allFields)
1112      {
1113       result->type = (unsigned short) (*insSlot)->type;
1114       result->value = (*insSlot)->value;
1115       if (result->type == MULTIFIELD)
1116         {
1117          result->begin = 0;
1118          SetpDOEnd(result,GetMFLength((*insSlot)->value));
1119         }
1120       return;
1121      }
1122 
1123    /* =============================================
1124       Access a general field in a slot pattern with
1125       two or more multifield variables
1126       ============================================= */
1127    field = CalculateSlotField(theMarks,*insSlot,matchVar->whichField,&extent);
1128    if (extent == -1)
1129      {
1130       if ((*insSlot)->desc->multiple)
1131         {
1132          result->type = GetMFType((*insSlot)->value,field);
1133          result->value = GetMFValue((*insSlot)->value,field);
1134         }
1135       else
1136         {
1137          result->type = (unsigned short) (*insSlot)->type;
1138          result->value = (*insSlot)->value;
1139         }
1140      }
1141    else
1142      {
1143       result->type = MULTIFIELD;
1144       result->value = (*insSlot)->value;
1145       result->begin = field - 1;
1146       result->end = field + extent - 2;
1147      }
1148   }
1149 
1150 /***************************************************
1151   NAME         : GetObjectValueSimple
1152   DESCRIPTION  : Access function for getting
1153                  pattern variable values within the
1154                  object pattern and join networks
1155   INPUTS       : 1) The result data object buffer
1156                  2) The instance to access
1157                  3) Data for variable reference
1158   RETURNS      : Nothing useful
1159   SIDE EFFECTS : Data object is filled with the
1160                  values of the pattern variable
1161   NOTES        : None
1162  ***************************************************/
GetObjectValueSimple(void * theEnv,DATA_OBJECT * result,INSTANCE_TYPE * theInstance,struct ObjectMatchVar2 * matchVar)1163 static void GetObjectValueSimple(
1164   void *theEnv,
1165   DATA_OBJECT *result,
1166   INSTANCE_TYPE *theInstance,
1167   struct ObjectMatchVar2 *matchVar)
1168   {
1169    INSTANCE_SLOT **insSlot,*basisSlot;
1170    SEGMENT *segmentPtr;
1171    FIELD *fieldPtr;
1172 
1173    insSlot =
1174      &theInstance->slotAddresses
1175      [theInstance->cls->slotNameMap[matchVar->whichSlot] - 1];
1176 
1177    /* =========================================
1178       We need to reference the basis slots if
1179       the slot of this object has changed while
1180       the RHS was executing
1181 
1182       However, if the reference is being done
1183       by the LHS of a rule (as a consequence of
1184       an RHS action), give the pattern matcher
1185       the real value of the slot
1186       ========================================= */
1187    if ((theInstance->basisSlots != NULL) &&
1188        (! EngineData(theEnv)->JoinOperationInProgress))
1189      {
1190       basisSlot = theInstance->basisSlots + (insSlot - theInstance->slotAddresses);
1191       if (basisSlot->value != NULL)
1192         insSlot = &basisSlot;
1193      }
1194 
1195    if ((*insSlot)->desc->multiple)
1196      {
1197       segmentPtr = (SEGMENT *) (*insSlot)->value;
1198       if (matchVar->fromBeginning)
1199         {
1200          if (matchVar->fromEnd)
1201            {
1202             result->type = MULTIFIELD;
1203             result->value = (void *) segmentPtr;
1204             result->begin = matchVar->beginningOffset;
1205             SetpDOEnd(result,GetMFLength(segmentPtr) - matchVar->endOffset);
1206            }
1207          else
1208            {
1209             fieldPtr = &segmentPtr->theFields[matchVar->beginningOffset];
1210             result->type = fieldPtr->type;
1211             result->value = fieldPtr->value;
1212            }
1213         }
1214       else
1215         {
1216          fieldPtr = &segmentPtr->theFields[segmentPtr->multifieldLength -
1217                                            (matchVar->endOffset + 1)];
1218          result->type = fieldPtr->type;
1219          result->value = fieldPtr->value;
1220         }
1221      }
1222    else
1223      {
1224       result->type = (unsigned short) (*insSlot)->type;
1225       result->value = (*insSlot)->value;
1226      }
1227   }
1228 
1229 /****************************************************
1230   NAME         : CalculateSlotField
1231   DESCRIPTION  : Determines the actual index into the
1232                  an object slot for a given pattern
1233                  variable
1234   INPUTS       : 1) The list of markers to examine
1235                  2) The instance slot (can be NULL)
1236                  3) The pattern index of the variable
1237                  4) A buffer in which to store the
1238                     extent of the pattern variable
1239                     (-1 for single-field vars)
1240   RETURNS      : The actual index
1241   SIDE EFFECTS : None
1242   NOTES        : None
1243  ****************************************************/
CalculateSlotField(struct multifieldMarker * theMarkers,INSTANCE_SLOT * theSlot,long theIndex,long * extent)1244 static long CalculateSlotField(
1245   struct multifieldMarker *theMarkers,
1246   INSTANCE_SLOT *theSlot,
1247   long theIndex,
1248   long *extent)
1249   {
1250    register long actualIndex;
1251    void *theSlotName;
1252 
1253    actualIndex = theIndex;
1254    *extent = -1;
1255    if (theSlot == NULL)
1256      return(actualIndex);
1257    theSlotName = (void *) theSlot->desc->slotName->name;
1258    while (theMarkers != NULL)
1259      {
1260       if (theMarkers->where.whichSlot == theSlotName)
1261         break;
1262       theMarkers = theMarkers->next;
1263      }
1264    while ((theMarkers != NULL) ? (theMarkers->where.whichSlot == theSlotName) : FALSE)
1265      {
1266       if (theMarkers->whichField == theIndex)
1267         {
1268          *extent = theMarkers->endPosition - theMarkers->startPosition + 1;
1269          return(actualIndex);
1270         }
1271       if (theMarkers->whichField > theIndex)
1272         return(actualIndex);
1273       actualIndex += theMarkers->endPosition - theMarkers->startPosition;
1274       theMarkers = theMarkers->next;
1275      }
1276    return(actualIndex);
1277   }
1278 
1279 /****************************************************
1280   NAME         : GetInsMultiSlotField
1281   DESCRIPTION  : Gets the values of simple single
1282                  field references in multifield
1283                  slots for Rete comparisons
1284   INPUTS       : 1) A multifield field structure
1285                     to store the type and value in
1286                  2) The instance
1287                  3) The id of the slot
1288                  4) A flag indicating if offset is
1289                     from beginning or end of
1290                     multifield slot
1291                  5) The offset
1292   RETURNS      : The multifield field
1293   SIDE EFFECTS : None
1294   NOTES        : Should only be used to access
1295                  single-field reference in multifield
1296                  slots for pattern and join network
1297                  comparisons
1298  ****************************************************/
GetInsMultiSlotField(FIELD * theField,INSTANCE_TYPE * theInstance,unsigned theSlotID,unsigned fromBeginning,unsigned offset)1299 static void GetInsMultiSlotField(
1300   FIELD *theField,
1301   INSTANCE_TYPE *theInstance,
1302   unsigned theSlotID,
1303   unsigned fromBeginning,
1304   unsigned offset)
1305   {
1306    register INSTANCE_SLOT * insSlot;
1307    register SEGMENT *theSegment;
1308    register FIELD *tmpField;
1309 
1310    insSlot = theInstance->slotAddresses
1311                [theInstance->cls->slotNameMap[theSlotID] - 1];
1312 
1313    /* Bug fix for 6.05 */
1314 
1315    if (insSlot->desc->multiple)
1316      {
1317       theSegment = (SEGMENT *) insSlot->value;
1318       if (fromBeginning)
1319         tmpField = &theSegment->theFields[offset];
1320       else
1321         tmpField = &theSegment->theFields[theSegment->multifieldLength - offset - 1];
1322       theField->type = tmpField->type;
1323       theField->value = tmpField->value;
1324      }
1325    else
1326      {
1327       theField->type = (unsigned short) insSlot->type;
1328       theField->value = insSlot->value;
1329      }
1330   }
1331 
1332 #endif
1333 
1334