/********************************************************* NAME : SlotDefaultValue DESCRIPTION : Determines the default value for the specified slot of the specified class INPUTS : 1) The class 2) The slot name RETURNS : TRUE if slot default value is set, FALSE otherwise SIDE EFFECTS : Slot default value evaluated - dynamic defaults will cause any side effects NOTES : None *********************************************************/ globle intBool EnvSlotDefaultValue( void *theEnv, void *theDefclass, char *slotName, DATA_OBJECT_PTR theValue) { SLOT_DESC *sd; SetpType(theValue,SYMBOL); SetpValue(theValue,EnvFalseSymbol(theEnv)); if ((sd = LookupSlot(theEnv,(DEFCLASS *) theDefclass,slotName,TRUE)) == NULL) return(FALSE); if (sd->noDefault) { SetpType(theValue,SYMBOL); SetpValue(theValue,EnvAddSymbol(theEnv,"?NONE")); return(TRUE); } if (sd->dynamicDefault) return(EvaluateAndStoreInDataObject(theEnv,(int) sd->multiple, (EXPRESSION *) sd->defaultValue, theValue,TRUE)); GenCopyMemory(DATA_OBJECT,1,theValue,sd->defaultValue); return(TRUE); }
/*********************************************************************** NAME : PackSlots DESCRIPTION : Groups class-slots into a contiguous array "slots" field points to array "slotCount" field set INPUTS : 1) The class 2) The list of slots RETURNS : Nothing useful SIDE EFFECTS : Temporary list deallocated, contiguous array allocated, and nxt pointers linked Class pointer set for slots NOTES : Assumes class->slotCount == 0 && class->slots == NULL ***********************************************************************/ static void PackSlots( void *theEnv, DEFCLASS *cls, TEMP_SLOT_LINK *slots) { TEMP_SLOT_LINK *stmp,*sprv; long i; stmp = slots; while (stmp != NULL) { stmp->desc->cls = cls; cls->slotCount++; stmp = stmp->nxt; } cls->slots = (SLOT_DESC *) gm2(theEnv,(sizeof(SLOT_DESC) * cls->slotCount)); stmp = slots; for (i = 0 ; i < cls->slotCount ; i++) { sprv = stmp; stmp = stmp->nxt; GenCopyMemory(SLOT_DESC,1,&(cls->slots[i]),sprv->desc); cls->slots[i].sharedValue.desc = &(cls->slots[i]); cls->slots[i].sharedValue.value = NULL; rtn_struct(theEnv,slotDescriptor,sprv->desc); rtn_struct(theEnv,tempSlotLink,sprv); } }
/********************************************************************** NAME : SlotDefaultValueCommand DESCRIPTION : Determines the default avlue for the specified slot of the specified class INPUTS : None RETURNS : Nothing useful SIDE EFFECTS : None NOTES : H/L Syntax : (slot-default-value <class> <slot>) **********************************************************************/ globle void SlotDefaultValueCommand( void *theEnv, DATA_OBJECT_PTR theValue) { DEFCLASS *theDefclass; SLOT_DESC *sd; SetpType(theValue,SYMBOL); SetpValue(theValue,EnvFalseSymbol(theEnv)); sd = CheckSlotExists(theEnv,"slot-default-value",&theDefclass,TRUE,TRUE); if (sd == NULL) return; if (sd->noDefault) { SetpType(theValue,SYMBOL); SetpValue(theValue,EnvAddSymbol(theEnv,"?NONE")); return; } if (sd->dynamicDefault) EvaluateAndStoreInDataObject(theEnv,(int) sd->multiple, (EXPRESSION *) sd->defaultValue, theValue,TRUE); else GenCopyMemory(DATA_OBJECT,1,theValue,sd->defaultValue); }
/********************************************************************** NAME : SlotDefaultValueCommand DESCRIPTION : Determines the default avlue for the specified slot of the specified class INPUTS : None RETURNS : Nothing useful SIDE EFFECTS : None NOTES : H/L Syntax : (slot-default-value <class> <slot>) **********************************************************************/ void SlotDefaultValueCommand( Environment *theEnv, UDFContext *context, UDFValue *returnValue) { Defclass *theDefclass; SlotDescriptor *sd; returnValue->lexemeValue = FalseSymbol(theEnv); sd = CheckSlotExists(context,"slot-default-value",&theDefclass,true,true); if (sd == NULL) return; if (sd->noDefault) { returnValue->lexemeValue = CreateSymbol(theEnv,"?NONE"); return; } if (sd->dynamicDefault) EvaluateAndStoreInDataObject(theEnv,sd->multiple, (Expression *) sd->defaultValue, returnValue,true); else GenCopyMemory(UDFValue,1,returnValue,sd->defaultValue); }
/*************************************************** NAME : InsertHandlerHeader DESCRIPTION : Allocates a new handler header and inserts it in the proper (sorted) position in the class hnd array INPUTS : 1) The class 2) The handler name 3) The handler type RETURNS : The address of the new handler header, NULL on errors SIDE EFFECTS : Class handler array reallocated and resorted NOTES : Assumes handler does not exist ***************************************************/ globle HANDLER *InsertHandlerHeader( void *theEnv, EXEC_STATUS, DEFCLASS *cls, SYMBOL_HN *mname, int mtype) { HANDLER *nhnd,*hnd; unsigned *narr,*arr; long i; long j,ni = -1; hnd = cls->handlers; arr = cls->handlerOrderMap; nhnd = (HANDLER *) gm2(theEnv,execStatus,(sizeof(HANDLER) * (cls->handlerCount+1))); narr = (unsigned *) gm2(theEnv,execStatus,(sizeof(unsigned) * (cls->handlerCount+1))); GenCopyMemory(HANDLER,cls->handlerCount,nhnd,hnd); for (i = 0 , j = 0 ; i < cls->handlerCount ; i++ , j++) { if (ni == -1) { if ((hnd[arr[i]].name->bucket > mname->bucket) ? TRUE : (hnd[arr[i]].name == mname)) { ni = i; j++; } } narr[j] = arr[i]; } if (ni == -1) ni = (int) cls->handlerCount; narr[ni] = cls->handlerCount; nhnd[cls->handlerCount].system = 0; nhnd[cls->handlerCount].type = mtype; nhnd[cls->handlerCount].busy = 0; nhnd[cls->handlerCount].mark = 0; #if DEBUGGING_FUNCTIONS nhnd[cls->handlerCount].trace = MessageHandlerData(theEnv,execStatus)->WatchHandlers; #endif nhnd[cls->handlerCount].name = mname; nhnd[cls->handlerCount].cls = cls; nhnd[cls->handlerCount].minParams = 0; nhnd[cls->handlerCount].maxParams = 0; nhnd[cls->handlerCount].localVarCount = 0; nhnd[cls->handlerCount].actions = NULL; nhnd[cls->handlerCount].ppForm = NULL; nhnd[cls->handlerCount].usrData = NULL; if (cls->handlerCount != 0) { rm(theEnv,execStatus,(void *) hnd,(sizeof(HANDLER) * cls->handlerCount)); rm(theEnv,execStatus,(void *) arr,(sizeof(unsigned) * cls->handlerCount)); } cls->handlers = nhnd; cls->handlerOrderMap = narr; cls->handlerCount++; return(&nhnd[cls->handlerCount-1]); }
/***************************************************************** NAME : RemoveAllExplicitMethods DESCRIPTION : Deletes all explicit defmethods - generic headers are left intact (as well as a method for an overloaded system function) INPUTS : None RETURNS : TRUE if all methods deleted, FALSE otherwise SIDE EFFECTS : Explicit defmethods deleted NOTES : None *****************************************************************/ globle int RemoveAllExplicitMethods( void *theEnv, EXEC_STATUS, DEFGENERIC *gfunc) { long i,j; unsigned systemMethodCount = 0; DEFMETHOD *narr; if (MethodsExecuting(gfunc) == FALSE) { for (i = 0 ; i < gfunc->mcnt ; i++) { if (gfunc->methods[i].system) systemMethodCount++; else DeleteMethodInfo(theEnv,execStatus,gfunc,&gfunc->methods[i]); } if (systemMethodCount != 0) { narr = (DEFMETHOD *) gm2(theEnv,execStatus,(systemMethodCount * sizeof(DEFMETHOD))); i = 0; j = 0; while (i < gfunc->mcnt) { if (gfunc->methods[i].system) GenCopyMemory(DEFMETHOD,1,&narr[j++],&gfunc->methods[i]); i++; } rm(theEnv,execStatus,(void *) gfunc->methods,(sizeof(DEFMETHOD) * gfunc->mcnt)); gfunc->mcnt = (short) systemMethodCount; gfunc->methods = narr; } else { if (gfunc->mcnt != 0) rm(theEnv,execStatus,(void *) gfunc->methods,(sizeof(DEFMETHOD) * gfunc->mcnt)); gfunc->mcnt = 0; gfunc->methods = NULL; } return(TRUE); } return(FALSE); }
/***************************************************************** NAME : RemoveAllExplicitMethods DESCRIPTION : Deletes all explicit defmethods - generic headers are left intact (as well as a method for an overloaded system function) INPUTS : None RETURNS : TRUE if all methods deleted, FALSE otherwise SIDE EFFECTS : Explicit defmethods deleted NOTES : None *****************************************************************/ globle int RemoveAllExplicitMethods( DEFGENERIC *gfunc) { register int i,j; unsigned systemMethodCount = 0; DEFMETHOD *narr; if (MethodsExecuting(gfunc) == FALSE) { for (i = 0 ; i < gfunc->mcnt ; i++) { if (gfunc->methods[i].system) systemMethodCount++; else DeleteMethodInfo(gfunc,&gfunc->methods[i]); } if (systemMethodCount != 0) { narr = (DEFMETHOD *) gm2((int) (systemMethodCount * sizeof(DEFMETHOD))); i = 0; j = 0; while (i < gfunc->mcnt) { if (gfunc->methods[i].system) GenCopyMemory(DEFMETHOD,1,&narr[j++],&gfunc->methods[i]); i++; } rm((void *) gfunc->methods,(int) (sizeof(DEFMETHOD) * gfunc->mcnt)); gfunc->mcnt = systemMethodCount; gfunc->methods = narr; } else { if (gfunc->mcnt != 0) rm((void *) gfunc->methods,(int) (sizeof(DEFMETHOD) * gfunc->mcnt)); gfunc->mcnt = 0; gfunc->methods = NULL; } return(TRUE); } return(FALSE); }
/*************************************************** NAME : DeallocateMarkedHandlers DESCRIPTION : Removes any handlers from a class that have been previously marked for deletion. INPUTS : The class RETURNS : Nothing useful SIDE EFFECTS : Marked handlers are deleted NOTES : Assumes none of the handlers are currently executing or have a busy count != 0 for any reason ***************************************************/ globle void DeallocateMarkedHandlers( void *theEnv, EXEC_STATUS, DEFCLASS *cls) { short count; HANDLER *hnd,*nhnd; unsigned *arr,*narr; long i,j; for (i = 0 , count = 0 ; i < cls->handlerCount ; i++) { hnd = &cls->handlers[i]; if (hnd->mark == 1) { count++; DecrementSymbolCount(theEnv,execStatus,hnd->name); ExpressionDeinstall(theEnv,execStatus,hnd->actions); ReturnPackedExpression(theEnv,execStatus,hnd->actions); ClearUserDataList(theEnv,execStatus,hnd->usrData); if (hnd->ppForm != NULL) rm(theEnv,execStatus,(void *) hnd->ppForm, (sizeof(char) * (strlen(hnd->ppForm)+1))); } else /* ============================================ Use the busy field to count how many message-handlers are removed before this one ============================================ */ hnd->busy = count; } if (count == 0) return; if (count == cls->handlerCount) { rm(theEnv,execStatus,(void *) cls->handlers,(sizeof(HANDLER) * cls->handlerCount)); rm(theEnv,execStatus,(void *) cls->handlerOrderMap,(sizeof(unsigned) * cls->handlerCount)); cls->handlers = NULL; cls->handlerOrderMap = NULL; cls->handlerCount = 0; } else { count = (short) (cls->handlerCount - count); hnd = cls->handlers; arr = cls->handlerOrderMap; nhnd = (HANDLER *) gm2(theEnv,execStatus,(sizeof(HANDLER) * count)); narr = (unsigned *) gm2(theEnv,execStatus,(sizeof(unsigned) * count)); for (i = 0 , j = 0 ; j < count ; i++) { if (hnd[arr[i]].mark == 0) { /* ============================================================== The offsets in the map need to be decremented by the number of preceding nodes which were deleted. Use the value of the busy field set in the first loop. ============================================================== */ narr[j] = arr[i] - hnd[arr[i]].busy; j++; } } for (i = 0 , j = 0 ; j < count ; i++) { if (hnd[i].mark == 0) { hnd[i].busy = 0; GenCopyMemory(HANDLER,1,&nhnd[j],&hnd[i]); j++; } } rm(theEnv,execStatus,(void *) hnd,(sizeof(HANDLER) * cls->handlerCount)); rm(theEnv,execStatus,(void *) arr,(sizeof(unsigned) * cls->handlerCount)); cls->handlers = nhnd; cls->handlerOrderMap = narr; cls->handlerCount = count; } }
/******************************************************************** NAME : EvaluateSlotDefaultValue DESCRIPTION : Checks the default value against the slot constraints and evaluates static default values INPUTS : 1) The slot descriptor 2) The bitmap marking which facets were specified in the original slot definition RETURNS : TRUE if all OK, FALSE otherwise SIDE EFFECTS : Static default value expressions deleted and replaced with data object evaluation NOTES : On errors, slot is marked as dynamix so that DeleteSlots() will erase the slot expression ********************************************************************/ static intBool EvaluateSlotDefaultValue( void *theEnv, EXEC_STATUS, SLOT_DESC *sd, char *specbits) { DATA_OBJECT temp; int oldce,olddcc,vCode; /* =================================================================== Slot default value expression is marked as dynamic until now so that DeleteSlots() would erase in the event of an error. The delay was so that the evaluation of a static default value could be delayed until all the constraints were parsed. =================================================================== */ if (TestBitMap(specbits,DEFAULT_DYNAMIC_BIT) == 0) sd->dynamicDefault = 0; if (sd->noDefault) return(TRUE); if (sd->dynamicDefault == 0) { if (TestBitMap(specbits,DEFAULT_BIT)) { oldce = ExecutingConstruct(theEnv,execStatus); SetExecutingConstruct(theEnv,execStatus,TRUE); olddcc = EnvSetDynamicConstraintChecking(theEnv,execStatus,EnvGetStaticConstraintChecking(theEnv,execStatus)); vCode = EvaluateAndStoreInDataObject(theEnv,execStatus,(int) sd->multiple, (EXPRESSION *) sd->defaultValue,&temp,TRUE); if (vCode != FALSE) vCode = ValidSlotValue(theEnv,execStatus,&temp,sd,NULL,"slot default value"); EnvSetDynamicConstraintChecking(theEnv,execStatus,olddcc); SetExecutingConstruct(theEnv,execStatus,oldce); if (vCode) { ExpressionDeinstall(theEnv,execStatus,(EXPRESSION *) sd->defaultValue); ReturnPackedExpression(theEnv,execStatus,(EXPRESSION *) sd->defaultValue); sd->defaultValue = (void *) get_struct(theEnv,execStatus,dataObject); GenCopyMemory(DATA_OBJECT,1,sd->defaultValue,&temp); ValueInstall(theEnv,execStatus,(DATA_OBJECT *) sd->defaultValue); } else { sd->dynamicDefault = 1; return(FALSE); } } else if (sd->defaultSpecified == 0) { sd->defaultValue = (void *) get_struct(theEnv,execStatus,dataObject); DeriveDefaultFromConstraints(theEnv,execStatus,sd->constraint, (DATA_OBJECT *) sd->defaultValue,(int) sd->multiple,TRUE); ValueInstall(theEnv,execStatus,(DATA_OBJECT *) sd->defaultValue); } } else if (EnvGetStaticConstraintChecking(theEnv,execStatus)) { vCode = ConstraintCheckExpressionChain(theEnv,execStatus,(EXPRESSION *) sd->defaultValue,sd->constraint); if (vCode != NO_VIOLATION) { PrintErrorID(theEnv,execStatus,"CSTRNCHK",1,FALSE); EnvPrintRouter(theEnv,execStatus,WERROR,"Expression for "); PrintSlot(theEnv,execStatus,WERROR,sd,NULL,"dynamic default value"); ConstraintViolationErrorMessage(theEnv,execStatus,NULL,NULL,0,0,NULL,0, vCode,sd->constraint,FALSE); return(FALSE); } } return(TRUE); }
/************************************************************************** NAME : BuildCompositeFacets DESCRIPTION : Composite slots are ones that get their facets from more than one class. By default, the most specific class in object's precedence list specifies the complete set of facets for a slot. The composite facet in a slot allows facets that are not overridden by the most specific class to be obtained from other classes. Since all superclasses are predetermined before creating a new class based on them, this routine need only examine the immediately next most specific class for extra facets. Even if that slot is also composite, the other facets have already been filtered down. If the slot is no-inherit, the next most specific class must be examined. INPUTS : 1) The slot descriptor 2) The class precedence list 3) The bitmap marking which facets were specified in the original slot definition RETURNS : Nothing useful SIDE EFFECTS : Composite slot is updated to reflect facets from a less specific class NOTES : Assumes slot is composite *************************************************************************/ static void BuildCompositeFacets( void *theEnv, EXEC_STATUS, SLOT_DESC *sd, PACKED_CLASS_LINKS *preclist, char *specbits, CONSTRAINT_PARSE_RECORD *parsedConstraint) { SLOT_DESC *compslot = NULL; long i; for (i = 1 ; i < preclist->classCount ; i++) { compslot = FindClassSlot(preclist->classArray[i],sd->slotName->name); if ((compslot != NULL) ? (compslot->noInherit == 0) : FALSE) break; } if (compslot != NULL) { if ((sd->defaultSpecified == 0) && (compslot->defaultSpecified == 1)) { sd->dynamicDefault = compslot->dynamicDefault; sd->noDefault = compslot->noDefault; sd->defaultSpecified = 1; if (compslot->defaultValue != NULL) { if (sd->dynamicDefault) { sd->defaultValue = (void *) PackExpression(theEnv,execStatus,(EXPRESSION *) compslot->defaultValue); ExpressionInstall(theEnv,execStatus,(EXPRESSION *) sd->defaultValue); } else { sd->defaultValue = (void *) get_struct(theEnv,execStatus,dataObject); GenCopyMemory(DATA_OBJECT,1,sd->defaultValue,compslot->defaultValue); ValueInstall(theEnv,execStatus,(DATA_OBJECT *) sd->defaultValue); } } } if (TestBitMap(specbits,FIELD_BIT) == 0) sd->multiple = compslot->multiple; if (TestBitMap(specbits,STORAGE_BIT) == 0) sd->shared = compslot->shared; if (TestBitMap(specbits,ACCESS_BIT) == 0) { sd->noWrite = compslot->noWrite; sd->initializeOnly = compslot->initializeOnly; } #if DEFRULE_CONSTRUCT if (TestBitMap(specbits,MATCH_BIT) == 0) sd->reactive = compslot->reactive; #endif if (TestBitMap(specbits,VISIBILITY_BIT) == 0) sd->publicVisibility = compslot->publicVisibility; if (TestBitMap(specbits,CREATE_ACCESSOR_BIT) == 0) { sd->createReadAccessor = compslot->createReadAccessor; sd->createWriteAccessor = compslot->createWriteAccessor; } if ((TestBitMap(specbits,OVERRIDE_MSG_BIT) == 0) && compslot->overrideMessageSpecified) { DecrementSymbolCount(theEnv,execStatus,sd->overrideMessage); sd->overrideMessage = compslot->overrideMessage; IncrementSymbolCount(sd->overrideMessage); sd->overrideMessageSpecified = TRUE; } OverlayConstraint(theEnv,execStatus,parsedConstraint,sd->constraint,compslot->constraint); } }
/******************************************************************** NAME : EvaluateSlotDefaultValue DESCRIPTION : Checks the default value against the slot constraints and evaluates static default values INPUTS : 1) The slot descriptor 2) The bitmap marking which facets were specified in the original slot definition RETURNS : True if all OK, false otherwise SIDE EFFECTS : Static default value expressions deleted and replaced with data object evaluation NOTES : On errors, slot is marked as dynamix so that DeleteSlots() will erase the slot expression ********************************************************************/ static bool EvaluateSlotDefaultValue( Environment *theEnv, SlotDescriptor *sd, const char *specbits) { UDFValue temp; bool oldce,olddcc, vPass; ConstraintViolationType vCode; /* =================================================================== Slot default value expression is marked as dynamic until now so that DeleteSlots() would erase in the event of an error. The delay was so that the evaluation of a static default value could be delayed until all the constraints were parsed. =================================================================== */ if (! TestBitMap(specbits,DEFAULT_DYNAMIC_BIT)) sd->dynamicDefault = 0; if (sd->noDefault) return true; if (sd->dynamicDefault == 0) { if (TestBitMap(specbits,DEFAULT_BIT)) { oldce = ExecutingConstruct(theEnv); SetExecutingConstruct(theEnv,true); olddcc = SetDynamicConstraintChecking(theEnv,true); vPass = EvaluateAndStoreInDataObject(theEnv,sd->multiple, (Expression *) sd->defaultValue,&temp,true); if (vPass != false) vPass = (ValidSlotValue(theEnv,&temp,sd,NULL,"the 'default' facet") == PSE_NO_ERROR); SetDynamicConstraintChecking(theEnv,olddcc); SetExecutingConstruct(theEnv,oldce); if (vPass) { ExpressionDeinstall(theEnv,(Expression *) sd->defaultValue); ReturnPackedExpression(theEnv,(Expression *) sd->defaultValue); sd->defaultValue = get_struct(theEnv,udfValue); GenCopyMemory(UDFValue,1,sd->defaultValue,&temp); RetainUDFV(theEnv,(UDFValue *) sd->defaultValue); } else { sd->dynamicDefault = 1; return false; } } else if (sd->defaultSpecified == 0) { sd->defaultValue = get_struct(theEnv,udfValue); DeriveDefaultFromConstraints(theEnv,sd->constraint, (UDFValue *) sd->defaultValue,sd->multiple,true); RetainUDFV(theEnv,(UDFValue *) sd->defaultValue); } } else { vCode = ConstraintCheckExpressionChain(theEnv,(Expression *) sd->defaultValue,sd->constraint); if (vCode != NO_VIOLATION) { PrintErrorID(theEnv,"CSTRNCHK",1,false); WriteString(theEnv,STDERR,"Expression for "); PrintSlot(theEnv,STDERR,sd,NULL,"dynamic default value"); ConstraintViolationErrorMessage(theEnv,NULL,NULL,0,0,NULL,0, vCode,sd->constraint,false); return false; } } return true; }
/************************************************************************** NAME : BuildCompositeFacets DESCRIPTION : Composite slots are ones that get their facets from more than one class. By default, the most specific class in object's precedence list specifies the complete set of facets for a slot. The composite facet in a slot allows facets that are not overridden by the most specific class to be obtained from other classes. Since all superclasses are predetermined before creating a new class based on them, this routine need only examine the immediately next most specific class for extra facets. Even if that slot is also composite, the other facets have already been filtered down. If the slot is no-inherit, the next most specific class must be examined. INPUTS : 1) The slot descriptor 2) The class precedence list 3) The bitmap marking which facets were specified in the original slot definition RETURNS : Nothing useful SIDE EFFECTS : Composite slot is updated to reflect facets from a less specific class NOTES : Assumes slot is composite *************************************************************************/ static void BuildCompositeFacets( Environment *theEnv, SlotDescriptor *sd, PACKED_CLASS_LINKS *preclist, const char *specbits, CONSTRAINT_PARSE_RECORD *parsedConstraint) { SlotDescriptor *compslot = NULL; unsigned long i; for (i = 1 ; i < preclist->classCount ; i++) { compslot = FindClassSlot(preclist->classArray[i],sd->slotName->name); if ((compslot != NULL) ? (compslot->noInherit == 0) : false) break; } if (compslot != NULL) { if ((sd->defaultSpecified == 0) && (compslot->defaultSpecified == 1)) { sd->dynamicDefault = compslot->dynamicDefault; sd->noDefault = compslot->noDefault; sd->defaultSpecified = 1; if (compslot->defaultValue != NULL) { if (sd->dynamicDefault) { sd->defaultValue = PackExpression(theEnv,(Expression *) compslot->defaultValue); ExpressionInstall(theEnv,(Expression *) sd->defaultValue); } else { sd->defaultValue = get_struct(theEnv,udfValue); GenCopyMemory(UDFValue,1,sd->defaultValue,compslot->defaultValue); RetainUDFV(theEnv,(UDFValue *) sd->defaultValue); } } } if (! TestBitMap(specbits,FIELD_BIT)) sd->multiple = compslot->multiple; if (! TestBitMap(specbits,STORAGE_BIT)) sd->shared = compslot->shared; if (! TestBitMap(specbits,ACCESS_BIT)) { sd->noWrite = compslot->noWrite; sd->initializeOnly = compslot->initializeOnly; } #if DEFRULE_CONSTRUCT if (! TestBitMap(specbits,MATCH_BIT)) sd->reactive = compslot->reactive; #endif if (! TestBitMap(specbits,VISIBILITY_BIT)) sd->publicVisibility = compslot->publicVisibility; if (! TestBitMap(specbits,CREATE_ACCESSOR_BIT)) { sd->createReadAccessor = compslot->createReadAccessor; sd->createWriteAccessor = compslot->createWriteAccessor; } if ((! TestBitMap(specbits,OVERRIDE_MSG_BIT)) && compslot->overrideMessageSpecified) { ReleaseLexeme(theEnv,sd->overrideMessage); sd->overrideMessage = compslot->overrideMessage; IncrementLexemeCount(sd->overrideMessage); sd->overrideMessageSpecified = true; } OverlayConstraint(theEnv,parsedConstraint,sd->constraint,compslot->constraint); } }