📄 multifun.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/05/06 */
/* */
/* MULTIFIELD FUNCTIONS MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Contains the code for several multifield */
/* functions including first$, rest$, subseq$, delete$, */
/* delete-member$, replace-member$ */
/* replace$, insert$, explode$, implode$, nth$, member$, */
/* subsetp, progn$, str-implode, str-explode, subset, nth, */
/* mv-replace, member, mv-subseq, and mv-delete. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* Brian Donnell */
/* Barry Cameron */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
/* */
/* Changed name of variable exp to theExp */
/* because of Unix compiler warnings of shadowed */
/* definitions. */
/* */
/* 6.24: Renamed BOOLEAN macro type to intBool. */
/* */
/* Moved ImplodeMultifield to multifld.c. */
/* */
/*************************************************************/
#define _MULTIFUN_SOURCE_
#include "setup.h"
#if MULTIFIELD_FUNCTIONS || OBJECT_SYSTEM
#include <stdio.h>
#define _STDIO_INCLUDED_
#include <string.h>
#include "argacces.h"
#include "envrnmnt.h"
#include "exprnpsr.h"
#include "memalloc.h"
#include "multifld.h"
#include "multifun.h"
#include "prcdrpsr.h"
#include "prcdrfun.h"
#include "router.h"
#if (! BLOAD_ONLY) && (! RUN_TIME)
#include "scanner.h"
#endif
#include "utility.h"
#if OBJECT_SYSTEM
#include "object.h"
#endif
/**************/
/* STRUCTURES */
/**************/
typedef struct fieldVarStack
{
unsigned short type;
void *value;
long index;
struct fieldVarStack *nxt;
} FIELD_VAR_STACK;
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if MULTIFIELD_FUNCTIONS
static intBool MVRangeCheck(long,long,long *,int);
#if (! BLOAD_ONLY) && (! RUN_TIME)
static struct expr *MultifieldPrognParser(void *,struct expr *,char *);
static void ReplaceMvPrognFieldVars(void *,SYMBOL_HN *,struct expr *,int);
#endif
#endif
static void MVRangeError(void *,long,long,unsigned long,char *);
#endif
/***************************************/
/* LOCAL INTERNAL VARIABLE DEFINITIONS */
/***************************************/
#if MULTIFIELD_FUNCTIONS
#define MULTIFUN_DATA 10
struct multiFunctionData
{
FIELD_VAR_STACK *FieldVarStack;
};
#define MultiFunctionData(theEnv) ((struct multiFunctionData *) GetEnvironmentData(theEnv,MULTIFUN_DATA))
/**********************************************/
/* MultifieldFunctionDefinitions: Initializes */
/* the multifield functions. */
/**********************************************/
globle void MultifieldFunctionDefinitions(
void *theEnv)
{
AllocateEnvironmentData(theEnv,MULTIFUN_DATA,sizeof(struct multiFunctionData),NULL);
#if ! RUN_TIME
EnvDefineFunction2(theEnv,"first$", 'm', PTIEF FirstFunction, "FirstFunction", "11m");
EnvDefineFunction2(theEnv,"rest$", 'm', PTIEF RestFunction, "RestFunction", "11m");
EnvDefineFunction2(theEnv,"subseq$", 'm', PTIEF SubseqFunction, "SubseqFunction", "33im");
EnvDefineFunction2(theEnv,"delete-member$", 'm', PTIEF DeleteMemberFunction, "DeleteMemberFunction", "2*um");
EnvDefineFunction2(theEnv,"replace-member$", 'm', PTIEF ReplaceMemberFunction, "ReplaceMemberFunction","3*um");
EnvDefineFunction2(theEnv,"delete$", 'm', PTIEF DeleteFunction, "DeleteFunction", "33im");
EnvDefineFunction2(theEnv,"replace$", 'm', PTIEF ReplaceFunction, "ReplaceFunction","4**mii");
EnvDefineFunction2(theEnv,"insert$", 'm', PTIEF InsertFunction, "InsertFunction", "3**mi");
EnvDefineFunction2(theEnv,"explode$", 'm', PTIEF ExplodeFunction, "ExplodeFunction", "11s");
EnvDefineFunction2(theEnv,"implode$", 's', PTIEF ImplodeFunction, "ImplodeFunction", "11m");
EnvDefineFunction2(theEnv,"nth$", 'u', PTIEF NthFunction, "NthFunction", "22*im");
EnvDefineFunction2(theEnv,"member$", 'u', PTIEF MemberFunction, "MemberFunction", "22*um");
EnvDefineFunction2(theEnv,"subsetp", 'b', PTIEF SubsetpFunction, "SubsetpFunction", "22*mm");
EnvDefineFunction2(theEnv,"progn$", 'u', PTIEF MultifieldPrognFunction, "MultifieldPrognFunction", NULL);
EnvDefineFunction2(theEnv,"str-implode", 's', PTIEF ImplodeFunction, "ImplodeFunction", "11m");
EnvDefineFunction2(theEnv,"str-explode", 'm', PTIEF ExplodeFunction, "ExplodeFunction", "11s");
EnvDefineFunction2(theEnv,"subset", 'b', PTIEF SubsetpFunction, "SubsetpFunction", "22*mm");
EnvDefineFunction2(theEnv,"nth", 'u', PTIEF NthFunction, "NthFunction", "22*im");
EnvDefineFunction2(theEnv,"mv-replace", 'm', PTIEF MVReplaceFunction, "MVReplaceFunction","33*im");
EnvDefineFunction2(theEnv,"member", 'u', PTIEF MemberFunction, "MemberFunction", "22*um");
EnvDefineFunction2(theEnv,"mv-subseq", 'm', PTIEF MVSubseqFunction, "MVSubseqFunction", "33*iim");
EnvDefineFunction2(theEnv,"mv-delete", 'm', PTIEF MVDeleteFunction,"MVDeleteFunction", "22*im");
#if ! BLOAD_ONLY
AddFunctionParser(theEnv,"progn$",MultifieldPrognParser);
#endif
FuncSeqOvlFlags(theEnv,"progn$",FALSE,FALSE);
EnvDefineFunction2(theEnv,"(get-progn$-field)", 'u', PTIEF GetMvPrognField, "GetMvPrognField", "00");
EnvDefineFunction2(theEnv,"(get-progn$-index)", 'l', PTIEF GetMvPrognIndex, "GetMvPrognIndex", "00");
#endif
}
/****************************************/
/* DeleteFunction: H/L access routine */
/* for the delete$ function. */
/****************************************/
globle void DeleteFunction(
void *theEnv,
DATA_OBJECT_PTR returnValue)
{
DATA_OBJECT value1, value2, value3;
/*=======================================*/
/* Check for the correct argument types. */
/*=======================================*/
if ((EnvArgTypeCheck(theEnv,"delete$",1,MULTIFIELD,&value1) == FALSE) ||
(EnvArgTypeCheck(theEnv,"delete$",2,INTEGER,&value2) == FALSE) ||
(EnvArgTypeCheck(theEnv,"delete$",3,INTEGER,&value3) == FALSE))
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
/*=================================================*/
/* Delete the section out of the multifield value. */
/*=================================================*/
if (DeleteMultiValueField(theEnv,returnValue,&value1,
DOToLong(value2),DOToLong(value3),"delete$") == FALSE)
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
}
}
/******************************************/
/* MVDeleteFunction: H/L access routine */
/* for the mv-delete function. */
/******************************************/
globle void MVDeleteFunction(
void *theEnv,
DATA_OBJECT_PTR returnValue)
{
DATA_OBJECT value1, value2;
/*=======================================*/
/* Check for the correct argument types. */
/*=======================================*/
if ((EnvArgTypeCheck(theEnv,"mv-delete",1,INTEGER,&value1) == FALSE) ||
(EnvArgTypeCheck(theEnv,"mv-delete",2,MULTIFIELD,&value2) == FALSE))
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
/*=================================================*/
/* Delete the section out of the multifield value. */
/*=================================================*/
if (DeleteMultiValueField(theEnv,returnValue,&value2,
DOToLong(value1),DOToLong(value1),"mv-delete") == FALSE)
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
}
}
/*****************************************/
/* ReplaceFunction: H/L access routine */
/* for the replace$ function. */
/*****************************************/
globle void ReplaceFunction(
void *theEnv,
DATA_OBJECT_PTR returnValue)
{
DATA_OBJECT value1, value2, value3, value4;
EXPRESSION *fieldarg;
/*=======================================*/
/* Check for the correct argument types. */
/*=======================================*/
if ((EnvArgTypeCheck(theEnv,"replace$",1,MULTIFIELD,&value1) == FALSE) ||
(EnvArgTypeCheck(theEnv,"replace$",2,INTEGER,&value2) == FALSE) ||
(EnvArgTypeCheck(theEnv,"replace$",3,INTEGER,&value3) == FALSE))
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
/*===============================*/
/* Create the replacement value. */
/*===============================*/
fieldarg = GetFirstArgument()->nextArg->nextArg->nextArg;
if (fieldarg->nextArg != NULL)
{ StoreInMultifield(theEnv,&value4,fieldarg,TRUE); }
else
{ EvaluateExpression(theEnv,fieldarg,&value4); }
/*==============================================*/
/* Replace the section in the multifield value. */
/*==============================================*/
if (ReplaceMultiValueField(theEnv,returnValue,&value1,DOToInteger(value2),
DOToInteger(value3),&value4,"replace$") == FALSE)
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
}
}
/*******************************************/
/* MVReplaceFunction: H/L access routine */
/* for the mv-replace function. */
/*******************************************/
globle void MVReplaceFunction(
void *theEnv,
DATA_OBJECT_PTR returnValue)
{
DATA_OBJECT value1, value2, value3;
/*=======================================*/
/* Check for the correct argument types. */
/*=======================================*/
if ((EnvArgTypeCheck(theEnv,"mv-replace",1,INTEGER,&value1) == FALSE) ||
(EnvArgTypeCheck(theEnv,"mv-replace",2,MULTIFIELD,&value2) == FALSE))
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
/*===============================*/
/* Create the replacement value. */
/*===============================*/
EvaluateExpression(theEnv,GetFirstArgument()->nextArg->nextArg,&value3);
/*==============================================*/
/* Replace the section in the multifield value. */
/*==============================================*/
if (ReplaceMultiValueField(theEnv,returnValue,&value2,DOToInteger(value1),
DOToInteger(value1),&value3,"mv-replace") == FALSE)
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
}
}
/**********************************************/
/* DeleteMemberFunction: H/L access routine */
/* for the delete-member$ function. */
/**********************************************/
globle void DeleteMemberFunction(
void *theEnv,
DATA_OBJECT_PTR returnValue)
{
DATA_OBJECT resultValue,*delVals,tmpVal;
int i,argCnt;
unsigned delSize;
long j,k;
/*============================================*/
/* Check for the correct number of arguments. */
/*============================================*/
argCnt = EnvArgCountCheck(theEnv,"delete-member$",AT_LEAST,2);
if (argCnt == -1)
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
/*=======================================*/
/* Check for the correct argument types. */
/*=======================================*/
if (EnvArgTypeCheck(theEnv,"delete-member$",1,MULTIFIELD,&resultValue) == FALSE)
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
/*=================================================
For every value specified, delete all occurrences
of those values from the multifield
================================================= */
delSize = (sizeof(DATA_OBJECT) * (argCnt-1));
delVals = (DATA_OBJECT_PTR) gm2(theEnv,delSize);
for (i = 2 ; i <= argCnt ; i++)
{
if (!EnvRtnUnknown(theEnv,i,&delVals[i-2]))
{
rm(theEnv,(void *) delVals,delSize);
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
}
while (FindDOsInSegment(delVals,argCnt-1,&resultValue,&j,&k,NULL,0))
{
if (DeleteMultiValueField(theEnv,&tmpVal,&resultValue,
j,k,"delete-member$") == FALSE)
{
rm(theEnv,(void *) delVals,delSize);
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
GenCopyMemory(DATA_OBJECT,1,&resultValue,&tmpVal);
}
rm(theEnv,(void *) delVals,delSize);
GenCopyMemory(DATA_OBJECT,1,returnValue,&resultValue);
}
/***********************************************/
/* ReplaceMemberFunction: H/L access routine */
/* for the replace-member$ function. */
/***********************************************/
globle void ReplaceMemberFunction(
void *theEnv,
DATA_OBJECT_PTR returnValue)
{
DATA_OBJECT resultValue,replVal,*delVals,tmpVal;
int i,argCnt;
unsigned delSize;
long j,k,mink[2],*minkp;
long replLen = 1L;
/*============================================*/
/* Check for the correct number of arguments. */
/*============================================*/
argCnt = EnvArgCountCheck(theEnv,"replace-member$",AT_LEAST,3);
if (argCnt == -1)
{
SetEvaluationError(theEnv,TRUE);
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -