📄 bload.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/05/06 */
/* */
/* BLOAD MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides core routines for loading constructs */
/* from a binary file. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* Brian L. Donnell */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* */
/* 6.24: Renamed BOOLEAN macro type to intBool. */
/* */
/*************************************************************/
#define _BLOAD_SOURCE_
#include "setup.h"
#include "argacces.h"
#include "bsave.h"
#include "constrct.h"
#include "cstrnbin.h"
#include "envrnmnt.h"
#include "exprnpsr.h"
#include "memalloc.h"
#include "router.h"
#include "utility.h"
#include "bload.h"
#if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE)
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static struct FunctionDefinition **ReadNeededFunctions(void *,long *,int *);
static struct FunctionDefinition *FastFindFunction(void *,char *,struct FunctionDefinition *);
static int ClearBload(void *);
static void AbortBload(void *);
static int BloadOutOfMemoryFunction(void *,unsigned long);
static void DeallocateBloadData(void *);
/**********************************************/
/* InitializeBloadData: Allocates environment */
/* data for the bload command. */
/**********************************************/
globle void InitializeBloadData(
void *theEnv)
{
AllocateEnvironmentData(theEnv,BLOAD_DATA,sizeof(struct bloadData),NULL);
AddEnvironmentCleanupFunction(theEnv,"bload",DeallocateBloadData,-1500);
BloadData(theEnv)->BinaryPrefixID = "\1\2\3\4CLIPS";
BloadData(theEnv)->BinaryVersionID = "V6.20";
}
/************************************************/
/* DeallocateBloadData: Deallocates environment */
/* data for the bload command. */
/************************************************/
static void DeallocateBloadData(
void *theEnv)
{
DeallocateCallList(theEnv,BloadData(theEnv)->BeforeBloadFunctions);
DeallocateCallList(theEnv,BloadData(theEnv)->AfterBloadFunctions);
DeallocateCallList(theEnv,BloadData(theEnv)->ClearBloadReadyFunctions);
DeallocateCallList(theEnv,BloadData(theEnv)->AbortBloadFunctions);
}
/******************************/
/* EnvBload: C access routine */
/* for the bload command. */
/******************************/
globle int EnvBload(
void *theEnv,
char *fileName)
{
long numberOfFunctions;
unsigned long space;
int error;
char IDbuffer[20];
char constructBuffer[CONSTRUCT_HEADER_SIZE];
struct BinaryItem *biPtr;
struct callFunctionItem *bfPtr;
/*================*/
/* Open the file. */
/*================*/
if (GenOpenReadBinary(theEnv,"bload",fileName) == 0) return(FALSE);
/*=====================================*/
/* Determine if this is a binary file. */
/*=====================================*/
GenReadBinary(theEnv,IDbuffer,(unsigned long) strlen(BloadData(theEnv)->BinaryPrefixID) + 1);
if (strcmp(IDbuffer,BloadData(theEnv)->BinaryPrefixID) != 0)
{
PrintErrorID(theEnv,"BLOAD",2,FALSE);
EnvPrintRouter(theEnv,WERROR,"File ");
EnvPrintRouter(theEnv,WERROR,fileName);
EnvPrintRouter(theEnv,WERROR," is not a binary construct file.\n");
GenCloseBinary(theEnv);
return(FALSE);
}
/*=======================================*/
/* Determine if it's a binary file using */
/* a format from a different version. */
/*=======================================*/
GenReadBinary(theEnv,IDbuffer,(unsigned long) strlen(BloadData(theEnv)->BinaryVersionID) + 1);
if (strcmp(IDbuffer,BloadData(theEnv)->BinaryVersionID) != 0)
{
PrintErrorID(theEnv,"BLOAD",3,FALSE);
EnvPrintRouter(theEnv,WERROR,"File ");
EnvPrintRouter(theEnv,WERROR,fileName);
EnvPrintRouter(theEnv,WERROR," is an incompatible binary construct file.\n");
GenCloseBinary(theEnv);
return(FALSE);
}
/*====================*/
/* Clear environment. */
/*====================*/
if (BloadData(theEnv)->BloadActive)
{
if (ClearBload(theEnv) == FALSE)
{
GenCloseBinary(theEnv);
return(FALSE);
}
}
/*=================================*/
/* Determine if the KB environment */
/* was successfully cleared. */
/*=================================*/
if (ClearReady(theEnv) == FALSE)
{
GenCloseBinary(theEnv);
EnvPrintRouter(theEnv,WERROR,"The ");
EnvPrintRouter(theEnv,WERROR,APPLICATION_NAME);
EnvPrintRouter(theEnv,WERROR," environment could not be cleared.\n");
EnvPrintRouter(theEnv,WERROR,"Binary load cannot continue.\n");
return(FALSE);
}
/*==================================*/
/* Call the list of functions to be */
/* executed before a bload occurs. */
/*==================================*/
for (bfPtr = BloadData(theEnv)->BeforeBloadFunctions;
bfPtr != NULL;
bfPtr = bfPtr->next)
{
if (bfPtr->environmentAware)
{ (*bfPtr->func)(theEnv); }
else
{ (* (void (*)(void)) bfPtr->func)(); }
}
/*====================================================*/
/* Read in the functions needed by this binary image. */
/*====================================================*/
BloadData(theEnv)->FunctionArray = ReadNeededFunctions(theEnv,&numberOfFunctions,&error);
if (error)
{
GenCloseBinary(theEnv);
AbortBload(theEnv);
return(FALSE);
}
/*================================================*/
/* Read in the atoms needed by this binary image. */
/*================================================*/
ReadNeededAtomicValues(theEnv);
/*===========================================*/
/* Determine the number of expressions to be */
/* read and allocate the appropriate space */
/*===========================================*/
AllocateExpressions(theEnv);
/*==========================================================*/
/* Read in the memory requirements of the constructs stored */
/* in this binary image and allocate the necessary space */
/*==========================================================*/
for (GenReadBinary(theEnv,constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE);
strncmp(constructBuffer,BloadData(theEnv)->BinaryPrefixID,CONSTRUCT_HEADER_SIZE) != 0;
GenReadBinary(theEnv,constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE))
{
intBool found;
/*================================================*/
/* Search for the construct type in the list of */
/* binary items. If found, allocate the storage */
/* needed by the construct for this binary image. */
/*================================================*/
found = FALSE;
for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
biPtr != NULL;
biPtr = biPtr->next)
{
if (strncmp(biPtr->name,constructBuffer,CONSTRUCT_HEADER_SIZE) == 0)
{
if (biPtr->bloadStorageFunction != NULL)
{
(*biPtr->bloadStorageFunction)(theEnv);
found = TRUE;
}
break;
}
}
/*==========================================*/
/* If the construct type wasn't found, skip */
/* the storage binary load information for */
/* this construct. */
/*==========================================*/
if (! found)
{
GenReadBinary(theEnv,&space,(unsigned long) sizeof(unsigned long));
GetSeekCurBinary(theEnv,(long) space);
if (space != 0)
{
EnvPrintRouter(theEnv,WDIALOG,"\nSkipping ");
EnvPrintRouter(theEnv,WDIALOG,constructBuffer);
EnvPrintRouter(theEnv,WDIALOG," constructs because of unavailibility\n");
}
}
}
/*======================================*/
/* Refresh the pointers in expressions. */
/*======================================*/
RefreshExpressions(theEnv);
/*==========================*/
/* Read in the constraints. */
/*==========================*/
ReadNeededConstraints(theEnv);
/*======================================================*/
/* Read in the constructs stored in this binary image. */
/*======================================================*/
for (GenReadBinary(theEnv,constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE);
strncmp(constructBuffer,BloadData(theEnv)->BinaryPrefixID,CONSTRUCT_HEADER_SIZE) != 0;
GenReadBinary(theEnv,constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE))
{
intBool found;
/*==================================================*/
/* Search for the function to load the construct */
/* into the previously allocated storage. If found, */
/* call the function to load the construct. */
/*==================================================*/
found = FALSE;
for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
biPtr != NULL;
biPtr = biPtr->next)
{
if (strncmp(biPtr->name,constructBuffer,CONSTRUCT_HEADER_SIZE) == 0)
{
if (biPtr->bloadFunction != NULL)
{
(*biPtr->bloadFunction)(theEnv);
found = TRUE;
}
break;
}
}
/*==========================================*/
/* If the construct type wasn't found, skip */
/* the binary data for this construct. */
/*==========================================*/
if (! found)
{
GenReadBinary(theEnv,&space,(unsigned long) sizeof(unsigned long));
GetSeekCurBinary(theEnv,(long) space);
}
}
/*=================*/
/* Close the file. */
/*=================*/
GenCloseBinary(theEnv);
/*========================================*/
/* Free up temporary storage used for the */
/* function and atomic value information. */
/*========================================*/
if (BloadData(theEnv)->FunctionArray != NULL)
{
genlongfree(theEnv,(void *) BloadData(theEnv)->FunctionArray,
(unsigned long) sizeof(struct FunctionDefinition *) * numberOfFunctions);
}
FreeAtomicValueStorage(theEnv);
/*==================================*/
/* Call the list of functions to be */
/* executed after a bload occurs. */
/*==================================*/
for (bfPtr = BloadData(theEnv)->AfterBloadFunctions;
bfPtr != NULL;
bfPtr = bfPtr->next)
{
if (bfPtr->environmentAware)
{ (*bfPtr->func)(theEnv); }
else
{ (* (void (*)(void)) bfPtr->func)(); }
}
/*=======================================*/
/* Add a clear function to remove binary */
/* load when a clear command is issued. */
/*=======================================*/
BloadData(theEnv)->BloadActive = TRUE;
EnvAddClearFunction(theEnv,"bload",(void (*)(void *)) ClearBload,10000);
/*=============================*/
/* Return TRUE to indicate the */
/* binary load was successful. */
/*=============================*/
return(TRUE);
}
/************************************************************
NAME : BloadandRefresh
DESCRIPTION : Loads and refreshes objects - will bload
all objects at once, if possible, but
will aslo work in increments if memory is
restricted
INPUTS : 1) the number of objects to bload and update
2) the size of one object
3) An update function which takes a bloaded
object buffer and the index of the object
to refresh as arguments
RETURNS : Nothing useful
SIDE EFFECTS : Objects bloaded and updated
NOTES : Assumes binary file pointer is positioned
for bloads of the objects
************************************************************/
globle void BloadandRefresh(
void *theEnv,
long objcnt,
unsigned objsz,
void (*objupdate)(void *,void *,long))
{
register long i,bi;
char *buf;
long objsmaxread,objsread;
unsigned long space;
int (*oldOutOfMemoryFunction)(void *,unsigned long);
if (objcnt == 0L) return;
oldOutOfMemoryFunction = EnvSetOutOfMemoryFunction(theEnv,BloadOutOfMemoryFunction);
objsmaxread = objcnt;
do
{
space = objsmaxread * objsz;
buf = (char *) genlongalloc(theEnv,space);
if (buf == NULL)
{
if ((objsmaxread / 2) == 0)
{
if ((*oldOutOfMemoryFunction)(theEnv,space) == TRUE)
{
EnvSetOutOfMemoryFunction(theEnv,oldOutOfMemoryFunction);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -