📄 classfun.c
字号:
be deallocated ***************************************************/globle VOID AddClassLink(src,cls,posn) PACKED_CLASS_LINKS *src; DEFCLASS *cls; int posn; { PACKED_CLASS_LINKS dst; dst.classArray = (DEFCLASS **) gm2((int) (sizeof(DEFCLASS *) * (src->classCount + 1))); if (posn == -1) { CopyMemory(DEFCLASS *,src->classCount,dst.classArray,src->classArray); dst.classArray[src->classCount] = cls; } else { if (posn != 0) CopyMemory(DEFCLASS *,posn,dst.classArray,src->classArray); CopyMemory(DEFCLASS *,src->classCount - posn, dst.classArray + posn + 1,src->classArray + posn); dst.classArray[posn] = cls; } dst.classCount = (unsigned short) (src->classCount + 1); DeletePackedClassLinks(src,CLIPS_FALSE); src->classCount = dst.classCount; src->classArray = dst.classArray; }/*************************************************** NAME : DeleteSubclassLink DESCRIPTION : Removes a class from another class's subclass list INPUTS : 1) The superclass whose subclass list is to be modified 2) The subclass to be removed RETURNS : Nothing useful SIDE EFFECTS : The subclass list is changed NOTES : None ***************************************************/globle VOID DeleteSubclassLink(sclass,cls) DEFCLASS *sclass,*cls; { register unsigned deletedIndex; PACKED_CLASS_LINKS *src,dst; src = &sclass->directSubclasses; for (deletedIndex = 0 ; deletedIndex < src->classCount ; deletedIndex++) if (src->classArray[deletedIndex] == cls) break; if (deletedIndex == src->classCount) return; if (src->classCount > 1) { dst.classArray = (DEFCLASS **) gm2((int) (sizeof(DEFCLASS *) * (src->classCount - 1))); if (deletedIndex != 0) CopyMemory(DEFCLASS *,deletedIndex,dst.classArray,src->classArray); CopyMemory(DEFCLASS *,src->classCount - deletedIndex - 1, dst.classArray + deletedIndex,src->classArray + deletedIndex + 1); } else dst.classArray = NULL; dst.classCount = (unsigned short) (src->classCount - 1); DeletePackedClassLinks(src,CLIPS_FALSE); src->classCount = dst.classCount; src->classArray = dst.classArray; } /************************************************************** NAME : NewClass DESCRIPTION : Allocates and initalizes a new class structure INPUTS : The symbolic name of the new class RETURNS : The address of the new class SIDE EFFECTS : None NOTES : None **************************************************************/globle DEFCLASS *NewClass(className) SYMBOL_HN *className; { register DEFCLASS *cls; cls = get_struct(defclass); InitializeConstructHeader("defclass",(struct constructHeader *) cls,className); cls->id = 0; cls->installed = 0; cls->busy = 0; cls->system = 0; cls->abstract = 0; cls->reactive = 1;#if DEBUGGING_FUNCTIONS cls->traceInstances = WatchInstances; cls->traceSlots = WatchSlots;#endif cls->hashTableIndex = 0; cls->directSuperclasses.classCount = 0; cls->directSuperclasses.classArray = NULL; cls->directSubclasses.classCount = 0; cls->directSubclasses.classArray = NULL; cls->allSuperclasses.classCount = 0; cls->allSuperclasses.classArray = NULL; cls->slots = NULL; cls->instanceTemplate = NULL; cls->slotNameMap = NULL; cls->instanceSlotCount = 0; cls->localInstanceSlotCount = 0; cls->slotCount = 0; cls->maxSlotNameID = 0; cls->handlers = NULL; cls->handlerOrderMap = NULL; cls->handlerCount = 0; cls->instanceList = NULL; cls->instanceListBottom = NULL; cls->nxtHash = NULL; cls->scopeMap = NULL; ClearBitString(cls->traversalRecord,TRAVERSAL_BYTES); return(cls); }/*************************************************** NAME : DeletePackedClassLinks DESCRIPTION : Dealloacates a contiguous array holding class links INPUTS : 1) The class link segment 2) A flag indicating whether to delete the top pack structure RETURNS : Nothing useful SIDE EFFECTS : Class links deallocated NOTES : None ***************************************************/globle VOID DeletePackedClassLinks(plp,deleteTop) PACKED_CLASS_LINKS *plp; int deleteTop; { if (plp->classCount > 0) { rm((VOID *) plp->classArray,(int) (sizeof(DEFCLASS *) * plp->classCount)); plp->classCount = 0; plp->classArray = NULL; } if (deleteTop) rtn_struct(packedClassLinks,plp); } /*************************************************** NAME : AssignClassID DESCRIPTION : Assigns a unique id to a class and puts its address in the id map INPUTS : The class RETURNS : Nothing useful SIDE EFFECTS : Class id assigned and map set NOTES : None ***************************************************/globle VOID AssignClassID(cls) DEFCLASS *cls; { register unsigned i; if ((MaxClassID % CLASS_ID_MAP_CHUNK) == 0) { ClassIDMap = (DEFCLASS **) genrealloc((VOID *) ClassIDMap, (unsigned) (MaxClassID * sizeof(DEFCLASS *)), (unsigned) ((MaxClassID + CLASS_ID_MAP_CHUNK) * sizeof(DEFCLASS *))); for (i = MaxClassID ; i < (MaxClassID + CLASS_ID_MAP_CHUNK) ; i++) ClassIDMap[i] = NULL; } ClassIDMap[MaxClassID] = cls; cls->id = MaxClassID++; }/********************************************************* NAME : AddSlotName DESCRIPTION : Adds a new slot entry (or increments the use count of an existing node). INPUTS : 1) The slot name 2) The new canonical id for the slot name 3) A flag indicating whether the given id must be used or not RETURNS : The id of the (old) node SIDE EFFECTS : Slot name entry added or use count incremented NOTES : None *********************************************************/globle SLOT_NAME *AddSlotName(slotName,newid,usenewid) SYMBOL_HN *slotName; unsigned newid; int usenewid; { SLOT_NAME *snp; unsigned hashTableIndex; char *buf; int bufsz; hashTableIndex = HashSlotName(slotName); snp = SlotNameTable[hashTableIndex]; while ((snp != NULL) ? (snp->name != slotName) : CLIPS_FALSE) snp = snp->nxt; if (snp != NULL) { if (usenewid && (newid != snp->id)) { CLIPSSystemError("CLASSFUN",1); ExitCLIPS(2); } snp->use++; } else { snp = get_struct(slotName); snp->name = slotName; snp->hashTableIndex = hashTableIndex; snp->use = 1; snp->id = usenewid ? newid : NewSlotNameID(); snp->nxt = SlotNameTable[hashTableIndex]; SlotNameTable[hashTableIndex] = snp; IncrementSymbolCount(slotName); bufsz = (int) (sizeof(char) * (PUT_PREFIX_LENGTH + strlen(ValueToString(slotName)) + 1)); buf = (char *) gm2(bufsz); strcpy(buf,PUT_PREFIX); strcat(buf,ValueToString(slotName)); snp->putHandlerName = (SYMBOL_HN *) AddSymbol(buf); IncrementSymbolCount(snp->putHandlerName); rm((VOID *) buf,bufsz); snp->bsaveIndex = 0L; } return(snp); }/*************************************************** NAME : DeleteSlotName DESCRIPTION : Removes a slot name entry from the table of all slot names if no longer in use INPUTS : The slot name hash node RETURNS : Nothing useful SIDE EFFECTS : Slot name entry deleted or use count decremented NOTES : None ***************************************************/globle VOID DeleteSlotName(slotName) SLOT_NAME *slotName; { SLOT_NAME *snp,*prv; if (slotName == NULL) return; prv = NULL; snp = SlotNameTable[slotName->hashTableIndex]; while (snp != slotName) { prv = snp; snp = snp->nxt; } snp->use--; if (snp->use != 0) return; if (prv == NULL) SlotNameTable[snp->hashTableIndex] = snp->nxt; else prv->nxt = snp->nxt; DecrementSymbolCount(snp->name); DecrementSymbolCount(snp->putHandlerName); rtn_struct(slotName,snp); }/******************************************************************* NAME : RemoveDefclass DESCRIPTION : Deallocates a class structure and all its fields - returns all symbols in use by the class back to CLIPS for ephemeral removal INPUTS : The address of the class RETURNS : Nothing useful SIDE EFFECTS : None NOTES : Assumes class has no subclasses IMPORTANT WARNING!! : Assumes class busy count and all instances' busy counts are 0 and all handlers' busy counts are 0! *******************************************************************/LOCALE VOID RemoveDefclass(vcls) VOID *vcls; { DEFCLASS *cls = (DEFCLASS *) vcls; HANDLER *hnd; register int i; /* ==================================================== Remove all of this class's superclasses' links to it ==================================================== */ for (i = 0 ; i < cls->directSuperclasses.classCount ; i++) DeleteSubclassLink(cls->directSuperclasses.classArray[i],cls); RemoveClassFromTable(cls); InstallClass(cls,CLIPS_FALSE); DeletePackedClassLinks(&cls->directSuperclasses,CLIPS_FALSE); DeletePackedClassLinks(&cls->allSuperclasses,CLIPS_FALSE); DeletePackedClassLinks(&cls->directSubclasses,CLIPS_FALSE); for (i = 0 ; i < cls->slotCount ; i++) { if (cls->slots[i].defaultValue != NULL) { if (cls->slots[i].dynamicDefault) ReturnPackedExpression((EXPRESSION *) cls->slots[i].defaultValue); else rtn_struct(dataObject,cls->slots[i].defaultValue); } DeleteSlotName(cls->slots[i].slotName); RemoveConstraint(cls->slots[i].constraint); } if (cls->instanceSlotCount != 0) { rm((VOID *) cls->instanceTemplate, (int) (sizeof(SLOT_DESC *) * cls->instanceSlotCount)); rm((VOID *) cls->slotNameMap, (int) (sizeof(unsigned) * (cls->maxSlotNameID + 1))); } if (cls->slotCount != 0) rm((VOID *) cls->slots,(int) (sizeof(SLOT_DESC) * cls->slotCount)); for (i = 0 ; i < cls->handlerCount ; i++) { hnd = &cls->handlers[i]; if (hnd->actions != NULL) ReturnPackedExpression(hnd->actions); if (hnd->ppForm != NULL) rm((VOID *) hnd->ppForm,(int) (sizeof(char) * (strlen(hnd->ppForm)+1))); } if (cls->handlerCount != 0) { rm((VOID *) cls->handlers,(int) (sizeof(HANDLER) * cls->handlerCount)); rm((VOID *) cls->handlerOrderMap,(int) (sizeof(unsigned) * cls->handlerCount)); } SetDefclassPPForm((VOID *) cls,NULL); DeassignClassID((unsigned) cls->id); rtn_struct(defclass,cls); }/*************************************************** NAME : InstallClass DESCRIPTION : In(De)crements all symbol counts for for CLIPS symbols in use by class Disallows (allows) symbols to become ephemeral. INPUTS : 1) The class address 2) 1 - install, 0 - deinstall RETURNS : Nothing useful SIDE EFFECTS : None NOTES : None ***************************************************/globle VOID InstallClass(cls,set) DEFCLASS *cls; int set; { SLOT_DESC *slot; HANDLER *hnd; register int i; if ((set && cls->installed) || ((set == CLIPS_FALSE) && (cls->installed == 0))) return; /* ================================================================== Handler installation is handled when message-handlers are defined: see ParseDefmessageHandler() in MSGCOM.C Slot installation is handled by ParseSlot() in CLASSPSR.C Scope map installation is handled by CreateClassScopeMap() ================================================================== */ if (set == CLIPS_FALSE) { cls->installed = 0; DecrementSymbolCount(cls->header.name);#if DEFMODULE_CONSTRUCT DecrementBitMapCount(cls->scopeMap);#endif for (i = 0 ; i < cls->slotCount ; i++) { slot = &cls->slots[i]; DecrementSymbolCount(slot->overrideMessage); if (slot->defaultValue != NULL) { if (slot->dynamicDefault) ExpressionDeinstall((EXPRESSION *) slot->defaultValue); else ValueDeinstall((DATA_OBJECT *) slot->defaultValue); } } for (i = 0 ; i < cls->handlerCount ; i++) { hnd = &cls->handlers[i]; DecrementSymbolCount(hnd->name); if (hnd->actions != NULL) ExpressionDeinstall(hnd->actions); } } else { cls->installed = 1; IncrementSymbolCount(cls->header.name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -