/*************************************************** NAME : HandlerSlotPutFunction DESCRIPTION : Access function for handling the statically-bound direct slot bindings in message-handlers INPUTS : 1) The bitmap expression 2) A data object buffer RETURNS : TRUE if OK, FALSE on errors SIDE EFFECTS : Data object buffer gets symbol TRUE and slot is set. On errors, buffer gets symbol FALSE, EvaluationError is set and error messages are printed NOTES : It is possible for a handler (attached to a superclass of the currently active instance) containing these static references to be called for an instance which does not contain the slots (e.g., an instance of a subclass where the original slot was no-inherit or the subclass overrode the original slot) ***************************************************/ globle BOOLEAN HandlerSlotPutFunction( void *theValue, DATA_OBJECT *theResult) { HANDLER_SLOT_REFERENCE *theReference; DEFCLASS *theDefclass; INSTANCE_TYPE *theInstance; INSTANCE_SLOT *sp; unsigned instanceSlotIndex; DATA_OBJECT theSetVal; theReference = (HANDLER_SLOT_REFERENCE *) ValueToBitMap(theValue); theInstance = (INSTANCE_TYPE *) ProcParamArray[0].value; theDefclass = ClassIDMap[theReference->classID]; if (theInstance->garbage) { StaleInstanceAddress("for slot put",0); theResult->type = SYMBOL; theResult->value = FalseSymbol; SetEvaluationError(TRUE); return(FALSE); } if (theInstance->cls == theDefclass) { instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID]; sp = theInstance->slotAddresses[instanceSlotIndex - 1]; } else { if (theReference->slotID > theInstance->cls->maxSlotNameID) goto HandlerPutError; instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID]; if (instanceSlotIndex == 0) goto HandlerPutError; instanceSlotIndex--; sp = theInstance->slotAddresses[instanceSlotIndex]; if (sp->desc->cls != theDefclass) goto HandlerPutError; } /* ======================================================= The slot has already been verified not to be read-only. However, if it is initialize-only, we need to make sure that we are initializing the instance (something we could not verify at parse-time) ======================================================= */ if (sp->desc->initializeOnly && (!theInstance->initializeInProgress)) { SlotAccessViolationError(ValueToString(sp->desc->slotName->name), TRUE,(void *) theInstance); goto HandlerPutError2; } /* ====================================== No arguments means to use the special NoParamValue to reset the slot to its default value ====================================== */ if (GetFirstArgument()) { if (EvaluateAndStoreInDataObject((int) sp->desc->multiple, GetFirstArgument(),&theSetVal) == FALSE) goto HandlerPutError2; } else { SetDOBegin(theSetVal,1); SetDOEnd(theSetVal,0); SetType(theSetVal,MULTIFIELD); SetValue(theSetVal,NoParamValue); } if (PutSlotValue(theInstance,sp,&theSetVal,theResult,NULL) == FALSE) goto HandlerPutError2; return(TRUE); HandlerPutError: EarlySlotBindError(theInstance,theDefclass,theReference->slotID); HandlerPutError2: theResult->type = SYMBOL; theResult->value = FalseSymbol; SetEvaluationError(TRUE); return(FALSE); }
void CheckTemplateFact( void *theEnv, struct fact *theFact) { struct field *sublist; int i; struct deftemplate *theDeftemplate; struct templateSlot *slotPtr; DATA_OBJECT theData; char thePlace[20]; int rv; if (! EnvGetDynamicConstraintChecking(theEnv)) return; sublist = theFact->theProposition.theFields; /*========================================================*/ /* If the deftemplate corresponding to the first field of */ /* of the fact cannot be found, then the fact cannot be */ /* checked against the deftemplate format. */ /*========================================================*/ theDeftemplate = theFact->whichDeftemplate; if (theDeftemplate == NULL) return; if (theDeftemplate->implied) return; /*=============================================*/ /* Check each of the slots of the deftemplate. */ /*=============================================*/ i = 0; for (slotPtr = theDeftemplate->slotList; slotPtr != NULL; slotPtr = slotPtr->next) { /*================================================*/ /* Store the slot value in the appropriate format */ /* for a call to the constraint checking routine. */ /*================================================*/ if (slotPtr->multislot == false) { theData.type = sublist[i].type; theData.value = sublist[i].value; i++; } else { theData.type = MULTIFIELD; theData.value = (void *) sublist[i].value; SetDOBegin(theData,1); SetDOEnd(theData,((struct multifield *) sublist[i].value)->multifieldLength); i++; } /*=============================================*/ /* Call the constraint checking routine to see */ /* if a constraint violation occurred. */ /*=============================================*/ rv = ConstraintCheckDataObject(theEnv,&theData,slotPtr->constraints); if (rv != NO_VIOLATION) { gensprintf(thePlace,"fact f-%-5lld ",theFact->factIndex); PrintErrorID(theEnv,"CSTRNCHK",1,true); EnvPrintRouter(theEnv,WERROR,"Slot value "); PrintDataObject(theEnv,WERROR,&theData); EnvPrintRouter(theEnv,WERROR," "); ConstraintViolationErrorMessage(theEnv,NULL,thePlace,false,0,slotPtr->slotName, 0,rv,slotPtr->constraints,true); EnvSetHaltExecution(theEnv,true); return; } } return; }