📄 bsave.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/05/06 */
/* */
/* BSAVE MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides core routines for saving constructs to */
/* 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. */
/* */
/* Added environment parameter to GenClose. */
/* Added environment parameter to GenOpen. */
/* */
/*************************************************************/
#define _BSAVE_SOURCE_
#include "setup.h"
#include "argacces.h"
#include "bload.h"
#include "cstrnbin.h"
#include "envrnmnt.h"
#include "exprnpsr.h"
#include "memalloc.h"
#include "moduldef.h"
#include "router.h"
#include "symblbin.h"
#include "bsave.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if BLOAD_AND_BSAVE
static void FindNeededItems(void *);
static void InitializeFunctionNeededFlags(void *);
static void WriteNeededFunctions(void *,FILE *);
static unsigned long int FunctionBinarySize(void *);
static void WriteBinaryHeader(void *,FILE *);
static void WriteBinaryFooter(void *,FILE *);
#endif
static void DeallocateBsaveData(void *);
/**********************************************/
/* InitializeBsaveData: Allocates environment */
/* data for the bsave command. */
/**********************************************/
globle void InitializeBsaveData(
void *theEnv)
{
AllocateEnvironmentData(theEnv,BSAVE_DATA,sizeof(struct bsaveData),DeallocateBsaveData);
}
/************************************************/
/* DeallocateBsaveData: Deallocates environment */
/* data for the bsave command. */
/************************************************/
static void DeallocateBsaveData(
void *theEnv)
{
struct BinaryItem *tmpPtr, *nextPtr;
tmpPtr = BsaveData(theEnv)->ListOfBinaryItems;
while (tmpPtr != NULL)
{
nextPtr = tmpPtr->next;
rtn_struct(theEnv,BinaryItem,tmpPtr);
tmpPtr = nextPtr;
}
}
/**************************************/
/* BsaveCommand: H/L access routine */
/* for the bsave command. */
/**************************************/
globle int BsaveCommand(
void *theEnv)
{
#if (! RUN_TIME) && BLOAD_AND_BSAVE
char *fileName;
if (EnvArgCountCheck(theEnv,"bsave",EXACTLY,1) == -1) return(FALSE);
fileName = GetFileName(theEnv,"bsave",1);
if (fileName != NULL)
{ if (EnvBsave(theEnv,fileName)) return(TRUE); }
#else
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
#endif
return(FALSE);
}
#if BLOAD_AND_BSAVE
/******************************/
/* EnvBsave: C access routine */
/* for the bsave command. */
/******************************/
globle intBool EnvBsave(
void *theEnv,
char *fileName)
{
FILE *fp;
struct BinaryItem *biPtr;
char constructBuffer[CONSTRUCT_HEADER_SIZE];
long saveExpressionCount;
/*===================================*/
/* A bsave can't occur when a binary */
/* image is already loaded. */
/*===================================*/
if (Bloaded(theEnv))
{
PrintErrorID(theEnv,"BSAVE",1,FALSE);
EnvPrintRouter(theEnv,WERROR,
"Cannot perform a binary save while a binary load is in effect.\n");
return(0);
}
/*================*/
/* Open the file. */
/*================*/
if ((fp = GenOpen(theEnv,fileName,"wb")) == NULL)
{
OpenErrorMessage(theEnv,"bsave",fileName);
return(0);
}
/*==============================*/
/* Remember the current module. */
/*==============================*/
SaveCurrentModule(theEnv);
/*==================================*/
/* Write binary header to the file. */
/*==================================*/
WriteBinaryHeader(theEnv,fp);
/*===========================================*/
/* Initialize count variables, index values, */
/* and determine some of the data structures */
/* which need to be saved. */
/*===========================================*/
ExpressionData(theEnv)->ExpressionCount = 0;
InitializeFunctionNeededFlags(theEnv);
InitAtomicValueNeededFlags(theEnv);
FindHashedExpressions(theEnv);
FindNeededItems(theEnv);
SetAtomicValueIndices(theEnv,FALSE);
/*===============================*/
/* Save the functions and atoms. */
/*===============================*/
WriteNeededFunctions(theEnv,fp);
WriteNeededAtomicValues(theEnv,fp);
/*=========================================*/
/* Write out the number of expression data */
/* structures in the binary image. */
/*=========================================*/
GenWrite((void *) &ExpressionData(theEnv)->ExpressionCount,(unsigned long) sizeof(unsigned long),fp);
/*===========================================*/
/* Save the numbers indicating the amount of */
/* memory needed to bload the constructs. */
/*===========================================*/
for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
biPtr != NULL;
biPtr = biPtr->next)
{
if (biPtr->bsaveStorageFunction != NULL)
{
strncpy(constructBuffer,biPtr->name,CONSTRUCT_HEADER_SIZE);
GenWrite(constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE,fp);
(*biPtr->bsaveStorageFunction)(theEnv,fp);
}
}
/*====================================*/
/* Write a binary footer to the file. */
/*====================================*/
WriteBinaryFooter(theEnv,fp);
/*===================*/
/* Save expressions. */
/*===================*/
ExpressionData(theEnv)->ExpressionCount = 0;
BsaveHashedExpressions(theEnv,fp);
saveExpressionCount = ExpressionData(theEnv)->ExpressionCount;
BsaveConstructExpressions(theEnv,fp);
ExpressionData(theEnv)->ExpressionCount = saveExpressionCount;
/*===================*/
/* Save constraints. */
/*===================*/
WriteNeededConstraints(theEnv,fp);
/*==================*/
/* Save constructs. */
/*==================*/
for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
biPtr != NULL;
biPtr = biPtr->next)
{
if (biPtr->bsaveFunction != NULL)
{
strncpy(constructBuffer,biPtr->name,CONSTRUCT_HEADER_SIZE);
GenWrite(constructBuffer,(unsigned long) CONSTRUCT_HEADER_SIZE,fp);
(*biPtr->bsaveFunction)(theEnv,fp);
}
}
/*===================================*/
/* Save a binary footer to the file. */
/*===================================*/
WriteBinaryFooter(theEnv,fp);
/*===========*/
/* Clean up. */
/*===========*/
RestoreAtomicValueBuckets(theEnv);
/*=================*/
/* Close the file. */
/*=================*/
GenClose(theEnv,fp);
/*=============================*/
/* Restore the current module. */
/*=============================*/
RestoreCurrentModule(theEnv);
/*========================================*/
/* Return TRUE to indicate success. */
/*========================================*/
return(TRUE);
}
/*********************************************/
/* InitializeFunctionNeededFlags: Marks each */
/* function in the list of functions as */
/* being unneeded by this binary image. */
/*********************************************/
static void InitializeFunctionNeededFlags(
void *theEnv)
{
struct FunctionDefinition *functionList;
for (functionList = GetFunctionList(theEnv);
functionList != NULL;
functionList = functionList->next)
{ functionList->bsaveIndex = 0; }
}
/**********************************************************/
/* FindNeededItems: Searches through the constructs for */
/* the functions, constraints, or atoms that are needed */
/* by that construct. This routine also counts the */
/* number of expressions in use (through a global). */
/**********************************************************/
static void FindNeededItems(
void *theEnv)
{
struct BinaryItem *biPtr;
for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -