DIRECTORY CD, CDCellsInteractions, CDEnvironment, CDDesignCache, CDDirectory, CDImports, CDInstances, CDIO, CDMenuSpecials, CDOps, CDProperties, CDSequencer, IO, Process USING [PauseMsec], RefTab, Rope, SymTab, TerminalIO, TokenIO; CDImportCommands: CEDAR PROGRAM IMPORTS CD, CDCellsInteractions, CDDesignCache, CDDirectory, CDEnvironment, CDImports, CDInstances, CDIO, CDMenuSpecials, CDOps, CDProperties, CDSequencer, IO, Process, RefTab, Rope, SymTab, TerminalIO SHARES CDDirectory, CDImports = BEGIN ROPE: TYPE = Rope.ROPE; ImportSpecific: TYPE = CDImports.ImportSpecific; ImportRep: TYPE = CDImports.ImportRep; CacheListRec: TYPE = CDImports.CacheListRec; Cache: TYPE = CDImports.Cache; CacheList: TYPE = CDImports.CacheList; HasCachedImports: PROC [into: CD.Design] RETURNS [BOOL] = INLINE --gfi-- { cacheL: CDImports.CacheList _ CDImports.GetCacheList[into]; RETURN [cacheL#NIL AND cacheL^#NIL] }; SymTabToKeyList: PROC [ref: SymTab.Ref] RETURNS [list: LIST OF ROPE_NIL] = INLINE --gfi-- { Each: SymTab.EachPairAction = {list _ CONS[key, list]}; [] _ SymTab.Pairs[ref, Each]; }; RequestImporteeName: PROC [into: CD.Design, restrictedToCaches: BOOL_TRUE, fastIfNoChoice: BOOL_FALSE, offerAll: ROPE_NIL] RETURNS [importeeName: ROPE_NIL] = { optionsList: LIST OF ROPE; options: SymTab.Ref _ FindAllImportCaches[into]; IF ~restrictedToCaches THEN { name: ROPE _ NIL; d: CD.Design _ SelectedDesign[]; IF d#NIL THEN name _ d.name; IF ~Rope.IsEmpty[name] AND ~Rope.Equal[name, into.name] THEN [] _ SymTab.Insert[options, name, name] }; optionsList _ SymTabToKeyList[options]; IF ~Rope.IsEmpty[offerAll] AND optionsList#NIL THEN { optionsList _ CONS[offerAll, optionsList]; }; IF fastIfNoChoice AND restrictedToCaches AND SymTab.GetSize[options]=1 THEN { IF ~Rope.IsEmpty[importeeName] THEN RETURN [importeeName]; }; importeeName _ CDMenuSpecials.SelectOneOf[optionsList, "DESIGN name", ~restrictedToCaches]; }; LoadAndGetCache: PROC [into: CD.Design, importeeName: ROPE_NIL, allwaysNewFile: BOOL_FALSE, forceBind: BOOL _ FALSE, offerAll: BOOL _ FALSE] RETURNS [cache: Cache_NIL, done: BOOL_FALSE] = { checkCalled: BOOL _ FALSE; r, fn: ROPE; design: CD.Design_NIL; loaded: BOOL_FALSE; IF Rope.IsEmpty[importeeName] THEN importeeName _ RequestImporteeName[into: into, restrictedToCaches: FALSE, fastIfNoChoice: FALSE, offerAll: IF offerAll THEN "" ELSE NIL]; IF Rope.IsEmpty[importeeName] THEN { TerminalIO.PutRopes["no design name specified\n"]; RETURN }; IF Rope.Equal[importeeName, ""] THEN { BindAll[into, interactive]; TerminalIO.PutRope[" --\n"]; RETURN [NIL, TRUE]; }; IF Rope.Equal[importeeName, into.name] THEN { TerminalIO.PutRopes["a design can't import itself\n"]; RETURN }; cache _ CDImports.GetCache[into: into, importeeName: importeeName]; IF cache=NIL OR cache.importee=NIL OR allwaysNewFile THEN { menuHeader: ROPE _ Rope.Cat["FILE name for ", importeeName]; menuChoice: LIST OF ROPE _ LIST[importeeName]; IF cache#NIL AND cache.importee#NIL THEN TerminalIO.PutRopes["reload and cache design ", importeeName, "\n"]; fn _ CDDesignCache.MakeUpFile[into, importeeName]; IF ~Rope.IsEmpty[fn] THEN menuChoice _ CONS[fn, menuChoice]; r _ CDMenuSpecials.SelectOneOf[menuChoice, menuHeader, TRUE]; IF Rope.IsEmpty[r] THEN {TerminalIO.PutRope["discarded\n"]; RETURN}; fn _ CDEnvironment.FindFile[r, ".dale", into]; IF Rope.IsEmpty[fn] THEN TerminalIO.PutRopes["file ", r, " not found\n"] ELSE loaded _ CDImports.LoadAndBindDesign[into: into, importeeName: importeeName, forceBind: forceBind, allowConflicts: interactive, useCache: FALSE, fileName: fn, forceFile: TRUE]; IF loaded THEN cache _ CDImports.GetCache[into: into, importeeName: importeeName]; }; done _ cache#NIL; }; BindAll: PROC [importerDesign: CD.Design, allowConflicts: CDImports.BoolOrInteractive_false] = { IF CDImports.LoadAndBindAll[into: importerDesign, allowConflicts: allowConflicts, forceBind: FALSE] THEN DescribeUnboundImport[CDImports.HasUnloadedImports[importerDesign].where] ELSE TerminalIO.PutRope[" failed binding all imports\n"]; }; BindAllComm: PROC [comm: CDSequencer.Command] = { BindAll[comm.design, false]; }; DrawImportByNameComm: PROC [comm: CDSequencer.Command] = { objectName: ROPE; referenceOb: CD.Object; cache: Cache; TerminalIO.PutRope["draw object of imported design; "]; cache _ LoadAndGetCache[comm.design].cache; IF cache=NIL OR cache.importee=NIL THEN RETURN; objectName _ TerminalIO.RequestRope["object > "]; referenceOb _ CDImports.CreateImportFromCache[into: comm.design, objectName: objectName, importeeName: cache.importeeName]; IF referenceOb=NIL THEN { TerminalIO.PutF[" %g not found in design %g; not done\n", [rope[objectName]], [rope[cache.importeeName]] ]; RETURN }; [] _ CDOps.IncludeObjectI[design: comm.design, ob: referenceOb, location: comm.pos]; }; ImportReadCommand: PROC [comm: CDSequencer.Command] = { cache: Cache; done: BOOL; TerminalIO.PutRope["load (or reload) a design into the import cache\n"]; [cache, done] _ LoadAndGetCache[into: comm.design, importeeName: NIL, allwaysNewFile: TRUE, offerAll: TRUE, forceBind: TRUE]; TerminalIO.PutRope[IF ~done OR (cache#NIL AND cache.importee=NIL) THEN "not done\n" ELSE "done\n"]; }; GetImportFileHints: PROC [for: CD.Design] RETURNS [LIST OF ROPE_NIL] = { IF for#NIL THEN WITH CDProperties.GetDesignProp[for, $ImportHints] SELECT FROM rL: LIST OF ROPE => RETURN [rL]; ENDCASE => NULL; }; ChangeImportFileHint: PROC [for: CD.Design, imp, file: ROPE] = { RemKey: PROC [rl: LIST OF ROPE, key: ROPE] RETURNS [x: LIST OF ROPE_NIL] = { FOR list: LIST OF ROPE _ rl, list.rest WHILE list#NIL DO IF ~Rope.Equal[CDEnvironment.SplitLine[list.first].key, key] THEN x _ CONS[list.first, x] ENDLOOP; }; rl: LIST OF ROPE _ GetImportFileHints[for]; rl _ RemKey[rl, imp]; file _ CDEnvironment.RemoveSpaces[file]; IF file#NIL THEN rl _ CONS[Rope.Cat[imp, ": ", file], rl]; CDProperties.PutDesignProp[for, $ImportHints, rl]; }; ChangeImportFileHintComm: PROC [comm: CDSequencer.Command] = { importeeName, fileName: ROPE; TerminalIO.PutRope["specify a default file name for a particular import\n"]; importeeName _ RequestImporteeName[into: comm.design, restrictedToCaches: FALSE, fastIfNoChoice: FALSE, offerAll: NIL]; IF Rope.IsEmpty[importeeName] THEN TerminalIO.PutRope["no input design\n"] ELSE { fileName _ TerminalIO.RequestRope["FILE name > "]; ChangeImportFileHint[comm.design, importeeName, fileName]; TerminalIO.PutRope[" ok\n"]; } }; FindAllImportCaches: PROC [design: CD.Design] RETURNS [dList: SymTab.Ref] = { CheckOne: PROC [d: CD.Design] = { IF RefTab.Insert[checked, d, d] THEN { FOR l: LIST OF CDImports.Cache _ CDImports.GetCacheList[d]^, l.rest WHILE l#NIL DO this: CDImports.Cache _ l.first; [] _ SymTab.Insert[dList, this.importeeName, $ok]; IF this.importee#NIL THEN [] _ SymTab.Store[dList, this.importeeName, $notLoaded] ELSE { dd: CD.Design _ CDDesignCache.Fetch[design, this.importeeName]; IF dd=NIL THEN [] _ SymTab.Store[dList, this.importeeName, $notLoaded] ELSE CheckOne[dd]; }; ENDLOOP; }; }; checked: RefTab.Ref _ RefTab.Create[]; dList _ SymTab.Create[]; CheckOne[design]; }; ListUnboundsIndirect: PROC [design: CD.Design] = { where: LIST OF CD.Object _ CDImports.HasUnloadedImports[design].where; IF where#NIL THEN DescribeUnboundImport[where] ELSE TerminalIO.PutRope[" has no [indirect] unbound imported object\n"] }; DisplayCachedDesigns: PROC [comm: CDSequencer.Command] = { ListEach: SymTab.EachPairAction = { cache: CDImports.Cache _ CDImports.GetCache[design, key]; loaded: BOOL _ cache#NIL AND cache.importee#NIL; hasImpDesign _ TRUE; IF ~loaded THEN hasUnloadedDesign _ TRUE; TerminalIO.PutRopes[" ", key, (IF loaded THEN " (cached)\n" ELSE " (not cached)\n")]; RETURN [FALSE] }; DisplayImportFileHints: PROC [for: CD.Design] = { rl: LIST OF ROPE _ GetImportFileHints[for]; IF rl#NIL THEN { key, rest: ROPE _ NIL; TerminalIO.PutRopes["file name hints to be used on imports:\n"]; FOR list: LIST OF ROPE _ rl, list.rest WHILE list#NIL DO [key, rest] _ CDEnvironment.SplitLine[list.first]; rest _ CDEnvironment.RemoveSpaces[rest]; TerminalIO.PutRopes[" design: ", key]; TerminalIO.PutRopes[" file: ", rest, "\n"]; ENDLOOP; }; }; design: CD.Design _ comm.design; hasUnloadedDesign: BOOL _ FALSE; hasImpDesign: BOOL _ FALSE; TerminalIO.PutRopes[CD.DesignName[design], "'s import cache: \n"]; [] _ SymTab.Pairs[FindAllImportCaches[design], ListEach]; IF ~hasImpDesign THEN TerminalIO.PutRope[" has no imported designs in cache\n"]; IF ~hasUnloadedDesign THEN ListUnboundsIndirect[design]; DisplayImportFileHints[design]; TerminalIO.PutRope[" --\n"]; }; DescribeUnboundImport: PROC [where: LIST OF CD.Object, design: CD.Design_NIL] = { Desc1: PROC [lst: LIST OF CD.Object] RETURNS [ROPE] = { RETURN [CD.Describe[lst.first, NIL, IF lst.rest=NIL THEN design ELSE NIL]] }; IF where=NIL THEN RETURN; TerminalIO.PutRopes[" **some imported object is not bound: ", Desc1[where]]; FOR lst: LIST OF CD.Object _ where.rest, lst.rest WHILE lst#NIL DO TerminalIO.PutRopes[" accessed through ", Desc1[lst]]; ENDLOOP; TerminalIO.PutRope["\n"]; }; DisplayImportsComm: PROC [comm: CDSequencer.Command] = { CheckObject: CDDirectory.EachObjectProc = { WITH me.specific SELECT FROM ip: CDImports.ImportSpecific => IF cache=NIL OR Rope.Equal[ip.designName, cache.importeeName] THEN { totalCount _ totalCount+1; IF cache#NIL THEN TerminalIO.PutF[" %g ", IO.rope[CD.Describe[me, NIL, design]]]; IF ip.boundOb=NIL THEN { unboundCount _ unboundCount+1; TerminalIO.PutRope[" not bound"]; }; TerminalIO.PutRope["\n"]; }; ENDCASE => NULL }; design: CD.Design _ comm.design; totalCount, unboundCount: INT _ 0; importeeName: ROPE; cache: Cache_NIL; cl: CacheList _ CDImports.GetCacheList[design]; IF cl=NIL OR cl.list=NIL THEN { [] _ CDDirectory.EnumerateDesign[design, CheckObject]; IF totalCount=0 THEN TerminalIO.PutRope["design does not have any imported objects\n"] ELSE { TerminalIO.PutF["design has %g imported objects; ", [integer[totalCount]]]; IF unboundCount#0 THEN TerminalIO.PutF["%g not bound\n", [integer[unboundCount]]] ELSE ListUnboundsIndirect[design] }; RETURN; }; importeeName _ RequestImporteeName[into: design, fastIfNoChoice: TRUE, offerAll: ""]; IF Rope.IsEmpty[importeeName] THEN { TerminalIO.PutRope["no design selected\n"]; RETURN; }; IF Rope.Equal[importeeName, ""] THEN { DisplayCachedDesigns[comm]; RETURN }; cache _ CDImports.GetCache[design, importeeName, false]; TerminalIO.PutRopes["design ", importeeName]; IF cache=NIL THEN {TerminalIO.PutRope[" not cached\n"]; RETURN}; IF cache.importee#NIL THEN TerminalIO.PutRope[" cached\n"] ELSE TerminalIO.PutRope[" not cached\n"]; [] _ CDDirectory.EnumerateDesign[design, CheckObject]; IF totalCount=0 THEN TerminalIO.PutRope[" no objects really used\n"] ELSE { TerminalIO.PutF[" %g objects imported from %g\n", [integer[totalCount]], [rope[importeeName]]]; IF unboundCount#0 THEN TerminalIO.PutF[" %g objects not bound\n", [integer[unboundCount]]] ELSE TerminalIO.PutRope[" (all bound, but indirect imports are not checked)\n"] }; }; SelectedDesign: PROC [] RETURNS [CD.Design] = { WITH CDProperties.GetProp[$SelectedDesign, $SelectedDesign] SELECT FROM d: CD.Design => RETURN [d]; ENDCASE => RETURN [NIL]; }; SelectADesign: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRopes["select ", CD.DesignName[comm.design], " as source-design for the command [drawing imports]\n"]; IF Rope.IsEmpty[comm.design.name] THEN TerminalIO.PutRope[" design has no name; not done\n"] ELSE CDProperties.PutProp[$SelectedDesign, $SelectedDesign, comm.design]; }; InterDesignCopyComm: PROC [comm: CDSequencer.Command] = { inst: CD.Instance; --copy of sourceInst Fail: PROC [r1, r2, r3: ROPE_NIL] = { TerminalIO.PutRope[Rope.Cat[" failed: ", r1, r2, r3, "\n"]]; }; ForwardNormalCopy: PROC [comm: CDSequencer.Command] = { p: CDSequencer.CommandProc _ CDSequencer.FetchCommand[$CopyS].proc; comm.data _ NIL; IF p=NIL THEN Fail["command not available"] ELSE { TerminalIO.PutRope[" forward as simple copy\n"]; CDSequencer.ExecuteProc[p, comm.design, dontQueue, comm]; }; }; IncludeOb: PROC [ob: CD.Object] = { IF ob=NIL THEN Fail["NIL object"] ELSE { [] _ CDOps.IncludeObjectI[design, ob, comm.pos, inst.trans.orient]; TerminalIO.PutRopes[" ", CD.Describe[ob, NIL, design], " included\n"]; }; }; multiple, forceBind: BOOL _ FALSE; design: CD.Design _ comm.design; obName: ROPE; ob: CD.Object; sourceDesign: CD.Design _ NIL; sdName: ROPE; sourceInst: CD.Instance; cache: Cache; TerminalIO.PutRope["interdesign copy\n"]; WITH comm.data SELECT FROM d: CD.Design => sourceDesign _ d; ENDCASE => sourceDesign _ NIL; IF sourceDesign=design THEN {ForwardNormalCopy[comm]; RETURN}; IF sourceDesign=NIL THEN {Fail["source design not found"]; RETURN}; IF sourceDesign.technology#design.technology THEN {Fail["technology missmatch"]; RETURN}; [sourceInst, multiple] _ CDOps.SelectedInstance[sourceDesign]; --asynchronous for source !! IF multiple THEN {Fail["multiple selection in source design"]; RETURN}; IF sourceInst=NIL THEN {Fail["no selection in source design"]; RETURN}; inst _ CDInstances.Copy[sourceInst]; --because of asynchronity problem IF inst.ob=NIL THEN {Fail["asynchronity problem"]; RETURN}; IF ~inst.ob.class.composed OR inst.ob.immutable THEN {IncludeOb[inst.ob]; RETURN}; IF ~CDDirectory.IsIncluded[sourceDesign, inst.ob] THEN { ob _ CDDirectory.AnotherRecursed[me: inst.ob, into: design, fromOrNil: sourceDesign]; IF ob#NIL THEN IncludeOb[ob] ELSE Fail["object is not included in directory"]; RETURN; }; obName _ CDDirectory.Name[inst.ob, sourceDesign]; sdName _ sourceDesign.name; IF Rope.IsEmpty[obName] THEN {Fail["object not named"]; RETURN}; IF Rope.IsEmpty[sdName] THEN {Fail["can not cache from un-named design"]; RETURN}; IF Rope.Equal[sdName, design.name] THEN { ob _ CDDirectory.Fetch[design, obName].object; IF ob#NIL THEN TerminalIO.PutRope[" design names match; use object with same name\n"] ELSE ob _ CDDirectory.AnotherRecursed[me: inst.ob, into: design, fromOrNil: sourceDesign]; IF ob#NIL THEN IncludeOb[ob] ELSE Fail["object ", obName, " not found in directory"]; RETURN }; IF CDImports.IsImport[inst.ob] THEN { --don't make indirect imports ip: CDImports.ImportSpecific _ NARROW[inst.ob.specific]; ob _ CDDirectory.AnotherRecursed[me: inst.ob, into: design, fromOrNil: sourceDesign]; IF ob#NIL THEN {IncludeOb[ob]; RETURN} }; cache _ CDImports.GetCache[into: design, importeeName: sdName]; IF cache#NIL AND cache.importee#NIL THEN { IF sourceDesign.edited THEN TerminalIO.PutRope[" use already imported design; ignores edits\n"] ELSE TerminalIO.PutRope[" use already imported design\n"] } ELSE { question: ROPE _ Rope.Concat["import design ", sdName]; Process.PauseMsec[300]; IF sourceDesign.edited THEN question _ Rope.Concat[question, " (edits are ignored)"]; IF ~TerminalIO.Confirm[question] THEN {Fail["gives up"]; RETURN}; }; cache _ LoadAndGetCache[into: design, importeeName: sdName, allwaysNewFile: FALSE, forceBind: forceBind].cache; IF cache=NIL OR cache.importee=NIL THEN {Fail[sdName, " not loaded"]; RETURN}; ob _ CDImports.CreateImportFromCache[into: design, objectName: obName, importeeName: sdName]; IF ob=NIL THEN Fail[obName, " not found"] ELSE IncludeOb[ob]; }; MerginImportCommand: PROC [comm: CDSequencer.Command] = { importeeName: ROPE; cache: Cache; TerminalIO.PutRope["make imports resident [merge in]\n"]; IF ~HasCachedImports[comm.design] THEN { TerminalIO.PutRope["design has no cached imports\n"]; }; Process.PauseMsec[200]; --flush for sure!? importeeName _ RequestImporteeName[into: comm.design, fastIfNoChoice: TRUE]; IF Rope.IsEmpty[importeeName] THEN { TerminalIO.PutRope["no imported design specified\n"]; RETURN }; cache _ CDImports.GetCache[comm.design, importeeName, false]; IF cache=NIL THEN { TerminalIO.PutRopes[importeeName, " not cached; not done\n"]; RETURN } ELSE IF cache.importee=NIL THEN { TerminalIO.PutRopes[importeeName, " no design in cache yet\n"]; IF LoadAndGetCache[comm.design, importeeName].cache=NIL THEN RETURN; IF cache.importee=NIL THEN RETURN; }; CDImports.MergeInImports[into: comm.design, importeeName: importeeName]; TerminalIO.PutRope["end merge\n"]; }; UndoMergeInComm: PROC [comm: CDSequencer.Command] = { replaceList: RefTab.Ref _ RefTab.Create[]; FindObjects: CDDirectory.EachObjectProc = { WITH CDProperties.GetObjectProp[me, $CameFrom] SELECT FROM r: ROPE => [] _ RefTab.Insert[replaceList, me, CDProperties.GetObjectProp[me, $OriginalName]]; ENDCASE => NULL }; ReplaceObjects: RefTab.EachPairAction = { quit _ FALSE; WITH val SELECT FROM r: ROPE => { ob: CD.Object _ NARROW[key]; oldName: ROPE _ CDDirectory.Name[ob, design]; new: CD.Object _ CDImports.CreateImportFromCache[into: design, objectName: r, importeeName: cache.importeeName]; IF new#NIL THEN { msg: ROPE; oldRope: ROPE _ CD.Describe[ob, NIL, design, 0]; CDDirectory.ReplaceObject[design, ob, new]; IF oldName#NIL THEN [] _ CDDirectory.Remove[design, oldName, ob]; msg _ IF new.bbox=ob.bbox AND CD.InterestRect[new]=CD.InterestRect[ob] THEN "replaced" ELSE "replaced (size conflict)"; TerminalIO.PutF[" for %g: %g %g by %g\n", IO.rope[r], IO.rope[msg], IO.rope[oldRope], IO.rope[CD.Describe[new, NIL, design, 0]] ]; }; CDSequencer.CheckAborted[design]; }; ENDCASE => NULL }; cache: Cache; design: CD.Design _ comm.design; TerminalIO.PutRope["replace resident objects by imports where possible\n"]; cache _ LoadAndGetCache[comm.design].cache; IF cache=NIL THEN {TerminalIO.PutRope[" not loaded\n"]; RETURN}; [] _ CDDirectory.EnumerateDesign[design, FindObjects]; [] _ RefTab.Pairs[replaceList, ReplaceObjects]; TerminalIO.PutRope[" --\n"]; }; IncludeComm: PROC [comm: CDSequencer.Command] = { MergeIn: PROC [design: CD.Design, from: CD.Design, name: Rope.ROPE_NIL] RETURNS [dummyOb: CD.Object_NIL] = { recursiveImports: LIST OF CD.Object _ NIL; SkipAt: PROC [n: Rope.ROPE] RETURNS [Rope.ROPE] = { RETURN [Rope.Substr[base: n, len: Rope.SkipTo[s: n, skip: "@"]]] }; ChangeOwnerShip: CDDirectory.EachObjectProc = { CDDirectory.SetOwner[design, me, FALSE]; CDProperties.PutObjectProp[me, $CameFrom, from.name]; WITH me.specific SELECT FROM ip: CDImports.ImportSpecific => IF Rope.Equal[ip.designName, design.name] THEN recursiveImports _ CONS[me, recursiveImports]; ENDCASE => NULL; }; IncludeOneEntry: CDDirectory.EachEntryAction = { name _ SkipAt[name]; [] _ CDDirectory.Include[design: design, object: ob, name: name]; CDProperties.PutObjectProp[ob, $OriginalName, name]; }; ReplaceRecursiveImports: PROC [] = { FOR obl: LIST OF CD.Object _ recursiveImports, obl.rest WHILE obl#NIL DO WITH obl.first.specific SELECT FROM ip: CDImports.ImportSpecific => { original: CD.Object _ CDDirectory.Fetch[design, ip.objectName]; IF original#NIL THEN CDDirectory.ReplaceObject[design: design, old: obl.first, new: original]; }; ENDCASE => NULL; ENDLOOP; }; inst: CD.Instance; IF design=from THEN RETURN; IF design.technology#from.technology THEN RETURN WITH ERROR CD.Error[calling, "technology missmatch"]; IF from.mutability#findOut THEN RETURN WITH ERROR CD.Error[calling, "wrong mutability"]; CDSequencer.MarkChangedIOOnly[design]; inst _ CDCellsInteractions.MakeTopInstance[from]; IF inst#NIL THEN dummyOb _ inst.ob; [] _ CDDirectory.EnumerateDesign[design: from, proc: ChangeOwnerShip, dir: TRUE, top: TRUE, recurse: TRUE, dummy: TRUE]; [] _ CDDirectory.Enumerate[design: from, action: IncludeOneEntry]; ReplaceRecursiveImports[]; CDOps.ResetDesign[from]; from.mutability _ inaccessible; }; Check: PROC [h: TokenIO.Handle] RETURNS [ok: BOOL] = { design: CD.Design _ CDIO.DesignInReadOperation[h]; ok _ design.technology=comm.design.technology; IF NOT ok THEN TerminalIO.PutRopes["technology miss-match: includee is ", design.technology.name, "\n"]; }; done: BOOL _ FALSE; design: CD.Design; ob: CD.Object; srcDesign: Rope.ROPE _ WITH comm.data SELECT FROM r: Rope.ROPE => r, ENDCASE => NIL; TerminalIO.PutRope["include resident copy of input design; \n"]; design _ CDIO.ReadDesign [srcDesign, Check, CDEnvironment.GetWorkingDirectory[comm.design]]; IF design#NIL THEN { [ob] _ MergeIn[design: comm.design, from: design]; IF ob#NIL THEN {[] _ CDOps.PlaceInst[comm.design, ob, comm]; done _ TRUE}; }; IF done THEN TerminalIO.PutRope["include done\n"] ELSE TerminalIO.PutRope["include not done\n"]; }; [] _ CDProperties.RegisterProperty[$SelectedDesign, $chj]; [] _ CDProperties.RegisterProperty[$ImportHints, $chj]; CDSequencer.ImplementCommand[$DrawImported, DrawImportByNameComm]; CDSequencer.ImplementCommand[$DisplayImportedEntries, DisplayImportsComm,, doQueue]; CDSequencer.ImplementCommand[$ImportADesign, ImportReadCommand]; CDSequencer.ImplementCommand[$SelectADesign, SelectADesign,, doQueue]; CDSequencer.ImplementCommand[$MerginImport, MerginImportCommand]; CDSequencer.ImplementCommand[$UnqueuedLoadAllImps, BindAllComm,, dontQueue]; CDSequencer.ImplementCommand[$ReplaceByImp, UndoMergeInComm]; CDSequencer.ImplementCommand[$ImportDefaultName, ChangeImportFileHintComm]; CDSequencer.ImplementCommand[$UnqueuedCopyInterDesign, InterDesignCopyComm]; CDSequencer.ImplementCommand[$IncludeADesign, IncludeComm,, doQueueAndMark]; END. \CDImportCommands.mesa (part of ChipNDale) Copyright c 1984, 1987, 1988 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, March 20, 1984 5:50:51 pm PST Last edited by: Christian Jacobi, February 26, 1988 1:45:09 pm PST Don Curry February 18, 1988 4:47:15 pm PST --requests a design name for imports into "into" --restrictedToCaches: -- FALSE => user may type any name; the name of the selected design is included in list -- TRUE => only designs having a cache entry in into are allowed --fastIfNoChoice: -- FALSE => user sees always an interactive selection querry -- TRUE => if only a single option exists it is returned without bothering user --offerAll: offers to say offerAll if there is more than one cached import --deal with selected design --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --xx binding --hack, called from io commands --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --xx simple imports --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --xx default files [hint files] offered to be used --A future import of design imp into for offers the use of file file --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --xx lists for feedback --returns SymTab with names of imported designs as keys --recursively because of indirect imports --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --xx inter design copies --Try atomic objects --Object is mutable --Object is in directory --Designs have equal names; try matching objects from directory first --Designs have different names; try imports --already imported design --wow!, here 2 design viewers, the terminal and pop up menus will be involved... --this pause might help to prevent some kind of viewer wedges CDSequencer.ImplementCommand[$DrawCorrespondingObject, DrawImportedCopy]; DrawImportedCopy: PROC [comm: CDSequencer.Command] = { GlobalSelection: PROC [expectedTechnology: CD.Technology] RETURNS [foundNamed: BOOL_FALSE, foundWithoutChildren: BOOL_FALSE, moduleName: ROPE_NIL, objectName: ROPE_NIL, object: CD.Object_NIL, orient: CD.Orientation_CD.Orientation[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 Out: PROC [t: ROPE] = { TerminalIO.PutRope[t] }; from: CD.Design = SelectedDesign[]; -- so it does not change IF from=NIL THEN Out[" no selected design"] ELSE { fromName: 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 { inst: CD.Instance; -- the referred instance to support the name multiple: BOOL; [inst, multiple] _ CDOps.SelectedInstance[from]; IF multiple THEN Out[" multiple selection"] ELSE IF inst=NIL THEN Out[" no selection"] ELSE { orient _ inst.trans.orient; IF ~inst.ob.class.composed THEN { object _ inst.ob; foundWithoutChildren _ TRUE; } ELSE { entryName: ROPE = CDDirectory.Name[inst.ob, from]; IF Rope.IsEmpty[entryName] THEN Out[" object has no name"] ELSE { moduleName _ fromName; objectName _ entryName; foundNamed _ TRUE; } } } } } }; foundNamed, foundWithoutChildren: BOOL; moduleName, objectName: ROPE; referenceOb, referedOb: CD.Object _ NIL; orient: CD.Orientation; TerminalIO.PutRope["draw corresponding object (import); "]; [foundNamed: foundNamed, foundWithoutChildren: foundWithoutChildren, moduleName: moduleName, objectName: objectName, object: referedOb, orient: orient] _ GlobalSelection[comm.design.technology]; IF foundWithoutChildren THEN referenceOb _ referedOb ELSE IF foundNamed THEN { IF Rope.Equal[moduleName, comm.design.name] THEN { TerminalIO.PutRopes[moduleName, " is selected design; simply copy object\n"]; referenceOb _ CDDirectory.Fetch[comm.design, objectName].object; } ELSE { cache: Cache _ LoadAndGetCache[comm.design, moduleName].cache; IF cache#NIL AND cache.importee#NIL THEN { referenceOb _ CDImports.CreateImportFromCache[into: comm.design, objectName: objectName, importeeName: moduleName]; IF referenceOb=NIL THEN TerminalIO.PutF[" %g not found in imported design %g; ", IO.rope[objectName], IO.rope[moduleName]]; } } }; IF referenceOb=NIL THEN TerminalIO.PutRope[" not done\n"] ELSE { [] _ CDOps.IncludeObjectI[comm.design, referenceOb, comm.pos, orient]; TerminalIO.PutRopes[CD.Describe[referenceOb], " included\n"]; } }; --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --xx Merge and Un-Merge --uses global replaceList --putting the objectnames in the RefTab keeps them even if replacement is in wrong order --uses globals cache --DANGEROUS PROC --"from" is transfered to an object, and is included (transitive) to "design"'s directory --Warning: This procedure destroys "from" --The caller is assumed to have the locks of both designs --if "from" is pushed in, it's merged copy will be popped out, either by flushing, --replacing or creating new cells --"name" replaces "from"'s design name for the new created object, but it is a hint only --the "from"'s object's may change name to avoid conflicts with "design"'s directory --dummyOb gets nil if "from" 's top level is empty --technologies must be compatible --skip everything after and inclusive first "@" ΚC˜codešœ+™+Kšœ Οmœ=™HKšœ;™;K™BK™*K˜—šΟk ˜ Kšžœ˜K˜K˜K˜K˜ Kšœ ˜ Kšœ ž˜ Kšœ˜Kšœ˜Kšœ˜K˜ Kšœ ˜ Kšžœ˜Kšœžœ ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜—K˜šΟnœžœžœ˜ KšžœžœXžœ9žœ+˜ΙKšžœ˜—Kšž˜K˜Kšžœžœžœ˜Kšœžœ˜1Kšœ žœ˜&Kšœžœ˜,Kšœžœ˜Kšœ žœ˜&K˜šŸœžœžœ žœžœžœΟcœ˜JKšœ;˜;Kšžœ žœžœ žœ˜#Kšœ˜—K˜šŸœžœžœžœžœžœžœžœ œ˜[KšŸœ"žœ ˜7Kšœ˜K˜—K˜šŸœžœžœžœžœžœžœ žœžœžœžœžœ˜ŸKš 0™0Kš ™Kš Y™YKš B™BKš ™Kš >™>Kš Q™QKš J™JKšœ žœžœžœ˜Kšœ0˜0Kš ™šžœžœ˜Kšœžœžœ˜Kšœžœ˜ Kšžœžœžœ˜šžœžœžœ˜=Kšœ'˜'—Kšœ˜—Kšœ'˜'šžœžœ žœžœ˜5Kšœžœ˜*K˜—šžœžœžœžœ˜MKšžœžœžœ˜:K˜—Kšœ[˜[Kšœ˜—K˜šŸœžœžœžœžœžœžœ žœžœ žœžœžœžœžœžœ˜½Kšœ žœžœ˜Kšœžœ˜ Kšœžœžœ˜Kšœžœžœ˜šžœžœ˜#Kš œCžœžœ žœ žœžœžœ˜—šžœžœ˜$Kšœ3ž˜9K˜—šžœ2žœ˜:Kšœ˜Kšœ˜Kšžœžœžœ˜K˜—šžœ%žœ˜-Kšœ7ž˜=K˜—KšœC˜Cš žœžœžœžœžœžœ˜;Kšœ žœ,˜Kš œžœžœžœžœ˜ Kšžœžœ˜——K˜—K˜šŸœžœžœžœ˜@KšœE™EšŸœžœžœžœžœžœžœžœžœžœžœ˜Lš žœžœžœžœžœžœž˜8Kšžœ;žœžœ˜YKšžœ˜—K˜—Kšœžœžœžœ˜+Kšœ˜Kšœ(˜(Kšžœžœžœžœ ˜:Kšœ2˜2Kšœ˜—K˜šŸœžœ ˜>Kšœžœ˜KšœL˜LKšœJžœžœ žœ˜wKšžœžœ(˜Jšžœ˜Kšœ2˜2Kšœ:˜:Kšœ˜K˜—Kšœ˜—K™Kšœ"™"Kšœ™K˜šŸœžœ žœ žœ˜MKš  œ '™7Kš )™)šŸœžœžœ ˜!šžœžœ˜&š žœžœžœ6žœžœž˜RKšœ ˜ Kšœ2˜2Kšžœžœ8˜Qšžœ˜Kšœžœ9˜?Kšžœžœžœ8˜FKšžœ˜K˜—Kšžœ˜ —K˜—K˜—Kšœ&˜&Kšœ˜Kšœ˜Kšœ˜—K˜šŸœžœ žœ ˜2Jšœžœžœžœ5˜FJšžœžœžœ˜.KšžœE˜IK˜—K˜šŸœžœ ˜:šŸœ˜#Kšœ9˜9Kš œžœ žœžœžœ˜0Kšœžœ˜Kšžœ žœžœ˜)Kšœ!žœžœžœ˜WJšžœžœ˜J˜—šŸœžœžœ ˜1Kšœžœžœžœ˜+šžœžœžœ˜Kšœ žœžœ˜Kšœ@˜@š žœžœžœžœžœžœž˜8Kšœ2˜2Kšœ(˜(Kšœ(˜(Kšœ-˜-Kšžœ˜—K˜—Kšœ˜—Kšœžœ˜ Kšœžœžœ˜ Kšœžœžœ˜Kšœžœ,˜BJšœ9˜9Kšžœžœ=˜RKšžœžœ˜8Kšœ˜Kšœ˜Kšœ˜K˜—šŸœžœ žœžœžœžœžœ˜QšŸœžœžœžœžœ žœžœ˜7Jšžœžœžœžœ žœžœžœžœ˜JJšœ˜—Jšžœžœžœžœ˜KšœN˜Nš žœžœžœžœžœžœž˜BJšœ6˜6Jšžœ˜—Kšœ˜J˜—K™šŸœžœ ˜8K˜š‘ œ ˜+šžœ žœžœ˜š œ žœžœžœ/žœ˜dKšœ˜Kš žœžœžœžœžœžœ ˜Sšžœ žœžœ˜Kšœ˜Kšœ!˜!K˜—Kšœ˜K˜—Kšžœž˜—Kšœ˜K˜—Kšœ ˜ Kšœžœžœžœ˜IKšœ/˜/š žœžœžœ žœžœ˜Kšœ6˜6KšžœžœB˜Všžœ˜KšœK˜Kšžœ˜Kšžœ;˜?Kšžœ˜!—K˜—Kšžœ˜K˜—KšœAžœ%˜jšžœžœ˜$Kšœ,žœ˜3K˜—šžœ3žœ˜;Kšœž˜"K˜—Kšœ8˜8Kšœ-˜-Kšžœžœžœ'žœ˜@šžœžœ˜Kšžœ!˜%Kšžœ%˜)—Kšœ6˜6Kšžœžœ2˜Fšžœ˜Kšœa˜ašžœ˜KšžœF˜JKšžœM˜Q—K˜—Kšœ˜K˜—K™Kšœ"™"Kšœ™K™šŸœžœžœžœ ˜/šžœ8žœž˜GKšœžœ žœ˜Kšžœžœžœ˜—Kšœ˜—K˜šŸ œžœ ˜3Kšœ˜šžœ žœ˜'Kšœ6˜6—šž˜KšœD˜D—Kšœ˜—K™šŸœžœ ˜9Kšœžœ  ˜'šŸœžœžœ˜%Kšœ>˜>K˜—šŸœžœ ˜7JšœC˜CKšœ žœ˜Kšžœžœžœ˜+šžœ˜Kšœ2˜2Kšœ9˜9K˜—K˜—šŸ œžœžœ ˜#Kšžœžœžœ˜!šžœ˜KšœC˜CKšœžœžœ˜GK˜—K˜—Kšœžœžœ˜#Kšœžœ)žœ˜=Kšœžœ žœžœ ˜EKšœ ˜ Kšœ*˜*šžœ žœž˜Kšœžœ˜!Kšžœžœ˜—Kšžœžœžœ˜>Kšžœžœžœ#žœ˜CKšžœ+žœ žœ˜YKšœ? ˜\Kšžœ žœ/žœ˜GKšžœ žœžœ)žœ˜GKšœ% !˜FKšžœ žœžœ žœ˜;KšŸ™Kšžœžœžœžœ˜RKšŸ™šžœ0žœ˜8KšœV˜Všžœžœ˜ Kšžœ˜Kšžœ.˜2—Kšžœ˜K˜—KšŸ™Kšœ1˜1Kšœ˜Kšžœžœžœ˜@Kšžœžœ.žœ˜Ršžœ!žœ˜)Kš E™EKšœ.˜.šžœžœ˜ KšžœH˜LKšžœV˜Z—šžœžœ˜ Kšžœ˜Kšžœ4˜8—Kšž˜K˜—KšŸ+™+šžœžœ ˜CKšœžœ˜8KšœV˜VKšžœžœžœžœ˜&K˜—Kšœ?˜?š žœžœžœžœžœ˜*Kš ™šžœ˜KšžœE˜IJšžœ6˜:—K˜—šžœ˜Kšœ žœ)˜7šœ˜Kš P™PKš >™>—Kšžœžœ:˜UKšžœžœžœ˜AK˜—KšœLžœ˜oKš žœžœžœžœžœžœ˜NKšœ]˜]šžœžœ˜ Kšžœ˜Kšžœ˜—Kšœ˜—K™K™KšœI™IšŸœžœ!™7K™š Ÿœžœžœ žœžœžœžœžœžœžœžœžœ žœžœ žœ žœ™τKšœI™IKšœ)™)Kšœ7™7šŸœžœžœ™Kšœ™Kšœ™—Kšœžœ ™=Kšžœžœžœ™,šžœ™Kšœ žœ ™5Kšžœžœ%™Cš žœžœ$žœžœž™JKšœ™—šžœ™Kšœžœ  ,™@Kšœ žœ™Kšœ0™0Kšžœ žœ™.Kšžœžœžœžœ™-šžœ™Kšœ™šžœžœžœ™!Kšœ™Kšœžœ™Kšœ™—šžœ™Kšœ žœ#™2Kšžœžœ™<šžœ™Kšœ™Kšœ™Kšœ žœ™K™—K™—K™—K™—K™—Kšœ™—K™Kšœ"žœ™'Kšœžœ™Kšœžœ žœ™(Kšœžœ ™Kšœ<™™>š žœžœžœžœžœ™*Kšœs™sKš žœ žœžœ;žœžœ™|K™—K™—Kšœ™—Kšžœ žœžœ"™9šžœ™KšœF™FKšœžœ'™=K™—Kšœ™—K™Kšœ"™"Kšœ™K˜šŸœžœ ˜9Kšœžœ˜!Kšœ9˜9šžœ žœ˜(Kšœ6˜6K˜—Kšœ ˜*KšœFžœ˜Lšžœžœ˜$Kšœ6ž˜ž˜DK˜—šžœžœžœžœ˜!Kšœ?˜?Kšžœ2žœžœžœ˜DKšžœžœžœžœ˜"K˜—KšœH˜HKšœ"˜"Kšœ˜—K˜šŸœžœ ˜5Kšœ+˜+K˜š‘ œ ˜+Kšœ™šžœ+žœž˜:KšœX™Xšœžœ˜ KšœS˜S—Kšžœž˜—Kšœ˜K˜—š‘œ˜)Kšœ™Kšœžœ˜ šžœžœž˜šœžœ˜ Kšœžœ žœ˜Kšœ žœ ˜-Kšœžœj˜qšžœžœžœ˜Kšœžœ˜ Kšœ ž œžœ ˜0Kšœ+˜+Kšžœ žœžœ.˜Aš œžœžœžœžœ˜GKšžœ ˜Kšžœ˜ —šœ*˜*Kšžœ ˜ Kšžœ ˜Kšžœ˜Kšžœžœžœ ˜)Kšœ˜—K˜—Kšœ!˜!Kšœ˜—Kšžœž˜—Kšœ˜—K˜Kšœ˜Kšœžœ˜ KšœK˜KKšœ+˜+Kšžœžœžœ(žœ˜AKšœ6˜6Kšœ/˜/Kšœ˜Kšœ˜—K˜šŸ œžœ ˜1šŸœžœ žœžœžœžœžœ žœžœ˜lKšœ™KšœY™YKšœ*™*Kšœ9™9KšœS™SKšœ!™!KšœX™XKšœT™TKšœ2™2Kšœ!™!Kš œžœžœžœ žœ˜*š Ÿœžœ žœžœžœ˜3Kšœ/™/Kšžœ:˜@Kšœ˜—šŸœ ˜/Kšœ!žœ˜(Kšœ5˜5šžœ žœž˜šœ ˜ šžœ(ž˜.Kšœžœ˜.——Kšžœžœ˜—Kšœ˜—š‘œ!˜0Kšœ˜KšœA˜AKšœ4˜4Kšœ˜—šŸœžœ˜$š žœžœžœžœ%žœžœž˜Hšžœžœž˜#šœ!˜!Kšœ žœ3˜?šžœ žœžœ˜KšœI˜I—K˜—Kšžœžœ˜—Kšžœ˜—K˜—Kšœžœ ˜Kšžœ žœžœ˜šžœ#žœ˜*Kšžœžœžœžœ(˜<—šžœžœ˜ Kšžœžœžœžœ$˜8—Kšœ&˜&Kšœ1˜1Jšžœžœžœ˜#Kš œKžœžœ žœ žœ˜xKšœB˜BKšœ˜Kšœ˜Kšœ˜Kšœ˜—šŸœžœžœžœ˜6Kšœžœ žœ˜2Kšœ.˜.šžœžœžœ˜KšœY˜Y—Kšœ˜—Kšœžœžœ˜Kšœžœ˜!šœžœ˜šžœ žœž˜Kšœžœ˜Kšžœžœ˜——Kšœ@˜@šœ žœ ˜KšœC˜C—šžœžœžœ˜Kšœ2˜2Kšžœžœžœ6žœ˜JK˜—šžœ˜Kšžœ%ž˜*Kšžœ*˜.—Kšœ˜—K˜Kšœ:˜:Kšœ7˜7KšœB˜BKšœT˜TKšœ@˜@KšœF˜FKšœA˜AKšœL˜LKšœ=˜=KšœK˜KKšœL˜LKšœL˜LKšžœ˜K˜—…—Rπƒ