📄 insfile.c
字号:
instances)
RETURNS : The number of instances saved
SIDE EFFECTS : Appropriate instances saved
NOTES : None
***************************************************/
static long SaveOrMarkInstancesOfClass(
void *theEnv,
void *theOutput,
struct defmodule *currentModule,
int saveCode,
DEFCLASS *theDefclass,
intBool inheritFlag,
int traversalID,
void (*saveInstanceFunc)(void *,void *,INSTANCE_TYPE *))
{
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(theEnv,theDefclass,currentModule)))
{
for (theInstance = (INSTANCE_TYPE *)
EnvGetNextInstanceInClass(theEnv,(void *) theDefclass,NULL) ;
theInstance != NULL ;
theInstance = (INSTANCE_TYPE *)
EnvGetNextInstanceInClass(theEnv,(void *) theDefclass,(void *) theInstance))
{
if (saveInstanceFunc != NULL)
(*saveInstanceFunc)(theEnv,theOutput,theInstance);
instanceCount++;
}
}
if (inheritFlag)
{
for (i = 0 ; i < theDefclass->directSubclasses.classCount ; i++)
{
subclass = theDefclass->directSubclasses.classArray[i];
instanceCount += SaveOrMarkInstancesOfClass(theEnv,theOutput,currentModule,saveCode,
subclass,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(
void *theEnv,
void *vLogicalName,
INSTANCE_TYPE *theInstance)
{
register unsigned i;
INSTANCE_SLOT *sp;
char *logicalName = (char *) vLogicalName;
EnvPrintRouter(theEnv,logicalName,"([");
EnvPrintRouter(theEnv,logicalName,ValueToString(theInstance->name));
EnvPrintRouter(theEnv,logicalName,"] of ");
EnvPrintRouter(theEnv,logicalName,ValueToString(theInstance->cls->header.name));
for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
{
sp = theInstance->slotAddresses[i];
EnvPrintRouter(theEnv,logicalName,"\n (");
EnvPrintRouter(theEnv,logicalName,ValueToString(sp->desc->slotName->name));
if (sp->type != MULTIFIELD)
{
EnvPrintRouter(theEnv,logicalName," ");
PrintAtom(theEnv,logicalName,(int) sp->type,sp->value);
}
else if (GetInstanceSlotLength(sp) != 0)
{
EnvPrintRouter(theEnv,logicalName," ");
PrintMultifield(theEnv,logicalName,(MULTIFIELD_PTR) sp->value,0,
(long) (GetInstanceSlotLength(sp) - 1),FALSE);
}
EnvPrintRouter(theEnv,logicalName,")");
}
EnvPrintRouter(theEnv,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(
void *theEnv,
FILE *bsaveFP)
{
fwrite((void *) InstanceFileData(theEnv)->InstanceBinaryPrefixID,
(STD_SIZE) (strlen(InstanceFileData(theEnv)->InstanceBinaryPrefixID) + 1),1,bsaveFP);
fwrite((void *) InstanceFileData(theEnv)->InstanceBinaryVersionID,
(STD_SIZE) (strlen(InstanceFileData(theEnv)->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
#endif
static void MarkSingleInstance(
void *theEnv,
void *theOutput,
INSTANCE_TYPE *theInstance)
{
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theOutput)
#endif
INSTANCE_SLOT *sp;
register unsigned i,j;
InstanceFileData(theEnv)->BinaryInstanceFileSize += (unsigned long) (sizeof(long) * 2);
theInstance->name->neededSymbol = TRUE;
theInstance->cls->header.name->neededSymbol = TRUE;
InstanceFileData(theEnv)->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 = TRUE;
if (sp->desc->multiple)
{
for (j = 1 ; j <= GetInstanceSlotLength(sp) ; j++)
MarkNeededAtom(theEnv,GetMFType(sp->value,j),GetMFValue(sp->value,j));
}
else
MarkNeededAtom(theEnv,(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(
void *theEnv,
int type,
void *value)
{
InstanceFileData(theEnv)->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 = TRUE;
break;
case FLOAT:
((FLOAT_HN *) value)->neededFloat = TRUE;
break;
case INTEGER:
((INTEGER_HN *) value)->neededInteger = TRUE;
break;
case INSTANCE_ADDRESS:
GetFullInstanceName(theEnv,(INSTANCE_TYPE *) value)->neededSymbol = 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(
void *theEnv,
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;
unsigned 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(theEnv,GetMFType(sp->value,j),GetMFValue(sp->value,j),bsaveFP);
}
else
SaveAtomBinary(theEnv,(unsigned short) 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(
void *theEnv,
unsigned short 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(theEnv,(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(
void *theEnv,
char *file,
int usemsgs,
int isFileName)
{
DATA_OBJECT temp;
FILE *sfile = NULL,*svload = NULL;
char *ilog;
EXPRESSION *top;
int svoverride;
long instanceCount = 0L;
if (isFileName) {
if ((sfile = GenOpen(theEnv,file,"r")) == NULL)
{
SetEvaluationError(theEnv,TRUE);
return(-1L);
}
svload = GetFastLoad(theEnv);
ilog = (char *) sfile;
SetFastLoad(theEnv,sfile);
} else {
ilog = file;
}
top = GenConstant(theEnv,FCALL,(void *) FindFunction(theEnv,"make-instance"));
GetToken(theEnv,ilog,&DefclassData(theEnv)->ObjectParseToken);
svoverride = InstanceData(theEnv)->MkInsMsgPass;
InstanceData(theEnv)->MkInsMsgPass = usemsgs;
while ((GetType(DefclassData(theEnv)->ObjectParseToken) != STOP) && (EvaluationData(theEnv)->HaltExecution != TRUE))
{
if (GetType(DefclassData(theEnv)->ObjectParseToken) != LPAREN)
{
SyntaxErrorMessage(theEnv,"instance definition");
rtn_struct(theEnv,expr,top);
if (isFileName) {
GenClose(theEnv,sfile);
SetFastLoad(theEnv,svload);
}
SetEvaluationError(theEnv,TRUE);
InstanceData(theEnv)->MkInsMsgPass = svoverride;
return(instanceCount);
}
if (ParseSimpleInstance(theEnv,top,ilog) == NULL)
{
if (isFileName) {
GenClose(theEnv,sfile);
SetFastLoad(theEnv,svload);
}
InstanceData(theEnv)->MkInsMsgPass = svoverride;
SetEvaluationError(theEnv,TRUE);
return(instanceCount);
}
ExpressionInstall(theEnv,top);
EvaluateExpression(theEnv,top,&temp);
ExpressionDeinstall(theEnv,top);
if (! EvaluationData(theEnv)->EvaluationError)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -