?? multifld.c
字號(hào):
/*******************************************************/ /* "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, long size) { struct multifield *theSegment; long newSize = size; if (size <= 0) newSize = 1; theSegment = get_var_struct(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_struct(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, long size) { struct multifield *theSegment; long newSize; if (size <= 0) newSize = 1; else newSize = size; theSegment = get_var_struct(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_struct(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; }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -