envrnmnt.c

来自「clips源代码」· C语言 代码 · 共 672 行 · 第 1/2 页

C
672
字号
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.30  10/19/06            */   /*                                                     */   /*                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).  *//*                                                           *//*      6.30: Added support for passing context information  */ /*            to user defined functions.                     *//*                                                           *//*************************************************************/#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)     {      printf("\n[ENVRNMNT5] Unable to create new environment.\n");      return(NULL);     }   theData = malloc(sizeof(void *) * MAXIMUM_ENVIRONMENT_POSITIONS);      if (theData == NULL)     {      free(theEnvironment);      printf("\n[ENVRNMNT6] Unable to create environment data.\n");      return(NULL);     }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?