DIRECTORY CD; CDProperties: CEDAR DEFINITIONS = BEGIN PropList: TYPE = CD.PropList; PropRef: TYPE = CD.PropRef; --ABSOLUTELY NEVER NIL InitPropRef: PROC [] RETURNS [PropRef] = INLINE { RETURN [NEW[PropList_NIL]] }; RegisterProperty: PROC [prop: REF, registrationKey: REF_NIL] RETURNS [first: BOOLEAN]; PutProp: PROC [onto: REF, prop: REF, val: REF_NIL]; GetProp: PROC [from: REF, prop: REF] RETURNS [REF]; GetPropFromList: PROC [propList: PropList, prop: REF] RETURNS [REF]; PutPropOnInstance: PROC [onto: CD.Instance, prop: REF, val: REF_NIL]; PutPropOnDesign: PROC [onto: CD.Design, prop: REF, val: REF_NIL]; PutPropOnTechnology: PROC [onto: CD.Technology, prop: REF, val: REF_NIL]; PutPropOnAtom: PROC [onto: ATOM, prop: REF, val: REF_NIL]; PutPropOnObject: PROC [onto: CD.Object, prop: REF, val: REF_NIL]; PutPropOnLayer: PROC [onto: CD.Layer, prop: REF, val: REF_NIL]; PutPropOnPropRef: PROC [onto: CD.PropRef, prop: REF, val: REF_NIL]; GetPropFromInstance: PROC [from: CD.Instance, prop: REF] RETURNS [REF] = INLINE { RETURN [GetPropFromList[from.properties, prop]] }; GetPropFromDesign: PROC [from: CD.Design, prop: REF] RETURNS [REF] = INLINE { RETURN [GetPropFromList[from.properties^, prop]] }; GetPropFromTechnology: PROC [from: CD.Technology, prop: REF] RETURNS [REF] = INLINE { RETURN [GetPropFromList[from.properties^, prop]] }; GetPropFromAtom: PROC [from: ATOM, prop: REF] RETURNS [REF]; GetPropFromObject: PROC [from: CD.Object, prop: REF] RETURNS [REF] = INLINE { RETURN [GetPropFromList[from.properties, prop]] }; GetPropFromLayer: PROC [from: CD.Layer, prop: REF] RETURNS [REF]; GetPropFromPropRef: PROC [from: CD.PropRef, prop: REF] RETURNS [REF] = INLINE { RETURN [GetPropFromList[from^, prop]] }; InstallProcs: PROC [prop: REF, new: PropertyProcsRec _ [properties: NIL]]; FetchProcs: PROC [prop: REF] RETURNS [PropertyProcs]; RegisterAndInstall: PROC [prop: REF, new: PropertyProcsRec _ [properties: NIL], registrationKey: REF _ NIL] RETURNS [first: BOOLEAN]; PropertyProcs: TYPE = REF PropertyProcsRec; PropertyProcsRec: TYPE = RECORD [ makeCopy: MakeCopyProc _ NIL, internalWrite: InternalPWriteProc _ NIL, internalRead: InternalPReadProc _ NIL, exclusive: BOOL _ FALSE, --the implementation requests others not too fool with key: REF _ NIL, --the prop field of registration properties: PropList _ NIL ]; MakeCopyProc: TYPE = PROC [prop: REF, val: REF, purpose: REF_NIL] RETURNS [valCopy: REF]; InternalPWriteProc: TYPE = PROC [prop: REF, val: REF]; InternalPReadProc: TYPE = PROC [prop: ATOM] RETURNS [val: REF]; CopyProps: PROC [propList: PropList, putOnto: REF, purpose: REF_NIL]; AppendProps: PROC [winner, looser: PropList_NIL, putOnto: REF, purpose: REF_NIL]; DangerousCopyProps: PROC [propList: PropList, purpose: REF_NIL] RETURNS [copy: PropList]; DangerousAppendProps: PROC [winner, looser: PropList_NIL, purpose: REF_NIL] RETURNS [copy: PropList]; DoWithinLock: PRIVATE PROC [p: PROC]; DontCopy: PROC [prop: REF, val: REF, purpose: REF_NIL] RETURNS [nil: REF]; CopyVal: PROC [prop: REF, val: REF, purpose: REF_NIL] RETURNS [valCopy: REF]; RopePWrite: PROC [prop: REF, val: REF]; RopePRead: PROC [prop: ATOM] RETURNS [val: REF]; IntPWrite: PROC [prop: REF, val: REF]; IntPRead: PROC [prop: ATOM] RETURNS [val: REF]; AtomPWrite: PROC [prop: REF, val: REF]; AtomPRead: PROC [prop: ATOM] RETURNS [val: REF]; SomePWrite: PROC [prop: REF, val: REF]; SomePRead: PROC [prop: ATOM] RETURNS [val: REF]; END. nCDProperties.mesa a ChipNDale module Copyright c 1983, 1984 by Xerox Corporation. All rights reserved. by Ch. Jacobi, September 27, 1983 2:06 pm last edited Christian Jacobi, September 20, 1985 5:18:33 pm PDT Rules for property usage A property list requires following the ChipNDale access and registration rules when it is of type CD.PropList, CDProperties.PropList, CD.PropRef, CDProperties.PropRef or a derived type from one of those. If a property list is declared as Properties.PropList directly, then the ChipNDale access and registration rules do NOT apply. Violating access rules will cause chaos for ChipNDale at some time. Violating registration rules might prevent correct behaviour of unrelated ChipNDale tools; it is considered unfair. Violating user restrictions will cause only the violator to fail; ChipNDale does not care. Access rules NEVER access or modify ChipNDale PropList's directly with Properties; Direct use of Properties will probably cause chaos in ChipNDale, which frequently accesses PropList's from concurrent processes. Registration rules Atoms which start with the letters "CDX" or "CDx" (e.g. $CDxNMosTransitors) must be manual registered by the registrar and RegisterProperty must not be used. Atoms which start with the letters "CDY" or "CDy" (e.g. $CDyNMosTransitors) must not be registered, and there is no waranty of non-conflict. These may be used for debugging only. Atoms which start with other letters must be registered with RegisterProperty. RegisterProperty allows a registrationKey to enable re-registration. Use your name or the module name of the module you are implementing as registrationKey. Other REF-types need not be registered, since no conflicts may occur. Every module is allowed to introduce only a finite (fixed at compile time) number of "property names"s; they are kept in a table for "ever". User restrictions Enumeration of PropList's is highly not recomended; ChipNDale might asynchronously change the order of the properties in the PropList at any time. --Types and registration --Use only CDProperties to access ChipNDale PropList's; Never Properties directly. --Direct use of Properties can cause chaos in ChipNDale, which depends heavy --on concurrent processes accessing PropList's. --Initialization value for a PropRef --An object MUST be NOT accessible for ChipNDale until all its PropRef's are initialized. --Registers "prop" for usage; any program which wants to use an ATOM as a "prop" can --make sure it is the only user of this "prop". --If registrationKey#NIL and registrationKey is equal to registrationKey of previous --registration, a property may be multiple registered. --Otherwise raise CD.Error[doubleRegistration] if prop was already registered. --Property names cannot be removed, since they may reside somewhere in the --stored data. --Usage --Puts a prop val pair on a property list --a NIL val removes the property --Fetches a value from a property list; NIL if not found --Reorders list partially; next GetProp of the same prop may be faster --Fetches a value from a property list; NIL if not found --Reorders list partially; next GetPropFromList of the same prop may be faster --PutProp and GetProp "understand" the following types: CD.Instance CD.Object CD.PropRef (CDProperties.PropRef) some more types which are only of secondary importance. --Speed ups and special cases --a NIL val removes the property --a NIL val removes the property --a NIL val removes the property --this property is NOT fetchable with Atom.GetProp --The onto Atom need not be registered anywhere, the registration of the --prop is enough to prevent conflicts. --a NIL val removes the property --a NIL val removes the property --warning: different objects may share bits, property owners loose! --a NIL val removes the property --a NIL val removes the property --NIL if prop is not found --NIL if prop is not found --NIL if prop is not found --does NOT fetch properties put on an ATOM with Atom.PutProp --The from Atom need not be registered anywhere, the registration of the --prop is enough to prevent conflicts --NIL if prop is not found --NIL if prop is not found --warning: different objects may share bits, property owners loose! --NIL if prop is not found --NIL if prop is not found --general property procedures --Installs procedures for a property registration --Overwrites values for which new has non NIL entries (except key). --prop must be registered and yours. --Exceptional rule: The actual parameter new.properties might have been -- created with Properties directly, if the caller can assert that -- they are not reordered for the time of this call to InstallProcs. --Fetches the procedures on the property registration --Never copy PropertyProcs^; it can be extended by future calls of InstallProcs --Short cut for conveniance --Registers property and, if this was the first registration then installs procedures. --Parameters and raised exceptions are the same as in RegisterProperty and InstallProcs --valCopy: may be NIL if property should not be copied --purpose: -- copy procs will not recognize most purposes... -- but a particular property might want a particular handling from some tool --The procedure types of PropertyProcs will be called within CDProperties monitor lock. --They must not call any other procedure from CDProperties (wedges!!); But they may --call Properties directly. --Copies properties individually using their MakeCopyProc's and defaults for some types --The resulting propList is put on putOnto --Copies properties individually using their MakeCopyProc's and defaults for some types. --Works like first copying looser, then copying winner. --copy is a different list from both, looser and winner --The resulting propList copy is put on putOnto --Like CopyProps, but returns PropList; --Consider: if you assign the copy to somewhere, the previous PropList might have been --changed after making the copy and before the assignment is finished. --Like AppendProps, but returns PropList; --Consider: if you assign the copy to somewhere, the previous PropList might have been --changed after making the copy and before the assignment is finished. --Executes arbitrary code within CDProperties monitor lock. Dangerous. --Must not call any other procedure from CDProperties (wedges!!) --May call Properties directly --particular property procedures for implementors --to be shure that no copy is made; trivial procedure --copy of val; trivial procedure; is for some types a default anyway Design considerations A registeration procedure for property names is needed to prevent the same property name beeing used by two independent modules. Props are unique, and not used per technology since they hang on objects where the technology does not hang and some procs haven't a design or technology parameter. CDProperties serves for object classes with few numbers of properties, CDValue serves for object classes with huge numbers of "properties" CDProperties relies on the fact that if Properties reorders a property list, it does not change the front property of the list. (Otherwise CDProperties.GetPropFromList and (e.g.) CDProperties.CopyProps would not by synchronizable correctly) Κ ^˜codešœ&™&Kšœ Οmœ7™BKšœ)™)Kšœ?™?K˜—šΟk ˜ Kšžœ˜—K˜KšΠln œžœž œ˜"Kšž˜K˜šΠbl™K™KšœΝ™ΝK™KšœC™CKšœs™sKšœZ™ZK™—šΟb ™ KšœΖ™ΖK™—š‘™Kšœ™K™Kšœ³™³K™Kšœξ™ξK™K™EK™KšœŒ™ŒK™—š‘™Kšœ’™’K™K™—K™Kšœ™K˜Kšœ žœžœ ˜šœ žœžœ Οc˜2KšœR™RKšœL™LKšœ/™/K˜K˜—šΟn œžœžœ žœ˜1Kšœ$™$Kšœ\™\Kšžœžœ žœ˜K˜K˜—š £œžœžœžœžœ žœ˜VKšœU™UKšœ0™0KšœU™UKšœ7™7KšœN™NK™KšœJ™JKšœ™K™—K˜Kšœ™K˜š £œžœžœžœžœžœ˜3Kšœ)™)Kšœ ™ K˜—š £œžœžœžœžœžœ˜3Kšœ8™8KšœF™FK˜—š £œžœžœžœžœ˜DKšœ8™8KšœN™NK˜—šœ7žœ žœc™«K˜—K˜Kšœ™K˜š £œžœžœžœžœžœ˜EKšœ ™ —š £œžœžœžœžœžœ˜AKšœ ™ —š £œžœžœžœžœžœ˜IKšœ ™ —š £ œžœžœžœžœžœ˜:Kšœ‘œ™2KšœH™HKšœ&™&Kšœ ™ —š £œžœžœžœžœžœ˜AKšœ ™ K™C—š £œžœžœžœžœžœ˜?Kšœ ™ —š £œžœžœžœžœžœ˜CKšœ ™ K™—š£œžœžœžœžœžœžœ˜QKšœ™Kšžœ)˜/K˜—š£œžœžœžœžœžœžœ˜MKšœ™Kšžœ*˜0K˜—š£œžœžœžœžœžœžœ˜UKšœ™Kšžœ*˜0K˜—š £œžœžœžœžœžœ˜