📄 insfile.c
字号:
(or file pointer for binary output) 2) The current module 3) A flag indicating local or visible saves 4) The defclass 5) A flag indicating whether to save subclass instances or not 6) A traversal id for marking visited classes 7) A pointer to the instance manipulation function to call (can be NULL for only counting instances) RETURNS : The number of instances saved SIDE EFFECTS : Appropriate instances saved NOTES : None ***************************************************/static long SaveOrMarkInstancesOfClass(theOutput,currentModule,saveCode, theDefclass,inheritFlag,traversalID, saveInstanceFunc) VOID *theOutput; struct defmodule *currentModule; int saveCode; DEFCLASS *theDefclass; BOOLEAN inheritFlag; int traversalID;#if ANSI_COMPILER VOID (*saveInstanceFunc)(VOID *,INSTANCE_TYPE *);#else VOID (*saveInstanceFunc)();#endif { INSTANCE_TYPE *theInstance; DEFCLASS *subclass; register unsigned i; long instanceCount = 0L; if (TestTraversalID(theDefclass->traversalRecord,traversalID)) return(instanceCount); SetTraversalID(theDefclass->traversalRecord,traversalID); if (((saveCode == LOCAL_SAVE) && (theDefclass->header.whichModule->theModule == currentModule)) || ((saveCode == VISIBLE_SAVE) && DefclassInScope(theDefclass,currentModule))) { for (theInstance = (INSTANCE_TYPE *) GetNextInstanceInClass((VOID *) theDefclass,NULL) ; theInstance != NULL ; theInstance = (INSTANCE_TYPE *) GetNextInstanceInClass((VOID *) theDefclass,(VOID *) theInstance)) { if (saveInstanceFunc != NULL) (*saveInstanceFunc)(theOutput,theInstance); instanceCount++; } } if (inheritFlag) { for (i = 0 ; i < theDefclass->directSubclasses.classCount ; i++) { subclass = theDefclass->directSubclasses.classArray[i]; instanceCount += SaveOrMarkInstancesOfClass(theOutput,currentModule,saveCode, subclass,CLIPS_TRUE,traversalID, saveInstanceFunc); } } return(instanceCount); } /*************************************************** NAME : SaveSingleInstanceText DESCRIPTION : Writes given instance to file INPUTS : 1) The logical name of the output 2) The instance to save RETURNS : Nothing useful SIDE EFFECTS : Instance written NOTES : None ***************************************************/static VOID SaveSingleInstanceText(vLogicalName,theInstance) VOID *vLogicalName; INSTANCE_TYPE *theInstance; { register unsigned i; INSTANCE_SLOT *sp; char *logicalName = (char *) vLogicalName; PrintCLIPS(logicalName,"(["); PrintCLIPS(logicalName,ValueToString(theInstance->name)); PrintCLIPS(logicalName,"] of "); PrintCLIPS(logicalName,ValueToString(theInstance->cls->header.name)); for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++) { sp = theInstance->slotAddresses[i]; PrintCLIPS(logicalName,"\n ("); PrintCLIPS(logicalName,ValueToString(sp->desc->slotName->name)); if (sp->type != MULTIFIELD) { PrintCLIPS(logicalName," "); PrintAtom(logicalName,(int) sp->type,sp->value); } else if (GetInstanceSlotLength(sp) != 0) { PrintCLIPS(logicalName," "); PrintMultifield(logicalName,(MULTIFIELD_PTR) sp->value,0, GetInstanceSlotLength(sp) - 1,CLIPS_FALSE); } PrintCLIPS(logicalName,")"); } PrintCLIPS(logicalName,")\n\n"); }#if BSAVE_INSTANCES/*************************************************** NAME : WriteBinaryHeader DESCRIPTION : Writes identifying string to instance binary file to assist in later verification INPUTS : The binary file pointer RETURNS : Nothing useful SIDE EFFECTS : Binary prefix headers written NOTES : None ***************************************************/static VOID WriteBinaryHeader(bsaveFP) FILE *bsaveFP; { fwrite((VOID *) InstanceBinaryPrefixID, (CLIPS_STD_SIZE) (strlen(InstanceBinaryPrefixID) + 1),1,bsaveFP); fwrite((VOID *) InstanceBinaryVersionID, (CLIPS_STD_SIZE) (strlen(InstanceBinaryVersionID) + 1),1,bsaveFP); }/*************************************************** NAME : MarkSingleInstance DESCRIPTION : Marks all the atoms needed in the slot values of an instance INPUTS : 1) The output (ignored) 2) The instance RETURNS : Nothing useful SIDE EFFECTS : Instance slot value atoms marked NOTES : None ***************************************************/#if IBM_TBC#pragma argsused#endifstatic VOID MarkSingleInstance(theOutput,theInstance) VOID *theOutput; INSTANCE_TYPE *theInstance; {#if MAC_MPW || MAC_MCW#pragma unused(theOutput)#endif INSTANCE_SLOT *sp; register unsigned i,j; BinaryInstanceFileSize += (unsigned long) (sizeof(long) * 2); theInstance->name->neededSymbol = CLIPS_TRUE; theInstance->cls->header.name->neededSymbol = CLIPS_TRUE; BinaryInstanceFileSize += (unsigned long) ((sizeof(long) * 2) + (sizeof(struct bsaveSlotValue) * theInstance->cls->instanceSlotCount) + sizeof(unsigned long) + sizeof(unsigned)); for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++) { sp = theInstance->slotAddresses[i]; sp->desc->slotName->name->neededSymbol = CLIPS_TRUE; if (sp->desc->multiple) { for (j = 1 ; j <= GetInstanceSlotLength(sp) ; j++) MarkNeededAtom(GetMFType(sp->value,j),GetMFValue(sp->value,j)); } else MarkNeededAtom((int) sp->type,sp->value); } }/*************************************************** NAME : MarkNeededAtom DESCRIPTION : Marks an integer/float/symbol as being need by a set of instances INPUTS : 1) The type of atom 2) The value of the atom RETURNS : Nothing useful SIDE EFFECTS : Atom marked for saving NOTES : None ***************************************************/static VOID MarkNeededAtom(type,value) int type; VOID *value; { BinaryInstanceFileSize += (unsigned long) sizeof(struct bsaveSlotValueAtom); /* ===================================== Assumes slot value atoms can only be floats, integers, symbols, strings, instance-names, instance-addresses, fact-addresses or external-addresses ===================================== */ switch (type) { case SYMBOL: case STRING: case INSTANCE_NAME: ((SYMBOL_HN *) value)->neededSymbol = CLIPS_TRUE; break; case FLOAT: ((FLOAT_HN *) value)->neededFloat = CLIPS_TRUE; break; case INTEGER: ((INTEGER_HN *) value)->neededInteger = CLIPS_TRUE; break; case INSTANCE_ADDRESS: GetFullInstanceName((INSTANCE_TYPE *) value)->neededSymbol = CLIPS_TRUE; break; } } /**************************************************** NAME : SaveSingleInstanceBinary DESCRIPTION : Writes given instance to binary file INPUTS : 1) Binary file pointer 2) The instance to save RETURNS : Nothing useful SIDE EFFECTS : Instance written NOTES : None ****************************************************/static VOID SaveSingleInstanceBinary(vBsaveFP,theInstance) VOID *vBsaveFP; INSTANCE_TYPE *theInstance; { long nameIndex; register unsigned i,j; INSTANCE_SLOT *sp; FILE *bsaveFP = (FILE *) vBsaveFP; struct bsaveSlotValue bs; unsigned long totalValueCount = 0L; int slotLen; /* =========================== Write out the instance name =========================== */ nameIndex = (long) theInstance->name->bucket; fwrite((VOID *) &nameIndex,(int) sizeof(long),1,bsaveFP); /* ======================== Write out the class name ======================== */ nameIndex = (long) theInstance->cls->header.name->bucket; fwrite((VOID *) &nameIndex,(int) sizeof(long),1,bsaveFP); /* ====================================== Write out the number of slot-overrides ====================================== */ fwrite((VOID *) &theInstance->cls->instanceSlotCount, (int) sizeof(unsigned),1,bsaveFP); /* ========================================= Write out the slot names and value counts ========================================= */ for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++) { sp = theInstance->slotAddresses[i]; /* =============================================== Write out the number of atoms in the slot value =============================================== */ bs.slotName = (long) sp->desc->slotName->name->bucket; bs.valueCount = sp->desc->multiple ? GetInstanceSlotLength(sp) : 1; fwrite((VOID *) &bs,(int) sizeof(struct bsaveSlotValue),1,bsaveFP); totalValueCount += (unsigned long) bs.valueCount; } /* ================================== Write out the number of slot value atoms for the whole instance ================================== */ if (totalValueCount != 0L) fwrite((VOID *) &totalValueCount,(int) sizeof(unsigned long),1,bsaveFP); /* ============================== Write out the slot value atoms ============================== */ for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++) { sp = theInstance->slotAddresses[i]; slotLen = sp->desc->multiple ? GetInstanceSlotLength(sp) : 1; /* ========================================= Write out the type and index of each atom ========================================= */ if (sp->desc->multiple) { for (j = 1 ; j <= slotLen ; j++) SaveAtomBinary(GetMFType(sp->value,j),GetMFValue(sp->value,j),bsaveFP); } else SaveAtomBinary((int) sp->type,sp->value,bsaveFP); } }/*************************************************** NAME : SaveAtomBinary DESCRIPTION : Writes out an instance slot value atom to the binary file INPUTS : 1) The atom type 2) The atom value 3) The binary file pointer RETURNS : Nothing useful SIDE EFFECTS : atom written NOTES : ***************************************************/static VOID SaveAtomBinary(type,value,bsaveFP) int type; VOID *value; FILE *bsaveFP; { struct bsaveSlotValueAtom bsa; /* ===================================== Assumes slot value atoms can only be floats, integers, symbols, strings, instance-names, instance-addresses, fact-addresses or external-addresses ===================================== */ bsa.type = type; switch (type) { case SYMBOL: case STRING: case INSTANCE_NAME: bsa.value = (long) ((SYMBOL_HN *) value)->bucket; break; case FLOAT: bsa.value = (long) ((FLOAT_HN *) value)->bucket; break; case INTEGER: bsa.value = (long) ((INTEGER_HN *) value)->bucket; break; case INSTANCE_ADDRESS: bsa.type = INSTANCE_NAME; bsa.value = (long) GetFullInstanceName((INSTANCE_TYPE *) value)->bucket; break; default: bsa.value = -1L; } fwrite((VOID *) &bsa,(int) sizeof(struct bsaveSlotValueAtom),1,bsaveFP); }#endif /********************************************************************** NAME : LoadOrRestoreInstances DESCRIPTION : Loads instances from named file INPUTS : 1) The name of the input file 2) An integer flag indicating whether or not to use message-passing to create the new instances and delete old versions 3) An integer flag indicating if arg #1 is a file name or the name of a string router RETURNS : The number of instances loaded/restored SIDE EFFECTS : Instances loaded from file NOTES : None **********************************************************************/static long LoadOrRestoreInstances(file,usemsgs,isFileName) char *file; int usemsgs,isFileName; { DATA_OBJECT temp; FILE *sfile,*svload; char *ilog; EXPRESSION *top; int svoverride; long instanceCount = 0L; if (isFileName) { if ((sfile = fopen(file,"r")) == NULL) { SetEvaluationError(CLIPS_TRUE); return(-1L); } svload = GetFastLoad(); ilog = (char *) sfile; SetFastLoad(sfile); } else { ilog = file; } top = GenConstant(FCALL,(VOID *) FindFunction("make-instance")); GetToken(ilog,&ObjectParseToken); svoverride = MkInsMsgPass; MkInsMsgPass = usemsgs; while ((GetType(ObjectParseToken) != STOP) && (HaltExecution != CLIPS_TRUE)) { if (GetType(ObjectParseToken) != LPAREN) { SyntaxErrorMessage("instance definition"); rtn_struct(expr,top); if (isFileName) { fclose(sfile); SetFastLoad(svload); } SetEvaluationError(CLIPS_TRUE); MkInsMsgPass = svoverride; return(instanceCount); } if (ParseSimpleInstance(top,ilog) == NULL) { if (isFileName) { fclose(sfile); SetFastLoad(svload); } MkInsMsgPass = svoverride; SetEvaluationError(CLIPS_TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -