📄 multifld.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/05/06 */
/* */
/* MULTIFIELD MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* Brian L. Donnell */
/* */
/* Revision History: */
/* */
/* 6.24: Renamed BOOLEAN macro type to intBool. */
/* */
/* Corrected code to remove compiler warnings. */
/* */
/* Moved ImplodeMultifield from multifun.c. */
/* */
/*************************************************************/
#define _MULTIFLD_SOURCE_
#include <stdio.h>
#define _STDIO_INCLUDED_
#include "setup.h"
#include "constant.h"
#include "memalloc.h"
#include "envrnmnt.h"
#include "evaluatn.h"
#include "scanner.h"
#include "router.h"
#include "strngrtr.h"
#include "utility.h"
#if OBJECT_SYSTEM
#include "object.h"
#endif
#include "multifld.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static void DeallocateMultifieldData(void *);
/***************************************************/
/* InitializeMultifieldData: Allocates environment */
/* data for multifield values. */
/***************************************************/
globle void InitializeMultifieldData(
void *theEnv)
{
AllocateEnvironmentData(theEnv,MULTIFIELD_DATA,sizeof(struct multifieldData),DeallocateMultifieldData);
}
/*****************************************************/
/* DeallocateMultifieldData: Deallocates environment */
/* data for multifield values. */
/*****************************************************/
static void DeallocateMultifieldData(
void *theEnv)
{
struct multifield *tmpPtr, *nextPtr;
tmpPtr = MultifieldData(theEnv)->ListOfMultifields;
while (tmpPtr != NULL)
{
nextPtr = tmpPtr->next;
ReturnMultifield(theEnv,tmpPtr);
tmpPtr = nextPtr;
}
}
/***********************************************************/
/* CreateMultifield2: */
/***********************************************************/
globle void *CreateMultifield2(
void *theEnv,
unsigned long size)
{
struct multifield *theSegment;
unsigned long newSize = size;
if (size <= 0) newSize = 1;
theSegment = get_var_struct2(theEnv,multifield,(long) sizeof(struct field) * (newSize - 1L));
theSegment->multifieldLength = size;
theSegment->depth = (short) EvaluationData(theEnv)->CurrentEvaluationDepth;
theSegment->busyCount = 0;
theSegment->next = NULL;
return((void *) theSegment);
}
/*****************************************************************/
/* ReturnMultifield: */
/*****************************************************************/
globle void ReturnMultifield(
void *theEnv,
struct multifield *theSegment)
{
unsigned long newSize;
if (theSegment == NULL) return;
if (theSegment->multifieldLength == 0) newSize = 1;
else newSize = theSegment->multifieldLength;
rtn_var_struct2(theEnv,multifield,sizeof(struct field) * (newSize - 1),theSegment);
}
/******************************/
/* MultifieldInstall: */
/******************************/
globle void MultifieldInstall(
void *theEnv,
struct multifield *theSegment)
{
unsigned long length, i;
struct field *theFields;
if (theSegment == NULL) return;
length = theSegment->multifieldLength;
theSegment->busyCount++;
theFields = theSegment->theFields;
for (i = 0 ; i < length ; i++)
{ AtomInstall(theEnv,theFields[i].type,theFields[i].value); }
}
/******************************/
/* MultifieldDeinstall: */
/******************************/
globle void MultifieldDeinstall(
void *theEnv,
struct multifield *theSegment)
{
unsigned long length, i;
struct field *theFields;
if (theSegment == NULL) return;
length = theSegment->multifieldLength;
theSegment->busyCount--;
theFields = theSegment->theFields;
for (i = 0 ; i < length ; i++)
{ AtomDeinstall(theEnv,theFields[i].type,theFields[i].value); }
}
/*******************************************************/
/* StringToMultifield: Returns a multifield structure */
/* that represents the string sent as the argument. */
/*******************************************************/
globle struct multifield *StringToMultifield(
void *theEnv,
char *theString)
{
struct token theToken;
struct multifield *theSegment;
struct field *theFields;
unsigned long numberOfFields = 0;
struct expr *topAtom = NULL, *lastAtom = NULL, *theAtom;
/*====================================================*/
/* Open the string as an input source and read in the */
/* list of values to be stored in the multifield. */
/*====================================================*/
OpenStringSource(theEnv,"multifield-str",theString,0);
GetToken(theEnv,"multifield-str",&theToken);
while (theToken.type != STOP)
{
if ((theToken.type == SYMBOL) || (theToken.type == STRING) ||
(theToken.type == FLOAT) || (theToken.type == INTEGER) ||
(theToken.type == INSTANCE_NAME))
{ theAtom = GenConstant(theEnv,theToken.type,theToken.value); }
else
{ theAtom = GenConstant(theEnv,STRING,EnvAddSymbol(theEnv,theToken.printForm)); }
numberOfFields++;
if (topAtom == NULL) topAtom = theAtom;
else lastAtom->nextArg = theAtom;
lastAtom = theAtom;
GetToken(theEnv,"multifield-str",&theToken);
}
CloseStringSource(theEnv,"multifield-str");
/*====================================================================*/
/* Create a multifield of the appropriate size for the values parsed. */
/*====================================================================*/
theSegment = (struct multifield *) EnvCreateMultifield(theEnv,numberOfFields);
theFields = theSegment->theFields;
/*====================================*/
/* Copy the values to the multifield. */
/*====================================*/
theAtom = topAtom;
numberOfFields = 0;
while (theAtom != NULL)
{
theFields[numberOfFields].type = theAtom->type;
theFields[numberOfFields].value = theAtom->value;
numberOfFields++;
theAtom = theAtom->nextArg;
}
/*===========================*/
/* Return the parsed values. */
/*===========================*/
ReturnExpression(theEnv,topAtom);
/*============================*/
/* Return the new multifield. */
/*============================*/
return(theSegment);
}
/**************************************************************/
/* EnvCreateMultifield: Creates a multifield of the specified */
/* size and adds it to the list of segments. */
/**************************************************************/
globle void *EnvCreateMultifield(
void *theEnv,
unsigned long size)
{
struct multifield *theSegment;
unsigned long newSize;
if (size <= 0) newSize = 1;
else newSize = size;
theSegment = get_var_struct2(theEnv,multifield,(long) sizeof(struct field) * (newSize - 1L));
theSegment->multifieldLength = size;
theSegment->depth = (short) EvaluationData(theEnv)->CurrentEvaluationDepth;
theSegment->busyCount = 0;
theSegment->next = NULL;
theSegment->next = MultifieldData(theEnv)->ListOfMultifields;
MultifieldData(theEnv)->ListOfMultifields = theSegment;
UtilityData(theEnv)->EphemeralItemCount++;
UtilityData(theEnv)->EphemeralItemSize += sizeof(struct multifield) + (sizeof(struct field) * newSize);
return((void *) theSegment);
}
/*********************************************************************/
/* DOToMultifield: */
/*********************************************************************/
globle void *DOToMultifield(
void *theEnv,
DATA_OBJECT *theValue)
{
struct multifield *dst, *src;
if (theValue->type != MULTIFIELD) return(NULL);
dst = (struct multifield *) CreateMultifield2(theEnv,(unsigned long) GetpDOLength(theValue));
src = (struct multifield *) theValue->value;
GenCopyMemory(struct field,dst->multifieldLength,
&(dst->theFields[0]),&(src->theFields[GetpDOBegin(theValue) - 1]));
return((void *) dst);
}
/***********************************************************/
/* AddToMultifieldList: */
/***********************************************************/
globle void AddToMultifieldList(
void *theEnv,
struct multifield *theSegment)
{
theSegment->depth = (short) EvaluationData(theEnv)->CurrentEvaluationDepth;
theSegment->next = MultifieldData(theEnv)->ListOfMultifields;
MultifieldData(theEnv)->ListOfMultifields = theSegment;
UtilityData(theEnv)->EphemeralItemCount++;
UtilityData(theEnv)->EphemeralItemSize += sizeof(struct multifield) + (sizeof(struct field) * theSegment->multifieldLength);
}
/***********************************************************/
/* FlushMultifields: */
/***********************************************************/
globle void FlushMultifields(
void *theEnv)
{
struct multifield *theSegment, *nextPtr, *lastPtr = NULL;
unsigned long newSize;
theSegment = MultifieldData(theEnv)->ListOfMultifields;
while (theSegment != NULL)
{
nextPtr = theSegment->next;
if ((theSegment->depth > EvaluationData(theEnv)->CurrentEvaluationDepth) && (theSegment->busyCount == 0))
{
UtilityData(theEnv)->EphemeralItemCount--;
UtilityData(theEnv)->EphemeralItemSize -= sizeof(struct multifield) +
(sizeof(struct field) * theSegment->multifieldLength);
if (theSegment->multifieldLength == 0) newSize = 1;
else newSize = theSegment->multifieldLength;
rtn_var_struct2(theEnv,multifield,sizeof(struct field) * (newSize - 1),theSegment);
if (lastPtr == NULL) MultifieldData(theEnv)->ListOfMultifields = nextPtr;
else lastPtr->next = nextPtr;
}
else
{ lastPtr = theSegment; }
theSegment = nextPtr;
}
}
/*********************************************************************/
/* DuplicateMultifield: Allocates a new segment and copies results from */
/* old value to new - NOT put on ListOfMultifields!! */
/*********************************************************************/
globle void DuplicateMultifield(
void *theEnv,
DATA_OBJECT_PTR dst,
DATA_OBJECT_PTR src)
{
dst->type = MULTIFIELD;
dst->begin = 0;
dst->end = src->end - src->begin;
dst->value = (void *) CreateMultifield2(theEnv,(unsigned long) dst->end + 1);
GenCopyMemory(struct field,dst->end + 1,&((struct multifield *) dst->value)->theFields[0],
&((struct multifield *) src->value)->theFields[src->begin]);
}
/*********************************************************************/
/* CopyMultifield: */
/*********************************************************************/
globle void *CopyMultifield(
void *theEnv,
struct multifield *src)
{
struct multifield *dst;
dst = (struct multifield *) CreateMultifield2(theEnv,src->multifieldLength);
GenCopyMemory(struct field,src->multifieldLength,&(dst->theFields[0]),&(src->theFields[0]));
return((void *) dst);
}
/**********************************************************/
/* PrintMultifield: Prints out a multifield */
/**********************************************************/
globle void PrintMultifield(
void *theEnv,
char *fileid,
struct multifield *segment,
long begin,
long end,
int printParens)
{
struct field *theMultifield;
int i;
theMultifield = segment->theFields;
if (printParens)
EnvPrintRouter(theEnv,fileid,"(");
i = begin;
while (i <= end)
{
PrintAtom(theEnv,fileid,theMultifield[i].type,theMultifield[i].value);
i++;
if (i <= end) EnvPrintRouter(theEnv,fileid," ");
}
if (printParens)
EnvPrintRouter(theEnv,fileid,")");
}
/*****************************************************/
/* StoreInMultifield: Append function for segments. */
/*****************************************************/
globle void StoreInMultifield(
void *theEnv,
DATA_OBJECT *returnValue,
EXPRESSION *expptr,
int garbageSegment)
{
DATA_OBJECT val_ptr;
DATA_OBJECT *val_arr;
struct multifield *theMultifield;
struct multifield *orig_ptr;
long start, end, i,j, k, argCount;
unsigned long seg_size;
argCount = CountArguments(expptr);
/*=========================================*/
/* If no arguments are given return a NULL */
/* multifield of length zero. */
/*=========================================*/
if (argCount == 0)
{
SetpType(returnValue,MULTIFIELD);
SetpDOBegin(returnValue,1);
SetpDOEnd(returnValue,0);
if (garbageSegment) theMultifield = (struct multifield *) EnvCreateMultifield(theEnv,0L);
else theMultifield = (struct multifield *) CreateMultifield2(theEnv,0L);
SetpValue(returnValue,(void *) theMultifield);
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -