?? 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 + -