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
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: REFNIL] 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: REFNIL] =
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: REFNIL] =
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: REFNIL] =
BEGIN ENABLE UNWIND => NULL;
PutOn[putOnto, InternalDangerousAppendProps[winner, looser, purpose] !
RuntimeError.UNCAUGHT => GOTO crashed]
EXITS crashed => RETURN WITH ERROR Err
END;
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.ROPENIL;
formatting: Rope.ROPENIL;
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.ROPENIL;
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 [ATOMNIL] = {
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 [BOOLTRUE] =
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, 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: ATOMCD.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;
Associate: PUBLIC PROC [key, a: ATOM] =
--not entry!
TRUSTED BEGIN
IF ~IsExclusive[a] AND ~IsExclusive[key] THEN {
list: LIST OF REF ANYWITH GetAtomProp[$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 PutAtomProp[onto: $RegistrationRoot, prop: key, val: n];
};
};
END;
AssociatePropCommand: Commander.CommandProc =
BEGIN
key: ATOMNIL;
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.