?? cstrnops.c
字號:
} else { tmpmin1 = constraint1->minFields; tmpmax1 = constraint1->maxFields; } /*===========================================*/ /* Loop through each of range/min/max values */ /* from the first constraint record. */ /*===========================================*/ for (; tmpmin1 != NULL; tmpmin1 = tmpmin1->nextArg, tmpmax1 = tmpmax1->nextArg) { /*============================================*/ /* Get the appropriate values from the second */ /* constraint record for comparison. */ /*============================================*/ if (range) { tmpmin2 = constraint2->minValue; tmpmax2 = constraint2->maxValue; } else { tmpmin2 = constraint2->minFields; tmpmax2 = constraint2->maxFields; } /*================================================*/ /* Loop through each of range/min/max values from */ /* the second constraint record comparing it to */ /* the values from the first constraint record. */ /*================================================*/ for (; tmpmin2 != NULL; tmpmin2 = tmpmin2->nextArg, tmpmax2 = tmpmax2->nextArg) { /*==============================================*/ /* Determine the relationship between the four */ /* combinations of min/max values (>, <, or =). */ /*==============================================*/ cmaxmax = CompareNumbers(theEnv,tmpmax1->type,tmpmax1->value, tmpmax2->type,tmpmax2->value); cminmin = CompareNumbers(theEnv,tmpmin1->type,tmpmin1->value, tmpmin2->type,tmpmin2->value); cmaxmin = CompareNumbers(theEnv,tmpmax1->type,tmpmax1->value, tmpmin2->type,tmpmin2->value); cminmax = CompareNumbers(theEnv,tmpmin1->type,tmpmin1->value, tmpmax2->type,tmpmax2->value); /*============================================*/ /* If the range/min/max values don't overlap, */ /* then proceed to the next pair of numbers */ /* to see if they overlap. */ /*============================================*/ if ((cmaxmin == LESS_THAN) || (cminmax == GREATER_THAN)) { continue; } /*=======================================*/ /* Compute the new minimum value for the */ /* intersected range/min/max values. */ /*=======================================*/ if (cminmin == GREATER_THAN) { theMin = GenConstant(theEnv,tmpmin1->type,tmpmin1->value); } else { theMin = GenConstant(theEnv,tmpmin2->type,tmpmin2->value); } /*=======================================*/ /* Compute the new maximum value for the */ /* intersected range/min/max values. */ /*=======================================*/ if (cmaxmax == LESS_THAN) { theMax = GenConstant(theEnv,tmpmax1->type,tmpmax1->value); } else { theMax = GenConstant(theEnv,tmpmax2->type,tmpmax2->value); } /*==================================*/ /* Add the new range/min/max values */ /* to the intersection list. */ /*==================================*/ if (lastMin == NULL) { theMinList = theMin; theMaxList = theMax; } else { lastMin->nextArg = theMin; lastMax->nextArg = theMax; } lastMin = theMin; lastMax = theMax; } } /*============================================================*/ /* If the intersection produced a pair of valid range/min/max */ /* values, then replace the previous values of the constraint */ /* record to the new intersected 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 intersection 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->singlefieldsAllowed = FALSE; newConstraint->multifieldsAllowed = FALSE; newConstraint->anyAllowed = FALSE; } } }/************************************************************//* UpdateRestrictionFlags: Updates the types allowed flags *//* based on the allowed values in a constraint record. *//* Intended to be called after the allowed values list *//* has been changed (for example after intersecting the *//* allowed-values list there may no be any values of a *//* particular type left even though the type is allowed). *//************************************************************/static void UpdateRestrictionFlags( CONSTRAINT_RECORD *rv) { if ((rv->anyRestriction) && (rv->restrictionList == NULL)) { SetAnyAllowedFlags(rv,TRUE); rv->anyAllowed = FALSE; } if ((rv->symbolRestriction) && (rv->symbolsAllowed)) { rv->symbolsAllowed = FindItemInExpression(SYMBOL,NULL,FALSE,rv->restrictionList); } if ((rv->stringRestriction) && (rv->stringsAllowed)) { rv->stringsAllowed = FindItemInExpression(STRING,NULL,FALSE,rv->restrictionList); } if ((rv->floatRestriction) && (rv->floatsAllowed)) { rv->floatsAllowed = FindItemInExpression(FLOAT,NULL,FALSE,rv->restrictionList); } if ((rv->integerRestriction) && (rv->integersAllowed)) { rv->integersAllowed = FindItemInExpression(INTEGER,NULL,FALSE,rv->restrictionList); } if ((rv->instanceNameRestriction) && (rv->instanceNamesAllowed)) { rv->instanceNamesAllowed = FindItemInExpression(INSTANCE_NAME,NULL,FALSE,rv->restrictionList); } }/*************************************************************//* FindItemInExpression: Determines if a particular constant *//* (such as 27) or a class of constants (such as integers) *//* can be found in a list of constants. Returns TRUE if *//* such a constant can be found, otherwise FALSE. *//*************************************************************/static int FindItemInExpression( int theType, void *theValue, int useValue, struct expr *theList) { while (theList != NULL) { if (theList->type == theType) { if (! useValue) return(TRUE); else if (theList->value == theValue) return(TRUE); } theList = theList->nextArg; } return(FALSE); }#if (! BLOAD_ONLY)/**************************************************//* RestrictionOnType: Determines if a restriction *//* is present for a specific type. Returns TRUE *//* if there is, otherwise FALSE. *//**************************************************/static int RestrictionOnType( int theType, CONSTRAINT_RECORD *theConstraint) { if (theConstraint == NULL) return(FALSE); if ((theConstraint->anyRestriction) || (theConstraint->symbolRestriction && (theType == SYMBOL)) || (theConstraint->stringRestriction && (theType == STRING)) || (theConstraint->floatRestriction && (theType == FLOAT)) || (theConstraint->integerRestriction && (theType == INTEGER)) || (theConstraint->classRestriction && ((theType == INSTANCE_ADDRESS) || (theType == INSTANCE_NAME))) || (theConstraint->instanceNameRestriction && (theType == INSTANCE_NAME))) { return(TRUE); } return(FALSE); }/**********************************************************//* UnionConstraints: Creates a new constraint record that *//* is the union of two other constraint records. *//**********************************************************/globle struct constraintRecord *UnionConstraints( void *theEnv, CONSTRAINT_RECORD *c1, CONSTRAINT_RECORD *c2) { struct constraintRecord *rv; int c1Changed = FALSE, c2Changed = FALSE; /*=================================================*/ /* If both constraint records are NULL,then create */ /* a constraint record that allows any value. */ /*=================================================*/ if ((c1 == NULL) && (c2 == NULL)) return(GetConstraintRecord(theEnv)); /*=====================================================*/ /* If one of the constraint records is NULL, then the */ /* union is the other constraint record. Note that */ /* this is different from the way that intersections */ /* were handled (a NULL constraint record implied that */ /* any value was legal which in turn would imply that */ /* the union would allow any value as well). */ /*=====================================================*/ if (c1 == NULL) return(CopyConstraintRecord(theEnv,c2)); if (c2 == NULL) return(CopyConstraintRecord(theEnv,c1)); /*=================================*/ /* Create a new constraint record. */ /*=================================*/ rv = GetConstraintRecord(theEnv); /*==========================*/ /* Union the allowed types. */ /*==========================*/ if (c1->multifieldsAllowed || c2->multifieldsAllowed) { rv->multifieldsAllowed = TRUE; } if (c1->singlefieldsAllowed || c2->singlefieldsAllowed) { rv->singlefieldsAllowed = TRUE; } if (c1->anyAllowed || c2->anyAllowed) rv->anyAllowed = TRUE; else { rv->anyAllowed = FALSE; rv->symbolsAllowed = (c1->symbolsAllowed || c2->symbolsAllowed); rv->stringsAllowed = (c1->stringsAllowed || c2->stringsAllowed); rv->floatsAllowed = (c1->floatsAllowed || c2->floatsAllowed); rv->integersAllowed = (c1->integersAllowed || c2->integersAllowed); rv->instanceNamesAllowed = (c1->instanceNamesAllowed || c2->instanceNamesAllowed); rv->instanceAddressesAllowed = (c1->instanceAddressesAllowed || c2->instanceAddressesAllowed); rv->externalAddressesAllowed = (c1->externalAddressesAllowed || c2->externalAddressesAllowed); rv->voidAllowed = (c1->voidAllowed || c2->voidAllowed); rv->factAddressesAllowed = (c1->factAddressesAllowed || c2->factAddressesAllowed); } /*=================================*/ /* Union the allowed-values flags. */ /*=================================*/ if (c1->anyRestriction && c2->anyRestriction) rv->anyRestriction = TRUE; else { if (c1->anyRestriction) { c1Changed = TRUE; SetAnyRestrictionFlags(c1,FALSE); } else if (c2->anyRestriction) { c2Changed = TRUE; SetAnyRestrictionFlags(c2,FALSE); } rv->anyRestriction = FALSE; rv->symbolRestriction = (c1->symbolRestriction && c2->symbolRestriction); rv->stringRestriction = (c1->stringRestriction && c2->stringRestriction); rv->floatRestriction = (c1->floatRestriction && c2->floatRestriction); rv->integerRestriction = (c1->integerRestriction && c2->integerRestriction); rv->classRestriction = (c1->classRestriction && c2->classRestriction); rv->instanceNameRestriction = (c1->instanceNameRestriction && c2->instanceNameRestriction); if (c1Changed) SetAnyRestrictionFlags(c1,FALSE); else if (c2Changed) SetAnyRestrictionFlags(c2,FALSE); } /*========================================*/ /* Union the allowed values list, the min */ /* and max values, and the range values. */ /*========================================*/ UnionAllowedValueExpressions(theEnv,c1,c2,rv); UnionAllowedClassExpressions(theEnv,c1,c2,rv); UnionNumericExpressions(theEnv,c1,c2,rv,TRUE); UnionNumericExpressions(theEnv,c1,c2,rv,FALSE); /*========================================*/ /* If multifields are allowed, then union */ /* the constraint record for them. */ /*========================================*/ if (rv->multifieldsAllowed) { rv->multifield = UnionConstraints(theEnv,c1->multifield,c2->multifield); } /*====================*/ /* Return the unioned */ /* constraint record. */ /*====================*/ return(rv); }/**************************************************//* UnionNumericExpressions: Creates the union of *//* two range or two min/max-fields constraints. *//**************************************************/static void UnionNumericExpressions( void *theEnv, CONSTRAINT_RECORD *constraint1, CONSTRAINT_RECORD *constraint2, CONSTRAINT_RECORD *newConstraint, int range) { struct expr *tmpmin, *tmpmax; struct expr *theMinList, *theMaxList; /*=========================================*/ /* Initialize the new range/min/max values */ /* for the union of the constraints. */ /*=========================================*/ theMinList = NULL; theMaxList = NULL; /*=================================*/ /* Determine the min/max values of */ /* the first constraint record. */ /*=================================*/ if (range) { tmpmin = constraint1->minValue; tmpmax = constraint1->maxValue; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -