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