📄 multifun.c
字号:
/*****************************************/
globle void MultifieldPrognFunction(
void *theEnv,
DATA_OBJECT_PTR result)
{
EXPRESSION *theExp;
DATA_OBJECT argval;
long i, end; /* 6.04 Bug Fix */
FIELD_VAR_STACK *tmpField;
tmpField = get_struct(theEnv,fieldVarStack);
tmpField->type = SYMBOL;
tmpField->value = EnvFalseSymbol(theEnv);
tmpField->nxt = MultiFunctionData(theEnv)->FieldVarStack;
MultiFunctionData(theEnv)->FieldVarStack = tmpField;
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
if (EnvArgTypeCheck(theEnv,"progn$",1,MULTIFIELD,&argval) == FALSE)
{
MultiFunctionData(theEnv)->FieldVarStack = tmpField->nxt;
rtn_struct(theEnv,fieldVarStack,tmpField);
return;
}
ValueInstall(theEnv,&argval);
end = GetDOEnd(argval);
for (i = GetDOBegin(argval) ; i <= end ; i++)
{
tmpField->type = GetMFType(argval.value,i);
tmpField->value = GetMFValue(argval.value,i);
/* tmpField->index = i; */
tmpField->index = (i - GetDOBegin(argval)) + 1;
for (theExp = GetFirstArgument()->nextArg ; theExp != NULL ; theExp = theExp->nextArg)
{
EvaluationData(theEnv)->CurrentEvaluationDepth++;
EvaluateExpression(theEnv,theExp,result);
EvaluationData(theEnv)->CurrentEvaluationDepth--;
if (ProcedureFunctionData(theEnv)->ReturnFlag == TRUE)
{ PropagateReturnValue(theEnv,result); }
PeriodicCleanup(theEnv,FALSE,TRUE);
if (EvaluationData(theEnv)->HaltExecution || ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
{
ValueDeinstall(theEnv,&argval);
ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
if (EvaluationData(theEnv)->HaltExecution)
{
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
}
MultiFunctionData(theEnv)->FieldVarStack = tmpField->nxt;
rtn_struct(theEnv,fieldVarStack,tmpField);
return;
}
}
}
ValueDeinstall(theEnv,&argval);
ProcedureFunctionData(theEnv)->BreakFlag = FALSE;
MultiFunctionData(theEnv)->FieldVarStack = tmpField->nxt;
rtn_struct(theEnv,fieldVarStack,tmpField);
}
/***************************************************/
/* GetMvPrognField */
/***************************************************/
globle void GetMvPrognField(
void *theEnv,
DATA_OBJECT_PTR result)
{
int depth;
FIELD_VAR_STACK *tmpField;
depth = ValueToInteger(GetFirstArgument()->value);
tmpField = MultiFunctionData(theEnv)->FieldVarStack;
while (depth > 0)
{
tmpField = tmpField->nxt;
depth--;
}
result->type = tmpField->type;
result->value = tmpField->value;
}
/***************************************************/
/* GetMvPrognIndex */
/***************************************************/
globle long GetMvPrognIndex(
void *theEnv)
{
int depth;
FIELD_VAR_STACK *tmpField;
depth = ValueToInteger(GetFirstArgument()->value);
tmpField = MultiFunctionData(theEnv)->FieldVarStack;
while (depth > 0)
{
tmpField = tmpField->nxt;
depth--;
}
return(tmpField->index);
}
#endif
#if OBJECT_SYSTEM || MULTIFIELD_FUNCTIONS
/**************************************************************************
NAME : ReplaceMultiValueField
DESCRIPTION : Performs a replace on the src multi-field value
storing the results in the dst multi-field value
INPUTS : 1) The destination value buffer
2) The source value (can be NULL)
3) Beginning of index range
4) End of range
5) The new field value
RETURNS : TRUE if successful, FALSE otherwise
SIDE EFFECTS : Allocates and sets a ephemeral segment (even if new
number of fields is 0)
Src value segment is not changed
NOTES : index is NOT guaranteed to be valid
src is guaranteed to be a multi-field variable or NULL
**************************************************************************/
globle int ReplaceMultiValueField(
void *theEnv,
DATA_OBJECT *dst,
DATA_OBJECT *src,
long rb,
long re,
DATA_OBJECT *field,
char *funcName)
{
long i,j,k;
struct field *deptr;
struct field *septr;
long srclen,dstlen;
srclen = ((src != NULL) ? (src->end - src->begin + 1) : 0);
if ((re < rb) ||
(rb < 1) || (re < 1) ||
(rb > srclen) || (re > srclen))
{
MVRangeError(theEnv,rb,re,(unsigned long) srclen,funcName);
return(FALSE);
}
rb = src->begin + rb - 1;
re = src->begin + re - 1;
if (field->type == MULTIFIELD)
dstlen = srclen + GetpDOLength(field) - (re-rb+1);
else
dstlen = srclen + 1 - (re-rb+1);
dst->type = MULTIFIELD;
dst->begin = 0;
dst->value = EnvCreateMultifield(theEnv,(unsigned long) dstlen);
SetpDOEnd(dst,dstlen);
for (i = 0 , j = src->begin ; j < rb ; i++ , j++)
{
deptr = &((struct multifield *) dst->value)->theFields[i];
septr = &((struct multifield *) src->value)->theFields[j];
deptr->type = septr->type;
deptr->value = septr->value;
}
if (field->type != MULTIFIELD)
{
deptr = &((struct multifield *) dst->value)->theFields[i++];
deptr->type = field->type;
deptr->value = field->value;
}
else
{
for (k = field->begin ; k <= field->end ; k++ , i++)
{
deptr = &((struct multifield *) dst->value)->theFields[i];
septr = &((struct multifield *) field->value)->theFields[k];
deptr->type = septr->type;
deptr->value = septr->value;
}
}
while (j < re)
j++;
for (j++ ; i < dstlen ; i++ , j++)
{
deptr = &((struct multifield *) dst->value)->theFields[i];
septr = &((struct multifield *) src->value)->theFields[j];
deptr->type = septr->type;
deptr->value = septr->value;
}
return(TRUE);
}
/**************************************************************************
NAME : InsertMultiValueField
DESCRIPTION : Performs an insert on the src multi-field value
storing the results in the dst multi-field value
INPUTS : 1) The destination value buffer
2) The source value (can be NULL)
3) The index for the change
4) The new field value
RETURNS : TRUE if successful, FALSE otherwise
SIDE EFFECTS : Allocates and sets a ephemeral segment (even if new
number of fields is 0)
Src value segment is not changed
NOTES : index is NOT guaranteed to be valid
src is guaranteed to be a multi-field variable or NULL
**************************************************************************/
globle int InsertMultiValueField(
void *theEnv,
DATA_OBJECT *dst,
DATA_OBJECT *src,
long theIndex,
DATA_OBJECT *field,
char *funcName)
{
register long i,j,k;
register FIELD *deptr, *septr;
unsigned long srclen,dstlen;
srclen = (unsigned long) ((src != NULL) ? (src->end - src->begin + 1) : 0);
if (theIndex < 1)
{
MVRangeError(theEnv,theIndex,theIndex,srclen+1,funcName);
return(FALSE);
}
if (theIndex > (long) (srclen + 1))
theIndex = (long) (srclen + 1);
dst->type = MULTIFIELD;
dst->begin = 0;
if (src == NULL)
{
if (field->type == MULTIFIELD)
{
DuplicateMultifield(theEnv,dst,field);
AddToMultifieldList(theEnv,(struct multifield *) dst->value);
}
else
{
dst->value = EnvCreateMultifield(theEnv,0L);
dst->end = 0;
deptr = &((struct multifield *) dst->value)->theFields[0];
deptr->type = field->type;
deptr->value = field->value;
}
return(TRUE);
}
dstlen = (field->type == MULTIFIELD) ? GetpDOLength(field) + srclen : srclen + 1;
dst->value = EnvCreateMultifield(theEnv,dstlen);
SetpDOEnd(dst,dstlen);
theIndex--;
for (i = 0 , j = src->begin ; i < theIndex ; i++ , j++)
{
deptr = &((struct multifield *) dst->value)->theFields[i];
septr = &((struct multifield *) src->value)->theFields[j];
deptr->type = septr->type;
deptr->value = septr->value;
}
if (field->type != MULTIFIELD)
{
deptr = &((struct multifield *) dst->value)->theFields[theIndex];
deptr->type = field->type;
deptr->value = field->value;
i++;
}
else
{
for (k = field->begin ; k <= field->end ; k++ , i++)
{
deptr = &((struct multifield *) dst->value)->theFields[i];
septr = &((struct multifield *) field->value)->theFields[k];
deptr->type = septr->type;
deptr->value = septr->value;
}
}
for ( ; j <= src->end ; i++ , j++)
{
deptr = &((struct multifield *) dst->value)->theFields[i];
septr = &((struct multifield *) src->value)->theFields[j];
deptr->type = septr->type;
deptr->value = septr->value;
}
return(TRUE);
}
/*******************************************************
NAME : MVRangeError
DESCRIPTION : Prints out an error messages for index
out-of-range errors in multi-field
access functions
INPUTS : 1) The bad range start
2) The bad range end
3) The max end of the range (min is
assumed to be 1)
RETURNS : Nothing useful
SIDE EFFECTS : None
NOTES : None
******************************************************/
static void MVRangeError(
void *theEnv,
long brb,
long bre,
unsigned long max,
char *funcName)
{
PrintErrorID(theEnv,"MULTIFUN",1,FALSE);
EnvPrintRouter(theEnv,WERROR,"Multifield index ");
if (brb == bre)
PrintLongInteger(theEnv,WERROR,(long) brb);
else
{
EnvPrintRouter(theEnv,WERROR,"range ");
PrintLongInteger(theEnv,WERROR,(long) brb);
EnvPrintRouter(theEnv,WERROR,"..");
PrintLongInteger(theEnv,WERROR,(long) bre);
}
EnvPrintRouter(theEnv,WERROR," out of range 1..");
PrintLongInteger(theEnv,WERROR,(long) max);
if (funcName != NULL)
{
EnvPrintRouter(theEnv,WERROR," in function ");
EnvPrintRouter(theEnv,WERROR,funcName);
}
EnvPrintRouter(theEnv,WERROR,".\n");
}
/**************************************************************************
NAME : DeleteMultiValueField
DESCRIPTION : Performs a modify on the src multi-field value
storing the results in the dst multi-field value
INPUTS : 1) The destination value buffer
2) The source value (can be NULL)
3) The beginning index for deletion
4) The ending index for deletion
RETURNS : TRUE if successful, FALSE otherwise
SIDE EFFECTS : Allocates and sets a ephemeral segment (even if new
number of fields is 0)
Src value segment is not changed
NOTES : index is NOT guaranteed to be valid
src is guaranteed to be a multi-field variable or NULL
**************************************************************************/
globle int DeleteMultiValueField(
void *theEnv,
DATA_OBJECT *dst,
DATA_OBJECT *src,
long rb,
long re,
char *funcName)
{
register long i,j;
register FIELD_PTR deptr,septr;
unsigned long srclen, dstlen;
srclen = (unsigned long) ((src != NULL) ? (src->end - src->begin + 1) : 0);
if ((re < rb) ||
(rb < 1) || (re < 1) ||
(rb > ((long) srclen)) || (re > ((long) srclen)))
{
MVRangeError(theEnv,rb,re,srclen,funcName);
return(FALSE);
}
dst->type = MULTIFIELD;
dst->begin = 0;
if (srclen == 0)
{
dst->value = EnvCreateMultifield(theEnv,0L);
dst->end = -1;
return(TRUE);
}
rb = src->begin + rb -1;
re = src->begin + re -1;
dstlen = srclen-(re-rb+1);
SetpDOEnd(dst,dstlen);
dst->value = EnvCreateMultifield(theEnv,dstlen);
for (i = 0 , j = src->begin ; j < rb ; i++ , j++)
{
deptr = &((struct multifield *) dst->value)->theFields[i];
septr = &((struct multifield *) src->value)->theFields[j];
deptr->type = septr->type;
deptr->value = septr->value;
}
while (j < re)
j++;
for (j++ ; i <= dst->end ; j++ , i++)
{
deptr = &((struct multifield *) dst->value)->theFields[i];
septr = &((struct multifield *) src->value)->theFields[j];
deptr->type = septr->type;
deptr->value = septr->value;
}
return(TRUE);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -