📄 insfile.c
字号:
2) A flag indicating whether to save local (current module only) or visible instances LOCAL_SAVE or VISIBLE_SAVE 3) A list of expressions containing the names of classes for which instances are to be saved 4) A flag indicating if the subclasses of specified classes shoudl also be processed RETURNS : The number of instances saved SIDE EFFECTS : Instances saved to file NOTES : None *******************************************************/globle long EnvSaveInstances( void *theEnv, char *file, int saveCode, EXPRESSION *classExpressionList, intBool inheritFlag) { FILE *sfile = NULL; int oldPEC,oldATS,oldIAN; DATA_OBJECT *classList; long instanceCount; classList = ProcessSaveClassList(theEnv,"save-instances",classExpressionList, saveCode,inheritFlag); if ((classList == NULL) && (classExpressionList != NULL)) return(0L); SaveOrMarkInstances(theEnv,(void *) sfile,saveCode,classList, inheritFlag,TRUE,NULL); if ((sfile = GenOpen(theEnv,file,"w")) == NULL) { OpenErrorMessage(theEnv,"save-instances",file); ReturnSaveClassList(theEnv,classList); SetEvaluationError(theEnv,TRUE); return(0L); } oldPEC = PrintUtilityData(theEnv)->PreserveEscapedCharacters; PrintUtilityData(theEnv)->PreserveEscapedCharacters = TRUE; oldATS = PrintUtilityData(theEnv)->AddressesToStrings; PrintUtilityData(theEnv)->AddressesToStrings = TRUE; oldIAN = PrintUtilityData(theEnv)->InstanceAddressesToNames; PrintUtilityData(theEnv)->InstanceAddressesToNames = TRUE; SetFastSave(theEnv,sfile); instanceCount = SaveOrMarkInstances(theEnv,(void *) sfile,saveCode,classList, inheritFlag,TRUE,SaveSingleInstanceText); GenClose(theEnv,sfile); SetFastSave(theEnv,NULL); PrintUtilityData(theEnv)->PreserveEscapedCharacters = oldPEC; PrintUtilityData(theEnv)->AddressesToStrings = oldATS; PrintUtilityData(theEnv)->InstanceAddressesToNames = oldIAN; ReturnSaveClassList(theEnv,classList); return(instanceCount); }#if BSAVE_INSTANCES/**************************************************************************** NAME : BinarySaveInstancesCommand DESCRIPTION : H/L interface for saving current instances to a binary file INPUTS : None RETURNS : The number of instances saved SIDE EFFECTS : Instances saved (in binary format) to named file NOTES : H/L Syntax : (bsave-instances <file> [local|visible [[inherit] <class>+]]) *****************************************************************************/globle long BinarySaveInstancesCommand( void *theEnv) { return(InstancesSaveCommandParser(theEnv,"bsave-instances",EnvBinarySaveInstances)); }/******************************************************* NAME : EnvBinarySaveInstances DESCRIPTION : Saves current instances to binary file INPUTS : 1) The name of the output file 2) A flag indicating whether to save local (current module only) or visible instances LOCAL_SAVE or VISIBLE_SAVE 3) A list of expressions containing the names of classes for which instances are to be saved 4) A flag indicating if the subclasses of specified classes shoudl also be processed RETURNS : The number of instances saved SIDE EFFECTS : Instances saved to file NOTES : None *******************************************************/globle long EnvBinarySaveInstances( void *theEnv, char *file, int saveCode, EXPRESSION *classExpressionList, intBool inheritFlag) { DATA_OBJECT *classList; FILE *bsaveFP; long instanceCount; classList = ProcessSaveClassList(theEnv,"bsave-instances",classExpressionList, saveCode,inheritFlag); if ((classList == NULL) && (classExpressionList != NULL)) return(0L); InstanceFileData(theEnv)->BinaryInstanceFileSize = 0L; InitAtomicValueNeededFlags(theEnv); instanceCount = SaveOrMarkInstances(theEnv,NULL,saveCode,classList,inheritFlag, FALSE,MarkSingleInstance); if ((bsaveFP = GenOpen(theEnv,file,"wb")) == NULL) { OpenErrorMessage(theEnv,"bsave-instances",file); ReturnSaveClassList(theEnv,classList); SetEvaluationError(theEnv,TRUE); return(0L); } WriteBinaryHeader(theEnv,bsaveFP); WriteNeededAtomicValues(theEnv,bsaveFP); fwrite((void *) &InstanceFileData(theEnv)->BinaryInstanceFileSize,sizeof(unsigned long),1,bsaveFP); fwrite((void *) &instanceCount,sizeof(long),1,bsaveFP); SetAtomicValueIndices(theEnv,FALSE); SaveOrMarkInstances(theEnv,(void *) bsaveFP,saveCode,classList, inheritFlag,FALSE,SaveSingleInstanceBinary); RestoreAtomicValueBuckets(theEnv); GenClose(theEnv,bsaveFP); ReturnSaveClassList(theEnv,classList); return(instanceCount); }#endif/* ========================================= ***************************************** INTERNALLY VISIBLE FUNCTIONS ========================================= ***************************************** *//****************************************************** NAME : InstancesSaveCommandParser DESCRIPTION : Argument parser for save-instances and bsave-instances INPUTS : 1) The name of the calling function 2) A pointer to the support function to call for the save/bsave RETURNS : The number of instances saved SIDE EFFECTS : Instances saved/bsaved NOTES : None ******************************************************/static long InstancesSaveCommandParser( void *theEnv, char *functionName, long (*saveFunction)(void *,char *,int,EXPRESSION *,intBool)) { char *fileFound; DATA_OBJECT temp; int argCount,saveCode = LOCAL_SAVE; EXPRESSION *classList = NULL; intBool inheritFlag = FALSE; if (EnvArgTypeCheck(theEnv,functionName,1,SYMBOL_OR_STRING,&temp) == FALSE) return(0L); fileFound = DOToString(temp); argCount = EnvRtnArgCount(theEnv); if (argCount > 1) { if (EnvArgTypeCheck(theEnv,functionName,2,SYMBOL,&temp) == FALSE) { ExpectedTypeError1(theEnv,functionName,2,"symbol \"local\" or \"visible\""); SetEvaluationError(theEnv,TRUE); return(0L); } if (strcmp(DOToString(temp),"local") == 0) saveCode = LOCAL_SAVE; else if (strcmp(DOToString(temp),"visible") == 0) saveCode = VISIBLE_SAVE; else { ExpectedTypeError1(theEnv,functionName,2,"symbol \"local\" or \"visible\""); SetEvaluationError(theEnv,TRUE); return(0L); } classList = GetFirstArgument()->nextArg->nextArg; /* =========================== Check for "inherit" keyword Must be at least one class name following =========================== */ if ((classList != NULL) ? (classList->nextArg != NULL) : FALSE) { if ((classList->type != SYMBOL) ? FALSE : (strcmp(ValueToString(classList->value),"inherit") == 0)) { inheritFlag = TRUE; classList = classList->nextArg; } } } return((*saveFunction)(theEnv,fileFound,saveCode,classList,inheritFlag)); }/**************************************************** NAME : ProcessSaveClassList DESCRIPTION : Evaluates a list of class name expressions and stores them in a data object list INPUTS : 1) The name of the calling function 2) The class expression list 3) A flag indicating if only local or all visible instances are being saved 4) A flag indicating if inheritance relationships should be checked between classes RETURNS : The evaluated class pointer data objects - NULL on errors SIDE EFFECTS : Data objects allocated and classes validated NOTES : None ****************************************************/static DATA_OBJECT *ProcessSaveClassList( void *theEnv, char *functionName, EXPRESSION *classExps, int saveCode, intBool inheritFlag) { DATA_OBJECT *head = NULL,*prv,*newItem,tmp; DEFCLASS *theDefclass; struct defmodule *currentModule; int argIndex = inheritFlag ? 4 : 3; currentModule = ((struct defmodule *) EnvGetCurrentModule(theEnv)); while (classExps != NULL) { if (EvaluateExpression(theEnv,classExps,&tmp)) goto ProcessClassListError; if (tmp.type != SYMBOL) goto ProcessClassListError; if (saveCode == LOCAL_SAVE) theDefclass = LookupDefclassAnywhere(theEnv,currentModule,DOToString(tmp)); else theDefclass = LookupDefclassInScope(theEnv,DOToString(tmp)); if (theDefclass == NULL) goto ProcessClassListError; else if (theDefclass->abstract && (inheritFlag == FALSE)) goto ProcessClassListError; prv = newItem = head; while (newItem != NULL) { if (newItem->value == (void *) theDefclass) goto ProcessClassListError; else if (inheritFlag) { if (HasSuperclass((DEFCLASS *) newItem->value,theDefclass) || HasSuperclass(theDefclass,(DEFCLASS *) newItem->value)) goto ProcessClassListError; } prv = newItem; newItem = newItem->next; } newItem = get_struct(theEnv,dataObject); newItem->type = DEFCLASS_PTR; newItem->value = (void *) theDefclass; newItem->next = NULL; if (prv == NULL) head = newItem; else prv->next = newItem; argIndex++; classExps = classExps->nextArg; } return(head);ProcessClassListError: ExpectedTypeError1(theEnv,functionName,argIndex, (char *) (inheritFlag ? "valid class name" : "valid concrete class name")); ReturnSaveClassList(theEnv,head); SetEvaluationError(theEnv,TRUE); return(NULL); }/**************************************************** NAME : ReturnSaveClassList DESCRIPTION : Deallocates the class data object list created by ProcessSaveClassList INPUTS : The class data object list RETURNS : Nothing useful SIDE EFFECTS : Class data object returned NOTES : None ****************************************************/static void ReturnSaveClassList( void *theEnv, DATA_OBJECT *classList) { DATA_OBJECT *tmp; while (classList != NULL) { tmp = classList; classList = classList->next; rtn_struct(theEnv,dataObject,tmp); } }/*************************************************** NAME : SaveOrMarkInstances DESCRIPTION : Iterates through all specified instances either marking needed atoms or writing instances in binary/text format INPUTS : 1) NULL (for marking), logical name (for text saves) file pointer (for binary saves) 2) A cope flag indicating LOCAL or VISIBLE saves only 3) A list of data objects containing the names of classes of instances to be saved 4) A flag indicating whether to include subclasses of arg #3 5) A flag indicating if the iteration can be interrupted or not 6) The access function to mark or save an instance (can be NULL if only counting instances) RETURNS : The number of instances saved SIDE EFFECTS : Instances amrked or saved NOTES : None ***************************************************/static long SaveOrMarkInstances( void *theEnv, void *theOutput, int saveCode, DATA_OBJECT *classList, intBool inheritFlag, intBool interruptOK, void (*saveInstanceFunc)(void *,void *,INSTANCE_TYPE *)) { struct defmodule *currentModule; int traversalID; DATA_OBJECT *tmp; INSTANCE_TYPE *ins; long instanceCount = 0L; currentModule = ((struct defmodule *) EnvGetCurrentModule(theEnv)); if (classList != NULL) { traversalID = GetTraversalID(theEnv); if (traversalID != -1) { for (tmp = classList ; (! ((tmp == NULL) || (EvaluationData(theEnv)->HaltExecution && interruptOK))) ; tmp = tmp->next) instanceCount += SaveOrMarkInstancesOfClass(theEnv,theOutput,currentModule,saveCode, (DEFCLASS *) tmp->value,inheritFlag, traversalID,saveInstanceFunc); ReleaseTraversalID(theEnv); } } else { for (ins = (INSTANCE_TYPE *) GetNextInstanceInScope(theEnv,NULL) ; (ins != NULL) && (EvaluationData(theEnv)->HaltExecution != TRUE) ; ins = (INSTANCE_TYPE *) GetNextInstanceInScope(theEnv,(void *) ins)) { if ((saveCode == VISIBLE_SAVE) ? TRUE : (ins->cls->header.whichModule->theModule == currentModule)) { if (saveInstanceFunc != NULL) (*saveInstanceFunc)(theEnv,theOutput,ins); instanceCount++; } } } return(instanceCount); }/*************************************************** NAME : SaveOrMarkInstancesOfClass DESCRIPTION : Saves off the direct (and indirect) instance of the specified class INPUTS : 1) The logical name of the output (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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -