00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define _CSTRNOPS_SOURCE_
00026
00027 #include "setup.h"
00028
00029 #include <stdio.h>
00030 #define _STDIO_INCLUDED_
00031 #include <stdlib.h>
00032
00033 #if (! RUN_TIME)
00034
00035 #include "constant.h"
00036 #include "envrnmnt.h"
00037 #include "memalloc.h"
00038 #include "router.h"
00039 #include "extnfunc.h"
00040 #include "scanner.h"
00041 #include "multifld.h"
00042 #include "constrnt.h"
00043 #include "cstrnchk.h"
00044 #include "cstrnutl.h"
00045
00046 #include "cstrnops.h"
00047
00048
00049
00050
00051
00052 static void IntersectNumericExpressions(void *,
00053 CONSTRAINT_RECORD *,
00054 CONSTRAINT_RECORD *,
00055 CONSTRAINT_RECORD *,int);
00056 static void IntersectAllowedValueExpressions(void *,
00057 CONSTRAINT_RECORD *,
00058 CONSTRAINT_RECORD *,
00059 CONSTRAINT_RECORD *);
00060 static void IntersectAllowedClassExpressions(void *,
00061 CONSTRAINT_RECORD *,
00062 CONSTRAINT_RECORD *,
00063 CONSTRAINT_RECORD *);
00064 static int FindItemInExpression(int,void *,int,struct expr *);
00065 static void UpdateRestrictionFlags(CONSTRAINT_RECORD *);
00066 #if (! BLOAD_ONLY)
00067 static void UnionRangeMinMaxValueWithList(void *,
00068 struct expr *,
00069 struct expr *,
00070 struct expr **,
00071 struct expr **);
00072 static void UnionNumericExpressions(void *,
00073 CONSTRAINT_RECORD *,
00074 CONSTRAINT_RECORD *,
00075 CONSTRAINT_RECORD *,int);
00076 static struct expr *AddToUnionList(void *,
00077 struct expr *,struct expr *,
00078 CONSTRAINT_RECORD *);
00079 static void UnionAllowedValueExpressions(void *,
00080 CONSTRAINT_RECORD *,
00081 CONSTRAINT_RECORD *,
00082 CONSTRAINT_RECORD *);
00083 static void UnionAllowedClassExpressions(void *,
00084 CONSTRAINT_RECORD *,
00085 CONSTRAINT_RECORD *,
00086 CONSTRAINT_RECORD *);
00087 static int RestrictionOnType(int,CONSTRAINT_RECORD *);
00088 #endif
00089
00090
00091
00092
00093
00094 globle struct constraintRecord *IntersectConstraints(
00095 void *theEnv,
00096 CONSTRAINT_RECORD *c1,
00097 CONSTRAINT_RECORD *c2)
00098 {
00099 struct constraintRecord *rv;
00100 int c1Changed = FALSE, c2Changed = FALSE;
00101
00102
00103
00104
00105
00106
00107 if ((c1 == NULL) && (c2 == NULL))
00108 {
00109 rv = GetConstraintRecord(theEnv);
00110 rv->multifieldsAllowed = TRUE;
00111 return(rv);
00112 }
00113
00114
00115
00116
00117
00118
00119
00120 if (c1 == NULL) return(CopyConstraintRecord(theEnv,c2));
00121
00122 if (c2 == NULL) return(CopyConstraintRecord(theEnv,c1));
00123
00124
00125
00126
00127
00128 rv = GetConstraintRecord(theEnv);
00129
00130
00131
00132
00133
00134 if ((c1->multifieldsAllowed != c2->multifieldsAllowed) &&
00135 (c1->singlefieldsAllowed != c2->singlefieldsAllowed))
00136 {
00137 rv->anyAllowed = FALSE;
00138 return(rv);
00139 }
00140
00141 if (c1->multifieldsAllowed && c2->multifieldsAllowed)
00142 { rv->multifieldsAllowed = TRUE; }
00143 else
00144 { rv->multifieldsAllowed = FALSE; }
00145
00146 if (c1->singlefieldsAllowed && c2->singlefieldsAllowed)
00147 { rv->singlefieldsAllowed = TRUE; }
00148 else
00149 { rv->singlefieldsAllowed = FALSE; }
00150
00151 if (c1->anyAllowed && c2->anyAllowed) rv->anyAllowed = TRUE;
00152 else
00153 {
00154 if (c1->anyAllowed)
00155 {
00156 c1Changed = TRUE;
00157 SetAnyAllowedFlags(c1,FALSE);
00158 }
00159 else if (c2->anyAllowed)
00160 {
00161 c2Changed = TRUE;
00162 SetAnyAllowedFlags(c2,FALSE);
00163 }
00164
00165 rv->anyAllowed = FALSE;
00166 rv->symbolsAllowed = (c1->symbolsAllowed && c2->symbolsAllowed);
00167 rv->stringsAllowed = (c1->stringsAllowed && c2->stringsAllowed);
00168 rv->floatsAllowed = (c1->floatsAllowed && c2->floatsAllowed);
00169 rv->integersAllowed = (c1->integersAllowed && c2->integersAllowed);
00170 rv->instanceNamesAllowed = (c1->instanceNamesAllowed && c2->instanceNamesAllowed);
00171 rv->instanceAddressesAllowed = (c1->instanceAddressesAllowed && c2->instanceAddressesAllowed);
00172 rv->externalAddressesAllowed = (c1->externalAddressesAllowed && c2->externalAddressesAllowed);
00173 rv->voidAllowed = (c1->voidAllowed && c2->voidAllowed);
00174 rv->multifieldsAllowed = (c1->multifieldsAllowed && c2->multifieldsAllowed);
00175 rv->factAddressesAllowed = (c1->factAddressesAllowed && c2->factAddressesAllowed);
00176
00177 if (c1Changed) SetAnyAllowedFlags(c1,TRUE);
00178 if (c2Changed) SetAnyAllowedFlags(c2,TRUE);
00179 }
00180
00181
00182
00183
00184
00185 if (c1->anyRestriction || c2->anyRestriction) rv->anyRestriction = TRUE;
00186 else
00187 {
00188 rv->anyRestriction = FALSE;
00189 rv->symbolRestriction = (c1->symbolRestriction || c2->symbolRestriction);
00190 rv->stringRestriction = (c1->stringRestriction || c2->stringRestriction);
00191 rv->floatRestriction = (c1->floatRestriction || c2->floatRestriction);
00192 rv->integerRestriction = (c1->integerRestriction || c2->integerRestriction);
00193 rv->classRestriction = (c1->classRestriction || c2->classRestriction);
00194 rv->instanceNameRestriction = (c1->instanceNameRestriction || c2->instanceNameRestriction);
00195 }
00196
00197
00198
00199
00200
00201
00202 IntersectAllowedValueExpressions(theEnv,c1,c2,rv);
00203 IntersectAllowedClassExpressions(theEnv,c1,c2,rv);
00204 IntersectNumericExpressions(theEnv,c1,c2,rv,TRUE);
00205 IntersectNumericExpressions(theEnv,c1,c2,rv,FALSE);
00206
00207
00208
00209
00210
00211
00212
00213 UpdateRestrictionFlags(rv);
00214
00215
00216
00217
00218
00219
00220 if (rv->multifieldsAllowed)
00221 {
00222 rv->multifield = IntersectConstraints(theEnv,c1->multifield,c2->multifield);
00223 if (UnmatchableConstraint(rv->multifield))
00224 { rv->multifieldsAllowed = FALSE; }
00225 }
00226
00227
00228
00229
00230
00231
00232 return(rv);
00233 }
00234
00235
00236
00237
00238
00239 static void IntersectAllowedValueExpressions(
00240 void *theEnv,
00241 CONSTRAINT_RECORD *constraint1,
00242 CONSTRAINT_RECORD *constraint2,
00243 CONSTRAINT_RECORD *newConstraint)
00244 {
00245 struct expr *theList1, *theList2;
00246 struct expr *theHead = NULL, *tmpExpr;
00247
00248
00249
00250
00251
00252
00253
00254
00255 for (theList1 = constraint1->restrictionList;
00256 theList1 != NULL;
00257 theList1 = theList1->nextArg)
00258 {
00259 if (CheckAllowedValuesConstraint(theList1->type,theList1->value,constraint1) &&
00260 CheckAllowedValuesConstraint(theList1->type,theList1->value,constraint2))
00261 {
00262 tmpExpr = GenConstant(theEnv,theList1->type,theList1->value);
00263 tmpExpr->nextArg = theHead;
00264 theHead = tmpExpr;
00265 }
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275 for (theList2 = constraint2->restrictionList;
00276 theList2 != NULL;
00277 theList2 = theList2->nextArg)
00278 {
00279 if (FindItemInExpression(theList2->type,theList2->value,TRUE,theHead))
00280 { }
00281 else if (CheckAllowedValuesConstraint(theList2->type,theList2->value,constraint1) &&
00282 CheckAllowedValuesConstraint(theList2->type,theList2->value,constraint2))
00283 {
00284 tmpExpr = GenConstant(theEnv,theList2->type,theList2->value);
00285 tmpExpr->nextArg = theHead;
00286 theHead = tmpExpr;
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295
00296 newConstraint->restrictionList = theHead;
00297 }
00298
00299
00300
00301
00302
00303 static void IntersectAllowedClassExpressions(
00304 void *theEnv,
00305 CONSTRAINT_RECORD *constraint1,
00306 CONSTRAINT_RECORD *constraint2,
00307 CONSTRAINT_RECORD *newConstraint)
00308 {
00309 struct expr *theList1, *theList2;
00310 struct expr *theHead = NULL, *tmpExpr;
00311
00312
00313
00314
00315
00316
00317
00318
00319 for (theList1 = constraint1->classList;
00320 theList1 != NULL;
00321 theList1 = theList1->nextArg)
00322 {
00323 if (CheckAllowedClassesConstraint(theEnv,theList1->type,theList1->value,constraint1) &&
00324 CheckAllowedClassesConstraint(theEnv,theList1->type,theList1->value,constraint2))
00325 {
00326 tmpExpr = GenConstant(theEnv,theList1->type,theList1->value);
00327 tmpExpr->nextArg = theHead;
00328 theHead = tmpExpr;
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 for (theList2 = constraint2->classList;
00340 theList2 != NULL;
00341 theList2 = theList2->nextArg)
00342 {
00343 if (FindItemInExpression(theList2->type,theList2->value,TRUE,theHead))
00344 { }
00345 else if (CheckAllowedClassesConstraint(theEnv,theList2->type,theList2->value,constraint1) &&
00346 CheckAllowedClassesConstraint(theEnv,theList2->type,theList2->value,constraint2))
00347 {
00348 tmpExpr = GenConstant(theEnv,theList2->type,theList2->value);
00349 tmpExpr->nextArg = theHead;
00350 theHead = tmpExpr;
00351 }
00352 }
00353
00354
00355
00356
00357
00358
00359
00360 newConstraint->classList = theHead;
00361 }
00362
00363
00364
00365
00366
00367 static void IntersectNumericExpressions(
00368 void *theEnv,
00369 CONSTRAINT_RECORD *constraint1,
00370 CONSTRAINT_RECORD *constraint2,
00371 CONSTRAINT_RECORD *newConstraint,
00372 int range)
00373 {
00374 struct expr *tmpmin1, *tmpmax1, *tmpmin2, *tmpmax2, *theMin, *theMax;
00375 struct expr *theMinList, *theMaxList, *lastMin = NULL, *lastMax = NULL;
00376 int cmaxmax, cminmin, cmaxmin, cminmax;
00377
00378
00379
00380
00381
00382
00383 theMinList = NULL;
00384 theMaxList = NULL;
00385
00386
00387
00388
00389
00390
00391 if (range)
00392 {
00393 tmpmin1 = constraint1->minValue;
00394 tmpmax1 = constraint1->maxValue;
00395 }
00396 else
00397 {
00398 tmpmin1 = constraint1->minFields;
00399 tmpmax1 = constraint1->maxFields;
00400 }
00401
00402
00403
00404
00405
00406
00407 for (;
00408 tmpmin1 != NULL;
00409 tmpmin1 = tmpmin1->nextArg, tmpmax1 = tmpmax1->nextArg)
00410 {
00411
00412
00413
00414
00415
00416 if (range)
00417 {
00418 tmpmin2 = constraint2->minValue;
00419 tmpmax2 = constraint2->maxValue;
00420 }
00421 else
00422 {
00423 tmpmin2 = constraint2->minFields;
00424 tmpmax2 = constraint2->maxFields;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433 for (;
00434 tmpmin2 != NULL;
00435 tmpmin2 = tmpmin2->nextArg, tmpmax2 = tmpmax2->nextArg)
00436 {
00437
00438
00439
00440
00441
00442 cmaxmax = CompareNumbers(theEnv,tmpmax1->type,tmpmax1->value,
00443 tmpmax2->type,tmpmax2->value);
00444
00445 cminmin = CompareNumbers(theEnv,tmpmin1->type,tmpmin1->value,
00446 tmpmin2->type,tmpmin2->value);
00447
00448 cmaxmin = CompareNumbers(theEnv,tmpmax1->type,tmpmax1->value,
00449 tmpmin2->type,tmpmin2->value);
00450
00451 cminmax = CompareNumbers(theEnv,tmpmin1->type,tmpmin1->value,
00452 tmpmax2->type,tmpmax2->value);
00453
00454
00455
00456
00457
00458
00459
00460 if ((cmaxmin == LESS_THAN) || (cminmax == GREATER_THAN))
00461 { continue; }
00462
00463
00464
00465
00466
00467
00468 if (cminmin == GREATER_THAN)
00469 { theMin = GenConstant(theEnv,tmpmin1->type,tmpmin1->value); }
00470 else
00471 { theMin = GenConstant(theEnv,tmpmin2->type,tmpmin2->value); }
00472
00473
00474
00475
00476
00477
00478 if (cmaxmax == LESS_THAN)
00479 { theMax = GenConstant(theEnv,tmpmax1->type,tmpmax1->value); }
00480 else
00481 { theMax = GenConstant(theEnv,tmpmax2->type,tmpmax2->value); }
00482
00483
00484
00485
00486
00487
00488 if (lastMin == NULL)
00489 {
00490 theMinList = theMin;
00491 theMaxList = theMax;
00492 }
00493 else
00494 {
00495 lastMin->nextArg = theMin;
00496 lastMax->nextArg = theMax;
00497 }
00498
00499 lastMin = theMin;
00500 lastMax = theMax;
00501 }
00502 }
00503
00504
00505
00506
00507
00508
00509
00510 if (theMinList != NULL)
00511 {
00512 if (range)
00513 {
00514 ReturnExpression(theEnv,newConstraint->minValue);
00515 ReturnExpression(theEnv,newConstraint->maxValue);
00516 newConstraint->minValue = theMinList;
00517 newConstraint->maxValue = theMaxList;
00518 }
00519 else
00520 {
00521 ReturnExpression(theEnv,newConstraint->minFields);
00522 ReturnExpression(theEnv,newConstraint->maxFields);
00523 newConstraint->minFields = theMinList;
00524 newConstraint->maxFields = theMaxList;
00525 }
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535 else
00536 {
00537 if (range)
00538 {
00539 if (newConstraint->anyAllowed) SetAnyAllowedFlags(newConstraint,FALSE);
00540 newConstraint->integersAllowed = FALSE;
00541 newConstraint->floatsAllowed = FALSE;
00542 }
00543 else
00544 {
00545 SetAnyAllowedFlags(newConstraint,TRUE);
00546 newConstraint->singlefieldsAllowed = FALSE;
00547 newConstraint->multifieldsAllowed = FALSE;
00548 newConstraint->anyAllowed = FALSE;
00549 }
00550 }
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 static void UpdateRestrictionFlags(
00562 CONSTRAINT_RECORD *rv)
00563 {
00564 if ((rv->anyRestriction) && (rv->restrictionList == NULL))
00565 {
00566 SetAnyAllowedFlags(rv,TRUE);
00567 rv->anyAllowed = FALSE;
00568 }
00569
00570 if ((rv->symbolRestriction) && (rv->symbolsAllowed))
00571 { rv->symbolsAllowed = FindItemInExpression(SYMBOL,NULL,FALSE,rv->restrictionList); }
00572
00573 if ((rv->stringRestriction) && (rv->stringsAllowed))
00574 { rv->stringsAllowed = FindItemInExpression(STRING,NULL,FALSE,rv->restrictionList); }
00575
00576 if ((rv->floatRestriction) && (rv->floatsAllowed))
00577 { rv->floatsAllowed = FindItemInExpression(FLOAT,NULL,FALSE,rv->restrictionList); }
00578
00579 if ((rv->integerRestriction) && (rv->integersAllowed))
00580 { rv->integersAllowed = FindItemInExpression(INTEGER,NULL,FALSE,rv->restrictionList); }
00581
00582 if ((rv->instanceNameRestriction) && (rv->instanceNamesAllowed))
00583 { rv->instanceNamesAllowed = FindItemInExpression(INSTANCE_NAME,NULL,FALSE,rv->restrictionList); }
00584 }
00585
00586
00587
00588
00589
00590
00591
00592 static int FindItemInExpression(
00593 int theType,
00594 void *theValue,
00595 int useValue,
00596 struct expr *theList)
00597 {
00598 while (theList != NULL)
00599 {
00600 if (theList->type == theType)
00601 {
00602 if (! useValue) return(TRUE);
00603 else if (theList->value == theValue) return(TRUE);
00604 }
00605
00606 theList = theList->nextArg;
00607 }
00608
00609 return(FALSE);
00610 }
00611
00612 #if (! BLOAD_ONLY)
00613
00614
00615
00616
00617
00618
00619 static int RestrictionOnType(
00620 int theType,
00621 CONSTRAINT_RECORD *theConstraint)
00622 {
00623 if (theConstraint == NULL) return(FALSE);
00624
00625 if ((theConstraint->anyRestriction) ||
00626 (theConstraint->symbolRestriction && (theType == SYMBOL)) ||
00627 (theConstraint->stringRestriction && (theType == STRING)) ||
00628 (theConstraint->floatRestriction && (theType == FLOAT)) ||
00629 (theConstraint->integerRestriction && (theType == INTEGER)) ||
00630 (theConstraint->classRestriction && ((theType == INSTANCE_ADDRESS) ||
00631 (theType == INSTANCE_NAME))) ||
00632 (theConstraint->instanceNameRestriction && (theType == INSTANCE_NAME)))
00633 { return(TRUE); }
00634
00635 return(FALSE);
00636 }
00637
00638
00639
00640
00641
00642 globle struct constraintRecord *UnionConstraints(
00643 void *theEnv,
00644 CONSTRAINT_RECORD *c1,
00645 CONSTRAINT_RECORD *c2)
00646 {
00647 struct constraintRecord *rv;
00648 int c1Changed = FALSE, c2Changed = FALSE;
00649
00650
00651
00652
00653
00654
00655 if ((c1 == NULL) && (c2 == NULL)) return(GetConstraintRecord(theEnv));
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 if (c1 == NULL) return(CopyConstraintRecord(theEnv,c2));
00667
00668 if (c2 == NULL) return(CopyConstraintRecord(theEnv,c1));
00669
00670
00671
00672
00673
00674 rv = GetConstraintRecord(theEnv);
00675
00676
00677
00678
00679
00680 if (c1->multifieldsAllowed || c2->multifieldsAllowed)
00681 { rv->multifieldsAllowed = TRUE; }
00682
00683 if (c1->singlefieldsAllowed || c2->singlefieldsAllowed)
00684 { rv->singlefieldsAllowed = TRUE; }
00685
00686 if (c1->anyAllowed || c2->anyAllowed) rv->anyAllowed = TRUE;
00687 else
00688 {
00689 rv->anyAllowed = FALSE;
00690 rv->symbolsAllowed = (c1->symbolsAllowed || c2->symbolsAllowed);
00691 rv->stringsAllowed = (c1->stringsAllowed || c2->stringsAllowed);
00692 rv->floatsAllowed = (c1->floatsAllowed || c2->floatsAllowed);
00693 rv->integersAllowed = (c1->integersAllowed || c2->integersAllowed);
00694 rv->instanceNamesAllowed = (c1->instanceNamesAllowed || c2->instanceNamesAllowed);
00695 rv->instanceAddressesAllowed = (c1->instanceAddressesAllowed || c2->instanceAddressesAllowed);
00696 rv->externalAddressesAllowed = (c1->externalAddressesAllowed || c2->externalAddressesAllowed);
00697 rv->voidAllowed = (c1->voidAllowed || c2->voidAllowed);
00698 rv->factAddressesAllowed = (c1->factAddressesAllowed || c2->factAddressesAllowed);
00699 }
00700
00701
00702
00703
00704
00705 if (c1->anyRestriction && c2->anyRestriction) rv->anyRestriction = TRUE;
00706 else
00707 {
00708 if (c1->anyRestriction)
00709 {
00710 c1Changed = TRUE;
00711 SetAnyRestrictionFlags(c1,FALSE);
00712 }
00713 else if (c2->anyRestriction)
00714 {
00715 c2Changed = TRUE;
00716 SetAnyRestrictionFlags(c2,FALSE);
00717 }
00718
00719 rv->anyRestriction = FALSE;
00720 rv->symbolRestriction = (c1->symbolRestriction && c2->symbolRestriction);
00721 rv->stringRestriction = (c1->stringRestriction && c2->stringRestriction);
00722 rv->floatRestriction = (c1->floatRestriction && c2->floatRestriction);
00723 rv->integerRestriction = (c1->integerRestriction && c2->integerRestriction);
00724 rv->classRestriction = (c1->classRestriction && c2->classRestriction);
00725 rv->instanceNameRestriction = (c1->instanceNameRestriction && c2->instanceNameRestriction);
00726
00727 if (c1Changed) SetAnyRestrictionFlags(c1,FALSE);
00728 else if (c2Changed) SetAnyRestrictionFlags(c2,FALSE);
00729 }
00730
00731
00732
00733
00734
00735
00736 UnionAllowedValueExpressions(theEnv,c1,c2,rv);
00737 UnionAllowedClassExpressions(theEnv,c1,c2,rv);
00738 UnionNumericExpressions(theEnv,c1,c2,rv,TRUE);
00739 UnionNumericExpressions(theEnv,c1,c2,rv,FALSE);
00740
00741
00742
00743
00744
00745
00746 if (rv->multifieldsAllowed)
00747 { rv->multifield = UnionConstraints(theEnv,c1->multifield,c2->multifield); }
00748
00749
00750
00751
00752
00753
00754 return(rv);
00755 }
00756
00757
00758
00759
00760
00761 static void UnionNumericExpressions(
00762 void *theEnv,
00763 CONSTRAINT_RECORD *constraint1,
00764 CONSTRAINT_RECORD *constraint2,
00765 CONSTRAINT_RECORD *newConstraint,
00766 int range)
00767 {
00768 struct expr *tmpmin, *tmpmax;
00769 struct expr *theMinList, *theMaxList;
00770
00771
00772
00773
00774
00775
00776 theMinList = NULL;
00777 theMaxList = NULL;
00778
00779
00780
00781
00782
00783
00784 if (range)
00785 {
00786 tmpmin = constraint1->minValue;
00787 tmpmax = constraint1->maxValue;
00788 }
00789 else
00790 {
00791 tmpmin = constraint1->minFields;
00792 tmpmax = constraint1->maxFields;
00793 }
00794
00795
00796
00797
00798
00799
00800 for (;
00801 tmpmin != NULL;
00802 tmpmin = tmpmin->nextArg,tmpmax = tmpmax->nextArg)
00803 { UnionRangeMinMaxValueWithList(theEnv,tmpmin,tmpmax,&theMinList,&theMaxList); }
00804
00805
00806
00807
00808
00809
00810 if (range)
00811 {
00812 tmpmin = constraint2->minValue;
00813 tmpmax = constraint2->maxValue;
00814 }
00815 else
00816 {
00817 tmpmin = constraint2->minFields;
00818 tmpmax = constraint2->maxFields;
00819 }
00820
00821
00822
00823
00824
00825
00826 for (;
00827 tmpmin != NULL;
00828 tmpmin = tmpmin->nextArg,tmpmax = tmpmax->nextArg)
00829 { UnionRangeMinMaxValueWithList(theEnv,tmpmin,tmpmax,&theMinList,&theMaxList); }
00830
00831
00832
00833
00834
00835
00836
00837 if (theMinList != NULL)
00838 {
00839 if (range)
00840 {
00841 ReturnExpression(theEnv,newConstraint->minValue);
00842 ReturnExpression(theEnv,newConstraint->maxValue);
00843 newConstraint->minValue = theMinList;
00844 newConstraint->maxValue = theMaxList;
00845 }
00846 else
00847 {
00848 ReturnExpression(theEnv,newConstraint->minFields);
00849 ReturnExpression(theEnv,newConstraint->maxFields);
00850 newConstraint->minFields = theMinList;
00851 newConstraint->maxFields = theMaxList;
00852 }
00853 }
00854
00855
00856
00857
00858
00859
00860
00861
00862 else
00863 {
00864 if (range)
00865 {
00866 if (newConstraint->anyAllowed) SetAnyAllowedFlags(newConstraint,FALSE);
00867 newConstraint->integersAllowed = FALSE;
00868 newConstraint->floatsAllowed = FALSE;
00869 }
00870 else
00871 {
00872 SetAnyAllowedFlags(newConstraint,TRUE);
00873 newConstraint->anyAllowed = TRUE;
00874 }
00875 }
00876 }
00877
00878
00879
00880
00881
00882 static void UnionRangeMinMaxValueWithList(
00883 void *theEnv,
00884 struct expr *addmin,
00885 struct expr *addmax,
00886 struct expr **theMinList,
00887 struct expr **theMaxList)
00888 {
00889 struct expr *tmpmin, *tmpmax, *lastmin, *lastmax;
00890 struct expr *themin, *themax, *nextmin, *nextmax;
00891 int cmaxmin, cmaxmax, cminmin, cminmax;
00892
00893
00894
00895
00896
00897 if (*theMinList == NULL)
00898 {
00899 *theMinList = GenConstant(theEnv,addmin->type,addmin->value);
00900 *theMaxList = GenConstant(theEnv,addmax->type,addmax->value);
00901 return;
00902 }
00903
00904 lastmin = NULL;
00905 lastmax = NULL;
00906 tmpmin = (*theMinList);
00907 tmpmax = (*theMaxList);
00908
00909 while (tmpmin != NULL)
00910 {
00911 cmaxmax = CompareNumbers(theEnv,addmax->type,addmax->value,
00912 tmpmax->type,tmpmax->value);
00913
00914 cminmin = CompareNumbers(theEnv,addmin->type,addmin->value,
00915 tmpmin->type,tmpmin->value);
00916
00917 cmaxmin = CompareNumbers(theEnv,addmax->type,addmax->value,
00918 tmpmin->type,tmpmin->value);
00919
00920 cminmax = CompareNumbers(theEnv,addmin->type,addmin->value,
00921 tmpmax->type,tmpmax->value);
00922
00923
00924
00925
00926
00927
00928 if (((cmaxmax == LESS_THAN) || (cmaxmax == EQUAL)) &&
00929 ((cminmin == GREATER_THAN) || (cminmin == EQUAL)))
00930 { return; }
00931
00932
00933
00934
00935
00936 if ((cmaxmax == GREATER_THAN) &&
00937 ((cminmax == LESS_THAN) || (cminmax == EQUAL)))
00938 {
00939 tmpmax->type = addmax->type;
00940 tmpmax->value = addmax->value;
00941 }
00942
00943
00944
00945
00946
00947 if ((cminmin == LESS_THAN) &&
00948 ((cmaxmin == GREATER_THAN) || (cmaxmin == EQUAL)))
00949 {
00950 tmpmin->type = addmin->type;
00951 tmpmin->value = addmin->value;
00952 }
00953
00954
00955
00956
00957
00958 if (cmaxmin == LESS_THAN)
00959 {
00960 if (lastmax == NULL)
00961 {
00962 themin = GenConstant(theEnv,addmin->type,addmin->value);
00963 themax = GenConstant(theEnv,addmax->type,addmax->value);
00964 themin->nextArg = *theMinList;
00965 themax->nextArg = *theMaxList;
00966 *theMinList = themin;
00967 *theMaxList = themax;
00968 return;
00969 }
00970
00971 if (CompareNumbers(theEnv,addmin->type,addmin->value,
00972 lastmax->type,lastmax->value) == GREATER_THAN)
00973 {
00974 themin = GenConstant(theEnv,addmin->type,addmin->value);
00975 themax = GenConstant(theEnv,addmax->type,addmax->value);
00976
00977 themin->nextArg = lastmin->nextArg;
00978 themax->nextArg = lastmax->nextArg;
00979
00980 lastmin->nextArg = themin;
00981 lastmax->nextArg = themax;
00982 return;
00983 }
00984 }
00985
00986
00987
00988
00989
00990 tmpmin = tmpmin->nextArg;
00991 tmpmax = tmpmax->nextArg;
00992 }
00993
00994
00995
00996
00997
00998 tmpmin = (*theMinList);
00999 tmpmax = (*theMaxList);
01000
01001 while (tmpmin != NULL)
01002 {
01003 nextmin = tmpmin->nextArg;
01004 nextmax = tmpmax->nextArg;
01005 if (nextmin != NULL)
01006 {
01007 cmaxmin = CompareNumbers(theEnv,tmpmax->type,tmpmax->value,
01008 nextmin->type,nextmin->value);
01009 if ((cmaxmin == GREATER_THAN) || (cmaxmin == EQUAL))
01010 {
01011 tmpmax->type = nextmax->type;
01012 tmpmax->value = nextmax->value;
01013 tmpmax->nextArg = nextmax->nextArg;
01014 tmpmin->nextArg = nextmin->nextArg;
01015
01016 rtn_struct(theEnv,expr,nextmin);
01017 rtn_struct(theEnv,expr,nextmax);
01018 }
01019 else
01020 {
01021 tmpmin = tmpmin->nextArg;
01022 tmpmax = tmpmax->nextArg;
01023 }
01024 }
01025 else
01026 {
01027 tmpmin = nextmin;
01028 tmpmax = nextmax;
01029 }
01030 }
01031 }
01032
01033
01034
01035
01036
01037 static void UnionAllowedClassExpressions(
01038 void *theEnv,
01039 CONSTRAINT_RECORD *constraint1,
01040 CONSTRAINT_RECORD *constraint2,
01041 CONSTRAINT_RECORD *newConstraint)
01042 {
01043 struct expr *theHead = NULL;
01044
01045 theHead = AddToUnionList(theEnv,constraint1->classList,theHead,newConstraint);
01046 theHead = AddToUnionList(theEnv,constraint2->classList,theHead,newConstraint);
01047
01048 newConstraint->classList = theHead;
01049 }
01050
01051
01052
01053
01054
01055 static void UnionAllowedValueExpressions(
01056 void *theEnv,
01057 CONSTRAINT_RECORD *constraint1,
01058 CONSTRAINT_RECORD *constraint2,
01059 CONSTRAINT_RECORD *newConstraint)
01060 {
01061 struct expr *theHead = NULL;
01062
01063 theHead = AddToUnionList(theEnv,constraint1->restrictionList,theHead,newConstraint);
01064 theHead = AddToUnionList(theEnv,constraint2->restrictionList,theHead,newConstraint);
01065
01066 newConstraint->restrictionList = theHead;
01067 }
01068
01069
01070
01071
01072
01073
01074 static struct expr *AddToUnionList(
01075 void *theEnv,
01076 struct expr *theList1,
01077 struct expr *theHead,
01078 CONSTRAINT_RECORD *theConstraint)
01079 {
01080 struct expr *theList2;
01081 int flag;
01082
01083
01084
01085
01086
01087
01088 for (;theList1 != NULL; theList1 = theList1->nextArg)
01089 {
01090
01091
01092
01093
01094
01095 flag = TRUE;
01096 for (theList2 = theHead;
01097 theList2 != NULL;
01098 theList2 = theList2->nextArg)
01099 {
01100 if ((theList1->type == theList2->type) &&
01101 (theList1->value == theList2->value))
01102 {
01103 flag = FALSE;
01104 break;
01105 }
01106 }
01107
01108
01109
01110
01111
01112
01113
01114 if (flag)
01115 {
01116 if (RestrictionOnType(theList1->type,theConstraint))
01117 {
01118 theList2 = GenConstant(theEnv,theList1->type,theList1->value);
01119 theList2->nextArg = theHead;
01120 theHead = theList2;
01121 }
01122 }
01123 }
01124
01125
01126
01127
01128
01129 return(theHead);
01130 }
01131
01132
01133
01134
01135
01136
01137 globle void RemoveConstantFromConstraint(
01138 void *theEnv,
01139 int theType,
01140 void *theValue,
01141 CONSTRAINT_RECORD *theConstraint)
01142 {
01143 struct expr *theList, *lastOne = NULL, *tmpList;
01144
01145 if (theConstraint == NULL) return;
01146
01147 theList = theConstraint->restrictionList;
01148 theConstraint->restrictionList = NULL;
01149
01150 while (theList != NULL)
01151 {
01152 if ((theList->type != theType) || (theList->value != theValue))
01153 {
01154 if (lastOne == NULL)
01155 { theConstraint->restrictionList = theList; }
01156 else
01157 { lastOne->nextArg = theList; }
01158 lastOne = theList;
01159 theList = theList->nextArg;
01160 lastOne->nextArg = NULL;
01161 }
01162 else
01163 {
01164 tmpList = theList;
01165 theList = theList->nextArg;
01166 tmpList->nextArg = NULL;
01167 ReturnExpression(theEnv,tmpList);
01168 }
01169 }
01170
01171 UpdateRestrictionFlags(theConstraint);
01172 }
01173
01174 #endif
01175
01176 #endif
01177
01178
01179
01180