📄 extnfunc.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/02/06 */
/* */
/* EXTERNAL FUNCTION MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Routines for adding new user or system defined */
/* functions. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* Brian L. Donnell */
/* */
/* Revision History: */
/* */
/* 6.24: Corrected code to remove run-time program */
/* compiler warning. */
/* */
/*************************************************************/
#define _EXTNFUNC_SOURCE_
#include "setup.h"
#include <ctype.h>
#include <stdlib.h>
#include "constant.h"
#include "envrnmnt.h"
#include "router.h"
#include "memalloc.h"
#include "evaluatn.h"
#include "extnfunc.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static void AddHashFunction(void *,struct FunctionDefinition *);
static void InitializeFunctionHashTable(void *);
static void DeallocateExternalFunctionData(void *);
#if (! RUN_TIME)
static int RemoveHashFunction(void *,struct FunctionDefinition *);
#endif
/*********************************************************/
/* InitializeExternalFunctionData: Allocates environment */
/* data for external functions. */
/*********************************************************/
globle void InitializeExternalFunctionData(
void *theEnv)
{
AllocateEnvironmentData(theEnv,EXTERNAL_FUNCTION_DATA,sizeof(struct externalFunctionData),DeallocateExternalFunctionData);
}
/***********************************************************/
/* DeallocateExternalFunctionData: Deallocates environment */
/* data for external functions. */
/***********************************************************/
static void DeallocateExternalFunctionData(
void *theEnv)
{
struct FunctionHash *fhPtr, *nextFHPtr;
int i;
#if ! RUN_TIME
struct FunctionDefinition *tmpPtr, *nextPtr;
tmpPtr = ExternalFunctionData(theEnv)->ListOfFunctions;
while (tmpPtr != NULL)
{
nextPtr = tmpPtr->next;
rtn_struct(theEnv,FunctionDefinition,tmpPtr);
tmpPtr = nextPtr;
}
#endif
if (ExternalFunctionData(theEnv)->FunctionHashtable == NULL)
{ return; }
for (i = 0; i < SIZE_FUNCTION_HASH; i++)
{
fhPtr = ExternalFunctionData(theEnv)->FunctionHashtable[i];
while (fhPtr != NULL)
{
nextFHPtr = fhPtr->next;
rtn_struct(theEnv,FunctionHash,fhPtr);
fhPtr = nextFHPtr;
}
}
genfree(theEnv,ExternalFunctionData(theEnv)->FunctionHashtable,
(int) sizeof (struct FunctionHash *) * SIZE_FUNCTION_HASH);
}
#if (! RUN_TIME)
/************************************************************/
/* DefineFunction: Used to define a system or user external */
/* function so that the KB can access it. */
/************************************************************/
#if (! ENVIRONMENT_API_ONLY) && ALLOW_ENVIRONMENT_GLOBALS
globle int DefineFunction(
char *name,
int returnType,
int (*pointer)(void),
char *actualName)
{
void *theEnv;
theEnv = GetCurrentEnvironment();
return(DefineFunction3(theEnv,name,returnType,
(int (*)(void *)) pointer,
actualName,NULL,FALSE));
}
#endif
/***************************************************************/
/* EnvDefineFunction: Used to define a system or user external */
/* function so that the KB can access it. */
/***************************************************************/
globle int EnvDefineFunction(
void *theEnv,
char *name,
int returnType,
int (*pointer)(void *),
char *actualName)
{
return(DefineFunction3(theEnv,name,returnType,pointer,actualName,NULL,TRUE));
}
/*************************************************************/
/* DefineFunction2: Used to define a system or user external */
/* function so that the KB can access it. */
/*************************************************************/
#if (! ENVIRONMENT_API_ONLY) && ALLOW_ENVIRONMENT_GLOBALS
globle int DefineFunction2(
char *name,
int returnType,
int (*pointer)(void),
char *actualName,
char *restrictions)
{
void *theEnv;
theEnv = GetCurrentEnvironment();
return(DefineFunction3(theEnv,name,returnType,
(int (*)(void *)) pointer,
actualName,restrictions,FALSE));
}
#endif
/*************************************************************/
/* EnvDefineFunction2: Used to define a system or user external */
/* function so that the KB can access it. */
/*************************************************************/
globle int EnvDefineFunction2(
void *theEnv,
char *name,
int returnType,
int (*pointer)(void *),
char *actualName,
char *restrictions)
{
return(DefineFunction3(theEnv,name,returnType,pointer,actualName,restrictions,TRUE));
}
/*************************************************************/
/* DefineFunction3: Used to define a system or user external */
/* function so that the KB can access it. Allows argument */
/* restrictions to be attached to the function. */
/* Return types are: */
/* a - external address */
/* b - boolean integer (converted to symbol) */
/* c - character (converted to symbol) */
/* d - double precision float */
/* f - single precision float (converted to double) */
/* i - integer (converted to long integer) */
/* j - unknown (symbol, string, */
/* or instance name by convention) */
/* k - unknown (symbol or string by convention) */
/* l - long integer */
/* m - unknown (multifield by convention) */
/* n - unknown (integer or float by convention) */
/* o - instance name */
/* s - string */
/* u - unknown */
/* v - void */
/* w - symbol */
/* x - instance address */
/*************************************************************/
globle int DefineFunction3(
void *theEnv,
char *name,
int returnType,
int (*pointer)(void *),
char *actualName,
char *restrictions,
intBool environmentAware)
{
struct FunctionDefinition *newFunction;
if ( (returnType != 'a') &&
(returnType != 'b') &&
(returnType != 'c') &&
(returnType != 'd') &&
(returnType != 'f') &&
(returnType != 'i') &&
(returnType != 'j') &&
(returnType != 'k') &&
(returnType != 'l') &&
(returnType != 'm') &&
(returnType != 'n') &&
#if OBJECT_SYSTEM
(returnType != 'o') &&
#endif
(returnType != 's') &&
(returnType != 'u') &&
(returnType != 'v') &&
#if OBJECT_SYSTEM
(returnType != 'x') &&
#endif
(returnType != 'w') )
{ return(0); }
newFunction = FindFunction(theEnv,name);
if (newFunction == NULL)
{
newFunction = get_struct(theEnv,FunctionDefinition);
newFunction->callFunctionName = (SYMBOL_HN *) EnvAddSymbol(theEnv,name);
IncrementSymbolCount(newFunction->callFunctionName);
newFunction->next = GetFunctionList(theEnv);
ExternalFunctionData(theEnv)->ListOfFunctions = newFunction;
AddHashFunction(theEnv,newFunction);
}
newFunction->returnValueType = (char) returnType;
newFunction->functionPointer = (int (*)(void)) pointer;
newFunction->actualFunctionName = actualName;
if (restrictions != NULL)
{
if (((int) (strlen(restrictions)) < 2) ? TRUE :
((! isdigit(restrictions[0]) && (restrictions[0] != '*')) ||
(! isdigit(restrictions[1]) && (restrictions[1] != '*'))))
restrictions = NULL;
}
newFunction->restrictions = restrictions;
newFunction->parser = NULL;
newFunction->overloadable = TRUE;
newFunction->sequenceuseok = TRUE;
newFunction->environmentAware = (short) environmentAware;
newFunction->usrData = NULL;
return(1);
}
/***********************************************/
/* UndefineFunction: Used to remove a function */
/* definition from the list of functions. */
/***********************************************/
globle int UndefineFunction(
void *theEnv,
char *functionName)
{
SYMBOL_HN *findValue;
struct FunctionDefinition *fPtr, *lastPtr = NULL;
findValue = (SYMBOL_HN *) FindSymbolHN(theEnv,functionName);
for (fPtr = ExternalFunctionData(theEnv)->ListOfFunctions;
fPtr != NULL;
fPtr = fPtr->next)
{
if (fPtr->callFunctionName == findValue)
{
DecrementSymbolCount(theEnv,fPtr->callFunctionName);
RemoveHashFunction(theEnv,fPtr);
if (lastPtr == NULL)
{ ExternalFunctionData(theEnv)->ListOfFunctions = fPtr->next; }
else
{ lastPtr->next = fPtr->next; }
ClearUserDataList(theEnv,fPtr->usrData);
rtn_struct(theEnv,FunctionDefinition,fPtr);
return(TRUE);
}
lastPtr = fPtr;
}
return(FALSE);
}
/******************************************/
/* RemoveHashFunction: Removes a function */
/* from the function hash table. */
/******************************************/
static int RemoveHashFunction(
void *theEnv,
struct FunctionDefinition *fdPtr)
{
struct FunctionHash *fhPtr, *lastPtr = NULL;
unsigned hashValue;
hashValue = HashSymbol(ValueToString(fdPtr->callFunctionName),SIZE_FUNCTION_HASH);
for (fhPtr = ExternalFunctionData(theEnv)->FunctionHashtable[hashValue];
fhPtr != NULL;
fhPtr = fhPtr->next)
{
if (fhPtr->fdPtr == fdPtr)
{
if (lastPtr == NULL)
{ ExternalFunctionData(theEnv)->FunctionHashtable[hashValue] = fhPtr->next; }
else
{ lastPtr->next = fhPtr->next; }
rtn_struct(theEnv,FunctionHash,fhPtr);
return(TRUE);
}
lastPtr = fhPtr;
}
return(FALSE);
}
/***************************************************************************/
/* AddFunctionParser: Associates a specialized expression parsing function */
/* with the function entry for a function which was defined using */
/* DefineFunction. When this function is parsed, the specialized parsing */
/* function will be called to parse the arguments of the function. Only */
/* user and system defined functions can have specialized parsing */
/* routines. Generic functions and deffunctions can not have specialized */
/* parsing routines. */
/***************************************************************************/
globle int AddFunctionParser(
void *theEnv,
char *functionName,
struct expr *(*fpPtr)(void *,struct expr *,char *))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -