CDPropertiesImpl.mesa a ChipNDale module
Copyright © 1983, 1986 by Xerox Corporation. All rights reserved.
by Ch. Jacobi, September 27, 1983 2:06 pm
last edited Christian Jacobi, March 25, 1986 2:32:23 pm PST
Last Edited by: Jacobi June 12, 1986 1:51:54 pm PDT
DIRECTORY
CDProperties,
CDPropertyTools,
CD,
CDPrivate,
Atom,
Commander,
CommandTool,
HashTable,
List,
PropertyLists,
Rope,
RopeList,
RuntimeError USING [UNCAUGHT],
TokenIO,
UserProfile USING [Boolean],
ViewerTools USING [TiogaContents, TiogaContentsRec];
CDPropertiesImpl:
CEDAR
MONITOR
IMPORTS CD, CDPrivate, CDProperties, Atom, Commander, CommandTool, HashTable, List, PropertyLists, Rope, RopeList, RuntimeError, TokenIO, UserProfile
EXPORTS CDProperties, CDPropertyTools =
BEGIN
PropList: TYPE = CD.PropList;
PropertyProcs: TYPE = CDProperties.PropertyProcs;
PropertyProcsRec: TYPE = CDProperties.PropertyProcsRec;
atomTab: HashTable.Table = HashTable.Create[33];
-- contains atoms [maybe in future ref's] where properties hang
--Registration
propertyNameTab: HashTable.Table = HashTable.Create[33]; -- key: propertynames; value: PropertyProcs
registrationTab: HashTable.Table = HashTable.Create[33]; -- contains registrationKeys
RegisterProperty:
PUBLIC
ENTRY PROC [prop:
REF, registrationKey:
REF←
NIL]
RETURNS [first:
BOOL←TRUE] =
BEGIN
val: HashTable.Value;
found: BOOL;
[found, val] ← HashTable.Fetch[registrationTab, 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;
[] ← HashTable.Insert[propertyNameTab, prop, pp]; -- procs
[] ← HashTable.Insert[registrationTab, prop, registrationKey]; -- registration
};
END;
--Usage
Err: ERROR = CODE;
PutProp:
PUBLIC
PROC [onto:
REF, prop:
REF, val:
REF] =
BEGIN
WITH onto
SELECT
FROM
a: CD.Instance => PutInstanceProp[a, prop, val];
o: CD.Object => PutObjectProp[o, prop, val];
pr: CD.PropRef => PutPRefProp[pr, prop, val];
d: CD.Design => PutDesignProp[d, prop, val];
t: CD.Technology => PutTechnologyProp[t, prop, val];
at: ATOM => PutAtomProp[at, prop, val];
class: CD.ObjectClass => PutObjectClassProp[class, prop, val];
pp: PropertyProcs => PutPropertyClassProp[pp, prop, val];
pl: PropertyLists.PropList => RETURN WITH ERROR Err; --explicitely forbidden
ENDCASE => RETURN WITH ERROR Err
END;
GetProp:
PUBLIC
ENTRY PROC [from:
REF, prop:
REF]
RETURNS [
REF] =
BEGIN
ENABLE UNWIND => NULL;
WITH from
SELECT
FROM
a: CD.Instance => RETURN[PropertyLists.GetProp[a.properties, prop]];
o: CD.Object => RETURN[PropertyLists.GetProp[o.properties, prop]];
pr: CD.PropRef => RETURN[PropertyLists.GetProp[pr^, prop]];
pl: CD.PropList => RETURN[PropertyLists.GetProp[pl, prop]];
at: ATOM => RETURN[GetRefAnyPropf[at, prop]];
d: CD.Design => RETURN[PropertyLists.GetProp[d.properties^, prop]];
t: CD.Technology => RETURN[PropertyLists.GetProp[t.properties^, prop]];
class: CD.ObjectClass => RETURN[PropertyLists.GetProp[class.properties^, prop]];
pp: PropertyProcs => RETURN[PropertyLists.GetProp[pp.properties, prop]];
ENDCASE => RETURN WITH ERROR Err;
END;
GetListProp:
PUBLIC ENTRY
PROC [propList: PropList, prop:
REF]
RETURNS [
REF] = {
ENABLE UNWIND => NULL;
RETURN [PropertyLists.GetProp[propList, prop]]
};
--speed ups
PutPRefProp:
PUBLIC
ENTRY
PROC [onto:
CD.PropRef, prop:
REF, val:
REF] =
BEGIN
ENABLE UNWIND => NULL;
IF onto=NIL THEN RETURN WITH ERROR CD.Error[other, "nil property field"];
onto^ ← PropertyLists.PutProp[onto^, prop, val]
END;
PutObjectProp:
PUBLIC
ENTRY
PROC [onto:
CD.Object, prop:
REF, val:
REF] =
BEGIN
ENABLE UNWIND => NULL;
IF onto=NIL THEN RETURN WITH ERROR CD.Error[other, "NIL Object"];
onto.properties ← PropertyLists.PutProp[onto.properties, prop, val]
END;
PutInstanceProp:
PUBLIC
ENTRY
PROC[onto:
CD.Instance, prop:
REF, val:
REF] =
BEGIN
ENABLE UNWIND => NULL;
IF onto=NIL THEN RETURN WITH ERROR CD.Error[other, "NIL Instance"];
onto.properties ← PropertyLists.PutProp[onto.properties, prop, val]
END;
PutDesignProp:
PUBLIC
ENTRY
PROC [onto:
CD.Design, prop:
REF, val:
REF] =
BEGIN ENABLE UNWIND => NULL;
IF onto=
NIL
OR onto.properties=
NIL THEN
RETURN WITH ERROR CD.Error[other, "NIL property field"];
onto.properties^ ← PropertyLists.PutProp[onto.properties^, prop, val]
END;
PutTechnologyProp:
PUBLIC
ENTRY
PROC[onto:
CD.Technology, prop:
REF, val:
REF] =
BEGIN ENABLE UNWIND => NULL;
IF onto=
NIL
OR onto.properties=
NIL THEN
RETURN WITH ERROR CD.Error[other, "nil property field"];
onto.properties^ ← PropertyLists.PutProp[onto.properties^, prop, val]
END;
PutObjectClassProp:
ENTRY
PROC[onto:
CD.ObjectClass, prop:
REF, val:
REF] =
BEGIN ENABLE UNWIND => NULL;
IF onto=
NIL
OR onto.properties=
NIL
THEN
RETURN WITH ERROR CD.Error[other, "nil property field"];
onto.properties^ ← PropertyLists.PutProp[onto.properties^, prop, val]
END;
PutAtomProp:
PUBLIC
PROC[onto:
ATOM, prop:
REF, val:
REF] = {
PutPropOnRef[onto: onto, prop: prop, val: val]
};
PutLayerProp:
PUBLIC
ENTRY
PROC[onto:
CD.Layer, prop:
REF, val:
REF] =
BEGIN ENABLE UNWIND => NULL;
CDPrivate.layers[onto].properties^ ← PropertyLists.PutProp[CDPrivate.layers[onto].properties^, prop, val]
END;
PutPropertyClassProp:
ENTRY
PROC[onto: PropertyProcs, prop:
REF, val:
REF] =
BEGIN
ENABLE UNWIND => NULL;
IF onto=
NIL
OR onto.properties=
NIL
THEN
RETURN WITH ERROR CD.Error[other, "nil PropertyProcs"];
onto.properties ← PropertyLists.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] ← HashTable.Fetch[atomTab, onto];
IF found THEN pp ← NARROW[x, REF CD.PropList]
ELSE {
IF prop=NIL THEN RETURN;
pp ← NEW[CD.PropList←NIL];
[] ← HashTable.Store[atomTab, onto, pp];
};
pp^ ← PropertyLists.PutProp[pp^, prop, val];
IF pp^=NIL THEN [] ← HashTable.Delete[atomTab, onto];
END;
GetRefAnyPropf:
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] ← HashTable.Fetch[atomTab, from];
IF NOT found THEN RETURN[NIL];
pp ← NARROW[x, REF CD.PropList];
RETURN [PropertyLists.GetProp[pp^, prop]]
END;
GetObjectProp:
PUBLIC
PROC [from:
CD.Object, prop:
REF]
RETURNS [
REF] =
BEGIN ENABLE UNWIND => NULL;
RETURN[PropertyLists.GetProp[from.properties, prop]]
END;
GetInstanceProp:
PUBLIC
PROC [from:
CD.Instance, prop:
REF]
RETURNS [
REF] =
BEGIN ENABLE UNWIND => NULL;
RETURN[PropertyLists.GetProp[from.properties, prop]]
END;
GetDesignProp:
PUBLIC
PROC [from:
CD.Design, prop:
REF]
RETURNS [
REF] =
BEGIN ENABLE UNWIND => NULL;
RETURN[PropertyLists.GetProp[from.properties^, prop]]
END;
GetTechnologyProp:
PUBLIC
PROC [from:
CD.Technology, prop:
REF]
RETURNS [
REF] =
BEGIN ENABLE UNWIND => NULL;
RETURN[PropertyLists.GetProp[from.properties^, prop]]
END;
GetLayerProp:
PUBLIC
PROC [from:
CD.Layer, prop:
REF]
RETURNS [
REF] =
BEGIN ENABLE UNWIND => NULL;
RETURN[PropertyLists.GetProp[CDPrivate.layers[from].properties^, prop]]
END;
GetAtomProp:
PUBLIC
ENTRY PROC [from:
ATOM, prop:
REF]
RETURNS [
REF] =
BEGIN ENABLE UNWIND => NULL;
RETURN[GetRefAnyPropf[from: from, prop: prop]];
END;
--property procedures
RegisterAndInstall:
PUBLIC PROC [prop:
REF, new: PropertyProcsRec, registrationKey:
REF]
RETURNS [first:
BOOL] =
BEGIN
first ← RegisterProperty[prop, registrationKey];
InstallProcs[prop, new];
END;
InstallProcs:
PUBLIC
ENTRY
PROC [prop:
REF, new: PropertyProcsRec] =
BEGIN
ENABLE UNWIND => NULL;
pp: PropertyProcs;
IF (pp ← FetchProcs[prop])#
NIL
THEN {
IF new.exclusive THEN pp.exclusive←TRUE;
IF new.autoRem THEN pp.autoRem←TRUE;
IF new.reserved THEN pp.reserved←TRUE;
IF new.makeCopy#NIL THEN pp.makeCopy ← new.makeCopy;
IF new.internalWrite#NIL THEN pp.internalWrite ← new.internalWrite;
IF new.internalRead#NIL THEN pp.internalRead ← new.internalRead;
IF new.properties#
NIL
THEN
FOR l: PropList ← new.properties, l.rest
WHILE l#
NIL
DO
pp.properties ← PropertyLists.PutProp[pp.properties, l.first.key, l.first.val];
ENDLOOP;
}
END;
FetchProcs:
PUBLIC
PROC [prop:
REF]
RETURNS [pp: PropertyProcs] =
BEGIN
pp ← NARROW[HashTable.Fetch[propertyNameTab, prop].value];
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 Err
END;
CopyProps:
PUBLIC
ENTRY
PROC [propList: PropList, putOnto:
REF, purpose:
REF←
NIL] =
BEGIN ENABLE UNWIND => NULL;
PutOn[putOnto, InternalDangerousCopyProps[propList, purpose] !
RuntimeError.UNCAUGHT => GOTO crashed];
EXITS crashed => RETURN WITH ERROR Err
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 Err
DCopyProps:
PUBLIC
ENTRY
PROC [propList: PropList, purpose:
REF]
RETURNS [copy: PropList←
NIL] =
BEGIN ENABLE UNWIND => NULL;
copy ← InternalDangerousCopyProps[propList, purpose]
END;
DAppendProps:
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: PropertyLists.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 ← PropertyLists.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 ← PropertyLists.PutProp[list, item.key, r];
at: ATOM => newList ← PropertyLists.PutProp[list, item.key, at];
ri: REF INT => newList ← PropertyLists.PutProp[list, item.key, NEW[INT←ri^]];
pl: CD.PropList => newList ← PropertyLists.PutProp[list, item.key, InternalDangerousCopyProps[pl, purpose]];
rl: LIST OF Rope.ROPE => newList ← PropertyLists.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, 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 PutAtomProp[onto: atom, prop: a, val: NIL];
PutAtomProp[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, ToLORA[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 {
PutAtomProp[onto: atom, prop: reg, val: NIL];
PutAtomProp[onto: reg, prop: atom, val: NIL];
};
PutLayerProp[onto: l, prop: atom, val: NIL];
ENDLOOP;
END;
RemoveProperties:
PUBLIC
PROC[key:
ATOM] =
--not entry!
BEGIN
IF ~IsExclusive[key]
THEN {
PutAtomProp[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;
ToLORA:
PROC [loa:
LIST
OF
ATOM]
RETURNS [lora:
LIST
OF
REF
ANY←
NIL] = {
FOR l:
LIST
OF
ATOM ← loa, l.rest
WHILE l#
NIL
DO
lora ← CONS[l.first, lora];
ENDLOOP
};
Associate:
PUBLIC PROC [key, a:
ATOM] =
--not entry!
TRUSTED BEGIN
IF ~IsExclusive[a]
AND ~IsExclusive[key]
THEN {
list:
LIST
OF
REF
ANY ←
WITH GetAtomProp[$RegistrationRoot, key]
SELECT
FROM
lora: LIST OF REF ANY => lora,
loa: LIST OF ATOM => ToLORA[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 PutAtomProp[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", --used by ChipNDale command files only
proc: RemovePropCommand,
doc: "removes properties from all ChipNDale layers"
];
Commander.Register[
key: "///ChipNDale/CDAssociateRegistration", --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.