📄 multifld.c
字号:
{ EphemeralItemCount--; EphemeralItemSize -= sizeof(struct multifield) + (sizeof(struct field) * theSegment->multifieldLength); if (theSegment->multifieldLength == 0) newSize = 1; else newSize = theSegment->multifieldLength; rtn_var_struct2(multifield,sizeof(struct field) * (newSize - 1),theSegment); if (lastPtr == NULL) 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(dst,src) DATA_OBJECT_PTR dst, src; { dst->type = MULTIFIELD; dst->begin = 0; dst->end = src->end - src->begin; dst->value = (VOID *) CreateMultifield2(dst->end + 1); CopyMemory(struct field,dst->end + 1,&((struct multifield *) dst->value)->theFields[0], &((struct multifield *) src->value)->theFields[src->begin]); } /*********************************************************************//* CopyMultifield: *//*********************************************************************/globle VOID *CopyMultifield(src) struct multifield *src; { struct multifield *dst; dst = (struct multifield *) CreateMultifield2(src->multifieldLength); CopyMemory(struct field,src->multifieldLength,&(dst->theFields[0]),&(src->theFields[0])); return((VOID *) dst); } /**********************************************************//* PrintMultifield: Prints out a multifield *//**********************************************************/globle VOID PrintMultifield(fileid,segment,begin,end,printParens) char *fileid; struct multifield *segment; long begin, end; int printParens; { struct field HUGE_ADDR *theMultifield; int i; theMultifield = segment->theFields; if (printParens) PrintCLIPS(fileid,"("); i = begin; while (i <= end) { PrintAtom(fileid,theMultifield[i].type,theMultifield[i].value); i++; if (i <= end) PrintCLIPS(fileid," "); } if (printParens) PrintCLIPS(fileid,")"); }/*****************************************************//* StoreInMultifield: Append function for segments. *//*****************************************************/globle VOID StoreInMultifield(returnValue,expptr,garbageSegment) DATA_OBJECT *returnValue; EXPRESSION *expptr; int garbageSegment; { DATA_OBJECT val_ptr; DATA_OBJECT HUGE_ADDR *val_arr; struct multifield HUGE_ADDR *theMultifield; struct multifield *orig_ptr; long start, end, i,j, k, seg_size, argCount; 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 HUGE_ADDR *) CreateMultifield(0L); else theMultifield = (struct multifield HUGE_ADDR *) CreateMultifield2(0L); SetpValue(returnValue,(VOID *) theMultifield); return; } else { /*========================================*/ /* Get a new segment with length equal to */ /* the total length of all the arguments. */ /*========================================*/ val_arr = (DATA_OBJECT HUGE_ADDR *) gm3((long) sizeof(DATA_OBJECT) * argCount); seg_size = 0; for(i = 1 ; i <= argCount ; i++ , expptr = expptr->nextArg) { EvaluateExpression(expptr,&val_ptr); if (EvaluationError) { SetpType(returnValue,MULTIFIELD); SetpDOBegin(returnValue,1); SetpDOEnd(returnValue,0); if (garbageSegment) { theMultifield = (struct multifield HUGE_ADDR *) CreateMultifield(0L); } else theMultifield = (struct multifield HUGE_ADDR *) CreateMultifield2(0L); SetpValue(returnValue,(VOID *) theMultifield); rm3(val_arr,(long) sizeof(DATA_OBJECT) * argCount); return; } SetpType(val_arr+i-1,GetType(val_ptr)); if (GetType(val_ptr) == MULTIFIELD) { SetpValue(val_arr+i-1,GetpValue(&val_ptr)); start = GetDOBegin(val_ptr); end = GetDOEnd(val_ptr); } else if (GetType(val_ptr) == RVOID) { SetpValue(val_arr+i-1,GetValue(val_ptr)); start = 1; end = 0; } else { SetpValue(val_arr+i-1,GetValue(val_ptr)); start = end = -1; } seg_size += end - start + 1; SetpDOBegin(val_arr+i-1,start); SetpDOEnd(val_arr+i-1,end); } if (garbageSegment) { theMultifield = (struct multifield HUGE_ADDR *) CreateMultifield(seg_size); } else theMultifield = (struct multifield HUGE_ADDR *) CreateMultifield2(seg_size); /*========================================*/ /* Copy each argument into new segment. */ /*========================================*/ for(k=0,j=1; k < argCount;k++) { if (GetpType(val_arr+k) == MULTIFIELD) { start = GetpDOBegin(val_arr+k); end = GetpDOEnd(val_arr+k); orig_ptr = (struct multifield *) GetpValue(val_arr+k); for(i=start; i< end + 1; i++,j++) { SetMFType(theMultifield,j,(GetMFType(orig_ptr,i))); SetMFValue(theMultifield,j,(GetMFValue(orig_ptr,i))); } } else if (GetpType(val_arr+k) != MULTIFIELD) { SetMFType(theMultifield,j,(short) (GetpType(val_arr+k))); SetMFValue(theMultifield,j,(GetpValue(val_arr+k))); j++; } } /*=========================*/ /* Return the new segment. */ /*=========================*/ SetpType(returnValue,MULTIFIELD); SetpDOBegin(returnValue,1); SetpDOEnd(returnValue,seg_size); SetpValue(returnValue,(VOID *) theMultifield); rm3(val_arr,(long) sizeof(DATA_OBJECT) * argCount); return; } }/*************************************************************//* MultifieldDOsEqual: determines if two segments are equal. *//*************************************************************/globle BOOLEAN MultifieldDOsEqual(dobj1,dobj2) DATA_OBJECT_PTR dobj1,dobj2; { long extent1,extent2; /* 6.04 Bug Fix */ FIELD_PTR e1,e2; extent1 = GetpDOLength(dobj1); extent2 = GetpDOLength(dobj2); if (extent1 != extent2) { return(CLIPS_FALSE); } e1 = (FIELD_PTR) GetMFPtr(GetpValue(dobj1),GetpDOBegin(dobj1)); e2 = (FIELD_PTR) GetMFPtr(GetpValue(dobj2),GetpDOBegin(dobj2)); while (extent1 != 0) { if (e1->type != e2->type) { return(CLIPS_FALSE); } if (e1->value != e2->value) { return(CLIPS_FALSE); } extent1--; if (extent1 > 0) { e1++; e2++; } } return(CLIPS_TRUE); }/******************************************************************//* MultifieldsEqual: Determines if two multifields are identical. *//******************************************************************/globle int MultifieldsEqual(segment1,segment2) struct multifield *segment1, *segment2; { struct field HUGE_ADDR *elem1; struct field HUGE_ADDR *elem2; long length, i = 0; /* 6.04 Bug Fix */ length = segment1->multifieldLength; if (length != (int) segment2->multifieldLength) { return(CLIPS_FALSE); } elem1 = segment1->theFields; elem2 = segment2->theFields; /*==================================================*/ /* Compare each field of both facts until the facts */ /* match completely or the facts mismatch. */ /*==================================================*/ while (i < length) { if (elem1[i].type != elem2[i].type) { return(CLIPS_FALSE); } if (elem1[i].type == MULTIFIELD) { if (MultifieldsEqual(elem1[i].value,elem2[i].value) == CLIPS_FALSE) { return(CLIPS_FALSE); } } else if (elem1[i].value != elem2[i].value) { return(CLIPS_FALSE); } i++; } return(CLIPS_TRUE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -