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 _CSTRNPSR_SOURCE_
00031
00032 #include <stdio.h>
00033 #define _STDIO_INCLUDED_
00034 #include <stdlib.h>
00035
00036 #include "setup.h"
00037
00038 #include "constant.h"
00039 #include "envrnmnt.h"
00040 #include "memalloc.h"
00041 #include "router.h"
00042 #include "scanner.h"
00043 #include "cstrnutl.h"
00044 #include "cstrnchk.h"
00045 #include "sysdep.h"
00046
00047 #include "cstrnpsr.h"
00048
00049
00050
00051
00052
00053 #if (! RUN_TIME) && (! BLOAD_ONLY)
00054 static intBool ParseRangeCardinalityAttribute(void *,
00055 char *,CONSTRAINT_RECORD *,
00056 CONSTRAINT_PARSE_RECORD *,
00057 char *,int);
00058 static intBool ParseTypeAttribute(void *,char *,CONSTRAINT_RECORD *);
00059 static void AddToRestrictionList(void *,int,CONSTRAINT_RECORD *,
00060 CONSTRAINT_RECORD *);
00061 static intBool ParseAllowedValuesAttribute(void *,char *,char *,
00062 CONSTRAINT_RECORD *,
00063 CONSTRAINT_PARSE_RECORD *);
00064 static int GetConstraintTypeFromAllowedName(char *);
00065 static int GetConstraintTypeFromTypeName(char *);
00066 static int GetAttributeParseValue(char *,CONSTRAINT_PARSE_RECORD *);
00067 static void SetRestrictionFlag(int,CONSTRAINT_RECORD *,int);
00068 static void SetParseFlag(CONSTRAINT_PARSE_RECORD *,char *);
00069 static void NoConjunctiveUseError(void *,char *,char *);
00070 #endif
00071
00072
00073
00074
00075
00076
00077 globle intBool CheckConstraintParseConflicts(
00078 void *theEnv,
00079 CONSTRAINT_RECORD *constraints)
00080 {
00081
00082
00083
00084
00085
00086 if (constraints->anyAllowed == TRUE)
00087 { }
00088 else if (constraints->symbolRestriction &&
00089 (constraints->symbolsAllowed == FALSE))
00090 {
00091 AttributeConflictErrorMessage(theEnv,"type","allowed-symbols");
00092 return(FALSE);
00093 }
00094 else if (constraints->stringRestriction &&
00095 (constraints->stringsAllowed == FALSE))
00096 {
00097 AttributeConflictErrorMessage(theEnv,"type","allowed-strings");
00098 return(FALSE);
00099 }
00100 else if (constraints->integerRestriction &&
00101 (constraints->integersAllowed == FALSE))
00102 {
00103 AttributeConflictErrorMessage(theEnv,"type","allowed-integers/numbers");
00104 return(FALSE);
00105 }
00106 else if (constraints->floatRestriction &&
00107 (constraints->floatsAllowed == FALSE))
00108 {
00109 AttributeConflictErrorMessage(theEnv,"type","allowed-floats/numbers");
00110 return(FALSE);
00111 }
00112 else if (constraints->classRestriction &&
00113 (constraints->instanceAddressesAllowed == FALSE) &&
00114 (constraints->instanceNamesAllowed == FALSE))
00115 {
00116 AttributeConflictErrorMessage(theEnv,"type","allowed-classes");
00117 return(FALSE);
00118 }
00119 else if (constraints->instanceNameRestriction &&
00120 (constraints->instanceNamesAllowed == FALSE))
00121 {
00122 AttributeConflictErrorMessage(theEnv,"type","allowed-instance-names");
00123 return(FALSE);
00124 }
00125 else if (constraints->anyRestriction)
00126 {
00127 struct expr *theExp;
00128
00129 for (theExp = constraints->restrictionList;
00130 theExp != NULL;
00131 theExp = theExp->nextArg)
00132 {
00133 if (ConstraintCheckValue(theEnv,theExp->type,theExp->value,constraints) != NO_VIOLATION)
00134 {
00135 AttributeConflictErrorMessage(theEnv,"type","allowed-values");
00136 return(FALSE);
00137 }
00138 }
00139 }
00140
00141
00142
00143
00144
00145 if ((constraints->maxValue != NULL) &&
00146 (constraints->anyAllowed == FALSE))
00147 {
00148 if (((constraints->maxValue->type == INTEGER) &&
00149 (constraints->integersAllowed == FALSE)) ||
00150 ((constraints->maxValue->type == FLOAT) &&
00151 (constraints->floatsAllowed == FALSE)))
00152 {
00153 AttributeConflictErrorMessage(theEnv,"type","range");
00154 return(FALSE);
00155 }
00156 }
00157
00158 if ((constraints->minValue != NULL) &&
00159 (constraints->anyAllowed == FALSE))
00160 {
00161 if (((constraints->minValue->type == INTEGER) &&
00162 (constraints->integersAllowed == FALSE)) ||
00163 ((constraints->minValue->type == FLOAT) &&
00164 (constraints->floatsAllowed == FALSE)))
00165 {
00166 AttributeConflictErrorMessage(theEnv,"type","range");
00167 return(FALSE);
00168 }
00169 }
00170
00171
00172
00173
00174
00175
00176 if ((constraints->classList != NULL) &&
00177 (constraints->anyAllowed == FALSE) &&
00178 (constraints->instanceNamesAllowed == FALSE) &&
00179 (constraints->instanceAddressesAllowed == FALSE))
00180 {
00181 AttributeConflictErrorMessage(theEnv,"type","allowed-class");
00182 return(FALSE);
00183 }
00184
00185
00186
00187
00188
00189 return(TRUE);
00190 }
00191
00192
00193
00194
00195
00196 globle void AttributeConflictErrorMessage(
00197 void *theEnv,
00198 char *attribute1,
00199 char *attribute2)
00200 {
00201 PrintErrorID(theEnv,"CSTRNPSR",1,TRUE);
00202 EnvPrintRouter(theEnv,WERROR,"The ");
00203 EnvPrintRouter(theEnv,WERROR,attribute1);
00204 EnvPrintRouter(theEnv,WERROR," attribute conflicts with the ");
00205 EnvPrintRouter(theEnv,WERROR,attribute2);
00206 EnvPrintRouter(theEnv,WERROR," attribute.\n");
00207 }
00208
00209 #if (! RUN_TIME) && (! BLOAD_ONLY)
00210
00211
00212
00213
00214
00215
00216 globle void InitializeConstraintParseRecord(
00217 CONSTRAINT_PARSE_RECORD *parsedConstraints)
00218 {
00219 parsedConstraints->type = FALSE;
00220 parsedConstraints->range = FALSE;
00221 parsedConstraints->allowedSymbols = FALSE;
00222 parsedConstraints->allowedStrings = FALSE;
00223 parsedConstraints->allowedLexemes = FALSE;
00224 parsedConstraints->allowedIntegers = FALSE;
00225 parsedConstraints->allowedFloats = FALSE;
00226 parsedConstraints->allowedNumbers = FALSE;
00227 parsedConstraints->allowedValues = FALSE;
00228 parsedConstraints->allowedInstanceNames = FALSE;
00229 parsedConstraints->allowedClasses = FALSE;
00230 parsedConstraints->cardinality = FALSE;
00231 }
00232
00233
00234
00235
00236
00237 globle intBool StandardConstraint(
00238 char *constraintName)
00239 {
00240 if ((strcmp(constraintName,"type") == 0) ||
00241 (strcmp(constraintName,"range") == 0) ||
00242 (strcmp(constraintName,"cardinality") == 0) ||
00243 (strcmp(constraintName,"allowed-symbols") == 0) ||
00244 (strcmp(constraintName,"allowed-strings") == 0) ||
00245 (strcmp(constraintName,"allowed-lexemes") == 0) ||
00246 (strcmp(constraintName,"allowed-integers") == 0) ||
00247 (strcmp(constraintName,"allowed-floats") == 0) ||
00248 (strcmp(constraintName,"allowed-numbers") == 0) ||
00249 (strcmp(constraintName,"allowed-instance-names") == 0) ||
00250 (strcmp(constraintName,"allowed-classes") == 0) ||
00251 (strcmp(constraintName,"allowed-values") == 0))
00252
00253 { return(TRUE); }
00254
00255 return(FALSE);
00256 }
00257
00258
00259
00260
00261
00262 globle intBool ParseStandardConstraint(
00263 void *theEnv,
00264 char *readSource,
00265 char *constraintName,
00266 CONSTRAINT_RECORD *constraints,
00267 CONSTRAINT_PARSE_RECORD *parsedConstraints,
00268 int multipleValuesAllowed)
00269 {
00270 int rv = FALSE;
00271
00272
00273
00274
00275
00276 if (GetAttributeParseValue(constraintName,parsedConstraints))
00277 {
00278 AlreadyParsedErrorMessage(theEnv,constraintName," attribute");
00279 return(FALSE);
00280 }
00281
00282
00283
00284
00285
00286 if (strcmp(constraintName,"range") == 0)
00287 {
00288 rv = ParseRangeCardinalityAttribute(theEnv,readSource,constraints,parsedConstraints,
00289 constraintName,multipleValuesAllowed);
00290 }
00291
00292
00293
00294
00295
00296 else if (strcmp(constraintName,"cardinality") == 0)
00297 {
00298 rv = ParseRangeCardinalityAttribute(theEnv,readSource,constraints,parsedConstraints,
00299 constraintName,multipleValuesAllowed);
00300 }
00301
00302
00303
00304
00305
00306 else if (strcmp(constraintName,"type") == 0)
00307 { rv = ParseTypeAttribute(theEnv,readSource,constraints); }
00308
00309
00310
00311
00312
00313 else if ((strcmp(constraintName,"allowed-symbols") == 0) ||
00314 (strcmp(constraintName,"allowed-strings") == 0) ||
00315 (strcmp(constraintName,"allowed-lexemes") == 0) ||
00316 (strcmp(constraintName,"allowed-integers") == 0) ||
00317 (strcmp(constraintName,"allowed-floats") == 0) ||
00318 (strcmp(constraintName,"allowed-numbers") == 0) ||
00319 (strcmp(constraintName,"allowed-instance-names") == 0) ||
00320 (strcmp(constraintName,"allowed-classes") == 0) ||
00321 (strcmp(constraintName,"allowed-values") == 0))
00322 {
00323 rv = ParseAllowedValuesAttribute(theEnv,readSource,constraintName,
00324 constraints,parsedConstraints);
00325 }
00326
00327
00328
00329
00330
00331
00332 SetParseFlag(parsedConstraints,constraintName);
00333 return(rv);
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343 globle void OverlayConstraint(
00344 void *theEnv,
00345 CONSTRAINT_PARSE_RECORD *pc,
00346 CONSTRAINT_RECORD *cdst,
00347 CONSTRAINT_RECORD *csrc)
00348 {
00349 if (pc->type == 0)
00350 {
00351 cdst->anyAllowed = csrc->anyAllowed;
00352 cdst->symbolsAllowed = csrc->symbolsAllowed;
00353 cdst->stringsAllowed = csrc->stringsAllowed;
00354 cdst->floatsAllowed = csrc->floatsAllowed;
00355 cdst->integersAllowed = csrc->integersAllowed;
00356 cdst->instanceNamesAllowed = csrc->instanceNamesAllowed;
00357 cdst->instanceAddressesAllowed = csrc->instanceAddressesAllowed;
00358 cdst->externalAddressesAllowed = csrc->externalAddressesAllowed;
00359 cdst->voidAllowed = csrc->voidAllowed;
00360 cdst->factAddressesAllowed = csrc->factAddressesAllowed;
00361 }
00362
00363 if (pc->range == 0)
00364 {
00365 ReturnExpression(theEnv,cdst->minValue);
00366 ReturnExpression(theEnv,cdst->maxValue);
00367 cdst->minValue = CopyExpression(theEnv,csrc->minValue);
00368 cdst->maxValue = CopyExpression(theEnv,csrc->maxValue);
00369 }
00370
00371 if (pc->allowedClasses == 0)
00372 {
00373 ReturnExpression(theEnv,cdst->classList);
00374 cdst->classList = CopyExpression(theEnv,csrc->classList);
00375 }
00376
00377 if (pc->allowedValues == 0)
00378 {
00379 if ((pc->allowedSymbols == 0) &&
00380 (pc->allowedStrings == 0) &&
00381 (pc->allowedLexemes == 0) &&
00382 (pc->allowedIntegers == 0) &&
00383 (pc->allowedFloats == 0) &&
00384 (pc->allowedNumbers == 0) &&
00385 (pc->allowedInstanceNames == 0))
00386 {
00387 cdst->anyRestriction = csrc->anyRestriction;
00388 cdst->symbolRestriction = csrc->symbolRestriction;
00389 cdst->stringRestriction = csrc->stringRestriction;
00390 cdst->floatRestriction = csrc->floatRestriction;
00391 cdst->integerRestriction = csrc->integerRestriction;
00392 cdst->classRestriction = csrc->classRestriction;
00393 cdst->instanceNameRestriction = csrc->instanceNameRestriction;
00394 cdst->restrictionList = CopyExpression(theEnv,csrc->restrictionList);
00395 }
00396 else
00397 {
00398 if ((pc->allowedSymbols == 0) && csrc->symbolRestriction)
00399 {
00400 cdst->symbolRestriction = 1;
00401 AddToRestrictionList(theEnv,SYMBOL,cdst,csrc);
00402 }
00403 if ((pc->allowedStrings == 0) && csrc->stringRestriction)
00404 {
00405 cdst->stringRestriction = 1;
00406 AddToRestrictionList(theEnv,STRING,cdst,csrc);
00407 }
00408 if ((pc->allowedLexemes == 0) && csrc->symbolRestriction && csrc->stringRestriction)
00409 {
00410 cdst->symbolRestriction = 1;
00411 cdst->stringRestriction = 1;
00412 AddToRestrictionList(theEnv,SYMBOL,cdst,csrc);
00413 AddToRestrictionList(theEnv,STRING,cdst,csrc);
00414 }
00415 if ((pc->allowedIntegers == 0) && csrc->integerRestriction)
00416 {
00417 cdst->integerRestriction = 1;
00418 AddToRestrictionList(theEnv,INTEGER,cdst,csrc);
00419 }
00420 if ((pc->allowedFloats == 0) && csrc->floatRestriction)
00421 {
00422 cdst->floatRestriction = 1;
00423 AddToRestrictionList(theEnv,FLOAT,cdst,csrc);
00424 }
00425 if ((pc->allowedNumbers == 0) && csrc->integerRestriction && csrc->floatRestriction)
00426 {
00427 cdst->integerRestriction = 1;
00428 cdst->floatRestriction = 1;
00429 AddToRestrictionList(theEnv,INTEGER,cdst,csrc);
00430 AddToRestrictionList(theEnv,FLOAT,cdst,csrc);
00431 }
00432 if ((pc->allowedInstanceNames == 0) && csrc->instanceNameRestriction)
00433 {
00434 cdst->instanceNameRestriction = 1;
00435 AddToRestrictionList(theEnv,INSTANCE_NAME,cdst,csrc);
00436 }
00437 }
00438 }
00439
00440 if (pc->cardinality == 0)
00441 {
00442 ReturnExpression(theEnv,cdst->minFields);
00443 ReturnExpression(theEnv,cdst->maxFields);
00444 cdst->minFields = CopyExpression(theEnv,csrc->minFields);
00445 cdst->maxFields = CopyExpression(theEnv,csrc->maxFields);
00446 }
00447 }
00448
00449
00450
00451
00452
00453
00454 globle void OverlayConstraintParseRecord(
00455 CONSTRAINT_PARSE_RECORD *dst,
00456 CONSTRAINT_PARSE_RECORD *src)
00457 {
00458 if (src->type) dst->type = TRUE;
00459 if (src->range) dst->range = TRUE;
00460 if (src->allowedSymbols) dst->allowedSymbols = TRUE;
00461 if (src->allowedStrings) dst->allowedStrings = TRUE;
00462 if (src->allowedLexemes) dst->allowedLexemes = TRUE;
00463 if (src->allowedIntegers) dst->allowedIntegers = TRUE;
00464 if (src->allowedFloats) dst->allowedFloats = TRUE;
00465 if (src->allowedNumbers) dst->allowedNumbers = TRUE;
00466 if (src->allowedValues) dst->allowedValues = TRUE;
00467 if (src->allowedInstanceNames) dst->allowedInstanceNames = TRUE;
00468 if (src->allowedClasses) dst->allowedClasses = TRUE;
00469 if (src->cardinality) dst->cardinality = TRUE;
00470 }
00471
00472
00473
00474
00475
00476 static void AddToRestrictionList(
00477 void *theEnv,
00478 int type,
00479 CONSTRAINT_RECORD *cdst,
00480 CONSTRAINT_RECORD *csrc)
00481 {
00482 struct expr *theExp,*tmp;
00483
00484 for (theExp = csrc->restrictionList; theExp != NULL; theExp = theExp->nextArg)
00485 {
00486 if (theExp->type == type)
00487 {
00488 tmp = GenConstant(theEnv,theExp->type,theExp->value);
00489 tmp->nextArg = cdst->restrictionList;
00490 cdst->restrictionList = tmp;
00491 }
00492 }
00493 }
00494
00495
00496
00497
00498 static intBool ParseAllowedValuesAttribute(
00499 void *theEnv,
00500 char *readSource,
00501 char *constraintName,
00502 CONSTRAINT_RECORD *constraints,
00503 CONSTRAINT_PARSE_RECORD *parsedConstraints)
00504 {
00505 struct token inputToken;
00506 int expectedType, restrictionType, error = FALSE;
00507 struct expr *newValue, *lastValue;
00508 int constantParsed = FALSE, variableParsed = FALSE;
00509 char *tempPtr = NULL;
00510
00511
00512
00513
00514
00515
00516 if ((strcmp(constraintName,"allowed-values") == 0) &&
00517 ((parsedConstraints->allowedSymbols) ||
00518 (parsedConstraints->allowedStrings) ||
00519 (parsedConstraints->allowedLexemes) ||
00520 (parsedConstraints->allowedIntegers) ||
00521 (parsedConstraints->allowedFloats) ||
00522 (parsedConstraints->allowedNumbers) ||
00523 (parsedConstraints->allowedInstanceNames)))
00524 {
00525 if (parsedConstraints->allowedSymbols) tempPtr = "allowed-symbols";
00526 else if (parsedConstraints->allowedStrings) tempPtr = "allowed-strings";
00527 else if (parsedConstraints->allowedLexemes) tempPtr = "allowed-lexemes";
00528 else if (parsedConstraints->allowedIntegers) tempPtr = "allowed-integers";
00529 else if (parsedConstraints->allowedFloats) tempPtr = "allowed-floats";
00530 else if (parsedConstraints->allowedNumbers) tempPtr = "allowed-numbers";
00531 else if (parsedConstraints->allowedInstanceNames) tempPtr = "allowed-instance-names";
00532 NoConjunctiveUseError(theEnv,"allowed-values",tempPtr);
00533 return(FALSE);
00534 }
00535
00536
00537
00538
00539
00540
00541 if (((strcmp(constraintName,"allowed-values") == 0) ||
00542 (strcmp(constraintName,"allowed-numbers") == 0) ||
00543 (strcmp(constraintName,"allowed-integers") == 0) ||
00544 (strcmp(constraintName,"allowed-floats") == 0)) &&
00545 (parsedConstraints->range))
00546 {
00547 NoConjunctiveUseError(theEnv,constraintName,"range");
00548 return(FALSE);
00549 }
00550
00551
00552
00553
00554
00555
00556 if ((strcmp(constraintName,"allowed-values") != 0) &&
00557 (parsedConstraints->allowedValues))
00558 {
00559 NoConjunctiveUseError(theEnv,constraintName,"allowed-values");
00560 return(FALSE);
00561 }
00562
00563
00564
00565
00566
00567
00568
00569 if ((strcmp(constraintName,"allowed-numbers") == 0) &&
00570 ((parsedConstraints->allowedFloats) || (parsedConstraints->allowedIntegers)))
00571 {
00572 if (parsedConstraints->allowedFloats) tempPtr = "allowed-floats";
00573 else tempPtr = "allowed-integers";
00574 NoConjunctiveUseError(theEnv,"allowed-numbers",tempPtr);
00575 return(FALSE);
00576 }
00577
00578
00579
00580
00581
00582
00583 if (((strcmp(constraintName,"allowed-integers") == 0) ||
00584 (strcmp(constraintName,"allowed-floats") == 0)) &&
00585 (parsedConstraints->allowedNumbers))
00586 {
00587 NoConjunctiveUseError(theEnv,constraintName,"allowed-number");
00588 return(FALSE);
00589 }
00590
00591
00592
00593
00594
00595
00596
00597 if ((strcmp(constraintName,"allowed-lexemes") == 0) &&
00598 ((parsedConstraints->allowedSymbols) || (parsedConstraints->allowedStrings)))
00599 {
00600 if (parsedConstraints->allowedSymbols) tempPtr = "allowed-symbols";
00601 else tempPtr = "allowed-strings";
00602 NoConjunctiveUseError(theEnv,"allowed-lexemes",tempPtr);
00603 return(FALSE);
00604 }
00605
00606
00607
00608
00609
00610
00611 if (((strcmp(constraintName,"allowed-symbols") == 0) ||
00612 (strcmp(constraintName,"allowed-strings") == 0)) &&
00613 (parsedConstraints->allowedLexemes))
00614 {
00615 NoConjunctiveUseError(theEnv,constraintName,"allowed-lexemes");
00616 return(FALSE);
00617 }
00618
00619
00620
00621
00622
00623 restrictionType = GetConstraintTypeFromAllowedName(constraintName);
00624 SetRestrictionFlag(restrictionType,constraints,TRUE);
00625 if (strcmp(constraintName,"allowed-classes") == 0)
00626 { expectedType = SYMBOL; }
00627 else
00628 { expectedType = restrictionType; }
00629
00630
00631
00632
00633
00634
00635 if (strcmp(constraintName,"allowed-classes") == 0)
00636 { lastValue = constraints->classList; }
00637 else
00638 { lastValue = constraints->restrictionList; }
00639
00640 if (lastValue != NULL)
00641 { while (lastValue->nextArg != NULL) lastValue = lastValue->nextArg; }
00642
00643
00644
00645
00646
00647
00648 SavePPBuffer(theEnv," ");
00649 GetToken(theEnv,readSource,&inputToken);
00650
00651 while (inputToken.type != RPAREN)
00652 {
00653 SavePPBuffer(theEnv," ");
00654
00655
00656
00657
00658
00659
00660 switch(inputToken.type)
00661 {
00662 case INTEGER:
00663 if ((expectedType != UNKNOWN_VALUE) &&
00664 (expectedType != INTEGER) &&
00665 (expectedType != INTEGER_OR_FLOAT)) error = TRUE;
00666 constantParsed = TRUE;
00667 break;
00668
00669 case FLOAT:
00670 if ((expectedType != UNKNOWN_VALUE) &&
00671 (expectedType != FLOAT) &&
00672 (expectedType != INTEGER_OR_FLOAT)) error = TRUE;
00673 constantParsed = TRUE;
00674 break;
00675
00676 case STRING:
00677 if ((expectedType != UNKNOWN_VALUE) &&
00678 (expectedType != STRING) &&
00679 (expectedType != SYMBOL_OR_STRING)) error = TRUE;
00680 constantParsed = TRUE;
00681 break;
00682
00683 case SYMBOL:
00684 if ((expectedType != UNKNOWN_VALUE) &&
00685 (expectedType != SYMBOL) &&
00686 (expectedType != SYMBOL_OR_STRING)) error = TRUE;
00687 constantParsed = TRUE;
00688 break;
00689
00690 #if OBJECT_SYSTEM
00691 case INSTANCE_NAME:
00692 if ((expectedType != UNKNOWN_VALUE) &&
00693 (expectedType != INSTANCE_NAME)) error = TRUE;
00694 constantParsed = TRUE;
00695 break;
00696 #endif
00697
00698 case SF_VARIABLE:
00699 if (strcmp(inputToken.printForm,"?VARIABLE") == 0)
00700 { variableParsed = TRUE; }
00701 else
00702 {
00703 char tempBuffer[120];
00704 gensprintf(tempBuffer,"%s attribute",constraintName);
00705 SyntaxErrorMessage(theEnv,tempBuffer);
00706 return(FALSE);
00707 }
00708
00709 break;
00710
00711 default:
00712 {
00713 char tempBuffer[120];
00714 gensprintf(tempBuffer,"%s attribute",constraintName);
00715 SyntaxErrorMessage(theEnv,tempBuffer);
00716 }
00717 return(FALSE);
00718 }
00719
00720
00721
00722
00723
00724
00725 if (error)
00726 {
00727 PrintErrorID(theEnv,"CSTRNPSR",4,TRUE);
00728 EnvPrintRouter(theEnv,WERROR,"Value does not match the expected type for the ");
00729 EnvPrintRouter(theEnv,WERROR,constraintName);
00730 EnvPrintRouter(theEnv,WERROR," attribute\n");
00731 return(FALSE);
00732 }
00733
00734
00735
00736
00737
00738
00739 if (constantParsed && variableParsed)
00740 {
00741 char tempBuffer[120];
00742 gensprintf(tempBuffer,"%s attribute",constraintName);
00743 SyntaxErrorMessage(theEnv,tempBuffer);
00744 return(FALSE);
00745 }
00746
00747
00748
00749
00750
00751 newValue = GenConstant(theEnv,inputToken.type,inputToken.value);
00752 if (lastValue == NULL)
00753 {
00754 if (strcmp(constraintName,"allowed-classes") == 0)
00755 { constraints->classList = newValue; }
00756 else
00757 { constraints->restrictionList = newValue; }
00758 }
00759 else
00760 { lastValue->nextArg = newValue; }
00761 lastValue = newValue;
00762
00763
00764
00765
00766
00767 GetToken(theEnv,readSource,&inputToken);
00768 }
00769
00770
00771
00772
00773
00774 if ((! constantParsed) && (! variableParsed))
00775 {
00776 char tempBuffer[120];
00777 gensprintf(tempBuffer,"%s attribute",constraintName);
00778 SyntaxErrorMessage(theEnv,tempBuffer);
00779 return(FALSE);
00780 }
00781
00782
00783
00784
00785
00786
00787
00788 if (variableParsed)
00789 {
00790 switch(restrictionType)
00791 {
00792 case UNKNOWN_VALUE:
00793 constraints->anyRestriction = FALSE;
00794 break;
00795
00796 case SYMBOL:
00797 constraints->symbolRestriction = FALSE;
00798 break;
00799
00800 case STRING:
00801 constraints->stringRestriction = FALSE;
00802 break;
00803
00804 case INTEGER:
00805 constraints->integerRestriction = FALSE;
00806 break;
00807
00808 case FLOAT:
00809 constraints->floatRestriction = FALSE;
00810 break;
00811
00812 case INTEGER_OR_FLOAT:
00813 constraints->floatRestriction = FALSE;
00814 constraints->integerRestriction = FALSE;
00815 break;
00816
00817 case SYMBOL_OR_STRING:
00818 constraints->symbolRestriction = FALSE;
00819 constraints->stringRestriction = FALSE;
00820 break;
00821
00822 case INSTANCE_NAME:
00823 constraints->instanceNameRestriction = FALSE;
00824 break;
00825
00826 case INSTANCE_OR_INSTANCE_NAME:
00827 constraints->classRestriction = FALSE;
00828 break;
00829 }
00830 }
00831
00832
00833
00834
00835
00836 PPBackup(theEnv);
00837 PPBackup(theEnv);
00838 SavePPBuffer(theEnv,")");
00839
00840
00841
00842
00843
00844
00845 return(TRUE);
00846 }
00847
00848
00849
00850
00851
00852 static void NoConjunctiveUseError(
00853 void *theEnv,
00854 char *attribute1,
00855 char *attribute2)
00856 {
00857 PrintErrorID(theEnv,"CSTRNPSR",3,TRUE);
00858 EnvPrintRouter(theEnv,WERROR,"The ");
00859 EnvPrintRouter(theEnv,WERROR,attribute1);
00860 EnvPrintRouter(theEnv,WERROR," attribute cannot be used\n");
00861 EnvPrintRouter(theEnv,WERROR,"in conjunction with the ");
00862 EnvPrintRouter(theEnv,WERROR,attribute2);
00863 EnvPrintRouter(theEnv,WERROR," attribute.\n");
00864 }
00865
00866
00867
00868
00869 static intBool ParseTypeAttribute(
00870 void *theEnv,
00871 char *readSource,
00872 CONSTRAINT_RECORD *constraints)
00873 {
00874 int typeParsed = FALSE;
00875 int variableParsed = FALSE;
00876 int theType;
00877 struct token inputToken;
00878
00879
00880
00881
00882
00883
00884 SavePPBuffer(theEnv," ");
00885 for (GetToken(theEnv,readSource,&inputToken);
00886 inputToken.type != RPAREN;
00887 GetToken(theEnv,readSource,&inputToken))
00888 {
00889 SavePPBuffer(theEnv," ");
00890
00891
00892
00893
00894
00895 if (inputToken.type == SYMBOL)
00896 {
00897
00898
00899
00900
00901 if (variableParsed == TRUE)
00902 {
00903 SyntaxErrorMessage(theEnv,"type attribute");
00904 return(FALSE);
00905 }
00906
00907
00908
00909
00910
00911
00912 theType = GetConstraintTypeFromTypeName(ValueToString(inputToken.value));
00913 if (theType < 0)
00914 {
00915 SyntaxErrorMessage(theEnv,"type attribute");
00916 return(FALSE);
00917 }
00918
00919
00920
00921
00922
00923
00924
00925 if (SetConstraintType(theType,constraints))
00926 {
00927 SyntaxErrorMessage(theEnv,"type attribute");
00928 return(FALSE);
00929 }
00930
00931 constraints->anyAllowed = FALSE;
00932
00933
00934
00935
00936
00937 typeParsed = TRUE;
00938 }
00939
00940
00941
00942
00943
00944 else if (inputToken.type == SF_VARIABLE)
00945 {
00946
00947
00948
00949
00950 if (strcmp(inputToken.printForm,"?VARIABLE") != 0)
00951 {
00952 SyntaxErrorMessage(theEnv,"type attribute");
00953 return(FALSE);
00954 }
00955
00956
00957
00958
00959
00960
00961 if (typeParsed || variableParsed)
00962 {
00963 SyntaxErrorMessage(theEnv,"type attribute");
00964 return(FALSE);
00965 }
00966
00967
00968
00969
00970
00971 variableParsed = TRUE;
00972 }
00973
00974
00975
00976
00977
00978
00979 else
00980 {
00981 SyntaxErrorMessage(theEnv,"type attribute");
00982 return(FALSE);
00983 }
00984 }
00985
00986
00987
00988
00989
00990 PPBackup(theEnv);
00991 PPBackup(theEnv);
00992 SavePPBuffer(theEnv,")");
00993
00994
00995
00996
00997
00998 if ((! typeParsed) && (! variableParsed))
00999 {
01000 SyntaxErrorMessage(theEnv,"type attribute");
01001 return(FALSE);
01002 }
01003
01004
01005
01006
01007
01008
01009 return(TRUE);
01010 }
01011
01012
01013
01014
01015 static intBool ParseRangeCardinalityAttribute(
01016 void *theEnv,
01017 char *readSource,
01018 CONSTRAINT_RECORD *constraints,
01019 CONSTRAINT_PARSE_RECORD *parsedConstraints,
01020 char *constraintName,
01021 int multipleValuesAllowed)
01022 {
01023 struct token inputToken;
01024 int range;
01025 char *tempPtr = NULL;
01026
01027
01028
01029
01030
01031
01032 if (strcmp(constraintName,"range") == 0)
01033 {
01034 parsedConstraints->range = TRUE;
01035 range = TRUE;
01036 }
01037 else
01038 {
01039 parsedConstraints->cardinality = TRUE;
01040 range = FALSE;
01041 }
01042
01043
01044
01045
01046
01047 if ((range == FALSE) &&
01048 (multipleValuesAllowed == FALSE))
01049 {
01050 PrintErrorID(theEnv,"CSTRNPSR",5,TRUE);
01051 EnvPrintRouter(theEnv,WERROR,"The cardinality attribute ");
01052 EnvPrintRouter(theEnv,WERROR,"can only be used with multifield slots.\n");
01053 return(FALSE);
01054 }
01055
01056
01057
01058
01059
01060
01061 if ((range == TRUE) &&
01062 (parsedConstraints->allowedValues ||
01063 parsedConstraints->allowedNumbers ||
01064 parsedConstraints->allowedIntegers ||
01065 parsedConstraints->allowedFloats))
01066 {
01067 if (parsedConstraints->allowedValues) tempPtr = "allowed-values";
01068 else if (parsedConstraints->allowedIntegers) tempPtr = "allowed-integers";
01069 else if (parsedConstraints->allowedFloats) tempPtr = "allowed-floats";
01070 else if (parsedConstraints->allowedNumbers) tempPtr = "allowed-numbers";
01071 NoConjunctiveUseError(theEnv,"range",tempPtr);
01072 return(FALSE);
01073 }
01074
01075
01076
01077
01078
01079 SavePPBuffer(theEnv," ");
01080 GetToken(theEnv,readSource,&inputToken);
01081 if ((inputToken.type == INTEGER) || ((inputToken.type == FLOAT) && range))
01082 {
01083 if (range)
01084 {
01085 ReturnExpression(theEnv,constraints->minValue);
01086 constraints->minValue = GenConstant(theEnv,inputToken.type,inputToken.value);
01087 }
01088 else
01089 {
01090 ReturnExpression(theEnv,constraints->minFields);
01091 constraints->minFields = GenConstant(theEnv,inputToken.type,inputToken.value);
01092 }
01093 }
01094 else if ((inputToken.type == SF_VARIABLE) && (strcmp(inputToken.printForm,"?VARIABLE") == 0))
01095 { }
01096 else
01097 {
01098 char tempBuffer[120];
01099 gensprintf(tempBuffer,"%s attribute",constraintName);
01100 SyntaxErrorMessage(theEnv,tempBuffer);
01101 return(FALSE);
01102 }
01103
01104
01105
01106
01107
01108 SavePPBuffer(theEnv," ");
01109 GetToken(theEnv,readSource,&inputToken);
01110 if ((inputToken.type == INTEGER) || ((inputToken.type == FLOAT) && range))
01111 {
01112 if (range)
01113 {
01114 ReturnExpression(theEnv,constraints->maxValue);
01115 constraints->maxValue = GenConstant(theEnv,inputToken.type,inputToken.value);
01116 }
01117 else
01118 {
01119 ReturnExpression(theEnv,constraints->maxFields);
01120 constraints->maxFields = GenConstant(theEnv,inputToken.type,inputToken.value);
01121 }
01122 }
01123 else if ((inputToken.type == SF_VARIABLE) && (strcmp(inputToken.printForm,"?VARIABLE") == 0))
01124 { }
01125 else
01126 {
01127 char tempBuffer[120];
01128 gensprintf(tempBuffer,"%s attribute",constraintName);
01129 SyntaxErrorMessage(theEnv,tempBuffer);
01130 return(FALSE);
01131 }
01132
01133
01134
01135
01136
01137 GetToken(theEnv,readSource,&inputToken);
01138 if (inputToken.type != RPAREN)
01139 {
01140 SyntaxErrorMessage(theEnv,"range attribute");
01141 return(FALSE);
01142 }
01143
01144
01145
01146
01147
01148 if (range)
01149 {
01150 if (CompareNumbers(theEnv,constraints->minValue->type,
01151 constraints->minValue->value,
01152 constraints->maxValue->type,
01153 constraints->maxValue->value) == GREATER_THAN)
01154 {
01155 PrintErrorID(theEnv,"CSTRNPSR",2,TRUE);
01156 EnvPrintRouter(theEnv,WERROR,"Minimum range value must be less than\n");
01157 EnvPrintRouter(theEnv,WERROR,"or equal to the maximum range value\n");
01158 return(FALSE);
01159 }
01160 }
01161 else
01162 {
01163 if (CompareNumbers(theEnv,constraints->minFields->type,
01164 constraints->minFields->value,
01165 constraints->maxFields->type,
01166 constraints->maxFields->value) == GREATER_THAN)
01167 {
01168 PrintErrorID(theEnv,"CSTRNPSR",2,TRUE);
01169 EnvPrintRouter(theEnv,WERROR,"Minimum cardinality value must be less than\n");
01170 EnvPrintRouter(theEnv,WERROR,"or equal to the maximum cardinality value\n");
01171 return(FALSE);
01172 }
01173 }
01174
01175
01176
01177
01178
01179
01180 return(TRUE);
01181 }
01182
01183
01184
01185
01186
01187 static int GetConstraintTypeFromAllowedName(
01188 char *constraintName)
01189 {
01190 if (strcmp(constraintName,"allowed-values") == 0) return(UNKNOWN_VALUE);
01191 else if (strcmp(constraintName,"allowed-symbols") == 0) return(SYMBOL);
01192 else if (strcmp(constraintName,"allowed-strings") == 0) return(STRING);
01193 else if (strcmp(constraintName,"allowed-lexemes") == 0) return(SYMBOL_OR_STRING);
01194 else if (strcmp(constraintName,"allowed-integers") == 0) return(INTEGER);
01195 else if (strcmp(constraintName,"allowed-numbers") == 0) return(INTEGER_OR_FLOAT);
01196 else if (strcmp(constraintName,"allowed-instance-names") == 0) return(INSTANCE_NAME);
01197 else if (strcmp(constraintName,"allowed-classes") == 0) return(INSTANCE_OR_INSTANCE_NAME);
01198 else if (strcmp(constraintName,"allowed-floats") == 0) return(FLOAT);
01199
01200 return(-1);
01201 }
01202
01203
01204
01205
01206
01207 static int GetConstraintTypeFromTypeName(
01208 char *constraintName)
01209 {
01210 if (strcmp(constraintName,"SYMBOL") == 0) return(SYMBOL);
01211 else if (strcmp(constraintName,"STRING") == 0) return(STRING);
01212 else if (strcmp(constraintName,"LEXEME") == 0) return(SYMBOL_OR_STRING);
01213 else if (strcmp(constraintName,"INTEGER") == 0) return(INTEGER);
01214 else if (strcmp(constraintName,"FLOAT") == 0) return(FLOAT);
01215 else if (strcmp(constraintName,"NUMBER") == 0) return(INTEGER_OR_FLOAT);
01216 else if (strcmp(constraintName,"INSTANCE-NAME") == 0) return(INSTANCE_NAME);
01217 else if (strcmp(constraintName,"INSTANCE-ADDRESS") == 0) return(INSTANCE_ADDRESS);
01218 else if (strcmp(constraintName,"INSTANCE") == 0) return(INSTANCE_OR_INSTANCE_NAME);
01219 else if (strcmp(constraintName,"EXTERNAL-ADDRESS") == 0) return(EXTERNAL_ADDRESS);
01220 else if (strcmp(constraintName,"FACT-ADDRESS") == 0) return(FACT_ADDRESS);
01221
01222 return(-1);
01223 }
01224
01225
01226
01227
01228
01229 static int GetAttributeParseValue(
01230 char *constraintName,
01231 CONSTRAINT_PARSE_RECORD *parsedConstraints)
01232 {
01233 if (strcmp(constraintName,"type") == 0)
01234 { return(parsedConstraints->type); }
01235 else if (strcmp(constraintName,"range") == 0)
01236 { return(parsedConstraints->range); }
01237 else if (strcmp(constraintName,"cardinality") == 0)
01238 { return(parsedConstraints->cardinality); }
01239 else if (strcmp(constraintName,"allowed-values") == 0)
01240 { return(parsedConstraints->allowedValues); }
01241 else if (strcmp(constraintName,"allowed-symbols") == 0)
01242 { return(parsedConstraints->allowedSymbols); }
01243 else if (strcmp(constraintName,"allowed-strings") == 0)
01244 { return(parsedConstraints->allowedStrings); }
01245 else if (strcmp(constraintName,"allowed-lexemes") == 0)
01246 { return(parsedConstraints->allowedLexemes); }
01247 else if (strcmp(constraintName,"allowed-instance-names") == 0)
01248 { return(parsedConstraints->allowedInstanceNames); }
01249 else if (strcmp(constraintName,"allowed-classes") == 0)
01250 { return(parsedConstraints->allowedClasses); }
01251 else if (strcmp(constraintName,"allowed-integers") == 0)
01252 { return(parsedConstraints->allowedIntegers); }
01253 else if (strcmp(constraintName,"allowed-floats") == 0)
01254 { return(parsedConstraints->allowedFloats); }
01255 else if (strcmp(constraintName,"allowed-numbers") == 0)
01256 { return(parsedConstraints->allowedNumbers); }
01257
01258 return(TRUE);
01259 }
01260
01261
01262
01263
01264
01265
01266 static void SetRestrictionFlag(
01267 int restriction,
01268 CONSTRAINT_RECORD *constraints,
01269 int value)
01270 {
01271 switch (restriction)
01272 {
01273 case UNKNOWN_VALUE:
01274 constraints->anyRestriction = value;
01275 break;
01276
01277 case SYMBOL:
01278 constraints->symbolRestriction = value;
01279 break;
01280
01281 case STRING:
01282 constraints->stringRestriction = value;
01283 break;
01284
01285 case INTEGER:
01286 constraints->integerRestriction = value;
01287 break;
01288
01289 case FLOAT:
01290 constraints->floatRestriction = value;
01291 break;
01292
01293 case INTEGER_OR_FLOAT:
01294 constraints->integerRestriction = value;
01295 constraints->floatRestriction = value;
01296 break;
01297
01298 case SYMBOL_OR_STRING:
01299 constraints->symbolRestriction = value;
01300 constraints->stringRestriction = value;
01301 break;
01302
01303 case INSTANCE_NAME:
01304 constraints->instanceNameRestriction = value;
01305 break;
01306
01307 case INSTANCE_OR_INSTANCE_NAME:
01308 constraints->classRestriction = value;
01309 break;
01310 }
01311 }
01312
01313
01314
01315
01316
01317 static void SetParseFlag(
01318 CONSTRAINT_PARSE_RECORD *parsedConstraints,
01319 char *constraintName)
01320 {
01321 if (strcmp(constraintName,"range") == 0)
01322 { parsedConstraints->range = TRUE; }
01323 else if (strcmp(constraintName,"type") == 0)
01324 { parsedConstraints->type = TRUE; }
01325 else if (strcmp(constraintName,"cardinality") == 0)
01326 { parsedConstraints->cardinality = TRUE; }
01327 else if (strcmp(constraintName,"allowed-symbols") == 0)
01328 { parsedConstraints->allowedSymbols = TRUE; }
01329 else if (strcmp(constraintName,"allowed-strings") == 0)
01330 { parsedConstraints->allowedStrings = TRUE; }
01331 else if (strcmp(constraintName,"allowed-lexemes") == 0)
01332 { parsedConstraints->allowedLexemes = TRUE; }
01333 else if (strcmp(constraintName,"allowed-integers") == 0)
01334 { parsedConstraints->allowedIntegers = TRUE; }
01335 else if (strcmp(constraintName,"allowed-floats") == 0)
01336 { parsedConstraints->allowedFloats = TRUE; }
01337 else if (strcmp(constraintName,"allowed-numbers") == 0)
01338 { parsedConstraints->allowedNumbers = TRUE; }
01339 else if (strcmp(constraintName,"allowed-values") == 0)
01340 { parsedConstraints->allowedValues = TRUE; }
01341 else if (strcmp(constraintName,"allowed-classes") == 0)
01342 { parsedConstraints->allowedClasses = TRUE; }
01343 }
01344
01345 #endif
01346