static struct templateSlot *ParseSlot( void *theEnv, char *readSource, struct token *inputToken, struct templateSlot *slotList) { int parsingMultislot; SYMBOL_HN *slotName; struct templateSlot *newSlot; int rv; /*=====================================================*/ /* Slots must begin with keyword field or multifield. */ /*=====================================================*/ if ((strcmp(ValueToString(inputToken->value),"field") != 0) && (strcmp(ValueToString(inputToken->value),"multifield") != 0) && (strcmp(ValueToString(inputToken->value),"slot") != 0) && (strcmp(ValueToString(inputToken->value),"multislot") != 0)) { SyntaxErrorMessage(theEnv,"deftemplate"); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*===============================================*/ /* Determine if multifield slot is being parsed. */ /*===============================================*/ if ((strcmp(ValueToString(inputToken->value),"multifield") == 0) || (strcmp(ValueToString(inputToken->value),"multislot") == 0)) { parsingMultislot = TRUE; } else { parsingMultislot = FALSE; } /*========================================*/ /* The name of the slot must be a symbol. */ /*========================================*/ SavePPBuffer(theEnv," "); GetToken(theEnv,readSource,inputToken); if (inputToken->type != SYMBOL) { SyntaxErrorMessage(theEnv,"deftemplate"); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } slotName = (SYMBOL_HN *) inputToken->value; /*================================================*/ /* Determine if the slot has already been parsed. */ /*================================================*/ while (slotList != NULL) { if (slotList->slotName == slotName) { AlreadyParsedErrorMessage(theEnv,"slot ",ValueToString(slotList->slotName)); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } slotList = slotList->next; } /*===================================*/ /* Parse the attributes of the slot. */ /*===================================*/ newSlot = DefinedSlots(theEnv,readSource,slotName,parsingMultislot,inputToken); if (newSlot == NULL) { DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*=================================*/ /* Check for slot conflict errors. */ /*=================================*/ if (CheckConstraintParseConflicts(theEnv,newSlot->constraints) == FALSE) { ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } if ((newSlot->defaultPresent) || (newSlot->defaultDynamic)) { rv = ConstraintCheckExpressionChain(theEnv,newSlot->defaultList,newSlot->constraints); } else { rv = NO_VIOLATION; } if ((rv != NO_VIOLATION) && EnvGetStaticConstraintChecking(theEnv)) { char *temp; if (newSlot->defaultDynamic) temp = "the default-dynamic attribute"; else temp = "the default attribute"; ConstraintViolationErrorMessage(theEnv,"An expression",temp,FALSE,0, newSlot->slotName,0,rv,newSlot->constraints,TRUE); ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*==================*/ /* Return the slot. */ /*==================*/ return(newSlot); }
/************************************************************ NAME : ParseSlot DESCRIPTION : Parses slot definitions for a defclass statement INPUTS : 1) The logical name of the input source 2) The current slot list 3) The class precedence list for the class to which this slot is being attached (used to find facets for composite slots) 4) A flag indicating if this is a multifield slot or not 5) A flag indicating if the type of slot (single or multi) was explicitly specified or not RETURNS : The address of the list of slots, NULL if there was an error SIDE EFFECTS : The slot list is allocated NOTES : Assumes "(slot" has already been parsed. ************************************************************/ globle TEMP_SLOT_LINK *ParseSlot( void *theEnv, EXEC_STATUS, char *readSource, TEMP_SLOT_LINK *slist, PACKED_CLASS_LINKS *preclist, int multiSlot, int fieldSpecified) { SLOT_DESC *slot; CONSTRAINT_PARSE_RECORD parsedConstraint; char specbits[2]; int rtnCode; SYMBOL_HN *newOverrideMsg; /* =============================================================== Bits in specbits are when slot qualifiers are specified so that duplicate or conflicting qualifiers can be detected. Shared/local bit-0 Single/multiple bit-1 Read-only/Read-write/Initialize-Only bit-2 Inherit/No-inherit bit-3 Composite/Exclusive bit-4 Reactive/Nonreactive bit-5 Default bit-6 Default-dynamic bit-7 Visibility bit-8 Override-message bit-9 =============================================================== */ SavePPBuffer(theEnv,execStatus," "); specbits[0] = specbits[1] = '\0'; GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); if (GetType(DefclassData(theEnv,execStatus)->ObjectParseToken) != SYMBOL) { DeleteSlots(theEnv,execStatus,slist); SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); return(NULL); } if ((DefclassData(theEnv,execStatus)->ObjectParseToken.value == (void *) DefclassData(theEnv,execStatus)->ISA_SYMBOL) || (DefclassData(theEnv,execStatus)->ObjectParseToken.value == (void *) DefclassData(theEnv,execStatus)->NAME_SYMBOL)) { DeleteSlots(theEnv,execStatus,slist); SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); return(NULL); } slot = NewSlot(theEnv,execStatus,(SYMBOL_HN *) GetValue(DefclassData(theEnv,execStatus)->ObjectParseToken)); slist = InsertSlot(theEnv,execStatus,slist,slot); if (slist == NULL) return(NULL); if (multiSlot) slot->multiple = TRUE; if (fieldSpecified) SetBitMap(specbits,FIELD_BIT); GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); IncrementIndentDepth(theEnv,execStatus,3); InitializeConstraintParseRecord(&parsedConstraint); while (GetType(DefclassData(theEnv,execStatus)->ObjectParseToken) == LPAREN) { PPBackup(theEnv,execStatus); PPCRAndIndent(theEnv,execStatus); SavePPBuffer(theEnv,execStatus,"("); GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); if (GetType(DefclassData(theEnv,execStatus)->ObjectParseToken) != SYMBOL) { SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); goto ParseSlotError; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),DEFAULT_FACET) == 0) { if (ParseDefaultFacet(theEnv,execStatus,readSource,specbits,slot) == FALSE) goto ParseSlotError; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),DYNAMIC_FACET) == 0) { SetBitMap(specbits,DEFAULT_DYNAMIC_BIT); if (ParseDefaultFacet(theEnv,execStatus,readSource,specbits,slot) == FALSE) goto ParseSlotError; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),ACCESS_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,ACCESS_FACET,ACCESS_BIT, SLOT_RDWRT_RLN,SLOT_RDONLY_RLN,SLOT_INIT_RLN, NULL,NULL); if (rtnCode == -1) goto ParseSlotError; else if (rtnCode == 1) slot->noWrite = 1; else if (rtnCode == 2) slot->initializeOnly = 1; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),STORAGE_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,STORAGE_FACET,STORAGE_BIT, SLOT_LOCAL_RLN,SLOT_SHARE_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->shared = rtnCode; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),PROPAGATION_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,PROPAGATION_FACET,PROPAGATION_BIT, SLOT_INH_RLN,SLOT_NO_INH_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->noInherit = rtnCode; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),SOURCE_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,SOURCE_FACET,SOURCE_BIT, SLOT_EXCLUSIVE_RLN,SLOT_COMPOSITE_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->composite = rtnCode; } #if DEFRULE_CONSTRUCT else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),MATCH_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,MATCH_FACET,MATCH_BIT, SLOT_NONREACTIVE_RLN,SLOT_REACTIVE_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->reactive = rtnCode; } #endif else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),VISIBILITY_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,VISIBILITY_FACET,VISIBILITY_BIT, SLOT_PRIVATE_RLN,SLOT_PUBLIC_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->publicVisibility = rtnCode; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),CREATE_ACCESSOR_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,CREATE_ACCESSOR_FACET, CREATE_ACCESSOR_BIT, SLOT_READ_RLN,SLOT_WRITE_RLN,SLOT_RDWRT_RLN, SLOT_NONE_RLN,NULL); if (rtnCode == -1) goto ParseSlotError; if ((rtnCode == 0) || (rtnCode == 2)) slot->createReadAccessor = TRUE; if ((rtnCode == 1) || (rtnCode == 2)) slot->createWriteAccessor = TRUE; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),OVERRIDE_MSG_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,OVERRIDE_MSG_FACET,OVERRIDE_MSG_BIT, NULL,NULL,NULL,SLOT_DEFAULT_RLN,&newOverrideMsg); if (rtnCode == -1) goto ParseSlotError; if (rtnCode == 4) { DecrementSymbolCount(theEnv,execStatus,slot->overrideMessage); slot->overrideMessage = newOverrideMsg; IncrementSymbolCount(slot->overrideMessage); } slot->overrideMessageSpecified = TRUE; } else if (StandardConstraint(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken))) { if (ParseStandardConstraint(theEnv,execStatus,readSource,DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken), slot->constraint,&parsedConstraint,TRUE) == FALSE) goto ParseSlotError; } else { SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); goto ParseSlotError; } GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); } if (GetType(DefclassData(theEnv,execStatus)->ObjectParseToken) != RPAREN) { SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); goto ParseSlotError; } if (DefclassData(theEnv,execStatus)->ClassDefaultsMode == CONVENIENCE_MODE) { if (! TestBitMap(specbits,CREATE_ACCESSOR_BIT)) { slot->createReadAccessor = TRUE; if (! slot->noWrite) { slot->createWriteAccessor = TRUE; } } } if (slot->composite) BuildCompositeFacets(theEnv,execStatus,slot,preclist,specbits,&parsedConstraint); if (CheckForFacetConflicts(theEnv,execStatus,slot,&parsedConstraint) == FALSE) goto ParseSlotError; if (CheckConstraintParseConflicts(theEnv,execStatus,slot->constraint) == FALSE) goto ParseSlotError; if (EvaluateSlotDefaultValue(theEnv,execStatus,slot,specbits) == FALSE) goto ParseSlotError; if ((slot->dynamicDefault == 0) && (slot->noWrite == 1) && (slot->initializeOnly == 0)) slot->shared = 1; slot->constraint = AddConstraint(theEnv,execStatus,slot->constraint); DecrementIndentDepth(theEnv,execStatus,3); return(slist); ParseSlotError: DecrementIndentDepth(theEnv,execStatus,3); DeleteSlots(theEnv,execStatus,slist); return(NULL); }