1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 01/25/15 */
5 /* */
6 /* CONSTRAINT PARSER MODULE */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Provides functions for parsing constraint */
11 /* declarations. */
12 /* */
13 /* Principal Programmer(s): */
14 /* Gary D. Riley */
15 /* */
16 /* Contributing Programmer(s): */
17 /* Brian Dantes */
18 /* */
19 /* Revision History: */
20 /* */
21 /* 6.23: Changed name of variable exp to theExp */
22 /* because of Unix compiler warnings of shadowed */
23 /* definitions. */
24 /* */
25 /* 6.24: Added allowed-classes slot facet. */
26 /* */
27 /* Renamed BOOLEAN macro type to intBool. */
28 /* */
29 /* 6.30: Used gensprintf instead of sprintf. */
30 /* */
31 /* Added const qualifiers to remove C++ */
32 /* deprecation warnings. */
33 /* */
34 /* Slot cardinality bug fix for minimum < 0. */
35 /* */
36 /*************************************************************/
37
38 #define _CSTRNPSR_SOURCE_
39
40 #include <stdio.h>
41 #define _STDIO_INCLUDED_
42 #include <stdlib.h>
43
44 #include "setup.h"
45
46 #include "constant.h"
47 #include "envrnmnt.h"
48 #include "memalloc.h"
49 #include "router.h"
50 #include "scanner.h"
51 #include "cstrnutl.h"
52 #include "cstrnchk.h"
53 #include "sysdep.h"
54
55 #include "cstrnpsr.h"
56
57 /***************************************/
58 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
59 /***************************************/
60
61 #if (! RUN_TIME) && (! BLOAD_ONLY)
62 static intBool ParseRangeCardinalityAttribute(void *,
63 const char *,CONSTRAINT_RECORD *,
64 CONSTRAINT_PARSE_RECORD *,
65 const char *,int);
66 static intBool ParseTypeAttribute(void *,const char *,CONSTRAINT_RECORD *);
67 static void AddToRestrictionList(void *,int,CONSTRAINT_RECORD *,
68 CONSTRAINT_RECORD *);
69 static intBool ParseAllowedValuesAttribute(void *,const char *,const char *,
70 CONSTRAINT_RECORD *,
71 CONSTRAINT_PARSE_RECORD *);
72 static int GetConstraintTypeFromAllowedName(const char *);
73 static int GetConstraintTypeFromTypeName(const char *);
74 static int GetAttributeParseValue(const char *,CONSTRAINT_PARSE_RECORD *);
75 static void SetRestrictionFlag(int,CONSTRAINT_RECORD *,int);
76 static void SetParseFlag(CONSTRAINT_PARSE_RECORD *,const char *);
77 static void NoConjunctiveUseError(void *,const char *,const char *);
78 #endif
79
80 /********************************************************************/
81 /* CheckConstraintParseConflicts: Determines if a constraint record */
82 /* has any conflicts in the attribute specifications. Returns */
83 /* TRUE if no conflicts were detected, otherwise FALSE. */
84 /********************************************************************/
CheckConstraintParseConflicts(void * theEnv,CONSTRAINT_RECORD * constraints)85 globle intBool CheckConstraintParseConflicts(
86 void *theEnv,
87 CONSTRAINT_RECORD *constraints)
88 {
89 /*===================================================*/
90 /* Check to see if any of the allowed-... attributes */
91 /* conflict with the type attribute. */
92 /*===================================================*/
93
94 if (constraints->anyAllowed == TRUE)
95 { /* Do Nothing */ }
96 else if (constraints->symbolRestriction &&
97 (constraints->symbolsAllowed == FALSE))
98 {
99 AttributeConflictErrorMessage(theEnv,"type","allowed-symbols");
100 return(FALSE);
101 }
102 else if (constraints->stringRestriction &&
103 (constraints->stringsAllowed == FALSE))
104 {
105 AttributeConflictErrorMessage(theEnv,"type","allowed-strings");
106 return(FALSE);
107 }
108 else if (constraints->integerRestriction &&
109 (constraints->integersAllowed == FALSE))
110 {
111 AttributeConflictErrorMessage(theEnv,"type","allowed-integers/numbers");
112 return(FALSE);
113 }
114 else if (constraints->floatRestriction &&
115 (constraints->floatsAllowed == FALSE))
116 {
117 AttributeConflictErrorMessage(theEnv,"type","allowed-floats/numbers");
118 return(FALSE);
119 }
120 else if (constraints->classRestriction &&
121 (constraints->instanceAddressesAllowed == FALSE) &&
122 (constraints->instanceNamesAllowed == FALSE))
123 {
124 AttributeConflictErrorMessage(theEnv,"type","allowed-classes");
125 return(FALSE);
126 }
127 else if (constraints->instanceNameRestriction &&
128 (constraints->instanceNamesAllowed == FALSE))
129 {
130 AttributeConflictErrorMessage(theEnv,"type","allowed-instance-names");
131 return(FALSE);
132 }
133 else if (constraints->anyRestriction)
134 {
135 struct expr *theExp;
136
137 for (theExp = constraints->restrictionList;
138 theExp != NULL;
139 theExp = theExp->nextArg)
140 {
141 if (ConstraintCheckValue(theEnv,theExp->type,theExp->value,constraints) != NO_VIOLATION)
142 {
143 AttributeConflictErrorMessage(theEnv,"type","allowed-values");
144 return(FALSE);
145 }
146 }
147 }
148
149 /*================================================================*/
150 /* Check to see if range attribute conflicts with type attribute. */
151 /*================================================================*/
152
153 if ((constraints->maxValue != NULL) &&
154 (constraints->anyAllowed == FALSE))
155 {
156 if (((constraints->maxValue->type == INTEGER) &&
157 (constraints->integersAllowed == FALSE)) ||
158 ((constraints->maxValue->type == FLOAT) &&
159 (constraints->floatsAllowed == FALSE)))
160 {
161 AttributeConflictErrorMessage(theEnv,"type","range");
162 return(FALSE);
163 }
164 }
165
166 if ((constraints->minValue != NULL) &&
167 (constraints->anyAllowed == FALSE))
168 {
169 if (((constraints->minValue->type == INTEGER) &&
170 (constraints->integersAllowed == FALSE)) ||
171 ((constraints->minValue->type == FLOAT) &&
172 (constraints->floatsAllowed == FALSE)))
173 {
174 AttributeConflictErrorMessage(theEnv,"type","range");
175 return(FALSE);
176 }
177 }
178
179 /*=========================================*/
180 /* Check to see if allowed-class attribute */
181 /* conflicts with type attribute. */
182 /*=========================================*/
183
184 if ((constraints->classList != NULL) &&
185 (constraints->anyAllowed == FALSE) &&
186 (constraints->instanceNamesAllowed == FALSE) &&
187 (constraints->instanceAddressesAllowed == FALSE))
188 {
189 AttributeConflictErrorMessage(theEnv,"type","allowed-class");
190 return(FALSE);
191 }
192
193 /*=====================================================*/
194 /* Return TRUE to indicate no conflicts were detected. */
195 /*=====================================================*/
196
197 return(TRUE);
198 }
199
200 /********************************************************/
201 /* AttributeConflictErrorMessage: Generic error message */
202 /* for a constraint attribute conflict. */
203 /********************************************************/
AttributeConflictErrorMessage(void * theEnv,const char * attribute1,const char * attribute2)204 globle void AttributeConflictErrorMessage(
205 void *theEnv,
206 const char *attribute1,
207 const char *attribute2)
208 {
209 PrintErrorID(theEnv,"CSTRNPSR",1,TRUE);
210 EnvPrintRouter(theEnv,WERROR,"The ");
211 EnvPrintRouter(theEnv,WERROR,attribute1);
212 EnvPrintRouter(theEnv,WERROR," attribute conflicts with the ");
213 EnvPrintRouter(theEnv,WERROR,attribute2);
214 EnvPrintRouter(theEnv,WERROR," attribute.\n");
215 }
216
217 #if (! RUN_TIME) && (! BLOAD_ONLY)
218
219 /***************************************************************************/
220 /* InitializeConstraintParseRecord: Initializes the values of a constraint */
221 /* parse record which is used to determine whether one of the standard */
222 /* constraint specifications has already been parsed. */
223 /***************************************************************************/
InitializeConstraintParseRecord(CONSTRAINT_PARSE_RECORD * parsedConstraints)224 globle void InitializeConstraintParseRecord(
225 CONSTRAINT_PARSE_RECORD *parsedConstraints)
226 {
227 parsedConstraints->type = FALSE;
228 parsedConstraints->range = FALSE;
229 parsedConstraints->allowedSymbols = FALSE;
230 parsedConstraints->allowedStrings = FALSE;
231 parsedConstraints->allowedLexemes = FALSE;
232 parsedConstraints->allowedIntegers = FALSE;
233 parsedConstraints->allowedFloats = FALSE;
234 parsedConstraints->allowedNumbers = FALSE;
235 parsedConstraints->allowedValues = FALSE;
236 parsedConstraints->allowedInstanceNames = FALSE;
237 parsedConstraints->allowedClasses = FALSE;
238 parsedConstraints->cardinality = FALSE;
239 }
240
241 /************************************************************************/
242 /* StandardConstraint: Returns TRUE if the specified name is one of the */
243 /* standard constraints parseable by the routines in this module. */
244 /************************************************************************/
StandardConstraint(const char * constraintName)245 globle intBool StandardConstraint(
246 const char *constraintName)
247 {
248 if ((strcmp(constraintName,"type") == 0) ||
249 (strcmp(constraintName,"range") == 0) ||
250 (strcmp(constraintName,"cardinality") == 0) ||
251 (strcmp(constraintName,"allowed-symbols") == 0) ||
252 (strcmp(constraintName,"allowed-strings") == 0) ||
253 (strcmp(constraintName,"allowed-lexemes") == 0) ||
254 (strcmp(constraintName,"allowed-integers") == 0) ||
255 (strcmp(constraintName,"allowed-floats") == 0) ||
256 (strcmp(constraintName,"allowed-numbers") == 0) ||
257 (strcmp(constraintName,"allowed-instance-names") == 0) ||
258 (strcmp(constraintName,"allowed-classes") == 0) ||
259 (strcmp(constraintName,"allowed-values") == 0))
260
261 { return(TRUE); }
262
263 return(FALSE);
264 }
265
266 /***********************************************************************/
267 /* ParseStandardConstraint: Parses a standard constraint. Returns TRUE */
268 /* if the constraint was successfully parsed, otherwise FALSE. */
269 /***********************************************************************/
ParseStandardConstraint(void * theEnv,const char * readSource,const char * constraintName,CONSTRAINT_RECORD * constraints,CONSTRAINT_PARSE_RECORD * parsedConstraints,int multipleValuesAllowed)270 globle intBool ParseStandardConstraint(
271 void *theEnv,
272 const char *readSource,
273 const char *constraintName,
274 CONSTRAINT_RECORD *constraints,
275 CONSTRAINT_PARSE_RECORD *parsedConstraints,
276 int multipleValuesAllowed)
277 {
278 int rv = FALSE;
279
280 /*=====================================================*/
281 /* Determine if the attribute has already been parsed. */
282 /*=====================================================*/
283
284 if (GetAttributeParseValue(constraintName,parsedConstraints))
285 {
286 AlreadyParsedErrorMessage(theEnv,constraintName," attribute");
287 return(FALSE);
288 }
289
290 /*==========================================*/
291 /* If specified, parse the range attribute. */
292 /*==========================================*/
293
294 if (strcmp(constraintName,"range") == 0)
295 {
296 rv = ParseRangeCardinalityAttribute(theEnv,readSource,constraints,parsedConstraints,
297 constraintName,multipleValuesAllowed);
298 }
299
300 /*================================================*/
301 /* If specified, parse the cardinality attribute. */
302 /*================================================*/
303
304 else if (strcmp(constraintName,"cardinality") == 0)
305 {
306 rv = ParseRangeCardinalityAttribute(theEnv,readSource,constraints,parsedConstraints,
307 constraintName,multipleValuesAllowed);
308 }
309
310 /*=========================================*/
311 /* If specified, parse the type attribute. */
312 /*=========================================*/
313
314 else if (strcmp(constraintName,"type") == 0)
315 { rv = ParseTypeAttribute(theEnv,readSource,constraints); }
316
317 /*================================================*/
318 /* If specified, parse the allowed-... attribute. */
319 /*================================================*/
320
321 else if ((strcmp(constraintName,"allowed-symbols") == 0) ||
322 (strcmp(constraintName,"allowed-strings") == 0) ||
323 (strcmp(constraintName,"allowed-lexemes") == 0) ||
324 (strcmp(constraintName,"allowed-integers") == 0) ||
325 (strcmp(constraintName,"allowed-floats") == 0) ||
326 (strcmp(constraintName,"allowed-numbers") == 0) ||
327 (strcmp(constraintName,"allowed-instance-names") == 0) ||
328 (strcmp(constraintName,"allowed-classes") == 0) ||
329 (strcmp(constraintName,"allowed-values") == 0))
330 {
331 rv = ParseAllowedValuesAttribute(theEnv,readSource,constraintName,
332 constraints,parsedConstraints);
333 }
334
335 /*=========================================*/
336 /* Remember which constraint attribute was */
337 /* parsed and return the error status. */
338 /*=========================================*/
339
340 SetParseFlag(parsedConstraints,constraintName);
341 return(rv);
342 }
343
344 /***********************************************************/
345 /* OverlayConstraint: Overlays fields of source constraint */
346 /* record on destination based on which fields are set in */
347 /* the parsed constraint record. Assumes AddConstraint has */
348 /* not yet been called for the destination constraint */
349 /* record. */
350 /***********************************************************/
OverlayConstraint(void * theEnv,CONSTRAINT_PARSE_RECORD * pc,CONSTRAINT_RECORD * cdst,CONSTRAINT_RECORD * csrc)351 globle void OverlayConstraint(
352 void *theEnv,
353 CONSTRAINT_PARSE_RECORD *pc,
354 CONSTRAINT_RECORD *cdst,
355 CONSTRAINT_RECORD *csrc)
356 {
357 if (pc->type == 0)
358 {
359 cdst->anyAllowed = csrc->anyAllowed;
360 cdst->symbolsAllowed = csrc->symbolsAllowed;
361 cdst->stringsAllowed = csrc->stringsAllowed;
362 cdst->floatsAllowed = csrc->floatsAllowed;
363 cdst->integersAllowed = csrc->integersAllowed;
364 cdst->instanceNamesAllowed = csrc->instanceNamesAllowed;
365 cdst->instanceAddressesAllowed = csrc->instanceAddressesAllowed;
366 cdst->externalAddressesAllowed = csrc->externalAddressesAllowed;
367 cdst->voidAllowed = csrc->voidAllowed;
368 cdst->factAddressesAllowed = csrc->factAddressesAllowed;
369 }
370
371 if (pc->range == 0)
372 {
373 ReturnExpression(theEnv,cdst->minValue);
374 ReturnExpression(theEnv,cdst->maxValue);
375 cdst->minValue = CopyExpression(theEnv,csrc->minValue);
376 cdst->maxValue = CopyExpression(theEnv,csrc->maxValue);
377 }
378
379 if (pc->allowedClasses == 0)
380 {
381 ReturnExpression(theEnv,cdst->classList);
382 cdst->classList = CopyExpression(theEnv,csrc->classList);
383 }
384
385 if (pc->allowedValues == 0)
386 {
387 if ((pc->allowedSymbols == 0) &&
388 (pc->allowedStrings == 0) &&
389 (pc->allowedLexemes == 0) &&
390 (pc->allowedIntegers == 0) &&
391 (pc->allowedFloats == 0) &&
392 (pc->allowedNumbers == 0) &&
393 (pc->allowedInstanceNames == 0))
394 {
395 cdst->anyRestriction = csrc->anyRestriction;
396 cdst->symbolRestriction = csrc->symbolRestriction;
397 cdst->stringRestriction = csrc->stringRestriction;
398 cdst->floatRestriction = csrc->floatRestriction;
399 cdst->integerRestriction = csrc->integerRestriction;
400 cdst->classRestriction = csrc->classRestriction;
401 cdst->instanceNameRestriction = csrc->instanceNameRestriction;
402 cdst->restrictionList = CopyExpression(theEnv,csrc->restrictionList);
403 }
404 else
405 {
406 if ((pc->allowedSymbols == 0) && csrc->symbolRestriction)
407 {
408 cdst->symbolRestriction = 1;
409 AddToRestrictionList(theEnv,SYMBOL,cdst,csrc);
410 }
411 if ((pc->allowedStrings == 0) && csrc->stringRestriction)
412 {
413 cdst->stringRestriction = 1;
414 AddToRestrictionList(theEnv,STRING,cdst,csrc);
415 }
416 if ((pc->allowedLexemes == 0) && csrc->symbolRestriction && csrc->stringRestriction)
417 {
418 cdst->symbolRestriction = 1;
419 cdst->stringRestriction = 1;
420 AddToRestrictionList(theEnv,SYMBOL,cdst,csrc);
421 AddToRestrictionList(theEnv,STRING,cdst,csrc);
422 }
423 if ((pc->allowedIntegers == 0) && csrc->integerRestriction)
424 {
425 cdst->integerRestriction = 1;
426 AddToRestrictionList(theEnv,INTEGER,cdst,csrc);
427 }
428 if ((pc->allowedFloats == 0) && csrc->floatRestriction)
429 {
430 cdst->floatRestriction = 1;
431 AddToRestrictionList(theEnv,FLOAT,cdst,csrc);
432 }
433 if ((pc->allowedNumbers == 0) && csrc->integerRestriction && csrc->floatRestriction)
434 {
435 cdst->integerRestriction = 1;
436 cdst->floatRestriction = 1;
437 AddToRestrictionList(theEnv,INTEGER,cdst,csrc);
438 AddToRestrictionList(theEnv,FLOAT,cdst,csrc);
439 }
440 if ((pc->allowedInstanceNames == 0) && csrc->instanceNameRestriction)
441 {
442 cdst->instanceNameRestriction = 1;
443 AddToRestrictionList(theEnv,INSTANCE_NAME,cdst,csrc);
444 }
445 }
446 }
447
448 if (pc->cardinality == 0)
449 {
450 ReturnExpression(theEnv,cdst->minFields);
451 ReturnExpression(theEnv,cdst->maxFields);
452 cdst->minFields = CopyExpression(theEnv,csrc->minFields);
453 cdst->maxFields = CopyExpression(theEnv,csrc->maxFields);
454 }
455 }
456
457 /**********************************************/
458 /* OverlayConstraintParseRecord: Performs a */
459 /* field-wise "or" of the destination parse */
460 /* record with the source parse record. */
461 /**********************************************/
OverlayConstraintParseRecord(CONSTRAINT_PARSE_RECORD * dst,CONSTRAINT_PARSE_RECORD * src)462 globle void OverlayConstraintParseRecord(
463 CONSTRAINT_PARSE_RECORD *dst,
464 CONSTRAINT_PARSE_RECORD *src)
465 {
466 if (src->type) dst->type = TRUE;
467 if (src->range) dst->range = TRUE;
468 if (src->allowedSymbols) dst->allowedSymbols = TRUE;
469 if (src->allowedStrings) dst->allowedStrings = TRUE;
470 if (src->allowedLexemes) dst->allowedLexemes = TRUE;
471 if (src->allowedIntegers) dst->allowedIntegers = TRUE;
472 if (src->allowedFloats) dst->allowedFloats = TRUE;
473 if (src->allowedNumbers) dst->allowedNumbers = TRUE;
474 if (src->allowedValues) dst->allowedValues = TRUE;
475 if (src->allowedInstanceNames) dst->allowedInstanceNames = TRUE;
476 if (src->allowedClasses) dst->allowedClasses = TRUE;
477 if (src->cardinality) dst->cardinality = TRUE;
478 }
479
480 /************************************************************/
481 /* AddToRestrictionList: Prepends atoms of the specified */
482 /* type from the source restriction list to the destination */
483 /************************************************************/
AddToRestrictionList(void * theEnv,int type,CONSTRAINT_RECORD * cdst,CONSTRAINT_RECORD * csrc)484 static void AddToRestrictionList(
485 void *theEnv,
486 int type,
487 CONSTRAINT_RECORD *cdst,
488 CONSTRAINT_RECORD *csrc)
489 {
490 struct expr *theExp,*tmp;
491
492 for (theExp = csrc->restrictionList; theExp != NULL; theExp = theExp->nextArg)
493 {
494 if (theExp->type == type)
495 {
496 tmp = GenConstant(theEnv,theExp->type,theExp->value);
497 tmp->nextArg = cdst->restrictionList;
498 cdst->restrictionList = tmp;
499 }
500 }
501 }
502
503 /*******************************************************************/
504 /* ParseAllowedValuesAttribute: Parses the allowed-... attributes. */
505 /*******************************************************************/
ParseAllowedValuesAttribute(void * theEnv,const char * readSource,const char * constraintName,CONSTRAINT_RECORD * constraints,CONSTRAINT_PARSE_RECORD * parsedConstraints)506 static intBool ParseAllowedValuesAttribute(
507 void *theEnv,
508 const char *readSource,
509 const char *constraintName,
510 CONSTRAINT_RECORD *constraints,
511 CONSTRAINT_PARSE_RECORD *parsedConstraints)
512 {
513 struct token inputToken;
514 int expectedType, restrictionType, error = FALSE;
515 struct expr *newValue, *lastValue;
516 int constantParsed = FALSE, variableParsed = FALSE;
517 const char *tempPtr = NULL;
518
519 /*======================================================*/
520 /* The allowed-values attribute is not allowed if other */
521 /* allowed-... attributes have already been parsed. */
522 /*======================================================*/
523
524 if ((strcmp(constraintName,"allowed-values") == 0) &&
525 ((parsedConstraints->allowedSymbols) ||
526 (parsedConstraints->allowedStrings) ||
527 (parsedConstraints->allowedLexemes) ||
528 (parsedConstraints->allowedIntegers) ||
529 (parsedConstraints->allowedFloats) ||
530 (parsedConstraints->allowedNumbers) ||
531 (parsedConstraints->allowedInstanceNames)))
532 {
533 if (parsedConstraints->allowedSymbols) tempPtr = "allowed-symbols";
534 else if (parsedConstraints->allowedStrings) tempPtr = "allowed-strings";
535 else if (parsedConstraints->allowedLexemes) tempPtr = "allowed-lexemes";
536 else if (parsedConstraints->allowedIntegers) tempPtr = "allowed-integers";
537 else if (parsedConstraints->allowedFloats) tempPtr = "allowed-floats";
538 else if (parsedConstraints->allowedNumbers) tempPtr = "allowed-numbers";
539 else if (parsedConstraints->allowedInstanceNames) tempPtr = "allowed-instance-names";
540 NoConjunctiveUseError(theEnv,"allowed-values",tempPtr);
541 return(FALSE);
542 }
543
544 /*=======================================================*/
545 /* The allowed-values/numbers/integers/floats attributes */
546 /* are not allowed with the range attribute. */
547 /*=======================================================*/
548
549 if (((strcmp(constraintName,"allowed-values") == 0) ||
550 (strcmp(constraintName,"allowed-numbers") == 0) ||
551 (strcmp(constraintName,"allowed-integers") == 0) ||
552 (strcmp(constraintName,"allowed-floats") == 0)) &&
553 (parsedConstraints->range))
554 {
555 NoConjunctiveUseError(theEnv,constraintName,"range");
556 return(FALSE);
557 }
558
559 /*===================================================*/
560 /* The allowed-... attributes are not allowed if the */
561 /* allowed-values attribute has already been parsed. */
562 /*===================================================*/
563
564 if ((strcmp(constraintName,"allowed-values") != 0) &&
565 (parsedConstraints->allowedValues))
566 {
567 NoConjunctiveUseError(theEnv,constraintName,"allowed-values");
568 return(FALSE);
569 }
570
571 /*==================================================*/
572 /* The allowed-numbers attribute is not allowed if */
573 /* the allowed-integers or allowed-floats attribute */
574 /* has already been parsed. */
575 /*==================================================*/
576
577 if ((strcmp(constraintName,"allowed-numbers") == 0) &&
578 ((parsedConstraints->allowedFloats) || (parsedConstraints->allowedIntegers)))
579 {
580 if (parsedConstraints->allowedFloats) tempPtr = "allowed-floats";
581 else tempPtr = "allowed-integers";
582 NoConjunctiveUseError(theEnv,"allowed-numbers",tempPtr);
583 return(FALSE);
584 }
585
586 /*============================================================*/
587 /* The allowed-integers/floats attributes are not allowed if */
588 /* the allowed-numbers attribute has already been parsed. */
589 /*============================================================*/
590
591 if (((strcmp(constraintName,"allowed-integers") == 0) ||
592 (strcmp(constraintName,"allowed-floats") == 0)) &&
593 (parsedConstraints->allowedNumbers))
594 {
595 NoConjunctiveUseError(theEnv,constraintName,"allowed-number");
596 return(FALSE);
597 }
598
599 /*==================================================*/
600 /* The allowed-lexemes attribute is not allowed if */
601 /* the allowed-symbols or allowed-strings attribute */
602 /* has already been parsed. */
603 /*==================================================*/
604
605 if ((strcmp(constraintName,"allowed-lexemes") == 0) &&
606 ((parsedConstraints->allowedSymbols) || (parsedConstraints->allowedStrings)))
607 {
608 if (parsedConstraints->allowedSymbols) tempPtr = "allowed-symbols";
609 else tempPtr = "allowed-strings";
610 NoConjunctiveUseError(theEnv,"allowed-lexemes",tempPtr);
611 return(FALSE);
612 }
613
614 /*===========================================================*/
615 /* The allowed-symbols/strings attributes are not allowed if */
616 /* the allowed-lexemes attribute has already been parsed. */
617 /*===========================================================*/
618
619 if (((strcmp(constraintName,"allowed-symbols") == 0) ||
620 (strcmp(constraintName,"allowed-strings") == 0)) &&
621 (parsedConstraints->allowedLexemes))
622 {
623 NoConjunctiveUseError(theEnv,constraintName,"allowed-lexemes");
624 return(FALSE);
625 }
626
627 /*========================*/
628 /* Get the expected type. */
629 /*========================*/
630
631 restrictionType = GetConstraintTypeFromAllowedName(constraintName);
632 SetRestrictionFlag(restrictionType,constraints,TRUE);
633 if (strcmp(constraintName,"allowed-classes") == 0)
634 { expectedType = SYMBOL; }
635 else
636 { expectedType = restrictionType; }
637
638 /*=================================================*/
639 /* Get the last value in the restriction list (the */
640 /* allowed values will be appended there). */
641 /*=================================================*/
642
643 if (strcmp(constraintName,"allowed-classes") == 0)
644 { lastValue = constraints->classList; }
645 else
646 { lastValue = constraints->restrictionList; }
647
648 if (lastValue != NULL)
649 { while (lastValue->nextArg != NULL) lastValue = lastValue->nextArg; }
650
651 /*==================================================*/
652 /* Read the allowed values and add them to the list */
653 /* until a right parenthesis is encountered. */
654 /*==================================================*/
655
656 SavePPBuffer(theEnv," ");
657 GetToken(theEnv,readSource,&inputToken);
658
659 while (inputToken.type != RPAREN)
660 {
661 SavePPBuffer(theEnv," ");
662
663 /*=============================================*/
664 /* Determine the type of the token just parsed */
665 /* and if it is an appropriate value. */
666 /*=============================================*/
667
668 switch(inputToken.type)
669 {
670 case INTEGER:
671 if ((expectedType != UNKNOWN_VALUE) &&
672 (expectedType != INTEGER) &&
673 (expectedType != INTEGER_OR_FLOAT)) error = TRUE;
674 constantParsed = TRUE;
675 break;
676
677 case FLOAT:
678 if ((expectedType != UNKNOWN_VALUE) &&
679 (expectedType != FLOAT) &&
680 (expectedType != INTEGER_OR_FLOAT)) error = TRUE;
681 constantParsed = TRUE;
682 break;
683
684 case STRING:
685 if ((expectedType != UNKNOWN_VALUE) &&
686 (expectedType != STRING) &&
687 (expectedType != SYMBOL_OR_STRING)) error = TRUE;
688 constantParsed = TRUE;
689 break;
690
691 case SYMBOL:
692 if ((expectedType != UNKNOWN_VALUE) &&
693 (expectedType != SYMBOL) &&
694 (expectedType != SYMBOL_OR_STRING)) error = TRUE;
695 constantParsed = TRUE;
696 break;
697
698 #if OBJECT_SYSTEM
699 case INSTANCE_NAME:
700 if ((expectedType != UNKNOWN_VALUE) &&
701 (expectedType != INSTANCE_NAME)) error = TRUE;
702 constantParsed = TRUE;
703 break;
704 #endif
705
706 case SF_VARIABLE:
707 if (strcmp(inputToken.printForm,"?VARIABLE") == 0)
708 { variableParsed = TRUE; }
709 else
710 {
711 char tempBuffer[120];
712 gensprintf(tempBuffer,"%s attribute",constraintName);
713 SyntaxErrorMessage(theEnv,tempBuffer);
714 return(FALSE);
715 }
716
717 break;
718
719 default:
720 {
721 char tempBuffer[120];
722 gensprintf(tempBuffer,"%s attribute",constraintName);
723 SyntaxErrorMessage(theEnv,tempBuffer);
724 }
725 return(FALSE);
726 }
727
728 /*=====================================*/
729 /* Signal an error if an inappropriate */
730 /* value was found. */
731 /*=====================================*/
732
733 if (error)
734 {
735 PrintErrorID(theEnv,"CSTRNPSR",4,TRUE);
736 EnvPrintRouter(theEnv,WERROR,"Value does not match the expected type for the ");
737 EnvPrintRouter(theEnv,WERROR,constraintName);
738 EnvPrintRouter(theEnv,WERROR," attribute\n");
739 return(FALSE);
740 }
741
742 /*======================================*/
743 /* The ?VARIABLE argument can't be used */
744 /* in conjunction with constants. */
745 /*======================================*/
746
747 if (constantParsed && variableParsed)
748 {
749 char tempBuffer[120];
750 gensprintf(tempBuffer,"%s attribute",constraintName);
751 SyntaxErrorMessage(theEnv,tempBuffer);
752 return(FALSE);
753 }
754
755 /*===========================================*/
756 /* Add the constant to the restriction list. */
757 /*===========================================*/
758
759 newValue = GenConstant(theEnv,inputToken.type,inputToken.value);
760 if (lastValue == NULL)
761 {
762 if (strcmp(constraintName,"allowed-classes") == 0)
763 { constraints->classList = newValue; }
764 else
765 { constraints->restrictionList = newValue; }
766 }
767 else
768 { lastValue->nextArg = newValue; }
769 lastValue = newValue;
770
771 /*=======================================*/
772 /* Begin parsing the next allowed value. */
773 /*=======================================*/
774
775 GetToken(theEnv,readSource,&inputToken);
776 }
777
778 /*======================================================*/
779 /* There must be at least one value for this attribute. */
780 /*======================================================*/
781
782 if ((! constantParsed) && (! variableParsed))
783 {
784 char tempBuffer[120];
785 gensprintf(tempBuffer,"%s attribute",constraintName);
786 SyntaxErrorMessage(theEnv,tempBuffer);
787 return(FALSE);
788 }
789
790 /*======================================*/
791 /* If ?VARIABLE was parsed, then remove */
792 /* the restrictions for the type being */
793 /* restricted. */
794 /*======================================*/
795
796 if (variableParsed)
797 {
798 switch(restrictionType)
799 {
800 case UNKNOWN_VALUE:
801 constraints->anyRestriction = FALSE;
802 break;
803
804 case SYMBOL:
805 constraints->symbolRestriction = FALSE;
806 break;
807
808 case STRING:
809 constraints->stringRestriction = FALSE;
810 break;
811
812 case INTEGER:
813 constraints->integerRestriction = FALSE;
814 break;
815
816 case FLOAT:
817 constraints->floatRestriction = FALSE;
818 break;
819
820 case INTEGER_OR_FLOAT:
821 constraints->floatRestriction = FALSE;
822 constraints->integerRestriction = FALSE;
823 break;
824
825 case SYMBOL_OR_STRING:
826 constraints->symbolRestriction = FALSE;
827 constraints->stringRestriction = FALSE;
828 break;
829
830 case INSTANCE_NAME:
831 constraints->instanceNameRestriction = FALSE;
832 break;
833
834 case INSTANCE_OR_INSTANCE_NAME:
835 constraints->classRestriction = FALSE;
836 break;
837 }
838 }
839
840 /*=====================================*/
841 /* Fix up pretty print representation. */
842 /*=====================================*/
843
844 PPBackup(theEnv);
845 PPBackup(theEnv);
846 SavePPBuffer(theEnv,")");
847
848 /*=======================================*/
849 /* Return TRUE to indicate the attribute */
850 /* was successfully parsed. */
851 /*=======================================*/
852
853 return(TRUE);
854 }
855
856 /***********************************************************/
857 /* NoConjunctiveUseError: Generic error message indicating */
858 /* that two attributes can't be used in conjunction. */
859 /***********************************************************/
NoConjunctiveUseError(void * theEnv,const char * attribute1,const char * attribute2)860 static void NoConjunctiveUseError(
861 void *theEnv,
862 const char *attribute1,
863 const char *attribute2)
864 {
865 PrintErrorID(theEnv,"CSTRNPSR",3,TRUE);
866 EnvPrintRouter(theEnv,WERROR,"The ");
867 EnvPrintRouter(theEnv,WERROR,attribute1);
868 EnvPrintRouter(theEnv,WERROR," attribute cannot be used\n");
869 EnvPrintRouter(theEnv,WERROR,"in conjunction with the ");
870 EnvPrintRouter(theEnv,WERROR,attribute2);
871 EnvPrintRouter(theEnv,WERROR," attribute.\n");
872 }
873
874 /**************************************************/
875 /* ParseTypeAttribute: Parses the type attribute. */
876 /**************************************************/
ParseTypeAttribute(void * theEnv,const char * readSource,CONSTRAINT_RECORD * constraints)877 static intBool ParseTypeAttribute(
878 void *theEnv,
879 const char *readSource,
880 CONSTRAINT_RECORD *constraints)
881 {
882 int typeParsed = FALSE;
883 int variableParsed = FALSE;
884 int theType;
885 struct token inputToken;
886
887 /*======================================*/
888 /* Continue parsing types until a right */
889 /* parenthesis is encountered. */
890 /*======================================*/
891
892 SavePPBuffer(theEnv," ");
893 for (GetToken(theEnv,readSource,&inputToken);
894 inputToken.type != RPAREN;
895 GetToken(theEnv,readSource,&inputToken))
896 {
897 SavePPBuffer(theEnv," ");
898
899 /*==================================*/
900 /* If the token is a symbol then... */
901 /*==================================*/
902
903 if (inputToken.type == SYMBOL)
904 {
905 /*==============================================*/
906 /* ?VARIABLE can't be used with type constants. */
907 /*==============================================*/
908
909 if (variableParsed == TRUE)
910 {
911 SyntaxErrorMessage(theEnv,"type attribute");
912 return(FALSE);
913 }
914
915 /*========================================*/
916 /* Check for an appropriate type constant */
917 /* (e.g. SYMBOL, FLOAT, INTEGER, etc.). */
918 /*========================================*/
919
920 theType = GetConstraintTypeFromTypeName(ValueToString(inputToken.value));
921 if (theType < 0)
922 {
923 SyntaxErrorMessage(theEnv,"type attribute");
924 return(FALSE);
925 }
926
927 /*==================================================*/
928 /* Change the type restriction flags to reflect the */
929 /* type restriction. If the type restriction was */
930 /* already specified, then a error is generated. */
931 /*==================================================*/
932
933 if (SetConstraintType(theType,constraints))
934 {
935 SyntaxErrorMessage(theEnv,"type attribute");
936 return(FALSE);
937 }
938
939 constraints->anyAllowed = FALSE;
940
941 /*===========================================*/
942 /* Remember that a type constant was parsed. */
943 /*===========================================*/
944
945 typeParsed = TRUE;
946 }
947
948 /*==============================================*/
949 /* Otherwise if the token is a variable then... */
950 /*==============================================*/
951
952 else if (inputToken.type == SF_VARIABLE)
953 {
954 /*========================================*/
955 /* The only variable allowd is ?VARIABLE. */
956 /*========================================*/
957
958 if (strcmp(inputToken.printForm,"?VARIABLE") != 0)
959 {
960 SyntaxErrorMessage(theEnv,"type attribute");
961 return(FALSE);
962 }
963
964 /*===================================*/
965 /* ?VARIABLE can't be used more than */
966 /* once or with type constants. */
967 /*===================================*/
968
969 if (typeParsed || variableParsed)
970 {
971 SyntaxErrorMessage(theEnv,"type attribute");
972 return(FALSE);
973 }
974
975 /*======================================*/
976 /* Remember that a variable was parsed. */
977 /*======================================*/
978
979 variableParsed = TRUE;
980 }
981
982 /*====================================*/
983 /* Otherwise this is an invalid value */
984 /* for the type attribute. */
985 /*====================================*/
986
987 else
988 {
989 SyntaxErrorMessage(theEnv,"type attribute");
990 return(FALSE);
991 }
992 }
993
994 /*=====================================*/
995 /* Fix up pretty print representation. */
996 /*=====================================*/
997
998 PPBackup(theEnv);
999 PPBackup(theEnv);
1000 SavePPBuffer(theEnv,")");
1001
1002 /*=======================================*/
1003 /* The type attribute must have a value. */
1004 /*=======================================*/
1005
1006 if ((! typeParsed) && (! variableParsed))
1007 {
1008 SyntaxErrorMessage(theEnv,"type attribute");
1009 return(FALSE);
1010 }
1011
1012 /*===========================================*/
1013 /* Return TRUE indicating the type attibuted */
1014 /* was successfully parsed. */
1015 /*===========================================*/
1016
1017 return(TRUE);
1018 }
1019
1020 /***************************************************************************/
1021 /* ParseRangeCardinalityAttribute: Parses the range/cardinality attribute. */
1022 /***************************************************************************/
ParseRangeCardinalityAttribute(void * theEnv,const char * readSource,CONSTRAINT_RECORD * constraints,CONSTRAINT_PARSE_RECORD * parsedConstraints,const char * constraintName,int multipleValuesAllowed)1023 static intBool ParseRangeCardinalityAttribute(
1024 void *theEnv,
1025 const char *readSource,
1026 CONSTRAINT_RECORD *constraints,
1027 CONSTRAINT_PARSE_RECORD *parsedConstraints,
1028 const char *constraintName,
1029 int multipleValuesAllowed)
1030 {
1031 struct token inputToken;
1032 int range;
1033 const char *tempPtr = NULL;
1034
1035 /*=================================*/
1036 /* Determine if we're parsing the */
1037 /* range or cardinality attribute. */
1038 /*=================================*/
1039
1040 if (strcmp(constraintName,"range") == 0)
1041 {
1042 parsedConstraints->range = TRUE;
1043 range = TRUE;
1044 }
1045 else
1046 {
1047 parsedConstraints->cardinality = TRUE;
1048 range = FALSE;
1049 }
1050
1051 /*===================================================================*/
1052 /* The cardinality attribute can only be used with multifield slots. */
1053 /*===================================================================*/
1054
1055 if ((range == FALSE) &&
1056 (multipleValuesAllowed == FALSE))
1057 {
1058 PrintErrorID(theEnv,"CSTRNPSR",5,TRUE);
1059 EnvPrintRouter(theEnv,WERROR,"The cardinality attribute ");
1060 EnvPrintRouter(theEnv,WERROR,"can only be used with multifield slots.\n");
1061 return(FALSE);
1062 }
1063
1064 /*====================================================*/
1065 /* The range attribute is not allowed with the */
1066 /* allowed-values/numbers/integers/floats attributes. */
1067 /*====================================================*/
1068
1069 if ((range == TRUE) &&
1070 (parsedConstraints->allowedValues ||
1071 parsedConstraints->allowedNumbers ||
1072 parsedConstraints->allowedIntegers ||
1073 parsedConstraints->allowedFloats))
1074 {
1075 if (parsedConstraints->allowedValues) tempPtr = "allowed-values";
1076 else if (parsedConstraints->allowedIntegers) tempPtr = "allowed-integers";
1077 else if (parsedConstraints->allowedFloats) tempPtr = "allowed-floats";
1078 else if (parsedConstraints->allowedNumbers) tempPtr = "allowed-numbers";
1079 NoConjunctiveUseError(theEnv,"range",tempPtr);
1080 return(FALSE);
1081 }
1082
1083 /*==========================*/
1084 /* Parse the minimum value. */
1085 /*==========================*/
1086
1087 SavePPBuffer(theEnv," ");
1088 GetToken(theEnv,readSource,&inputToken);
1089 if ((inputToken.type == INTEGER) || ((inputToken.type == FLOAT) && range))
1090 {
1091 if (range)
1092 {
1093 ReturnExpression(theEnv,constraints->minValue);
1094 constraints->minValue = GenConstant(theEnv,inputToken.type,inputToken.value);
1095 }
1096 else
1097 {
1098 if (ValueToLong(inputToken.value) < 0LL)
1099 {
1100 PrintErrorID(theEnv,"CSTRNPSR",6,TRUE);
1101 EnvPrintRouter(theEnv,WERROR,"Minimum cardinality value must be greater than or equal to zero\n");
1102 return(FALSE);
1103 }
1104
1105 ReturnExpression(theEnv,constraints->minFields);
1106 constraints->minFields = GenConstant(theEnv,inputToken.type,inputToken.value);
1107 }
1108 }
1109 else if ((inputToken.type == SF_VARIABLE) && (strcmp(inputToken.printForm,"?VARIABLE") == 0))
1110 { /* Do nothing. */ }
1111 else
1112 {
1113 char tempBuffer[120];
1114 gensprintf(tempBuffer,"%s attribute",constraintName);
1115 SyntaxErrorMessage(theEnv,tempBuffer);
1116 return(FALSE);
1117 }
1118
1119 /*==========================*/
1120 /* Parse the maximum value. */
1121 /*==========================*/
1122
1123 SavePPBuffer(theEnv," ");
1124 GetToken(theEnv,readSource,&inputToken);
1125 if ((inputToken.type == INTEGER) || ((inputToken.type == FLOAT) && range))
1126 {
1127 if (range)
1128 {
1129 ReturnExpression(theEnv,constraints->maxValue);
1130 constraints->maxValue = GenConstant(theEnv,inputToken.type,inputToken.value);
1131 }
1132 else
1133 {
1134 ReturnExpression(theEnv,constraints->maxFields);
1135 constraints->maxFields = GenConstant(theEnv,inputToken.type,inputToken.value);
1136 }
1137 }
1138 else if ((inputToken.type == SF_VARIABLE) && (strcmp(inputToken.printForm,"?VARIABLE") == 0))
1139 { /* Do nothing. */ }
1140 else
1141 {
1142 char tempBuffer[120];
1143 gensprintf(tempBuffer,"%s attribute",constraintName);
1144 SyntaxErrorMessage(theEnv,tempBuffer);
1145 return(FALSE);
1146 }
1147
1148 /*================================*/
1149 /* Parse the closing parenthesis. */
1150 /*================================*/
1151
1152 GetToken(theEnv,readSource,&inputToken);
1153 if (inputToken.type != RPAREN)
1154 {
1155 SyntaxErrorMessage(theEnv,"range attribute");
1156 return(FALSE);
1157 }
1158
1159 /*====================================================*/
1160 /* Minimum value must be less than the maximum value. */
1161 /*====================================================*/
1162
1163 if (range)
1164 {
1165 if (CompareNumbers(theEnv,constraints->minValue->type,
1166 constraints->minValue->value,
1167 constraints->maxValue->type,
1168 constraints->maxValue->value) == GREATER_THAN)
1169 {
1170 PrintErrorID(theEnv,"CSTRNPSR",2,TRUE);
1171 EnvPrintRouter(theEnv,WERROR,"Minimum range value must be less than\n");
1172 EnvPrintRouter(theEnv,WERROR,"or equal to the maximum range value\n");
1173 return(FALSE);
1174 }
1175 }
1176 else
1177 {
1178 if (CompareNumbers(theEnv,constraints->minFields->type,
1179 constraints->minFields->value,
1180 constraints->maxFields->type,
1181 constraints->maxFields->value) == GREATER_THAN)
1182 {
1183 PrintErrorID(theEnv,"CSTRNPSR",2,TRUE);
1184 EnvPrintRouter(theEnv,WERROR,"Minimum cardinality value must be less than\n");
1185 EnvPrintRouter(theEnv,WERROR,"or equal to the maximum cardinality value\n");
1186 return(FALSE);
1187 }
1188 }
1189
1190 /*====================================*/
1191 /* Return TRUE to indicate that the */
1192 /* attribute was successfully parsed. */
1193 /*====================================*/
1194
1195 return(TRUE);
1196 }
1197
1198 /******************************************************************/
1199 /* GetConstraintTypeFromAllowedName: Returns the type restriction */
1200 /* associated with an allowed-... attribute. */
1201 /******************************************************************/
GetConstraintTypeFromAllowedName(const char * constraintName)1202 static int GetConstraintTypeFromAllowedName(
1203 const char *constraintName)
1204 {
1205 if (strcmp(constraintName,"allowed-values") == 0) return(UNKNOWN_VALUE);
1206 else if (strcmp(constraintName,"allowed-symbols") == 0) return(SYMBOL);
1207 else if (strcmp(constraintName,"allowed-strings") == 0) return(STRING);
1208 else if (strcmp(constraintName,"allowed-lexemes") == 0) return(SYMBOL_OR_STRING);
1209 else if (strcmp(constraintName,"allowed-integers") == 0) return(INTEGER);
1210 else if (strcmp(constraintName,"allowed-numbers") == 0) return(INTEGER_OR_FLOAT);
1211 else if (strcmp(constraintName,"allowed-instance-names") == 0) return(INSTANCE_NAME);
1212 else if (strcmp(constraintName,"allowed-classes") == 0) return(INSTANCE_OR_INSTANCE_NAME);
1213 else if (strcmp(constraintName,"allowed-floats") == 0) return(FLOAT);
1214
1215 return(-1);
1216 }
1217
1218 /*******************************************************/
1219 /* GetConstraintTypeFromTypeName: Converts a type name */
1220 /* to its equivalent integer type restriction. */
1221 /*******************************************************/
GetConstraintTypeFromTypeName(const char * constraintName)1222 static int GetConstraintTypeFromTypeName(
1223 const char *constraintName)
1224 {
1225 if (strcmp(constraintName,"SYMBOL") == 0) return(SYMBOL);
1226 else if (strcmp(constraintName,"STRING") == 0) return(STRING);
1227 else if (strcmp(constraintName,"LEXEME") == 0) return(SYMBOL_OR_STRING);
1228 else if (strcmp(constraintName,"INTEGER") == 0) return(INTEGER);
1229 else if (strcmp(constraintName,"FLOAT") == 0) return(FLOAT);
1230 else if (strcmp(constraintName,"NUMBER") == 0) return(INTEGER_OR_FLOAT);
1231 else if (strcmp(constraintName,"INSTANCE-NAME") == 0) return(INSTANCE_NAME);
1232 else if (strcmp(constraintName,"INSTANCE-ADDRESS") == 0) return(INSTANCE_ADDRESS);
1233 else if (strcmp(constraintName,"INSTANCE") == 0) return(INSTANCE_OR_INSTANCE_NAME);
1234 else if (strcmp(constraintName,"EXTERNAL-ADDRESS") == 0) return(EXTERNAL_ADDRESS);
1235 else if (strcmp(constraintName,"FACT-ADDRESS") == 0) return(FACT_ADDRESS);
1236
1237 return(-1);
1238 }
1239
1240 /**************************************************************/
1241 /* GetAttributeParseValue: Returns a boolean value indicating */
1242 /* whether a specific attribute has already been parsed. */
1243 /**************************************************************/
GetAttributeParseValue(const char * constraintName,CONSTRAINT_PARSE_RECORD * parsedConstraints)1244 static int GetAttributeParseValue(
1245 const char *constraintName,
1246 CONSTRAINT_PARSE_RECORD *parsedConstraints)
1247 {
1248 if (strcmp(constraintName,"type") == 0)
1249 { return(parsedConstraints->type); }
1250 else if (strcmp(constraintName,"range") == 0)
1251 { return(parsedConstraints->range); }
1252 else if (strcmp(constraintName,"cardinality") == 0)
1253 { return(parsedConstraints->cardinality); }
1254 else if (strcmp(constraintName,"allowed-values") == 0)
1255 { return(parsedConstraints->allowedValues); }
1256 else if (strcmp(constraintName,"allowed-symbols") == 0)
1257 { return(parsedConstraints->allowedSymbols); }
1258 else if (strcmp(constraintName,"allowed-strings") == 0)
1259 { return(parsedConstraints->allowedStrings); }
1260 else if (strcmp(constraintName,"allowed-lexemes") == 0)
1261 { return(parsedConstraints->allowedLexemes); }
1262 else if (strcmp(constraintName,"allowed-instance-names") == 0)
1263 { return(parsedConstraints->allowedInstanceNames); }
1264 else if (strcmp(constraintName,"allowed-classes") == 0)
1265 { return(parsedConstraints->allowedClasses); }
1266 else if (strcmp(constraintName,"allowed-integers") == 0)
1267 { return(parsedConstraints->allowedIntegers); }
1268 else if (strcmp(constraintName,"allowed-floats") == 0)
1269 { return(parsedConstraints->allowedFloats); }
1270 else if (strcmp(constraintName,"allowed-numbers") == 0)
1271 { return(parsedConstraints->allowedNumbers); }
1272
1273 return(TRUE);
1274 }
1275
1276 /**********************************************************/
1277 /* SetRestrictionFlag: Sets the restriction flag of a */
1278 /* constraint record indicating whether a specific */
1279 /* type has an associated allowed-... restriction list. */
1280 /**********************************************************/
SetRestrictionFlag(int restriction,CONSTRAINT_RECORD * constraints,int value)1281 static void SetRestrictionFlag(
1282 int restriction,
1283 CONSTRAINT_RECORD *constraints,
1284 int value)
1285 {
1286 switch (restriction)
1287 {
1288 case UNKNOWN_VALUE:
1289 constraints->anyRestriction = value;
1290 break;
1291
1292 case SYMBOL:
1293 constraints->symbolRestriction = value;
1294 break;
1295
1296 case STRING:
1297 constraints->stringRestriction = value;
1298 break;
1299
1300 case INTEGER:
1301 constraints->integerRestriction = value;
1302 break;
1303
1304 case FLOAT:
1305 constraints->floatRestriction = value;
1306 break;
1307
1308 case INTEGER_OR_FLOAT:
1309 constraints->integerRestriction = value;
1310 constraints->floatRestriction = value;
1311 break;
1312
1313 case SYMBOL_OR_STRING:
1314 constraints->symbolRestriction = value;
1315 constraints->stringRestriction = value;
1316 break;
1317
1318 case INSTANCE_NAME:
1319 constraints->instanceNameRestriction = value;
1320 break;
1321
1322 case INSTANCE_OR_INSTANCE_NAME:
1323 constraints->classRestriction = value;
1324 break;
1325 }
1326 }
1327
1328 /********************************************************************/
1329 /* SetParseFlag: Sets the flag in a parsed constraints data */
1330 /* structure indicating that a specific attribute has been parsed. */
1331 /********************************************************************/
SetParseFlag(CONSTRAINT_PARSE_RECORD * parsedConstraints,const char * constraintName)1332 static void SetParseFlag(
1333 CONSTRAINT_PARSE_RECORD *parsedConstraints,
1334 const char *constraintName)
1335 {
1336 if (strcmp(constraintName,"range") == 0)
1337 { parsedConstraints->range = TRUE; }
1338 else if (strcmp(constraintName,"type") == 0)
1339 { parsedConstraints->type = TRUE; }
1340 else if (strcmp(constraintName,"cardinality") == 0)
1341 { parsedConstraints->cardinality = TRUE; }
1342 else if (strcmp(constraintName,"allowed-symbols") == 0)
1343 { parsedConstraints->allowedSymbols = TRUE; }
1344 else if (strcmp(constraintName,"allowed-strings") == 0)
1345 { parsedConstraints->allowedStrings = TRUE; }
1346 else if (strcmp(constraintName,"allowed-lexemes") == 0)
1347 { parsedConstraints->allowedLexemes = TRUE; }
1348 else if (strcmp(constraintName,"allowed-integers") == 0)
1349 { parsedConstraints->allowedIntegers = TRUE; }
1350 else if (strcmp(constraintName,"allowed-floats") == 0)
1351 { parsedConstraints->allowedFloats = TRUE; }
1352 else if (strcmp(constraintName,"allowed-numbers") == 0)
1353 { parsedConstraints->allowedNumbers = TRUE; }
1354 else if (strcmp(constraintName,"allowed-values") == 0)
1355 { parsedConstraints->allowedValues = TRUE; }
1356 else if (strcmp(constraintName,"allowed-classes") == 0)
1357 { parsedConstraints->allowedClasses = TRUE; }
1358 }
1359
1360 #endif /* (! RUN_TIME) && (! BLOAD_ONLY) */
1361
1362