globle int ConstraintCheckDataObject( void *theEnv, DATA_OBJECT *theData, CONSTRAINT_RECORD *theConstraints) { long i; /* 6.04 Bug Fix */ int rv; struct field *theMultifield; if (theConstraints == NULL) return(NO_VIOLATION); if (theData->type == MULTIFIELD) { if (CheckCardinalityConstraint(theEnv,(theData->end - theData->begin) + 1, theConstraints) == FALSE) { return(CARDINALITY_VIOLATION); } theMultifield = ((struct multifield *) theData->value)->theFields; for (i = theData->begin; i <= theData->end; i++) { if ((rv = ConstraintCheckValue(theEnv,theMultifield[i].type, theMultifield[i].value, theConstraints)) != NO_VIOLATION) { return(rv); } } return(NO_VIOLATION); } if (CheckCardinalityConstraint(theEnv,1L,theConstraints) == FALSE) { return(CARDINALITY_VIOLATION); } return(ConstraintCheckValue(theEnv,theData->type,theData->value,theConstraints)); }
globle int ConstraintCheckExpressionChain( void *theEnv, EXEC_STATUS, struct expr *theExpression, CONSTRAINT_RECORD *theConstraints) { struct expr *theExp; int min = 0, max = 0, vCode; /*===========================================================*/ /* Determine the minimum and maximum number of value which */ /* can be derived from the expression chain (max of -1 means */ /* positive infinity). */ /*===========================================================*/ for (theExp = theExpression ; theExp != NULL ; theExp = theExp->nextArg) { if (ConstantType(theExp->type)) min++; else if (theExp->type == FCALL) { if ((ExpressionFunctionType(theExp) != 'm') && (ExpressionFunctionType(theExp) != 'u')) min++; else max = -1; } else max = -1; } /*====================================*/ /* Check for a cardinality violation. */ /*====================================*/ if (max == 0) max = min; if (CheckRangeAgainstCardinalityConstraint(theEnv,execStatus,min,max,theConstraints) == FALSE) { return(CARDINALITY_VIOLATION); } /*========================================*/ /* Check for other constraint violations. */ /*========================================*/ for (theExp = theExpression ; theExp != NULL ; theExp = theExp->nextArg) { vCode = ConstraintCheckValue(theEnv,execStatus,theExp->type,theExp->value,theConstraints); if (vCode != NO_VIOLATION) return(vCode); } return(NO_VIOLATION); }
globle int ConstraintCheckExpression( void *theEnv, struct expr *theExpression, CONSTRAINT_RECORD *theConstraints) { int rv = NO_VIOLATION; if (theConstraints == NULL) return(rv); while (theExpression != NULL) { rv = ConstraintCheckValue(theEnv,theExpression->type, theExpression->value, theConstraints); if (rv != NO_VIOLATION) return(rv); rv = ConstraintCheckExpression(theEnv,theExpression->argList,theConstraints); if (rv != NO_VIOLATION) return(rv); theExpression = theExpression->nextArg; } return(rv); }
globle intBool CheckConstraintParseConflicts( void *theEnv, CONSTRAINT_RECORD *constraints) { /*===================================================*/ /* Check to see if any of the allowed-... attributes */ /* conflict with the type attribute. */ /*===================================================*/ if (constraints->anyAllowed == TRUE) { /* Do Nothing */ } else if (constraints->symbolRestriction && (constraints->symbolsAllowed == FALSE)) { AttributeConflictErrorMessage(theEnv,"type","allowed-symbols"); return(FALSE); } else if (constraints->stringRestriction && (constraints->stringsAllowed == FALSE)) { AttributeConflictErrorMessage(theEnv,"type","allowed-strings"); return(FALSE); } else if (constraints->integerRestriction && (constraints->integersAllowed == FALSE)) { AttributeConflictErrorMessage(theEnv,"type","allowed-integers/numbers"); return(FALSE); } else if (constraints->floatRestriction && (constraints->floatsAllowed == FALSE)) { AttributeConflictErrorMessage(theEnv,"type","allowed-floats/numbers"); return(FALSE); } else if (constraints->classRestriction && (constraints->instanceAddressesAllowed == FALSE) && (constraints->instanceNamesAllowed == FALSE)) { AttributeConflictErrorMessage(theEnv,"type","allowed-classes"); return(FALSE); } else if (constraints->instanceNameRestriction && (constraints->instanceNamesAllowed == FALSE)) { AttributeConflictErrorMessage(theEnv,"type","allowed-instance-names"); return(FALSE); } else if (constraints->anyRestriction) { struct expr *theExp; for (theExp = constraints->restrictionList; theExp != NULL; theExp = theExp->nextArg) { if (ConstraintCheckValue(theEnv,theExp->type,theExp->value,constraints) != NO_VIOLATION) { AttributeConflictErrorMessage(theEnv,"type","allowed-values"); return(FALSE); } } } /*================================================================*/ /* Check to see if range attribute conflicts with type attribute. */ /*================================================================*/ if ((constraints->maxValue != NULL) && (constraints->anyAllowed == FALSE)) { if (((constraints->maxValue->type == INTEGER) && (constraints->integersAllowed == FALSE)) || ((constraints->maxValue->type == FLOAT) && (constraints->floatsAllowed == FALSE))) { AttributeConflictErrorMessage(theEnv,"type","range"); return(FALSE); } } if ((constraints->minValue != NULL) && (constraints->anyAllowed == FALSE)) { if (((constraints->minValue->type == INTEGER) && (constraints->integersAllowed == FALSE)) || ((constraints->minValue->type == FLOAT) && (constraints->floatsAllowed == FALSE))) { AttributeConflictErrorMessage(theEnv,"type","range"); return(FALSE); } } /*=========================================*/ /* Check to see if allowed-class attribute */ /* conflicts with type attribute. */ /*=========================================*/ if ((constraints->classList != NULL) && (constraints->anyAllowed == FALSE) && (constraints->instanceNamesAllowed == FALSE) && (constraints->instanceAddressesAllowed == FALSE)) { AttributeConflictErrorMessage(theEnv,"type","allowed-class"); return(FALSE); } /*=====================================================*/ /* Return TRUE to indicate no conflicts were detected. */ /*=====================================================*/ return(TRUE); }
static intBool UnboundVariablesInPattern( void *theEnv, struct lhsParseNode *theSlot, int pattern) { struct lhsParseNode *andField; struct lhsParseNode *rv; int result; struct lhsParseNode *orField; struct symbolHashNode *slotName; CONSTRAINT_RECORD *theConstraints; int theField; /*===================================================*/ /* If a multifield slot is being checked, then check */ /* each of the fields grouped with the multifield. */ /*===================================================*/ if (theSlot->multifieldSlot) { theSlot = theSlot->bottom; while (theSlot != NULL) { if (UnboundVariablesInPattern(theEnv,theSlot,pattern)) { return(TRUE); } theSlot = theSlot->right; } return(FALSE); } /*=======================*/ /* Check a single field. */ /*=======================*/ slotName = theSlot->slot; theField = theSlot->index; theConstraints = theSlot->constraints; /*===========================================*/ /* Loop through each of the '|' constraints. */ /*===========================================*/ for (orField = theSlot->bottom; orField != NULL; orField = orField->bottom) { /*===========================================*/ /* Loop through each of the fields connected */ /* by the '&' within the '|' constraint. */ /*===========================================*/ for (andField = orField; andField != NULL; andField = andField->right) { /*=======================================================*/ /* If this is not a binding occurence of a variable and */ /* there is no previous binding occurence of a variable, */ /* then generate an error message for a variable that is */ /* referred to but not bound. */ /*=======================================================*/ if (((andField->type == SF_VARIABLE) || (andField->type == MF_VARIABLE)) && (andField->referringNode == NULL)) { VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) andField->value,NULL,pattern, slotName,theField); return(TRUE); } /*==============================================*/ /* Check predicate and return value constraints */ /* to insure that all variables used within the */ /* constraint have been previously bound. */ /*==============================================*/ else if ((andField->type == PREDICATE_CONSTRAINT) || (andField->type == RETURN_VALUE_CONSTRAINT)) { rv = CheckExpression(theEnv,andField->expression,NULL,pattern,slotName,theField); if (rv != NULL) return(TRUE); } /*========================================================*/ /* If static constraint checking is being performed, then */ /* determine if constant values have violated the set of */ /* derived constraints for the slot/field (based on the */ /* deftemplate definition and propagated constraints). */ /*========================================================*/ else if (((andField->type == INTEGER) || (andField->type == FLOAT) || (andField->type == SYMBOL) || (andField->type == STRING) || (andField->type == INSTANCE_NAME)) && EnvGetStaticConstraintChecking(theEnv)) { result = ConstraintCheckValue(theEnv,andField->type,andField->value,theConstraints); if (result != NO_VIOLATION) { ConstraintViolationErrorMessage(theEnv,"A literal restriction value", NULL,FALSE,pattern, slotName,theField,result, theConstraints,TRUE); return(TRUE); } } } } /*===============================*/ /* Return FALSE to indicate that */ /* no errors were detected. */ /*===============================*/ return(FALSE); }