📄 envrnmnt.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 07/01/05 */
/* */
/* ENVIRONMENT MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Routines for supporting multiple environments. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Revision History: */
/* */
/* 6.24: Added code to CreateEnvironment to free */
/* already allocated data if one of the malloc */
/* calls fail. */
/* */
/* Modified AllocateEnvironmentData to print a */
/* message if it was unable to allocate memory. */
/* */
/* Renamed BOOLEAN macro type to intBool. */
/* */
/* Added CreateRuntimeEnvironment function. */
/* */
/* Added support for context information when an */
/* environment is created (i.e a pointer from the */
/* CLIPS environment to its parent environment). */
/* */
/*************************************************************/
#define _ENVRNMNT_SOURCE_
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "setup.h"
#include "memalloc.h"
#include "prntutil.h"
#include "router.h"
#include "engine.h"
#include "sysdep.h"
#include "utility.h"
#include "envrnmnt.h"
#define SIZE_ENVIRONMENT_HASH 131
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if ALLOW_ENVIRONMENT_GLOBALS
static void AddHashedEnvironment(struct environmentData *);
static struct environmentData *FindEnvironment(unsigned long);
static intBool RemoveHashedEnvironment(struct environmentData *);
static void InitializeEnvironmentHashTable(void);
#endif
static void RemoveEnvironmentCleanupFunctions(struct environmentData *);
static void *CreateEnvironmentDriver(struct symbolHashNode **,struct floatHashNode **,
struct integerHashNode **,struct bitMapHashNode **);
/***************************************/
/* LOCAL INTERNAL VARIABLE DEFINITIONS */
/***************************************/
#if ALLOW_ENVIRONMENT_GLOBALS
static unsigned long NextEnvironmentIndex = 0;
static struct environmentData **EnvironmentHashTable = NULL;
static struct environmentData *CurrentEnvironment = NULL;
#endif
/*******************************************************/
/* AllocateEnvironmentData: Allocates environment data */
/* for the specified environment data record. */
/*******************************************************/
globle intBool AllocateEnvironmentData(
void *vtheEnvironment,
unsigned int position,
unsigned long size,
void (*cleanupFunction)(void *))
{
struct environmentData *theEnvironment = (struct environmentData *) vtheEnvironment;
/*===========================================*/
/* Environment data can't be of length zero. */
/*===========================================*/
if (size <= 0)
{
printf("\n[ENVRNMNT1] Environment data position %d allocated with size of 0 or less.\n",position);
return(FALSE);
}
/*================================================================*/
/* Check to see if the data position exceeds the maximum allowed. */
/*================================================================*/
if (position >= MAXIMUM_ENVIRONMENT_POSITIONS)
{
printf("\n[ENVRNMNT2] Environment data position %d exceeds the maximum allowed.\n",position);
return(FALSE);
}
/*============================================================*/
/* Check if the environment data has already been registered. */
/*============================================================*/
if (theEnvironment->theData[position] != NULL)
{
printf("\n[ENVRNMNT3] Environment data position %d already allocated.\n",position);
return(FALSE);
}
/*====================*/
/* Allocate the data. */
/*====================*/
theEnvironment->theData[position] = malloc(size);
if (theEnvironment->theData[position] == NULL)
{
printf("\n[ENVRNMNT4] Environment data position %d could not be allocated.\n",position);
return(FALSE);
}
memset(theEnvironment->theData[position],0,size);
/*=============================*/
/* Store the cleanup function. */
/*=============================*/
theEnvironment->cleanupFunctions[position] = cleanupFunction;
/*===============================*/
/* Data successfully registered. */
/*===============================*/
return(TRUE);
}
/***************************************************************/
/* DeallocateEnvironmentData: Deallocates all environments */
/* stored in the environment hash table and then deallocates */
/* the environment hash table. */
/***************************************************************/
globle intBool DeallocateEnvironmentData()
{
#if ALLOW_ENVIRONMENT_GLOBALS
struct environmentData *theEnvironment, *nextEnvironment;
int i, rv = TRUE;
for (i = 0; i < SIZE_ENVIRONMENT_HASH; i++)
{
for (theEnvironment = EnvironmentHashTable[i];
theEnvironment != NULL;
)
{
nextEnvironment = theEnvironment->next;
if (! DestroyEnvironment(theEnvironment))
{ rv = FALSE; }
theEnvironment = nextEnvironment;
}
}
free(EnvironmentHashTable);
return(rv);
#else
return(FALSE);
#endif
}
#if ALLOW_ENVIRONMENT_GLOBALS
/*********************************************************/
/* InitializeEnvironmentHashTable: Initializes the table */
/* entries in the environment hash table to NULL. */
/*********************************************************/
static void InitializeEnvironmentHashTable()
{
int i;
if (EnvironmentHashTable != NULL)
{ return; }
EnvironmentHashTable = (struct environmentData **)
malloc(sizeof (struct environmentData *) * SIZE_ENVIRONMENT_HASH);
if (EnvironmentHashTable == NULL)
{
printf("\n[ENVRNMNT4] Unable to initialize environment hash table.\n");
return;
}
for (i = 0; i < SIZE_ENVIRONMENT_HASH; i++) EnvironmentHashTable[i] = NULL;
}
/*********************************************/
/* AddHashedEnvironment: Adds an environment */
/* entry to the environment hash table. */
/*********************************************/
static void AddHashedEnvironment(
struct environmentData *theEnvironment)
{
struct environmentData *temp;
unsigned long hashValue;
if (EnvironmentHashTable == NULL)
{ InitializeEnvironmentHashTable(); }
hashValue = theEnvironment->environmentIndex % SIZE_ENVIRONMENT_HASH;
temp = EnvironmentHashTable[hashValue];
EnvironmentHashTable[hashValue] = theEnvironment;
theEnvironment->next = temp;
}
/***************************************************/
/* RemoveHashedEnvironment: Removes an environment */
/* entry from the environment hash table. */
/***************************************************/
static intBool RemoveHashedEnvironment(
struct environmentData *theEnvironment)
{
unsigned long hashValue;
struct environmentData *hptr, *prev;
hashValue = theEnvironment->environmentIndex % SIZE_ENVIRONMENT_HASH;
for (hptr = EnvironmentHashTable[hashValue], prev = NULL;
hptr != NULL;
hptr = hptr->next)
{
if (hptr == theEnvironment)
{
if (prev == NULL)
{
EnvironmentHashTable[hashValue] = hptr->next;
return(TRUE);
}
else
{
prev->next = hptr->next;
return(TRUE);
}
}
prev = hptr;
}
return(FALSE);
}
/**********************************************************/
/* FindEnvironment: Determines if a specified environment */
/* index has an entry in the environment hash table. */
/**********************************************************/
static struct environmentData *FindEnvironment(
unsigned long environmentIndex)
{
struct environmentData *theEnvironment;
unsigned long hashValue;
hashValue = environmentIndex % SIZE_ENVIRONMENT_HASH;
for (theEnvironment = EnvironmentHashTable[hashValue];
theEnvironment != NULL;
theEnvironment = theEnvironment->next)
{
if (theEnvironment->environmentIndex == environmentIndex)
{ return(theEnvironment); }
}
return(NULL);
}
#endif
/************************************************************/
/* CreateEnvironment: Creates an environment data structure */
/* and initializes its content to zero/null. */
/************************************************************/
globle void *CreateEnvironment()
{
return CreateEnvironmentDriver(NULL,NULL,NULL,NULL);
}
/**********************************************************/
/* CreateRuntimeEnvironment: Creates an environment data */
/* structure and initializes its content to zero/null. */
/**********************************************************/
globle void *CreateRuntimeEnvironment(
struct symbolHashNode **symbolTable,
struct floatHashNode **floatTable,
struct integerHashNode **integerTable,
struct bitMapHashNode **bitmapTable)
{
return CreateEnvironmentDriver(symbolTable,floatTable,integerTable,bitmapTable);
}
/*********************************************************/
/* CreateEnvironmentDriver: Creates an environment data */
/* structure and initializes its content to zero/null. */
/*********************************************************/
globle void *CreateEnvironmentDriver(
struct symbolHashNode **symbolTable,
struct floatHashNode **floatTable,
struct integerHashNode **integerTable,
struct bitMapHashNode **bitmapTable)
{
struct environmentData *theEnvironment;
void *theData;
theEnvironment = (struct environmentData *) malloc(sizeof(struct environmentData));
if (theEnvironment == NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -