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
00026
00027
00028
00029
00030 #define _CONSTRNT_SOURCE_
00031
00032 #include <stdio.h>
00033 #define _STDIO_INCLUDED_
00034 #include <stdlib.h>
00035
00036 #include "setup.h"
00037
00038 #include "argacces.h"
00039 #include "constant.h"
00040 #include "envrnmnt.h"
00041 #include "extnfunc.h"
00042 #include "memalloc.h"
00043 #include "multifld.h"
00044 #include "router.h"
00045 #include "scanner.h"
00046
00047 #include "constrnt.h"
00048
00049
00050
00051
00052
00053 #if (! RUN_TIME) && (! BLOAD_ONLY)
00054 static void InstallConstraintRecord(void *,CONSTRAINT_RECORD *);
00055 static int ConstraintCompare(struct constraintRecord *,struct constraintRecord *);
00056 #endif
00057 #if (! RUN_TIME)
00058 static void ReturnConstraintRecord(void *,CONSTRAINT_RECORD *);
00059 static void DeinstallConstraintRecord(void *,CONSTRAINT_RECORD *);
00060 #endif
00061 static void DeallocateConstraintData(void *);
00062
00063
00064
00065
00066
00067
00068 globle void InitializeConstraints(
00069 void *theEnv)
00070 {
00071 #if (! RUN_TIME) && (! BLOAD_ONLY)
00072 int i;
00073 #endif
00074
00075 AllocateEnvironmentData(theEnv,CONSTRAINT_DATA,sizeof(struct constraintData),DeallocateConstraintData);
00076
00077 ConstraintData(theEnv)->StaticConstraintChecking = TRUE;
00078
00079 #if (! RUN_TIME) && (! BLOAD_ONLY)
00080
00081 ConstraintData(theEnv)->ConstraintHashtable = (struct constraintRecord **)
00082 gm2(theEnv,(int) sizeof (struct constraintRecord *) *
00083 SIZE_CONSTRAINT_HASH);
00084
00085 if (ConstraintData(theEnv)->ConstraintHashtable == NULL) EnvExitRouter(theEnv,EXIT_FAILURE);
00086
00087 for (i = 0; i < SIZE_CONSTRAINT_HASH; i++) ConstraintData(theEnv)->ConstraintHashtable[i] = NULL;
00088 #endif
00089
00090 #if (! RUN_TIME)
00091 EnvDefineFunction2(theEnv,"get-dynamic-constraint-checking",'b',GDCCommand,"GDCCommand", "00");
00092 EnvDefineFunction2(theEnv,"set-dynamic-constraint-checking",'b',SDCCommand,"SDCCommand", "11");
00093
00094 EnvDefineFunction2(theEnv,"get-static-constraint-checking",'b',GSCCommand,"GSCCommand", "00");
00095 EnvDefineFunction2(theEnv,"set-static-constraint-checking",'b',SSCCommand,"SSCCommand", "11");
00096 #endif
00097 }
00098
00099
00100
00101
00102
00103 static void DeallocateConstraintData(
00104 void *theEnv)
00105 {
00106 #if ! RUN_TIME
00107 struct constraintRecord *tmpPtr, *nextPtr;
00108 int i;
00109
00110 for (i = 0; i < SIZE_CONSTRAINT_HASH; i++)
00111 {
00112 tmpPtr = ConstraintData(theEnv)->ConstraintHashtable[i];
00113 while (tmpPtr != NULL)
00114 {
00115 nextPtr = tmpPtr->next;
00116 ReturnConstraintRecord(theEnv,tmpPtr);
00117 tmpPtr = nextPtr;
00118 }
00119 }
00120
00121 rm(theEnv,ConstraintData(theEnv)->ConstraintHashtable,
00122 (int) sizeof (struct constraintRecord *) * SIZE_CONSTRAINT_HASH);
00123 #else
00124 #if MAC_MCW || WIN_MCW || MAC_XCD
00125 #pragma unused(theEnv)
00126 #endif
00127 #endif
00128
00129 #if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) && (! RUN_TIME)
00130 if (ConstraintData(theEnv)->NumberOfConstraints != 0)
00131 {
00132 genfree(theEnv,(void *) ConstraintData(theEnv)->ConstraintArray,
00133 (sizeof(CONSTRAINT_RECORD) * ConstraintData(theEnv)->NumberOfConstraints));
00134 }
00135 #endif
00136 }
00137
00138 #if (! RUN_TIME)
00139
00140
00141
00142
00143
00144
00145 static void ReturnConstraintRecord(
00146 void *theEnv,
00147 CONSTRAINT_RECORD *constraints)
00148 {
00149 if (constraints == NULL) return;
00150
00151 if (constraints->bucket < 0)
00152 {
00153 ReturnExpression(theEnv,constraints->classList);
00154 ReturnExpression(theEnv,constraints->restrictionList);
00155 ReturnExpression(theEnv,constraints->maxValue);
00156 ReturnExpression(theEnv,constraints->minValue);
00157 ReturnExpression(theEnv,constraints->minFields);
00158 ReturnExpression(theEnv,constraints->maxFields);
00159 }
00160
00161 ReturnConstraintRecord(theEnv,constraints->multifield);
00162
00163 rtn_struct(theEnv,constraintRecord,constraints);
00164 }
00165
00166
00167
00168
00169
00170
00171 static void DeinstallConstraintRecord(
00172 void *theEnv,
00173 CONSTRAINT_RECORD *constraints)
00174 {
00175 if (constraints->bucket >= 0)
00176 {
00177 RemoveHashedExpression(theEnv,constraints->classList);
00178 RemoveHashedExpression(theEnv,constraints->restrictionList);
00179 RemoveHashedExpression(theEnv,constraints->maxValue);
00180 RemoveHashedExpression(theEnv,constraints->minValue);
00181 RemoveHashedExpression(theEnv,constraints->minFields);
00182 RemoveHashedExpression(theEnv,constraints->maxFields);
00183 }
00184 else
00185 {
00186 ExpressionDeinstall(theEnv,constraints->classList);
00187 ExpressionDeinstall(theEnv,constraints->restrictionList);
00188 ExpressionDeinstall(theEnv,constraints->maxValue);
00189 ExpressionDeinstall(theEnv,constraints->minValue);
00190 ExpressionDeinstall(theEnv,constraints->minFields);
00191 ExpressionDeinstall(theEnv,constraints->maxFields);
00192 }
00193
00194 if (constraints->multifield != NULL)
00195 { DeinstallConstraintRecord(theEnv,constraints->multifield); }
00196 }
00197
00198
00199
00200
00201
00202 globle void RemoveConstraint(
00203 void *theEnv,
00204 struct constraintRecord *theConstraint)
00205 {
00206 struct constraintRecord *tmpPtr, *prevPtr = NULL;
00207
00208 if (theConstraint == NULL) return;
00209
00210
00211
00212
00213
00214
00215
00216 if (theConstraint->bucket < 0)
00217 {
00218 ReturnConstraintRecord(theEnv,theConstraint);
00219 return;
00220 }
00221
00222
00223
00224
00225
00226
00227 tmpPtr = ConstraintData(theEnv)->ConstraintHashtable[theConstraint->bucket];
00228 while (tmpPtr != NULL)
00229 {
00230 if (tmpPtr == theConstraint)
00231 {
00232 theConstraint->count--;
00233 if (theConstraint->count == 0)
00234 {
00235 if (prevPtr == NULL)
00236 { ConstraintData(theEnv)->ConstraintHashtable[theConstraint->bucket] = theConstraint->next; }
00237 else
00238 { prevPtr->next = theConstraint->next; }
00239 DeinstallConstraintRecord(theEnv,theConstraint);
00240 ReturnConstraintRecord(theEnv,theConstraint);
00241 }
00242 return;
00243 }
00244
00245 prevPtr = tmpPtr;
00246 tmpPtr = tmpPtr->next;
00247 }
00248
00249 return;
00250 }
00251
00252 #endif
00253
00254 #if (! RUN_TIME) && (! BLOAD_ONLY)
00255
00256
00257
00258
00259
00260 globle unsigned long HashConstraint(
00261 struct constraintRecord *theConstraint)
00262 {
00263 int i = 0;
00264 unsigned long count = 0;
00265 unsigned long hashValue;
00266 struct expr *tmpPtr;
00267
00268 count += (unsigned long)
00269 (theConstraint->anyAllowed * 17) +
00270 (theConstraint->symbolsAllowed * 5) +
00271 (theConstraint->stringsAllowed * 23) +
00272 (theConstraint->floatsAllowed * 19) +
00273 (theConstraint->integersAllowed * 29) +
00274 (theConstraint->instanceNamesAllowed * 31) +
00275 (theConstraint->instanceAddressesAllowed * 17);
00276
00277 count += (unsigned long)
00278 (theConstraint->externalAddressesAllowed * 29) +
00279 (theConstraint->voidAllowed * 29) +
00280 (theConstraint->multifieldsAllowed * 29) +
00281 (theConstraint->factAddressesAllowed * 79) +
00282 (theConstraint->anyRestriction * 59) +
00283 (theConstraint->symbolRestriction * 61);
00284
00285 count += (unsigned long)
00286 (theConstraint->stringRestriction * 3) +
00287 (theConstraint->floatRestriction * 37) +
00288 (theConstraint->integerRestriction * 9) +
00289 (theConstraint->classRestriction * 11) +
00290 (theConstraint->instanceNameRestriction * 7);
00291
00292 for (tmpPtr = theConstraint->classList; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
00293 { count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
00294
00295 for (tmpPtr = theConstraint->restrictionList; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
00296 { count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
00297
00298 for (tmpPtr = theConstraint->minValue; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
00299 { count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
00300
00301 for (tmpPtr = theConstraint->maxValue; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
00302 { count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
00303
00304 for (tmpPtr = theConstraint->minFields; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
00305 { count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
00306
00307 for (tmpPtr = theConstraint->maxFields; tmpPtr != NULL; tmpPtr = tmpPtr->nextArg)
00308 { count += GetAtomicHashValue(tmpPtr->type,tmpPtr->value,i++); }
00309
00310 if (theConstraint->multifield != NULL)
00311 { count += HashConstraint(theConstraint->multifield); }
00312
00313 hashValue = (unsigned long) (count % SIZE_CONSTRAINT_HASH);
00314
00315 return(hashValue);
00316 }
00317
00318
00319
00320
00321
00322
00323 static int ConstraintCompare(
00324 struct constraintRecord *constraint1,
00325 struct constraintRecord *constraint2)
00326 {
00327 struct expr *tmpPtr1, *tmpPtr2;
00328
00329 if ((constraint1->anyAllowed != constraint2->anyAllowed) ||
00330 (constraint1->symbolsAllowed != constraint2->symbolsAllowed) ||
00331 (constraint1->stringsAllowed != constraint2->stringsAllowed) ||
00332 (constraint1->floatsAllowed != constraint2->floatsAllowed) ||
00333 (constraint1->integersAllowed != constraint2->integersAllowed) ||
00334 (constraint1->instanceNamesAllowed != constraint2->instanceNamesAllowed) ||
00335 (constraint1->instanceAddressesAllowed != constraint2->instanceAddressesAllowed) ||
00336 (constraint1->externalAddressesAllowed != constraint2->externalAddressesAllowed) ||
00337 (constraint1->voidAllowed != constraint2->voidAllowed) ||
00338 (constraint1->multifieldsAllowed != constraint2->multifieldsAllowed) ||
00339 (constraint1->singlefieldsAllowed != constraint2->singlefieldsAllowed) ||
00340 (constraint1->factAddressesAllowed != constraint2->factAddressesAllowed) ||
00341 (constraint1->anyRestriction != constraint2->anyRestriction) ||
00342 (constraint1->symbolRestriction != constraint2->symbolRestriction) ||
00343 (constraint1->stringRestriction != constraint2->stringRestriction) ||
00344 (constraint1->floatRestriction != constraint2->floatRestriction) ||
00345 (constraint1->integerRestriction != constraint2->integerRestriction) ||
00346 (constraint1->classRestriction != constraint2->classRestriction) ||
00347 (constraint1->instanceNameRestriction != constraint2->instanceNameRestriction))
00348 { return(FALSE); }
00349
00350 for (tmpPtr1 = constraint1->classList, tmpPtr2 = constraint2->classList;
00351 (tmpPtr1 != NULL) && (tmpPtr2 != NULL);
00352 tmpPtr1 = tmpPtr1->nextArg, tmpPtr2 = tmpPtr2->nextArg)
00353 {
00354 if ((tmpPtr1->type != tmpPtr2->type) || (tmpPtr1->value != tmpPtr2->value))
00355 { return(FALSE); }
00356 }
00357 if (tmpPtr1 != tmpPtr2) return(FALSE);
00358
00359 for (tmpPtr1 = constraint1->restrictionList, tmpPtr2 = constraint2->restrictionList;
00360 (tmpPtr1 != NULL) && (tmpPtr2 != NULL);
00361 tmpPtr1 = tmpPtr1->nextArg, tmpPtr2 = tmpPtr2->nextArg)
00362 {
00363 if ((tmpPtr1->type != tmpPtr2->type) || (tmpPtr1->value != tmpPtr2->value))
00364 { return(FALSE); }
00365 }
00366 if (tmpPtr1 != tmpPtr2) return(FALSE);
00367
00368 for (tmpPtr1 = constraint1->minValue, tmpPtr2 = constraint2->minValue;
00369 (tmpPtr1 != NULL) && (tmpPtr2 != NULL);
00370 tmpPtr1 = tmpPtr1->nextArg, tmpPtr2 = tmpPtr2->nextArg)
00371 {
00372 if ((tmpPtr1->type != tmpPtr2->type) || (tmpPtr1->value != tmpPtr2->value))
00373 { return(FALSE); }
00374 }
00375 if (tmpPtr1 != tmpPtr2) return(FALSE);
00376
00377 for (tmpPtr1 = constraint1->maxValue, tmpPtr2 = constraint2->maxValue;
00378 (tmpPtr1 != NULL) && (tmpPtr2 != NULL);
00379 tmpPtr1 = tmpPtr1->nextArg, tmpPtr2 = tmpPtr2->nextArg)
00380 {
00381 if ((tmpPtr1->type != tmpPtr2->type) || (tmpPtr1->value != tmpPtr2->value))
00382 { return(FALSE); }
00383 }
00384 if (tmpPtr1 != tmpPtr2) return(FALSE);
00385
00386 for (tmpPtr1 = constraint1->minFields, tmpPtr2 = constraint2->minFields;
00387 (tmpPtr1 != NULL) && (tmpPtr2 != NULL);
00388 tmpPtr1 = tmpPtr1->nextArg, tmpPtr2 = tmpPtr2->nextArg)
00389 {
00390 if ((tmpPtr1->type != tmpPtr2->type) || (tmpPtr1->value != tmpPtr2->value))
00391 { return(FALSE); }
00392 }
00393 if (tmpPtr1 != tmpPtr2) return(FALSE);
00394
00395 for (tmpPtr1 = constraint1->maxFields, tmpPtr2 = constraint2->maxFields;
00396 (tmpPtr1 != NULL) && (tmpPtr2 != NULL);
00397 tmpPtr1 = tmpPtr1->nextArg, tmpPtr2 = tmpPtr2->nextArg)
00398 {
00399 if ((tmpPtr1->type != tmpPtr2->type) || (tmpPtr1->value != tmpPtr2->value))
00400 { return(FALSE); }
00401 }
00402 if (tmpPtr1 != tmpPtr2) return(FALSE);
00403
00404 if (((constraint1->multifield == NULL) && (constraint2->multifield != NULL)) ||
00405 ((constraint1->multifield != NULL) && (constraint2->multifield == NULL)))
00406 { return(FALSE); }
00407 else if (constraint1->multifield == constraint2->multifield)
00408 { return(TRUE); }
00409
00410 return(ConstraintCompare(constraint1->multifield,constraint2->multifield));
00411 }
00412
00413
00414
00415
00416
00417 globle struct constraintRecord *AddConstraint(
00418 void *theEnv,
00419 struct constraintRecord *theConstraint)
00420 {
00421 struct constraintRecord *tmpPtr;
00422 unsigned long hashValue;
00423
00424 if (theConstraint == NULL) return(NULL);
00425
00426 hashValue = HashConstraint(theConstraint);
00427
00428 for (tmpPtr = ConstraintData(theEnv)->ConstraintHashtable[hashValue];
00429 tmpPtr != NULL;
00430 tmpPtr = tmpPtr->next)
00431 {
00432 if (ConstraintCompare(theConstraint,tmpPtr))
00433 {
00434 tmpPtr->count++;
00435 ReturnConstraintRecord(theEnv,theConstraint);
00436 return(tmpPtr);
00437 }
00438 }
00439
00440 InstallConstraintRecord(theEnv,theConstraint);
00441 theConstraint->count = 1;
00442 theConstraint->bucket = hashValue;
00443 theConstraint->next = ConstraintData(theEnv)->ConstraintHashtable[hashValue];
00444 ConstraintData(theEnv)->ConstraintHashtable[hashValue] = theConstraint;
00445 return(theConstraint);
00446 }
00447
00448
00449
00450
00451
00452
00453 static void InstallConstraintRecord(
00454 void *theEnv,
00455 CONSTRAINT_RECORD *constraints)
00456 {
00457 struct expr *tempExpr;
00458
00459 tempExpr = AddHashedExpression(theEnv,constraints->classList);
00460 ReturnExpression(theEnv,constraints->classList);
00461 constraints->classList = tempExpr;
00462
00463 tempExpr = AddHashedExpression(theEnv,constraints->restrictionList);
00464 ReturnExpression(theEnv,constraints->restrictionList);
00465 constraints->restrictionList = tempExpr;
00466
00467 tempExpr = AddHashedExpression(theEnv,constraints->maxValue);
00468 ReturnExpression(theEnv,constraints->maxValue);
00469 constraints->maxValue = tempExpr;
00470
00471 tempExpr = AddHashedExpression(theEnv,constraints->minValue);
00472 ReturnExpression(theEnv,constraints->minValue);
00473 constraints->minValue = tempExpr;
00474
00475 tempExpr = AddHashedExpression(theEnv,constraints->minFields);
00476 ReturnExpression(theEnv,constraints->minFields);
00477 constraints->minFields = tempExpr;
00478
00479 tempExpr = AddHashedExpression(theEnv,constraints->maxFields);
00480 ReturnExpression(theEnv,constraints->maxFields);
00481 constraints->maxFields = tempExpr;
00482
00483 if (constraints->multifield != NULL)
00484 { InstallConstraintRecord(theEnv,constraints->multifield); }
00485 }
00486
00487 #endif
00488
00489
00490
00491
00492
00493 globle int SDCCommand(
00494 void *theEnv)
00495 {
00496 int oldValue;
00497 DATA_OBJECT arg_ptr;
00498
00499 oldValue = EnvGetDynamicConstraintChecking(theEnv);
00500
00501 if (EnvArgCountCheck(theEnv,"set-dynamic-constraint-checking",EXACTLY,1) == -1)
00502 { return(oldValue); }
00503
00504 EnvRtnUnknown(theEnv,1,&arg_ptr);
00505
00506 if ((arg_ptr.value == EnvFalseSymbol(theEnv)) && (arg_ptr.type == SYMBOL))
00507 { EnvSetDynamicConstraintChecking(theEnv,FALSE); }
00508 else
00509 { EnvSetDynamicConstraintChecking(theEnv,TRUE); }
00510
00511 return(oldValue);
00512 }
00513
00514
00515
00516
00517
00518 globle int GDCCommand(
00519 void *theEnv)
00520 {
00521 int oldValue;
00522
00523 oldValue = EnvGetDynamicConstraintChecking(theEnv);
00524
00525 if (EnvArgCountCheck(theEnv,"get-dynamic-constraint-checking",EXACTLY,0) == -1)
00526 { return(oldValue); }
00527
00528 return(oldValue);
00529 }
00530
00531
00532
00533
00534
00535 globle int SSCCommand(
00536 void *theEnv)
00537 {
00538 int oldValue;
00539 DATA_OBJECT arg_ptr;
00540
00541 oldValue = EnvGetStaticConstraintChecking(theEnv);
00542
00543 if (EnvArgCountCheck(theEnv,"set-static-constraint-checking",EXACTLY,1) == -1)
00544 { return(oldValue); }
00545
00546 EnvRtnUnknown(theEnv,1,&arg_ptr);
00547
00548 if ((arg_ptr.value == EnvFalseSymbol(theEnv)) && (arg_ptr.type == SYMBOL))
00549 { EnvSetStaticConstraintChecking(theEnv,FALSE); }
00550 else
00551 { EnvSetStaticConstraintChecking(theEnv,TRUE); }
00552
00553 return(oldValue);
00554 }
00555
00556
00557
00558
00559
00560 globle int GSCCommand(
00561 void *theEnv)
00562 {
00563 int oldValue;
00564
00565 oldValue = EnvGetStaticConstraintChecking(theEnv);
00566
00567 if (EnvArgCountCheck(theEnv,"get-static-constraint-checking",EXACTLY,0) == -1)
00568 { return(oldValue); }
00569
00570 return(oldValue);
00571 }
00572
00573
00574
00575
00576
00577 globle intBool EnvSetDynamicConstraintChecking(
00578 void *theEnv,
00579 int value)
00580 {
00581 int ov;
00582 ov = ConstraintData(theEnv)->DynamicConstraintChecking;
00583 ConstraintData(theEnv)->DynamicConstraintChecking = value;
00584 return(ov);
00585 }
00586
00587
00588
00589
00590
00591 globle intBool EnvGetDynamicConstraintChecking(
00592 void *theEnv)
00593 {
00594 return(ConstraintData(theEnv)->DynamicConstraintChecking);
00595 }
00596
00597
00598
00599
00600
00601 globle intBool EnvSetStaticConstraintChecking(
00602 void *theEnv,
00603 int value)
00604 {
00605 int ov;
00606
00607 ov = ConstraintData(theEnv)->StaticConstraintChecking;
00608 ConstraintData(theEnv)->StaticConstraintChecking = value;
00609 return(ov);
00610 }
00611
00612
00613
00614
00615
00616 globle intBool EnvGetStaticConstraintChecking(
00617 void *theEnv)
00618 {
00619 return(ConstraintData(theEnv)->StaticConstraintChecking);
00620 }
00621