CDReferencesImpl.mesa (part of Chipndale)
by Christian Jacobi March 20, 1984 5:50:51 pm PST
last edited Christian Jacobi March 23, 1984 8:45:25 am PST
DIRECTORY
CD,
CDApplications,
CDCallSpecific,
CDDirectory,
CDEvents,
CDInline,
CDIO,
CDIOExtras,
CDOps,
CDOrient,
CDProperties,
CDSequencer,
CDValue,
FileNames,
List,
ProcessProps,
Rope,
TerminalIO,
TokenIO;
CDReferencesImpl:
CEDAR
PROGRAM
IMPORTS CD, CDApplications, CDDirectory, CDEvents, CDInline, CDIO, CDIOExtras, CDOps, CDOrient, CDSequencer, CDValue, FileNames, List, ProcessProps, Rope, TerminalIO, TokenIO
SHARES CDDirectory =
BEGIN
-- Terminology
-- importee: design (like module) which is imported
-- entry: object (like variable or procedure)
-- localName: mostly importeeName.entryName
-- no design is allowed to make circular imports
ReferencePtr: TYPE = REF ReferenceRep;
ReferenceRep:
TYPE =
RECORD [
boundApp: CD.ApplicationPtr←NIL, -- NIL means not yet bound
entryName: Rope.ROPE,
importeeName: Rope.ROPE,
localName: Rope.ROPE
--XXX key business not yet impl
];
-- all references must be accessible, to allow postboned binding
ImportList: TYPE = RECORD [list: LIST OF REF Import]; -- describes all the imports of a design
Import:
TYPE =
RECORD[
-- describes imports of one particular importee-design
importeeName: Rope.ROPE,
importee: CD.Design←NIL, -- NIL means not yet bound
referenceList: LIST OF CD.ObPtr←NIL
];
pForReference: REF CD.ObjectProcs = CD.RegisterObjectType[$Reference];
SetName:
PROC [me:
CD.ObPtr, r: Rope.
ROPE] =
BEGIN
rp: ReferencePtr = NARROW[me.specificRef];
rp.localName ← r
END;
Name:
PROC [me:
CD.ObPtr]
RETURNS [Rope.
ROPE] =
BEGIN
rp: ReferencePtr = NARROW[me.specificRef];
RETURN [rp.localName]
END;
Key:
PROC [me:
CD.ObPtr]
RETURNS [Rope.
ROPE] =
BEGIN
rp: ReferencePtr = NARROW[me.specificRef];
--XXX key business not yet impl
RETURN [NIL]
END;
ComputeBounds:
CD.RectProc
--PROC [ob: ObPtr] RETURNS [DesignRect]-- =
BEGIN
rp: ReferencePtr ~ NARROW[ob.specificRef];
sz: CD.DesignPosition ~ IF rp.boundApp#NIL THEN rp.boundApp.ob.size ELSE ob.size;
RETURN [CDInline.RectAt[[0, 0], sz]]
END;
EnumerateItsObjects:
PROC [me:
CD.ObPtr, p: CDDirectory.EnumerateObjectsProc, x:
REF] =
{--DON'T, they are not directly accessible--};
AdjustItself: CDDirectory.AdjustItselfProc
-- PROC [objToReposition: CD.ObPtr, newBound: CD.DesignRect] -- =
BEGIN
rp: ReferencePtr ~ NARROW[objToReposition.specificRef];
IF rp.boundApp#
NIL
THEN{
objToReposition.size ← rp.boundApp.ob.size
};
END;
RepositionElements: CDDirectory.RepositionElementsProc
-- PROC [me: CD.ObPtr, objToReposition: CD.ObPtr, oldSize: CD.DesignPosition, newBound: CD.DesignRect, design: CD.Design] -- =
{--there is nothing to do--};
InternalCreateReference:
PROC [design:
CD.Design, size:
CD.DesignPosition,
entryName, importeeName, localName: Rope.ROPE←NIL, include: BOOL←TRUE] RETURNS [CD.ObPtr] =
BEGIN
ob: CD.ObPtr;
rp: ReferencePtr;
import: REF Import ~ GetImport[design, importeeName];
--search first for existing object
FOR list:
LIST
OF
CD.ObPtr ← import.referenceList, list.rest
WHILE list#
NIL
DO
ob ← list.first;
rp ← NARROW[ob.specificRef, ReferencePtr];
IF Rope.Equal[rp.entryName, entryName]
AND Rope.Equal[rp.importeeName, importeeName] THEN RETURN [ob];
ENDLOOP;
--object has not been found; create one
ob ←
NEW[
CD.ObjectDefinition←[
size: CDInline.MaxPoint[size, [1, 1]],
p: pForReference,
level: CD.combined,
specificRef:
NEW[ReferenceRep ← [
entryName: entryName,
importeeName: importeeName,
localName: Rope.Cat[importeeName, ".", entryName]
]]
]];
import.referenceList ← CONS[ob, import.referenceList];
IF include THEN [] ← CDDirectory.Include[design, ob];
IF import.importee#NIL THEN [] ← BindReference[design, ob, import.importee, FALSE];
RETURN [ob]
END;
CreateReference:
--PUBLIC--
PROC [design:
CD.Design, size:
CD.DesignPosition,
entryName, importeeName, localName: Rope.ROPE←NIL] RETURNS [CD.ObPtr] =
BEGIN
RETURN [InternalCreateReference[design, size, entryName, importeeName, localName, TRUE]];
END;
DescribeReference:
PROC[me:
CD.ObPtr]
RETURNS [Rope.
ROPE] = {
RETURN [Rope.Concat["reference to ", Name[me]]]
};
DrawReference:
PROC [aptr:
CD.ApplicationPtr, pos:
CD.DesignPosition, orient:
CD.Orientation,
pr: CD.DrawRef] =
BEGIN
rp: ReferencePtr ~ NARROW[aptr.ob.specificRef];
IF rp.boundApp#NIL THEN pr.drawChild[rp.boundApp, pos, orient, pr]
ELSE {
pr.drawRect[CDOrient.RectAt[pos, aptr.ob.size, orient], CD.highLightShade, pr];
pr.drawComment[CDOrient.RectAt[pos, aptr.ob.size, orient],
IF rp.localName#NIL THEN rp.localName ELSE rp.entryName,
pr]
}
END;
QuickDrawReference:
PROC [aptr:
CD.ApplicationPtr, pos:
CD.DesignPosition, orient:
CD.Orientation,
pr: CD.DrawRef] =
BEGIN
rp: ReferencePtr ~ NARROW[aptr.ob.specificRef];
IF rp.boundApp#NIL THEN rp.boundApp.ob.p.quickDrawMe[rp.boundApp, pos, orient, pr]
ELSE {
pr.drawRect[CDOrient.RectAt[pos, aptr.ob.size, orient], CD.highLightShade, pr];
pr.drawComment[CDOrient.RectAt[pos, aptr.ob.size, orient],
IF rp.localName#NIL THEN rp.localName ELSE rp.entryName,
pr]
}
END;
DrawReferenceSelection:
PROC [aptr:
CD.ApplicationPtr, pos:
CD.DesignPosition, orient:
CD.Orientation,
pr: CD.DrawRef] =
BEGIN
rp: ReferencePtr ~ NARROW[aptr.ob.specificRef];
IF rp.boundApp#NIL THEN rp.boundApp.ob.p.showMeSelected[rp.boundApp, pos, orient, pr]
ELSE pr.outLineProc[CDOrient.RectAt[pos, aptr.ob.size, orient], pr]
END;
WriteReference:
CD.InternalWriteProc
-- PROC [me: ObPtr] -- =
BEGIN
rp: ReferencePtr = NARROW[me.specificRef];
TokenIO.WriteInt[me.size.x];
TokenIO.WriteInt[me.size.y];
TokenIO.WriteRope[rp.entryName];
TokenIO.WriteRope[rp.importeeName];
TokenIO.WriteRope[rp.localName];
END;
ReadReference:
CD.InternalReadProc
--PROC [] RETURNS [ObPtr]-- =
BEGIN
x: INT = TokenIO.ReadInt[];
y: INT = TokenIO.ReadInt[];
entryName: Rope.ROPE = TokenIO.ReadRope[];
importeeName: Rope.ROPE = TokenIO.ReadRope[];
localName: Rope.ROPE = TokenIO.ReadRope[]; -- and is ignored
ob:
CD.ObPtr = InternalCreateReference[
design: CDIO.DesignInReadOperation[],
size: [x, y],
entryName: entryName,
importeeName: importeeName,
include: FALSE
];
RETURN [ob]
END;
GetImportList:
PROC [design:
CD.Design]
RETURNS [imp:
REF ImportList←
NIL] =
BEGIN
x: REF ~ CDValue.Fetch[boundTo: design, key: $ImportedDesigns, propagation: design];
IF x#
NIL
AND
ISTYPE[x,
REF ImportList]
THEN {
imp ← NARROW[x, REF ImportList];
}
ELSE {
imp ← NEW[ImportList←[list: NIL]];
CDValue.Store[boundTo: design, key: $ImportedDesigns, value: imp];
};
END;
GetImport:
PROC [design:
CD.Design, importeeName: Rope.
ROPE←
NIL, createIfNotFound:
BOOL←
TRUE]
RETURNS [
REF Import] =
BEGIN
mdata: REF Import ← NIL;
impl: REF ImportList ~ GetImportList[design];
IF Rope.IsEmpty[importeeName]
THEN
ERROR
CD.Error[ec: other,
explanation: "design has empty name, but shouldn't"
];
IF impl#
NIL
THEN
FOR l:
LIST
OF
REF Import ← impl.list, l.rest
WHILE l#
NIL
DO
IF l.first#NIL AND Rope.Equal[l.first.importeeName, importeeName] THEN RETURN [l.first]
ENDLOOP;
IF createIfNotFound
THEN {
mdata ← NEW[Import←[importeeName: importeeName, importee: NIL, referenceList: NIL]];
impl.list ← CONS[mdata, impl.list]; --atomic--
};
RETURN [mdata]
END;
BindImportee:
PROC [importer, importee:
CD.Design, allowSizeConflicts:
BOOL ←
TRUE] =
BEGIN
ENABLE TerminalIO.UserAbort => GOTO UserAborted;
done: BOOL←TRUE;
mdata: REF Import ~ GetImport[importer, importee.name];
IF mdata=NIL THEN ERROR;
IF mdata.importee#
NIL
THEN {
IF
NOT TerminalIO.UserSaysYes[
text: "design already loaded; shall overload?\n",
label: "overload?"]
THEN {
TerminalIO.WriteRope["dont overload; not done\n"];
RETURN
}
};
mdata.importee ← importee;
FOR list:
LIST
OF
CD.ObPtr ← mdata.referenceList, list.rest
WHILE list#
NIL
DO
done ← done AND BindReference[importer, list.first, mdata.importee, allowSizeConflicts].ok
ENDLOOP;
IF NOT done THEN TerminalIO.WriteRope["some import not bound\n"];
CDOps.DelayedRedraw[importer];
EXITS
UserAborted => {TerminalIO.WriteRope["aborted, design not bound\n"]};
END;
BindReference:
PROC [design:
CD.Design, reference:
CD.ObPtr, importee:
CD.Design, allowSizeConflicts:
BOOL ←
TRUE]
RETURNS [ok:
BOOL←
FALSE] =
BEGIN
ENABLE TerminalIO.UserAbort => GOTO UserAborted;
rp: ReferencePtr ~ NARROW[reference.specificRef, ReferencePtr];
found: BOOL;
referedOb: CD.ObPtr;
[found, referedOb] ← CDDirectory.Fetch[importee, rp.entryName];
IF
NOT found
THEN {
TerminalIO.WriteRope["entry "];
TerminalIO.WriteRope[rp.entryName];
TerminalIO.WriteRope[" in "];
TerminalIO.WriteRope[importee.name];
TerminalIO.WriteRope[" not found\n"];
RETURN
};
IF referedOb.size=reference.size THEN rp.boundApp ← CDApplications.NewApplicationI[ob: referedOb]
ELSE {
TerminalIO.WriteRope["entry "];
TerminalIO.WriteRope[rp.entryName];
TerminalIO.WriteRope[" has different size; "];
IF
NOT allowSizeConflicts
THEN {
TerminalIO.WriteRope["not resolved\n"];
RETURN
};
IF
NOT TerminalIO.UserSaysYes[
text: "import it anyway? ",
label: "import different sized entry?"]
THEN {
TerminalIO.WriteRope["no\n"];
RETURN
};
TerminalIO.WriteRope["yes\n"];
rp.boundApp ← CDApplications.NewApplicationI[ob: referedOb];
CDDirectory.RepositionAnObject[design, reference];
};
ok ← TRUE;
EXITS
UserAborted => {TerminalIO.WriteRope["aborted, entry not replaced\n"]};
END;
DoImportation:
PROC [design:
CD.Design, importee:
CD.Design]
RETURNS [done:
BOOL←
FALSE] =
BEGIN
indirectImport: REF ImportList ~ GetImportList[importee];
IF indirectImport^.list#NIL THEN TerminalIO.WriteRope["There are indirect imports\n"];
-- check for forbidden circular import
FOR list:
LIST
OF
REF Import ← indirectImport^, list.rest
WHILE list#
NIL
DO
IF Rope.Equal[list.first.importeeName, design.name]
THEN {
TerminalIO.WriteRope["**CREATES CIRCULAR IMPORTS\n"];
RETURN
}
ENDLOOP;
-- no circular import
BindImportee[importer: design, importee: importee];
--check already imported designs for importing the new design
FOR list:
LIST
OF
REF Import ← GetImportList[design]^, list.rest
WHILE list#
NIL
DO
IF list.first.importee#
NIL
THEN
BindImportee[importer: list.first.importee, importee: importee, allowSizeConflicts: FALSE];
ENDLOOP;
--check the new design for importing of already imported designs
FOR list:
LIST
OF
REF Import ← indirectImport^, list.rest
WHILE list#
NIL
DO
IF list.first.importee=
NIL
THEN {
imp: REF Import ← GetImport[design, list.first.importeeName, FALSE];
IF imp#
NIL
AND imp.importee#
NIL
THEN
BindImportee[importer: importee, importee: imp.importee, allowSizeConflicts: FALSE];
}
ENDLOOP;
done←TRUE;
END;
GetImportedEntryCommand:
PROC [comm: CDSequencer.Command] =
BEGIN
importeeName, entryName: Rope.ROPE;
referenceOb, referedOb: CD.ObPtr;
found: BOOLEAN;
import: REF Import;
TerminalIO.WriteRope["Include referenced entry; "];
importeeName ← TerminalIO.RequestRope["design > "! TerminalIO.UserAbort => {GOTO aborted}];
IF Rope.IsEmpty[importeeName]
THEN {
TerminalIO.WriteRope[" empty name; not done\n"];
RETURN
};
import ← GetImport[design: comm.design, importeeName: importeeName, createIfNotFound: FALSE];
IF import=
NIL
OR import.importee=
NIL
THEN {
TerminalIO.WriteRope["design "];
TerminalIO.WriteRope[importeeName];
TerminalIO.WriteRope[" not yet imported; not done\n"];
RETURN
};
entryName ← TerminalIO.RequestRope["entry > "! TerminalIO.UserAbort => {GOTO aborted}];
[found, referedOb] ← CDDirectory.Fetch[import.importee, entryName];
IF
NOT found
THEN {
TerminalIO.WriteRope[entryName];
TerminalIO.WriteRope[" not found in design "];
TerminalIO.WriteRope[importeeName];
TerminalIO.WriteRope["; not done\n"];
RETURN
};
referenceOb ← CreateReference[design: comm.design, size: referedOb.size, entryName: entryName, importeeName: importeeName];
CDOps.AddAnObject[design: comm.design, ob: referenceOb, location: comm.pos, orientation: 0];
END;
DesignHasBeenRenamed: CDEvents.EventProc
--PROC [event: REF, design: CD.Design, x: REF] RETURNS [dont: BOOL←FALSE]-- =
-- prevent a renaming which would cause circularity
BEGIN
imp: REF Import ~ GetImport[design: design, importeeName: design.name, createIfNotFound: FALSE];
IF imp#
NIL
THEN {
dont←TRUE;
TerminalIO.WriteRope["rename causes circularities; not done\n"]
};
END;
DisplayImports:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope[comm.design.name];
TerminalIO.WriteRope["'s import list: "];
TerminalIO.WriteRope[comm.design.name];
TerminalIO.WriteRope["\n"];
FOR list:
LIST
OF
REF Import ← GetImportList[comm.design]^, list.rest
WHILE list#
NIL
DO
TerminalIO.WriteRope[" "];
TerminalIO.WriteRope[list.first.importeeName];
TerminalIO.WriteRope[IF list.first.importee=NIL THEN " -\n" ELSE " +\n"];
ENDLOOP;
TerminalIO.WriteRope["---\n"]
END;
sorry; does not work; problem: replace referenceobjects by imported reference....
IncludeImports: PROC [comm: CDSequencer.Command] =
BEGIN
importeeName: Rope.ROPE;
mdata: REF Import;
hasNotBound: BOOL ← FALSE;
TerminalIO.WriteRope["include imported design\n"];
importeeName ← TerminalIO.RequestRope["design > "! TerminalIO.UserAbort => {GOTO aborted}];
mdata ← GetImport[comm.design, importeeName, FALSE];
TerminalIO.WriteRope[importeeName];
IF mdata=NIL THEN {
TerminalIO.WriteRope[" not imported\n"];
RETURN
}
ELSE IF mdata.importee=NIL THEN {
TerminalIO.WriteRope[" not yet loaded\n"];
RETURN
};
FOR list: LIST OF CD.ObPtr ← mdata.referenceList, list.rest WHILE list#NIL DO
rp: ReferencePtr ~ NARROW[list.first.specificRef];
IF rp.boundApp=NIL THEN {
hasNotBound ← TRUE;
TerminalIO.WriteRope[rp.localName];
TerminalIO.WriteRope[" ("];
TerminalIO.WriteRope[rp.entryName];
TerminalIO.WriteRope[") not bound\n"];
};
ENDLOOP;
IF hasNotBound THEN {
TerminalIO.WriteRope[" not done\n"];
RETURN
};
END;
DisplayImportedEntries:
PROC [comm: CDSequencer.Command] =
BEGIN
hasNotBound: BOOL ← FALSE; -- if importee loaded
importeeName: Rope.ROPE;
mdata: REF Import;
TerminalIO.WriteRope["display used entries of imported design\n"];
importeeName ← TerminalIO.RequestRope["design > "! TerminalIO.UserAbort => {GOTO aborted}];
mdata ← GetImport[comm.design, importeeName, FALSE];
TerminalIO.WriteRope[importeeName];
IF mdata=
NIL
THEN {
TerminalIO.WriteRope[" not imported\n"];
RETURN
}
ELSE {
IF mdata.importee#NIL THEN TerminalIO.WriteRope[" already loaded\n"]
ELSE TerminalIO.WriteRope[" not yet loaded\n"];
FOR list:
LIST
OF
CD.ObPtr ← mdata.referenceList, list.rest
WHILE list#
NIL
DO
rp: ReferencePtr ~ NARROW[list.first.specificRef];
TerminalIO.WriteRope[" "];
TerminalIO.WriteRope[rp.localName];
TerminalIO.WriteRope[" ("];
TerminalIO.WriteRope[rp.entryName];
TerminalIO.WriteRope[")"];
IF rp.boundApp=
NIL
AND mdata.importee#
NIL THEN {
hasNotBound←TRUE;
TerminalIO.WriteRope[" not bound"];
};
TerminalIO.WriteRope["\n"];
ENDLOOP;
TerminalIO.WriteRope["---"];
IF hasNotBound
THEN {
TerminalIO.WriteRope[" has not bound entries"];
RETURN
};
TerminalIO.WriteRope["\n"]
};
END;
ImportReadCommand:
PROC [comm: CDSequencer.Command] =
BEGIN
Check:
PROC [design:
CD.Design]
RETURNS [ok:
BOOL] =
BEGIN
ok ← design.technology=comm.design.technology;
IF
NOT ok
THEN {
TerminalIO.WriteRope["Technology missmatch: includee is "];
TerminalIO.WriteRope[design.technology.name];
TerminalIO.WriteRope["\n"];
RETURN
};
ok ← NOT Rope.Equal[comm.design.name, CDIO.DesignInReadOperation[].name];
IF
NOT ok
THEN {
TerminalIO.WriteRope["design can not be imported, it has same name\n"];
};
END;
done: BOOL ← FALSE;
design: CD.Design;
TerminalIO.WriteRope["import the directory of an input design\n"];
[] ← UseDesignsWorkingDirectory[comm.design];
design ← CDIO.ReadDesign[NIL, Check];
IF design#
NIL
THEN {
done ← DoImportation[design: comm.design, importee: design];
};
TerminalIO.WriteRope[IF done THEN "include done\n" ELSE "include not done\n"];
END;
ReplaceImportCommand: PROC [comm: CDSequencer.Command] =
BEGIN
done: BOOL ← FALSE;
import, imp2: REF Import;
importeeName, newName: Rope.ROPE;
TerminalIO.WriteRope["replace an imported design\n"];
importeeName ← TerminalIO.RequestRope["design > "];
import ← GetImport[design: comm.design, importeeName: importeeName, createIfNotFound: FALSE];
IF import=NIL {
TerminalIO.WriteRope["design "];
TerminalIO.WriteRope[importeeName];
TerminalIO.WriteRope[" not yet referenced; not done\n"];
RETURN
};
IF import.importee#NILNIL {
TerminalIO.WriteRope["design "];
TerminalIO.WriteRope[importeeName];
TerminalIO.WriteRope[" already imported; not done\n"];
RETURN
};
newName ← TerminalIO.RequestRope["new design > "];
IF Rope.IsEmpty[newName] THEN {
TerminalIO.WriteRope[" bad name; not done\n"];
RETURN
};
imp2 ← GetImport[design: comm.design, importeeName: importeeName, createIfNotFound: FALSE];
IF imp2=NIL THEN {
TerminalIO.WriteRope[replace by ];
TerminalIO.WriteRope[newName];
import.importee.importeeName ← newName;
FOR l: LIST OF CD.ObPtr ← import.importee.referenceList, l.rest WHILE l#NIL DO
WITH l.first.specificref SELECT FROM
rp: ReferencePtr => {
rp.importeeName ← newName
};
ENDCASE => ERROR
ENDLOOP;
TerminalIO.WriteRope[" not done\n"];
}
END;
Init:
PROC [] =
INLINE
BEGIN
rp: REF CDDirectory.DirectoryProcs ~ CDDirectory.InstallDirectoryProcs[pForReference];
rp.enumerateChildObjects ← EnumerateItsObjects;
rp.adjustItself ← AdjustItself;
rp.repositionElements ← RepositionElements;
rp.computeBounds ← ComputeBounds;
rp.key ← Key;
rp.name ← Name;
rp.setName ← SetName;
pForReference.drawMe ← DrawReference;
pForReference.quickDrawMe ← QuickDrawReference;
pForReference.showMeSelected ← DrawReferenceSelection;
pForReference.internalRead ← ReadReference;
pForReference.internalWrite ← WriteReference;
pForReference.describe ← DescribeReference;
CDValue.EnregisterKey[$ImportedDesigns];
CDEvents.RegisterEventProc[$RenameDesign, DesignHasBeenRenamed];
CDSequencer.ImplementCommand[$DrawImportedCell, GetImportedEntryCommand];
CDSequencer.ImplementCommand[$DisplayImports, DisplayImports];
CDSequencer.ImplementCommand[$DisplayImportedEntries, DisplayImportedEntries];
CDSequencer.ImplementCommand[$ImportADesign, ImportReadCommand];
CDSequencer.ImplementCommand[$SelectADesign, SelectADesign];
CDSequencer.ImplementCommand[$DrawCorrespondingObject, DrawImportedCopy];
END;
--xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
--multi-design-copy feature
selectedDesign: CD.Design ← NIL;
SelectADesign:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["select "];
TerminalIO.WriteRope[comm.design.name];
TerminalIO.WriteRope[" for inter-design source\n"];
selectedDesign ← comm.design;
END;
GlobalSelection:
PROC [expectedTechnology:
CD.Technology]
RETURNS [foundNamed:
BOOL←
FALSE, foundWithoutChildren:
BOOL←
FALSE, moduleName: Rope.
ROPE←
NIL, objectName: Rope.
ROPE←
NIL, object:
CD.ObPtr←
NIL, orient:
CD.Orientation←
CD.original] =
--never returns with both foundNamed and foundWithoutChildren set to true
--if not found then message to TerminalIO
--if foundNamed then both, moduleName, objectName # NIL
BEGIN
Out: PROC [t: Rope.ROPE] = {TerminalIO.WriteRope[t]};
from: CD.Design = selectedDesign; -- so it does not change
IF from=NIL THEN Out[" no selected design"]
ELSE {
fromName: Rope.ROPE = from.name; -- so it does not change
IF Rope.IsEmpty[fromName] THEN Out[" selected design has no name"]
ELSE
IF expectedTechnology#from.technology
AND expectedTechnology#
NIL
THEN
Out[" different technologies"]
ELSE {
ap: CD.ApplicationPtr; -- the referred application to support the name
multiple: BOOLEAN;
[ap, multiple] ← CDOps.SelectedApplication[from];
IF multiple THEN Out[" multiple selection"]
ELSE IF ap=NIL THEN Out[" no selection"]
ELSE {
orient ← ap.orientation;
IF
NOT ap.ob.p.hasChildren
THEN {
object ← ap.ob;
foundWithoutChildren ← TRUE;
}
ELSE {
entryName: Rope.ROPE = CDDirectory.Name[ap.ob];
IF Rope.IsEmpty[entryName] THEN Out[" object has no name"]
ELSE {
moduleName ← fromName;
objectName ← entryName;
foundNamed ← TRUE;
}
}
}
}
}
END;
DrawImportedCopy:
PROC [comm: CDSequencer.Command] =
BEGIN
foundNamed: BOOL;
foundWithoutChildren: BOOL;
moduleName: Rope.ROPE;
objectName: Rope.ROPE;
referenceOb, referedOb: CD.ObPtr;
orient: CD.Orientation;
TerminalIO.WriteRope["create corresponding object; "];
[foundNamed: foundNamed, foundWithoutChildren: foundWithoutChildren, moduleName: moduleName, objectName: objectName, object: referedOb, orient: orient] ← GlobalSelection[comm.design.technology];
IF foundNamed
THEN {
import: REF Import ~ GetImport[design: comm.design, importeeName: moduleName, createIfNotFound: FALSE];
IF Rope.Equal[moduleName, comm.design.name]
THEN {
TerminalIO.WriteRope[" don't refer itself; not done\n "];
RETURN
};
IF import=
NIL
OR import.importee=
NIL
THEN {
TerminalIO.WriteRope[" design "];
TerminalIO.WriteRope[moduleName];
TerminalIO.WriteRope[" not yet imported; not done\n"];
RETURN
};
[foundNamed, referedOb] ← CDDirectory.Fetch[import.importee, objectName];
IF
NOT foundNamed
THEN {
TerminalIO.WriteRope[" "];
TerminalIO.WriteRope[objectName];
TerminalIO.WriteRope[" not found in imported design "];
TerminalIO.WriteRope[moduleName];
TerminalIO.WriteRope["; not done\n"];
RETURN
};
referenceOb ← CreateReference[design: comm.design, size: referedOb.size, entryName: objectName, importeeName: moduleName];
IF referenceOb=
NIL
THEN {
TerminalIO.WriteRope[" NIL object; not done\n"];
RETURN
};
CDOps.AddAnObject[design: comm.design, ob: referenceOb, location: comm.pos, orientation: orient];
TerminalIO.WriteRope[CDOps.Info[referenceOb]];
TerminalIO.WriteRope[" included\n"];
}
ELSE
IF foundWithoutChildren
THEN {
CDOps.AddAnObject[design: comm.design, ob: referedOb, location: comm.pos, orientation: orient];
TerminalIO.WriteRope[CDOps.Info[referedOb]];
TerminalIO.WriteRope[" copied\n"];
}
ELSE TerminalIO.WriteRope["; not done\n"];
END;
--xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
UseDesignsWorkingDirectory:
PROC [design:
CD.Design]
RETURNS [Rope.
ROPE] =
--set's it for the running process
--return's it
BEGIN
wDir: Rope.ROPE ← CDIOExtras.GetDesignsWorkingDirectory[design];
IF wDir#
NIL
THEN {
[] ← List.PutAssoc[key: $WorkingDirectory, val: wDir, aList: ProcessProps.GetPropList[]];
RETURN [wDir];
};
RETURN [FileNames.CurrentWorkingDirectory[]]
END;
Init[];
END.