📄 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,long,char *);#endif/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/#if MULTIFIELD_FUNCTIONS#define MULTIFUN_DATA 10struct 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, (long) DOToLong(value2),(long) DOToLong(value3),"delete$") == FALSE)/* TBD */ { 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, (long) DOToLong(value1),(long) DOToLong(value1),"mv-delete") == FALSE) /* TBD */ { 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,(long) DOToLong(value2), (long) DOToLong(value3),&value4,"replace$") == FALSE) /* TBD */ { 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,(long) DOToLong(value1), (long) DOToLong(value1),&value3,"mv-replace") == FALSE) /* TBD */ { 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 + -