CDPropertiesImpl.mesa a ChipNDale module
Copyright © 1983, 1985 by Xerox Corporation. All rights reserved.
by Ch. Jacobi, September 27, 1983 2:06 pm
last edited Christian Jacobi, January 28, 1986 3:09:49 pm PST
DIRECTORY
CDProperties,
CDPropertyTools,
CD,
CDPrivate,
Atom,
Commander,
CommandTool,
List,
Properties,
RefTab,
Rope,
RopeList,
RuntimeError USING [UNCAUGHT],
TokenIO,
UserProfile USING [Boolean],
ViewerTools USING [TiogaContents, TiogaContentsRec];
CDPropertiesImpl:
CEDAR
MONITOR
IMPORTS CD, CDPrivate, CDProperties, Atom, Commander, CommandTool, List, Properties, RefTab, Rope, RopeList, RuntimeError, TokenIO, UserProfile
EXPORTS CDProperties, CDPropertyTools =
BEGIN
PropList: TYPE = CD.PropList;
PropertyProcs: TYPE = CDProperties.PropertyProcs;
PropertyProcsRec: TYPE = CDProperties.PropertyProcsRec;
atomTab: RefTab.Ref = RefTab.Create[]; -- contains atoms [maybe in future ref's] where properties hang
--Registration
propertyNameTab: RefTab.Ref = RefTab.Create[]; -- key: propertynames; value: PropertyProcs
registrationTab: RefTab.Ref = RefTab.Create[]; -- contains registrationKeys
RegisterProperty:
PUBLIC
ENTRY PROC [prop:
REF, registrationKey:
REF←
NIL]
RETURNS [first:
BOOLEAN←TRUE] =
--registers "prop" in a table; any program which wants to use an ATOM
--as a "prop" gets to know if it is already in use.
BEGIN
val: RefTab.Val;
found: BOOL;
[found, val] ← RefTab.Fetch[x: registrationTab, key: prop]; -- returns a registration key
IF found
THEN {
IF registrationKey#NIL AND registrationKey=val THEN RETURN [FALSE];
RETURN WITH ERROR CD.Error[doubleRegistration]
}
ELSE {
pp: PropertyProcs ← NEW[PropertyProcsRec];
pp.key ← prop;
[] ← RefTab.Insert[propertyNameTab, prop, pp]; -- procs
[] ← RefTab.Insert[registrationTab, prop, registrationKey]; -- registration
};
END;
--Usage
HasNoCDProperties: ERROR = CODE;
PutProp:
PUBLIC
PROC [onto:
REF, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
WITH onto
SELECT
FROM
a: CD.Instance => PutPropOnInstance[a, prop, val];
o: CD.Object => PutPropOnObject[o, prop, val];
pr: CD.PropRef => PutPropOnPropRef[pr, prop, val];
d: CD.Design => PutPropOnDesign[d, prop, val];
t: CD.Technology => PutPropOnTechnology[t, prop, val];
at: ATOM => PutPropOnAtom[at, prop, val];
class: REF CD.ObjectClass => PutPropOnClass[class, prop, val];
pp: PropertyProcs => PutPropOnPropertyProcs[pp, prop, val];
ENDCASE => ERROR HasNoCDProperties
END;
GetProp:
PUBLIC
PROC [from:
REF, prop:
REF]
RETURNS [
REF] =
--NIL if prop is not found
BEGIN
RETURN [
WITH from
SELECT
FROM
a: CD.Instance => GetPropFromList[a.properties, prop],
o: CD.Object => GetPropFromList[o.properties, prop],
pr: CD.PropRef => GetPropFromList[pr^, prop],
pl: CD.PropList => GetPropFromList[pl, prop],
at: ATOM => GetPropFromAtom[at, prop],
d: CD.Design => GetPropFromList[d.properties^, prop],
t: CD.Technology => GetPropFromList[t.properties^, prop],
class: REF CD.ObjectClass => GetPropFromList[class.properties^, prop],
pp: PropertyProcs => GetPropFromList[pp.properties, prop],
ENDCASE => ERROR HasNoCDProperties]
END;
GetPropFromList:
PUBLIC ENTRY
PROC [propList: PropList, prop:
REF]
RETURNS [
REF] = {
ENABLE UNWIND => NULL;
RETURN [Properties.GetProp[propList, prop]]
};
--speed ups
PutPropOnPropRef:
PUBLIC
ENTRY
PROC [onto:
CD.PropRef, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
ENABLE UNWIND => NULL;
IF onto=NIL THEN RETURN WITH ERROR CD.Error[other, "nil property field"];
onto^ ← Properties.PutProp[onto^, prop, val]
END;
PutPropOnObject:
PUBLIC
ENTRY
PROC [onto:
CD.Object, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
ENABLE UNWIND => NULL;
IF onto=NIL THEN RETURN WITH ERROR CD.Error[other, "Nil Object"];
onto.properties ← Properties.PutProp[onto.properties, prop, val]
END;
PutPropOnInstance:
PUBLIC
ENTRY
PROC[onto:
CD.Instance, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
ENABLE UNWIND => NULL;
IF onto=NIL THEN RETURN WITH ERROR CD.Error[other, "nil Instance"];
onto.properties ← Properties.PutProp[onto.properties, prop, val]
END;
PutPropOnDesign:
PUBLIC
ENTRY
PROC [onto:
CD.Design, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
ENABLE UNWIND => NULL;
IF onto=
NIL
OR onto.properties=
NIL THEN
RETURN WITH ERROR CD.Error[other, "nil property field"];
onto.properties^ ← Properties.PutProp[onto.properties^, prop, val]
END;
PutPropOnTechnology:
PUBLIC
ENTRY
PROC[onto:
CD.Technology, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
ENABLE UNWIND => NULL;
IF onto=
NIL
OR onto.properties=
NIL THEN
RETURN WITH ERROR CD.Error[other, "nil property field"];
onto.properties^ ← Properties.PutProp[onto.properties^, prop, val]
END;
PutPropOnClass:
PUBLIC
ENTRY
PROC[onto:
REF
CD.ObjectClass, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
ENABLE UNWIND => NULL;
IF onto=
NIL
OR onto.properties=
NIL
THEN
RETURN WITH ERROR CD.Error[other, "nil property field"];
onto.properties^ ← Properties.PutProp[onto.properties^, prop, val]
END;
PutPropOnAtom:
PUBLIC
PROC[onto:
ATOM, prop:
REF, val:
REF] = {
--a NIL val removes the property
PutPropOnRef[onto: onto, prop: prop, val: val]
};
PutPropOnLayer:
PUBLIC
ENTRY
PROC[onto:
CD.Layer, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
ENABLE UNWIND => NULL;
CDPrivate.layers[onto].properties^ ← Properties.PutProp[CDPrivate.layers[onto].properties^, prop, val]
END;
PutPropOnPropertyProcs:
PUBLIC
ENTRY
PROC[onto: PropertyProcs, prop:
REF, val:
REF] =
--a NIL val removes the property
BEGIN
ENABLE UNWIND => NULL;
IF onto=
NIL
OR onto.properties=
NIL
THEN
RETURN WITH ERROR CD.Error[other, "nil PropertyProcs"];
onto.properties ← Properties.PutProp[onto.properties, prop, val]
END;
PutPropOnRef:
ENTRY
PROC[onto:
REF, prop:
REF, val:
REF] =
--a NIL val removes the property
--here onto MUST NOT be a ChipNDale ref pointing to a record with properties,
--since then the properties must be used, not the hash table
BEGIN
x: REF;
found: BOOL;
pp: REF CD.PropList;
[found, x] ← RefTab.Fetch[x: atomTab, key: onto];
IF found THEN pp ← NARROW[x, REF CD.PropList]
ELSE {
IF prop=NIL THEN RETURN;
pp ← NEW[CD.PropList←NIL];
[] ← RefTab.Store[x: atomTab, key: onto, val: pp];
};
pp^ ← Properties.PutProp[propList: pp^, prop: prop, val: val];
IF pp^=NIL THEN [] ← RefTab.Delete[x: atomTab, key: onto];
END;
GetPropFromRef:
ENTRY PROC [from:
REF, prop:
REF]
RETURNS [
REF] =
--NIL if prop is not found
--here from MUST NOT be a ChipNDale ref pointing to a record with properties,
--since then the properties must be used, not the hash table
INLINE BEGIN
x: REF;
found: BOOL;
pp: REF CD.PropList;
[found, x] ← RefTab.Fetch[x: atomTab, key: from];
IF NOT found THEN RETURN[NIL];
pp ← NARROW[x, REF CD.PropList];
RETURN[Properties.GetProp[propList: pp^, prop: prop]]
END;
GetPropFromObject:
PUBLIC
PROC [from:
CD.Object, prop:
REF]
RETURNS [
REF] =
--NIL if prop is not found
BEGIN
ENABLE UNWIND => NULL;
RETURN[Properties.GetProp[from.properties, prop]]
END;
GetPropFromInstance:
PUBLIC
PROC [from:
CD.Instance, prop:
REF]
RETURNS [
REF] =
--NIL if prop is not found
BEGIN
ENABLE UNWIND => NULL;
RETURN[Properties.GetProp[from.properties, prop]]
END;
GetPropFromDesign:
PUBLIC
PROC [from:
CD.Design, prop:
REF]
RETURNS [
REF] =
--NIL if prop is not found
BEGIN
ENABLE UNWIND => NULL;
RETURN[Properties.GetProp[from.properties^, prop]]
END;
GetPropFromTechnology:
PUBLIC
PROC [from:
CD.Technology, prop:
REF]
RETURNS [
REF] =
--NIL if prop is not found
BEGIN
ENABLE UNWIND => NULL;
RETURN[Properties.GetProp[from.properties^, prop]]
END;
GetPropFromLayer:
PUBLIC
PROC [from:
CD.Layer, prop:
REF]
RETURNS [
REF] =
--NIL if prop is not found
BEGIN
ENABLE UNWIND => NULL;
RETURN[Properties.GetProp[CDPrivate.layers[from].properties^, prop]]
END;
GetPropFromAtom:
PUBLIC
PROC [from:
ATOM, prop:
REF]
RETURNS [
REF] =
--NIL if prop is not found
BEGIN
RETURN[GetPropFromRef[from: from, prop: prop]];
END;
--property procedures
InstallProcs:
PUBLIC
ENTRY
PROC [prop:
REF, new: PropertyProcsRec] =
--prop must be registered and yours
--overwrites values for which new has non NIL entries
BEGIN
ENABLE UNWIND => NULL;
class: PropertyProcs ← FetchProcs[prop];
IF class#
NIL
THEN {
IF new.exclusive THEN class.exclusive←TRUE;
IF new.makeCopy#NIL THEN class.makeCopy ← new.makeCopy;
IF new.internalWrite#NIL THEN class.internalWrite ← new.internalWrite;
IF new.internalRead#NIL THEN class.internalRead ← new.internalRead;
IF new.properties
#NIL THEN
FOR l: PropList ← new.properties, l.rest
WHILE l#
NIL
DO
class.properties ← Properties.PutProp[class.properties, l.first.key, l.first.val];
ENDLOOP;
}
END;
FetchProcs:
PUBLIC
PROC [prop:
REF]
RETURNS [PropertyProcs] =
--never copy PropertyProcs^; it can be extended by future calls of InstallProcs
BEGIN
x: REF;
found: BOOL;
[found: found, val: x] ← RefTab.Fetch[propertyNameTab, prop];
IF found THEN RETURN [NARROW[x, PropertyProcs]] ELSE RETURN [NIL]
END;
CopyVal:
PUBLIC
PROC [prop:
REF, val:
REF, purpose:
REF]
RETURNS [valCopy:
REF] =
BEGIN
valCopy ← val;
END;
DontCopy:
PUBLIC
PROC [prop:
REF, val:
REF, purpose:
REF]
RETURNS [nil:
REF←
NIL] =
BEGIN
END;
PutOn:
PROC [putOnto:
REF, propList: PropList] =
--dangerous procedure; might crash
BEGIN
WITH putOnto
SELECT
FROM
a: CD.Instance => a.properties ← propList;
o: CD.Object => o.properties ← propList;
pr: CD.PropRef => pr^ ← propList;
d: CD.Design => d.properties^ ← propList;
t: CD.Technology => t.properties^ ← propList;
class: REF CD.ObjectClass => class.properties^ ← propList;
pp: PropertyProcs => pp.properties ← propList;
at: ATOM => ERROR;
ENDCASE => ERROR HasNoCDProperties
END;
CopyProps:
PUBLIC
ENTRY
PROC [propList: PropList, putOnto:
REF, purpose:
REF←
NIL] =
--Copies properties individually using their MakeCopyProc's and defaults for some types
--The resulting propList is put on putOnto
BEGIN
ENABLE UNWIND => NULL;
PutOn[putOnto, InternalDangerousCopyProps[propList, purpose] !
RuntimeError.UNCAUGHT => GOTO crashed];
EXITS crashed => RETURN WITH ERROR HasNoCDProperties
END;
AppendProps:
PUBLIC
ENTRY
PROC [winner, looser: PropList←
NIL, putOnto:
REF, purpose:
REF←
NIL] =
BEGIN
ENABLE UNWIND => NULL;
PutOn[putOnto, InternalDangerousAppendProps[winner, looser, purpose] !
RuntimeError.UNCAUGHT => GOTO crashed]
EXITS crashed => RETURN WITH ERROR HasNoCDProperties
DangerousCopyProps:
PUBLIC
ENTRY
PROC [propList: PropList, purpose:
REF]
RETURNS [copy: PropList←
NIL] =
BEGIN
ENABLE UNWIND => NULL;
copy ← InternalDangerousCopyProps[propList, purpose]
END;
DangerousAppendProps:
PUBLIC
ENTRY PROC [winner, looser: CDProperties.PropList
, purpose:
REF]
RETURNS [copy: CDProperties.PropList] =
BEGIN
ENABLE UNWIND => NULL;
copy ← InternalDangerousAppendProps[winner, looser, purpose]
END;
InternalDangerousCopyProps:
PROC [propList: PropList, purpose:
REF]
RETURNS [copy: PropList←
NIL] =
BEGIN
FOR l: PropList ← propList, l.rest
WHILE l#
NIL
DO
copy ← InternalCopyItem[copy, l.first, purpose]
ENDLOOP;
END;
InternalDangerousAppendProps:
PROC [winner, looser: CDProperties.PropList
, purpose:
REF]
RETURNS [copy: CDProperties.PropList] =
BEGIN
copy ← InternalDangerousCopyProps[looser, purpose];
FOR l: PropList ← winner, l.rest
WHILE l#
NIL
DO
copy ← InternalCopyItem[copy, l.first, purpose]
ENDLOOP;
END;
InternalCopyItem:
PROC[list: CDProperties.PropList, item: Properties.KeyVal, purpose:
REF]
RETURNS [newList: CDProperties.PropList] =
BEGIN
class: CDProperties.PropertyProcs = FetchProcs[item.key];
IF class#
NIL
AND class.makeCopy#
NIL
THEN {
newVal: REF = class.makeCopy[prop: item.key, val: item.val, purpose: purpose];
IF newVal=NIL THEN newList ← list
ELSE newList ← Properties.PutProp[list, item.key, newVal];
}
ELSE
IF
ISTYPE[item.key,
ATOM]
AND item.val#
NIL
THEN
WITH item.val
SELECT
FROM
r: Rope.ROPE => newList ← Properties.PutProp[list, item.key, r];
at: ATOM => newList ← Properties.PutProp[list, item.key, at];
ri: REF INT => newList ← Properties.PutProp[list, item.key, NEW[INT←ri^]];
pl: CD.PropList => newList ← Properties.PutProp[list, item.key, InternalDangerousCopyProps[pl, purpose]];
rl: LIST OF Rope.ROPE => newList ← Properties.PutProp[list, item.key, RopeList.CopyTopList[rl]];
ENDCASE => newList ← list
ELSE newList ← list;
END;
DoWithinLock:
PUBLIC ENTRY
PROC [p:
PROC] =
BEGIN
ENABLE
{
UNWIND => NULL;
RuntimeError.
UNCAUGHT =>
IF UserProfile.Boolean["ChipNDale.CatchLowLevelErrors", TRUE] THEN CONTINUE;
};
IF p#NIL THEN p[];
END;
RopePWrite:
PUBLIC PROC [prop:
REF, val:
REF] =
BEGIN
WITH val
SELECT
FROM
r: Rope.ROPE => TokenIO.WriteRope[r];
at: ATOM => TokenIO.WriteRope[Atom.GetPName[at]];
ENDCASE => TokenIO.WriteRope["bad property value"];
END;
AtomPWrite:
PUBLIC PROC [prop:
REF, val:
REF] =
BEGIN
WITH val
SELECT
FROM
at: ATOM => TokenIO.WriteAtom[at];
r: Rope.ROPE => TokenIO.WriteAtom[Atom.MakeAtom[r]];
ENDCASE => TokenIO.WriteAtom[$Bad];
END;
IntPWrite:
PUBLIC
PROC [prop:
REF, val:
REF] =
BEGIN
WITH val
SELECT
FROM
ri: REF INT => TokenIO.WriteInt[ri^];
rc: REF CARDINAL => TokenIO.WriteInt[rc^];
rn: REF NAT => TokenIO.WriteInt[rn^];
ENDCASE => TokenIO.WriteInt[0];
END;
SomePWrite:
PUBLIC
PROC [prop:
REF, val:
REF] =
BEGIN
WITH val
SELECT
FROM
at: ATOM => TokenIO.WriteAtom[at];
r: Rope.ROPE => TokenIO.WriteRope[r];
ri: REF INT => TokenIO.WriteInt[ri^];
rc: REF CARDINAL => TokenIO.WriteInt[rc^];
rn: REF NAT => TokenIO.WriteInt[rn^];
ENDCASE => TokenIO.WriteAtom[$Unknown];
END;
RopePRead:
PUBLIC PROC [prop:
ATOM]
RETURNS [val:
REF] =
BEGIN
val ← TokenIO.ReadRope[]
END;
AtomPRead:
PUBLIC PROC [prop:
ATOM]
RETURNS [val:
REF] =
BEGIN
val ← TokenIO.ReadAtom[]
END;
IntPRead:
PUBLIC
PROC [prop:
ATOM]
RETURNS [val:
REF] =
BEGIN
val ← NEW[INT←TokenIO.ReadInt[]]
END;
SomePRead:
PUBLIC
PROC [prop:
ATOM]
RETURNS [val:
REF] =
BEGIN
t: TokenIO.Token ← TokenIO.ReadToken[];
SELECT t.kind
FROM
atom, int, rope => val ← t.ref;
ENDCASE => val ← $Error;
END;
--------------------------
--now some special properties
TiogaPCopy:
PROC [prop:
REF, val:
REF, purpose:
REF]
RETURNS [copy:
REF] =
BEGIN
contents: Rope.ROPE ← NIL;
formatting: Rope.ROPE ← NIL;
WITH val
SELECT
FROM
t: ViewerTools.TiogaContents => {
contents ← t.contents;
formatting ← t.formatting};
r: Rope.ROPE => contents ← r;
ENDCASE => contents ← "$Error";
copy ← NEW[ViewerTools.TiogaContentsRec←[contents: contents, formatting: formatting]]
END;
TiogaPWrite:
PROC [prop:
REF, val:
REF] =
BEGIN
contents: Rope.ROPE ← NIL;
formatting: Rope.ROPE ← NIL;
WITH val
SELECT
FROM
t: ViewerTools.TiogaContents => {
contents ← t.contents;
formatting ← t.formatting};
r: Rope.ROPE => contents ← r;
ENDCASE => NULL;
TokenIO.WriteRope[contents];
TokenIO.WriteRope[formatting];
END;
TiogaPRead:
PROC [prop:
ATOM]
RETURNS [val:
REF] =
BEGIN
contents: Rope.ROPE ← TokenIO.ReadRope[];
formatting: Rope.ROPE ← TokenIO.ReadRope[];
val ← NEW[ViewerTools.TiogaContentsRec←[contents: contents, formatting: formatting]]
END;
Atomize:
PROC [r: Rope.
ROPE]
RETURNS [
ATOM←
NIL] = {
IF Rope.Length[r]>1 AND Rope.Fetch[r]='$ THEN r ← Rope.Substr[r, 1, Rope.Length[r]-1];
IF ~Rope.IsEmpty[r] THEN RETURN [Atom.MakeAtom[r]]
};
IsExclusive:
PROC [a:
ATOM]
RETURNS [
BOOL←
TRUE] =
BEGIN
IF a#
NIL
THEN {
pType: CDProperties.PropertyProcs = CDProperties.FetchProcs[a];
RETURN [pType#NIL AND pType.exclusive]
}
END;
RemovePropFromRegistrations:
PROC [atom:
ATOM] =
--removes from this atom all properties hanging on $RegistrationRoot
--removes this atom's property from all atoms hanging on $RegistrationRoot
BEGIN
RemProps:
PROC [atom:
ATOM, lora:
LIST
OF
REF
ANY] = {
FOR l:
LIST
OF
REF
ANY ← lora, l.rest
WHILE l#
NIL
DO
WITH l.first
SELECT
FROM
a:
ATOM => {
IF ~IsExclusive[a] THEN PutPropOnAtom[onto: atom, prop: a, val: NIL];
PutPropOnAtom[onto: a, prop: atom, val: NIL];
}
ENDCASE => NULL;
ENDLOOP;
};
IF atom=$RegistrationRoot THEN ERROR; --don't do this
WITH GetProp[$RegistrationRoot, atom]
SELECT
FROM
loa: LIST OF ATOM => TRUSTED {RemProps[atom, LOOPHOLE[loa]]};
lora: LIST OF REF ANY => RemProps[atom, lora];
a: ATOM => RemProps[atom, LIST[a]]
ENDCASE => NULL;
END;
RemovePropFromLayers:
PROC [atom:
ATOM] =
--removes atom-property from all layers, all layer's registrationkeys,
--and the layers registrationkeys-properties from atom
BEGIN
FOR l:
CD.Layer
IN
CD.Layer
DO
reg: ATOM ← CD.LayerKey[l];
IF reg#
NIL
THEN {
PutPropOnAtom[onto: atom, prop: reg, val: NIL];
PutPropOnAtom[onto: reg, prop: atom, val: NIL];
};
PutPropOnLayer[onto: l, prop: atom, val: NIL];
ENDLOOP;
END;
RemoveProperties:
PUBLIC
PROC[key:
ATOM] =
--not entry!
BEGIN
IF ~IsExclusive[key]
THEN {
PutPropOnAtom[onto: key, prop: key, val: NIL];
RemovePropFromRegistrations[key];
RemovePropFromLayers[key];
};
END;
RemovePropCommand: Commander.CommandProc =
--Allows to do un-registration from commandfiles which may run
--before the tool they are un-registrating
--This command is handy for lots of tools which set op their parameters with atom command file
BEGIN
FOR rl:
LIST
OF Rope.
ROPE ← CommandTool.ParseToList[cmd].list, rl.rest
WHILE rl#
NIL
DO
atom: ATOM ← Atomize[rl.first]; --this atoms registrations should be removed
IF IsExclusive[atom]
THEN
msg ← Rope.Cat[msg, " ", rl.first, " not removed (no or exclusive atom)\n"]
ELSE RemoveProperties[atom];
ENDLOOP;
END;
Associate:
PUBLIC PROC [key, a:
ATOM] =
--not entry!
TRUSTED BEGIN
IF ~IsExclusive[a]
AND ~IsExclusive[key]
THEN {
list:
LIST
OF
REF
ANY ←
WITH GetPropFromAtom[$RegistrationRoot, key]
SELECT
FROM
lora: LIST OF REF ANY => lora,
loa: LIST OF ATOM => LOOPHOLE[loa],
a: ATOM => LIST[a],
ENDCASE => NIL;
IF ~List.Memb[a, list]
THEN {
n: LIST OF REF ANY ← List.Nconc1[list, a];
IF n#list THEN PutPropOnAtom[onto: $RegistrationRoot, prop: key, val: n];
};
};
END;
AssociatePropCommand: Commander.CommandProc =
BEGIN
key: ATOM ← NIL;
rl: LIST OF Rope.ROPE ← CommandTool.ParseToList[cmd].list;
IF rl=
NIL
OR IsExclusive[key𡤊tomize[rl.first]]
THEN {
msg ← "no or exclusive key\n";
result ← $Failure;
RETURN
};
IF rl.rest=
NIL
THEN {
msg ← "no properties to associate with key\n";
result ← $Failure;
RETURN
};
FOR l:
LIST
OF Rope.
ROPE ← rl.rest, l.rest
WHILE l#
NIL
DO
a: ATOM ← Atomize[l.first];
IF IsExclusive[a] THEN msg ← Rope.Cat[msg, l.first, " not allowed\n"]
ELSE Associate[key, a];
ENDLOOP
END;
--module initialization
[] ← RegisterProperty[$RegistrationRoot];
InstallProcs[$RegistrationRoot, CDProperties.PropertyProcsRec[exclusive: TRUE]];
Commander.Register[
key: "///ChipNDale/CDRemoveRegistration", --command used by ChipNDale command files only
proc: RemovePropCommand,
doc: "removes properties from all ChipNDale layers"
];
Commander.Register[
key: "///ChipNDale/CDAssociateRegistration", --command used by ChipNDale command files only
proc: AssociatePropCommand,
doc: "associate ChipNDale properties for removal"
];
--does not really belong into this module
[] ← CDProperties.RegisterProperty[$SignalName];
[] ← CDProperties.RegisterProperty[$InstanceName];
[] ← CDProperties.RegisterProperty[$Tioga];
CDProperties.InstallProcs[prop: $SignalName, new:
CDProperties.PropertyProcsRec[
makeCopy: CDProperties.CopyVal,
internalWrite: CDProperties.RopePWrite,
internalRead: CDProperties.RopePRead
]];
CDProperties.InstallProcs[prop: $InstanceName, new:
CDProperties.PropertyProcsRec[
makeCopy: CDProperties.CopyVal,
internalWrite: CDProperties.RopePWrite,
internalRead: CDProperties.RopePRead
]];
CDProperties.InstallProcs[prop: $Tioga, new:
CDProperties.PropertyProcsRec[
makeCopy: TiogaPCopy,
internalWrite: TiogaPWrite,
internalRead: TiogaPRead
]];
END.