⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cstrnops.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
     }   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 + -