📄 cstrnops.c
字号:
else
{
tmpmin = constraint1->minFields;
tmpmax = constraint1->maxFields;
}
/*============================================*/
/* Add each range/min/max pair from the first */
/* constraint record to the union list. */
/*============================================*/
for (;
tmpmin != NULL;
tmpmin = tmpmin->nextArg,tmpmax = tmpmax->nextArg)
{ UnionRangeMinMaxValueWithList(theEnv,tmpmin,tmpmax,&theMinList,&theMaxList); }
/*=================================*/
/* Determine the min/max values of */
/* the second constraint record. */
/*=================================*/
if (range)
{
tmpmin = constraint2->minValue;
tmpmax = constraint2->maxValue;
}
else
{
tmpmin = constraint2->minFields;
tmpmax = constraint2->maxFields;
}
/*=============================================*/
/* Add each range/min/max pair from the second */
/* constraint record to the union list. */
/*=============================================*/
for (;
tmpmin != NULL;
tmpmin = tmpmin->nextArg,tmpmax = tmpmax->nextArg)
{ UnionRangeMinMaxValueWithList(theEnv,tmpmin,tmpmax,&theMinList,&theMaxList); }
/*=====================================================*/
/* If the union produced a pair of valid range/min/max */
/* values, then replace the previous values of the */
/* constraint record to the new unioned values. */
/*=====================================================*/
if (theMinList != NULL)
{
if (range)
{
ReturnExpression(theEnv,newConstraint->minValue);
ReturnExpression(theEnv,newConstraint->maxValue);
newConstraint->minValue = theMinList;
newConstraint->maxValue = theMaxList;
}
else
{
ReturnExpression(theEnv,newConstraint->minFields);
ReturnExpression(theEnv,newConstraint->maxFields);
newConstraint->minFields = theMinList;
newConstraint->maxFields = theMaxList;
}
}
/*==============================================================*/
/* Otherwise, the union produced no valid range/min/max values. */
/* For the range attribute, this means that no numbers can */
/* satisfy the constraint. For the min/max fields attribute, it */
/* means that no value can satisfy the constraint. */
/*==============================================================*/
else
{
if (range)
{
if (newConstraint->anyAllowed) SetAnyAllowedFlags(newConstraint,FALSE);
newConstraint->integersAllowed = FALSE;
newConstraint->floatsAllowed = FALSE;
}
else
{
SetAnyAllowedFlags(newConstraint,TRUE);
newConstraint->anyAllowed = TRUE;
}
}
}
/*********************************************************/
/* UnionRangeMinMaxValueWithList: Unions a range/min/max */
/* pair of values with a list of such values. */
/*********************************************************/
static void UnionRangeMinMaxValueWithList(
void *theEnv,
struct expr *addmin,
struct expr *addmax,
struct expr **theMinList,
struct expr **theMaxList)
{
struct expr *tmpmin, *tmpmax, *lastmin, *lastmax;
struct expr *themin, *themax, *nextmin, *nextmax;
int cmaxmin, cmaxmax, cminmin, cminmax;
/*=========================================================*/
/* If no values are on the lists, then use the new values. */
/*=========================================================*/
if (*theMinList == NULL)
{
*theMinList = GenConstant(theEnv,addmin->type,addmin->value);
*theMaxList = GenConstant(theEnv,addmax->type,addmax->value);
return;
}
lastmin = NULL;
lastmax = NULL;
tmpmin = (*theMinList);
tmpmax = (*theMaxList);
while (tmpmin != NULL)
{
cmaxmax = CompareNumbers(theEnv,addmax->type,addmax->value,
tmpmax->type,tmpmax->value);
cminmin = CompareNumbers(theEnv,addmin->type,addmin->value,
tmpmin->type,tmpmin->value);
cmaxmin = CompareNumbers(theEnv,addmax->type,addmax->value,
tmpmin->type,tmpmin->value);
cminmax = CompareNumbers(theEnv,addmin->type,addmin->value,
tmpmax->type,tmpmax->value);
/*=================================*/
/* Check to see if the range is */
/* contained within another range. */
/*=================================*/
if (((cmaxmax == LESS_THAN) || (cmaxmax == EQUAL)) &&
((cminmin == GREATER_THAN) || (cminmin == EQUAL)))
{ return; }
/*================================*/
/* Extend the greater than range. */
/*================================*/
if ((cmaxmax == GREATER_THAN) &&
((cminmax == LESS_THAN) || (cminmax == EQUAL)))
{
tmpmax->type = addmax->type;
tmpmax->value = addmax->value;
}
/*=============================*/
/* Extend the less than range. */
/*=============================*/
if ((cminmin == LESS_THAN) &&
((cmaxmin == GREATER_THAN) || (cmaxmin == EQUAL)))
{
tmpmin->type = addmin->type;
tmpmin->value = addmin->value;
}
/*====================*/
/* Handle insertions. */
/*====================*/
if (cmaxmin == LESS_THAN)
{
if (lastmax == NULL)
{
themin = GenConstant(theEnv,addmin->type,addmin->value);
themax = GenConstant(theEnv,addmax->type,addmax->value);
themin->nextArg = *theMinList;
themax->nextArg = *theMaxList;
*theMinList = themin;
*theMaxList = themax;
return;
}
if (CompareNumbers(theEnv,addmin->type,addmin->value,
lastmax->type,lastmax->value) == GREATER_THAN)
{
themin = GenConstant(theEnv,addmin->type,addmin->value);
themax = GenConstant(theEnv,addmax->type,addmax->value);
themin->nextArg = lastmin->nextArg;
themax->nextArg = lastmax->nextArg;
lastmin->nextArg = themin;
lastmax->nextArg = themax;
return;
}
}
/*==========================*/
/* Move on to the next one. */
/*==========================*/
tmpmin = tmpmin->nextArg;
tmpmax = tmpmax->nextArg;
}
/*===========================*/
/* Merge overlapping ranges. */
/*===========================*/
tmpmin = (*theMinList);
tmpmax = (*theMaxList);
while (tmpmin != NULL)
{
nextmin = tmpmin->nextArg;
nextmax = tmpmax->nextArg;
if (nextmin != NULL)
{
cmaxmin = CompareNumbers(theEnv,tmpmax->type,tmpmax->value,
nextmin->type,nextmin->value);
if ((cmaxmin == GREATER_THAN) || (cmaxmin == EQUAL))
{
tmpmax->type = nextmax->type;
tmpmax->value = nextmax->value;
tmpmax->nextArg = nextmax->nextArg;
tmpmin->nextArg = nextmin->nextArg;
rtn_struct(theEnv,expr,nextmin);
rtn_struct(theEnv,expr,nextmax);
}
else
{
tmpmin = tmpmin->nextArg;
tmpmax = tmpmax->nextArg;
}
}
else
{
tmpmin = nextmin;
tmpmax = nextmax;
}
}
}
/***************************************************/
/* UnionAllowedClassExpressions: Creates the union */
/* of two sets of allowed-classes expressions. */
/***************************************************/
static void UnionAllowedClassExpressions(
void *theEnv,
CONSTRAINT_RECORD *constraint1,
CONSTRAINT_RECORD *constraint2,
CONSTRAINT_RECORD *newConstraint)
{
struct expr *theHead = NULL;
theHead = AddToUnionList(theEnv,constraint1->classList,theHead,newConstraint);
theHead = AddToUnionList(theEnv,constraint2->classList,theHead,newConstraint);
newConstraint->classList = theHead;
}
/***************************************************/
/* UnionAllowedValueExpressions: Creates the union */
/* of two sets of allowed value expressions. */
/***************************************************/
static void UnionAllowedValueExpressions(
void *theEnv,
CONSTRAINT_RECORD *constraint1,
CONSTRAINT_RECORD *constraint2,
CONSTRAINT_RECORD *newConstraint)
{
struct expr *theHead = NULL;
theHead = AddToUnionList(theEnv,constraint1->restrictionList,theHead,newConstraint);
theHead = AddToUnionList(theEnv,constraint2->restrictionList,theHead,newConstraint);
newConstraint->restrictionList = theHead;
}
/************************************************************/
/* AddToUnionList: Adds a list of values to a unioned list */
/* making sure that duplicates are not added and that any */
/* value added satisfies the constraints for the list. */
/************************************************************/
static struct expr *AddToUnionList(
void *theEnv,
struct expr *theList1,
struct expr *theHead,
CONSTRAINT_RECORD *theConstraint)
{
struct expr *theList2;
int flag;
/*======================================*/
/* Loop through each value in the list */
/* being added to the unioned set. */
/*======================================*/
for (;theList1 != NULL; theList1 = theList1->nextArg)
{
/*===================================*/
/* Determine if the value is already */
/* in the unioned list. */
/*===================================*/
flag = TRUE;
for (theList2 = theHead;
theList2 != NULL;
theList2 = theList2->nextArg)
{
if ((theList1->type == theList2->type) &&
(theList1->value == theList2->value))
{
flag = FALSE;
break;
}
}
/*=====================================================*/
/* If the value wasn't in the unioned list and doesn't */
/* violate any of the unioned list's constraints, then */
/* add it to the list. */
/*=====================================================*/
if (flag)
{
if (RestrictionOnType(theList1->type,theConstraint))
{
theList2 = GenConstant(theEnv,theList1->type,theList1->value);
theList2->nextArg = theHead;
theHead = theList2;
}
}
}
/*==============================*/
/* Return the new unioned list. */
/*==============================*/
return(theHead);
}
/****************************************************/
/* RemoveConstantFromConstraint: Removes a constant */
/* value (including any duplicates) from the */
/* restriction list of a constraint record. */
/****************************************************/
globle void RemoveConstantFromConstraint(
void *theEnv,
int theType,
void *theValue,
CONSTRAINT_RECORD *theConstraint)
{
struct expr *theList, *lastOne = NULL, *tmpList;
if (theConstraint == NULL) return;
theList = theConstraint->restrictionList;
theConstraint->restrictionList = NULL;
while (theList != NULL)
{
if ((theList->type != theType) || (theList->value != theValue))
{
if (lastOne == NULL)
{ theConstraint->restrictionList = theList; }
else
{ lastOne->nextArg = theList; }
lastOne = theList;
theList = theList->nextArg;
lastOne->nextArg = NULL;
}
else
{
tmpList = theList;
theList = theList->nextArg;
tmpList->nextArg = NULL;
ReturnExpression(theEnv,tmpList);
}
}
UpdateRestrictionFlags(theConstraint);
}
#endif /* (! BLOAD_ONLY) */
#endif /* (! RUN_TIME) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -