📄 multifld.c
字号:
}
else
{
/*========================================*/
/* Get a new segment with length equal to */
/* the total length of all the arguments. */
/*========================================*/
val_arr = (DATA_OBJECT *) gm3(theEnv,(long) sizeof(DATA_OBJECT) * argCount);
seg_size = 0;
for(i = 1 ; i <= argCount ; i++ , expptr = expptr->nextArg)
{
EvaluateExpression(theEnv,expptr,&val_ptr);
if (EvaluationData(theEnv)->EvaluationError)
{
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);
rm3(theEnv,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 += (unsigned long) (end - start + 1);
SetpDOBegin(val_arr+i-1,start);
SetpDOEnd(val_arr+i-1,end);
}
if (garbageSegment)
{ theMultifield = (struct multifield *) EnvCreateMultifield(theEnv,seg_size); }
else theMultifield = (struct multifield *) CreateMultifield2(theEnv,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,(long) seg_size);
SetpValue(returnValue,(void *) theMultifield);
rm3(theEnv,val_arr,(long) sizeof(DATA_OBJECT) * argCount);
return;
}
}
/*************************************************************/
/* MultifieldDOsEqual: determines if two segments are equal. */
/*************************************************************/
globle intBool MultifieldDOsEqual(
DATA_OBJECT_PTR dobj1,
DATA_OBJECT_PTR dobj2)
{
long extent1,extent2; /* 6.04 Bug Fix */
FIELD_PTR e1,e2;
extent1 = GetpDOLength(dobj1);
extent2 = GetpDOLength(dobj2);
if (extent1 != extent2)
{ return(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(FALSE); }
if (e1->value != e2->value)
{ return(FALSE); }
extent1--;
if (extent1 > 0)
{
e1++;
e2++;
}
}
return(TRUE);
}
/******************************************************************/
/* MultifieldsEqual: Determines if two multifields are identical. */
/******************************************************************/
globle int MultifieldsEqual(
struct multifield *segment1,
struct multifield *segment2)
{
struct field *elem1;
struct field *elem2;
unsigned long length, i = 0;
length = segment1->multifieldLength;
if (length != segment2->multifieldLength)
{ return(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(FALSE); }
if (elem1[i].type == MULTIFIELD)
{
if (MultifieldsEqual((struct multifield *) elem1[i].value,
(struct multifield *) elem2[i].value) == FALSE)
{ return(FALSE); }
}
else if (elem1[i].value != elem2[i].value)
{ return(FALSE); }
i++;
}
return(TRUE);
}
/************************************************************/
/* HashMultifield: Returns the hash value for a multifield. */
/************************************************************/
unsigned HashMultifield(
struct multifield *theSegment,
unsigned theRange)
{
unsigned long length, i;
unsigned int tvalue;
unsigned int count;
struct field *fieldPtr;
union
{
double fv;
unsigned int liv;
} fis;
/*================================================*/
/* Initialize variables for computing hash value. */
/*================================================*/
count = 0;
length = theSegment->multifieldLength;
fieldPtr = theSegment->theFields;
/*====================================================*/
/* Loop through each value in the multifield, compute */
/* its hash value, and add it to the running total. */
/*====================================================*/
for (i = 0;
i < length;
i++)
{
switch(fieldPtr[i].type)
{
case MULTIFIELD:
count += HashMultifield((struct multifield *) fieldPtr[i].value,theRange);
break;
case FLOAT:
fis.fv = ValueToDouble(fieldPtr[i].value);
count += (fis.liv * (i + 29)) +
(int) ValueToDouble(fieldPtr[i].value);
break;
case INTEGER:
count += (((int) ValueToLong(fieldPtr[i].value)) * (i + 29)) +
ValueToLong(fieldPtr[i].value);
break;
case FACT_ADDRESS:
case EXTERNAL_ADDRESS:
#if OBJECT_SYSTEM
case INSTANCE_ADDRESS:
#endif
count += (unsigned int) (((int) fieldPtr[i].value) * (i + 29));
break;
case SYMBOL:
case STRING:
#if OBJECT_SYSTEM
case INSTANCE_NAME:
#endif
tvalue = (unsigned) HashSymbol(ValueToString(fieldPtr[i].value),theRange);
count += (unsigned) (tvalue * (i + 29));
break;
}
}
/*========================*/
/* Return the hash value. */
/*========================*/
return(count);
}
/**********************/
/* GetMultifieldList: */
/**********************/
globle struct multifield *GetMultifieldList(
void *theEnv)
{
return(MultifieldData(theEnv)->ListOfMultifields);
}
/***************************************/
/* ImplodeMultifield: C access routine */
/* for the implode$ function. */
/***************************************/
globle void *ImplodeMultifield(
void *theEnv,
DATA_OBJECT *value)
{
unsigned strsize = 0;
long i, j;
char *tmp_str;
char *ret_str;
void *rv;
struct multifield *theMultifield;
/*===================================================*/
/* Determine the size of the string to be allocated. */
/*===================================================*/
theMultifield = (struct multifield *) GetpValue(value);
for (i = GetpDOBegin(value) ; i <= GetpDOEnd(value) ; i++)
{
if (GetMFType(theMultifield,i) == FLOAT)
{
tmp_str = FloatToString(theEnv,ValueToDouble(GetMFValue(theMultifield,i)));
strsize += strlen(tmp_str) + 1;
}
else if (GetMFType(theMultifield,i) == INTEGER)
{
tmp_str = LongIntegerToString(theEnv,ValueToLong(GetMFValue(theMultifield,i)));
strsize += strlen(tmp_str) + 1;
}
else if (GetMFType(theMultifield,i) == STRING)
{
strsize += strlen(ValueToString(GetMFValue(theMultifield,i))) + 3;
tmp_str = ValueToString(GetMFValue(theMultifield,i));
while(*tmp_str)
{
if (*tmp_str == '"')
{ strsize++; }
else if (*tmp_str == '\\') /* GDR 111599 #835 */
{ strsize++; } /* GDR 111599 #835 */
tmp_str++;
}
}
#if OBJECT_SYSTEM
else if (GetMFType(theMultifield,i) == INSTANCE_NAME)
{ strsize += strlen(ValueToString(GetMFValue(theMultifield,i))) + 3; }
else if (GetMFType(theMultifield,i) == INSTANCE_ADDRESS)
{ strsize += strlen(ValueToString(((INSTANCE_TYPE *)
GetMFValue(theMultifield,i))->name)) + 3; }
#endif
else
{ strsize += strlen(ValueToString(GetMFValue(theMultifield,i))) + 1; }
}
/*=============================================*/
/* Allocate the string and copy all components */
/* of the MULTIFIELD variable to it. */
/*=============================================*/
if (strsize == 0) return(EnvAddSymbol(theEnv,""));
ret_str = (char *) gm2(theEnv,strsize);
for(j=0, i=GetpDOBegin(value); i <= GetpDOEnd(value) ; i++)
{
/*============================*/
/* Convert numbers to strings */
/*============================*/
if (GetMFType(theMultifield,i) == FLOAT)
{
tmp_str = FloatToString(theEnv,ValueToDouble(GetMFValue(theMultifield,i)));
while(*tmp_str)
{
*(ret_str+j) = *tmp_str;
j++, tmp_str++;
}
}
else if (GetMFType(theMultifield,i) == INTEGER)
{
tmp_str = LongIntegerToString(theEnv,ValueToLong(GetMFValue(theMultifield,i)));
while(*tmp_str)
{
*(ret_str+j) = *tmp_str;
j++, tmp_str++;
}
}
/*=======================================*/
/* Enclose strings in quotes and preceed */
/* imbedded quotes with a backslash */
/*=======================================*/
else if (GetMFType(theMultifield,i) == STRING)
{
tmp_str = ValueToString(GetMFValue(theMultifield,i));
*(ret_str+j) = '"';
j++;
while(*tmp_str)
{
if (*tmp_str == '"')
{
*(ret_str+j) = '\\';
j++;
}
else if (*tmp_str == '\\') /* GDR 111599 #835 */
{ /* GDR 111599 #835 */
*(ret_str+j) = '\\'; /* GDR 111599 #835 */
j++; /* GDR 111599 #835 */
} /* GDR 111599 #835 */
*(ret_str+j) = *tmp_str;
j++, tmp_str++;
}
*(ret_str+j) = '"';
j++;
}
#if OBJECT_SYSTEM
else if (GetMFType(theMultifield,i) == INSTANCE_NAME)
{
tmp_str = ValueToString(GetMFValue(theMultifield,i));
*(ret_str + j++) = '[';
while(*tmp_str)
{
*(ret_str+j) = *tmp_str;
j++, tmp_str++;
}
*(ret_str + j++) = ']';
}
else if (GetMFType(theMultifield,i) == INSTANCE_ADDRESS)
{
tmp_str = ValueToString(((INSTANCE_TYPE *) GetMFValue(theMultifield,i))->name);
*(ret_str + j++) = '[';
while(*tmp_str)
{
*(ret_str+j) = *tmp_str;
j++, tmp_str++;
}
*(ret_str + j++) = ']';
}
#endif
else
{
tmp_str = ValueToString(GetMFValue(theMultifield,i));
while(*tmp_str)
{
*(ret_str+j) = *tmp_str;
j++, tmp_str++;
}
}
*(ret_str+j) = ' ';
j++;
}
*(ret_str+j-1) = '\0';
/*====================*/
/* Return the string. */
/*====================*/
rv = EnvAddSymbol(theEnv,ret_str);
rm(theEnv,ret_str,strsize);
return(rv);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -