<> <> <> <> DIRECTORY CD, CDEnvironment, CDDirectory, CDGenerate, CDGenerateImports, CDImports, CDImportsBackdoor, CDInstances, CDIO, CDMenuSpecials, CDOps, CDProperties, CDRemote, CDSequencer, IO, Process, RefTab, Rope, SymTab, TerminalIO, TokenIO; CDImportCommands: CEDAR PROGRAM IMPORTS CD, CDDirectory, CDEnvironment, CDGenerate, CDGenerateImports, CDImports, CDImportsBackdoor, CDInstances, CDIO, CDMenuSpecials, CDOps, CDProperties, CDRemote, CDSequencer, IO, Process, RefTab, Rope, SymTab, TerminalIO SHARES CDRemote = BEGIN ROPE: TYPE = Rope.ROPE; ImportSpecific: TYPE = CDImports.ImportSpecific; ImportRep: TYPE = CDImports.ImportRep; ImportListRec: TYPE = CDImports.ImportListRec; ImportEntry: TYPE = CDImports.ImportEntry; HasImports: PROC [into: CD.Design] RETURNS [BOOL] = { il: CDImports.ImportList _ CDImports.GetImportList[into]; RETURN [il#NIL AND il^#NIL] }; RequestImporteeName: PROC [into: CD.Design, restricted: BOOL_TRUE, immediateSingle: BOOL_FALSE] RETURNS [importeeName: ROPE_NIL] = { <<--requests a design name for imports into "into">> <<--restricted: >> <<-- FALSE => user may type any name; the name of the selected design is included in list>> <<-- TRUE => only designs in into's import list are allowed>> <<--immediateSingle: >> <<-- FALSE => user sees always a selection>> <<-- TRUE => if only a single option exists it is returned without bothering user>> options: SymTab.Ref _ FindAllImports[into]; <<--deal with selected design>> IF ~restricted THEN { name: Rope.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] }; IF immediateSingle AND restricted AND SymTab.GetSize[options]=1 THEN { Check: SymTab.EachPairAction = { importeeName _ key; RETURN [TRUE] }; IF ~Rope.IsEmpty[importeeName] THEN RETURN [importeeName]; }; importeeName _ CDMenuSpecials.SelectOneOf[options, "DESIGN name", ~restricted]; }; OptionalLoad: PROC [into: CD.Design, importeeName: ROPE_NIL, allways: BOOL_FALSE, howOverload: CDImports.BoolOrInteractive _ interactive] RETURNS [import: ImportEntry_NIL] = { checkCalled: BOOL _ FALSE; Check: PROC [h: TokenIO.Handle] RETURNS [ok: BOOL] = { design: CD.Design _ CDIO.DesignInReadOperation[h]; n: ROPE; checkCalled _ TRUE; IF NOT design.technology=into.technology THEN { TerminalIO.PutRopes["technology missmatch: includee is ", design.technology.name, "\n"]; RETURN [ok_FALSE] }; IF Rope.IsEmpty[design.name] THEN { TerminalIO.PutRope["design has no name\n"]; RETURN [ok_FALSE] }; IF Rope.Equal[into.name, design.name] THEN { TerminalIO.PutRope["can't be imported, it would cause circularity\n"]; RETURN [ok_FALSE] }; IF ~Rope.Equal[importeeName, design.name] THEN { TerminalIO.PutRopes["file has different design: name = ", n, "\n"]; RETURN [ok_FALSE] }; RETURN [ok_TRUE] }; r, nameX, name1, name2: ROPE; design: CD.Design_NIL; loaded: BOOL_FALSE; IF Rope.IsEmpty[importeeName] THEN importeeName _ RequestImporteeName[into: into, restricted: FALSE, immediateSingle: FALSE]; IF Rope.IsEmpty[importeeName] THEN { TerminalIO.PutRopes["no design specified\n"]; RETURN }; IF Rope.Equal[importeeName, into.name] THEN { TerminalIO.PutRopes["a design can't import itself\n"]; RETURN }; import _ CDImports.GetImportEntry[into: into, importeeName: importeeName]; IF import=NIL OR ~import.loaded OR allways THEN { menuHeader: ROPE _ Rope.Cat["FILE name for ", importeeName]; menuChoice: LIST OF ROPE _ LIST[importeeName]; IF import#NIL AND import.loaded THEN TerminalIO.PutRopes["reload design ", importeeName, "\n"]; nameX _ CDRemote.MakupName[into, importeeName]; IF ~Rope.IsEmpty[nameX] THEN menuChoice _ CONS[nameX, menuChoice]; r _ CDMenuSpecials.SelectOneOf[menuChoice, menuHeader, TRUE]; IF Rope.IsEmpty[r] THEN {TerminalIO.PutRope["discarded\n"]; RETURN}; name1 _ CDIO.MakeName[base: r, wDir: CDIO.GetWorkingDirectory[into]]; design _ CDIO.ReadDesign[name1, Check]; IF design=NIL THEN { name2 _ CDIO.MakeName[base: r, wDir: CDIO.GetWorkingDirectory[NIL]]; IF ~Rope.Equal[name1, name2, FALSE] AND ~checkCalled THEN design _ CDIO.ReadDesign[name2, Check]; }; IF design=NIL THEN RETURN; CDRemote.CacheDesign[into, design]; loaded _ CDImportsBackdoor.LoadDesign[into: into, importeeName: importeeName, overload: howOverload, allowConflicts: interactive, useCache: TRUE]; IF loaded THEN RETURN [CDImports.GetImportEntry[into: into, importeeName: importeeName]] }; }; GetImportedEntryCommand: PROC [comm: CDSequencer.Command] = { objectName: ROPE; referenceOb: CD.Object; import: ImportEntry; TerminalIO.PutRope["draw object of imported design; "]; import _ OptionalLoad[comm.design]; IF import=NIL OR ~import.loaded THEN RETURN; objectName _ TerminalIO.RequestRope["object > "]; referenceOb _ CDImports.CreateImport[into: comm.design, objectName: objectName, importeeName: import.importeeName]; IF referenceOb=NIL THEN { TerminalIO.PutRopes[objectName, " not found in design ", import.importeeName]; TerminalIO.PutRope["; not done\n"]; RETURN }; CDOps.IncludeObjectI[design: comm.design, ob: referenceOb, location: comm.pos]; }; <<--============================================================>> GetHintList: 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; }; DisplayFiles: PROC [for: CD.Design] = { rl: LIST OF ROPE _ GetHintList[for]; IF rl#NIL THEN { key, rest: ROPE _ NIL; TerminalIO.PutRopes["file names 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; TerminalIO.PutRope[" --\n"]; }; }; 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; }; ChangeDefaultFileName: PROC [for: CD.Design, imp, file: ROPE] = { rl: LIST OF ROPE _ GetHintList[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]; }; ChangeDefaultFileNameComm: PROC [comm: CDSequencer.Command] = { importeeName, fileName: ROPE; TerminalIO.PutRope["set default file for import\n"]; importeeName _ RequestImporteeName[into: comm.design, restricted: FALSE, immediateSingle: FALSE]; IF Rope.IsEmpty[importeeName] THEN TerminalIO.PutRope["no input design\n"] ELSE { fileName _ TerminalIO.RequestRope["FILE name > "]; ChangeDefaultFileName[comm.design, importeeName, fileName]; TerminalIO.PutRope[" ok\n"]; } }; <<>> <<--============================================================>> FindAllImports: PROC [design: CD.Design] RETURNS [dList: SymTab.Ref] = { <<--returns symtab with names of imported designs as keys>> <<--recursively because of indirect imports>> Check: PROC [d: CD.Design] = { IF RefTab.Insert[checked, d, d] THEN { FOR l: LIST OF CDImports.ImportEntry _ CDImports.GetImportList[d]^, l.rest WHILE l#NIL DO this: CDImports.ImportEntry _ l.first; [] _ SymTab.Insert[dList, this.importeeName, $ok]; IF ~this.loaded THEN [] _ SymTab.Store[dList, this.importeeName, $notLoaded] ELSE { dd: CD.Design _ CDRemote.FetchDesign[design, this.importeeName]; IF dd=NIL THEN [] _ SymTab.Store[dList, this.importeeName, $notLoaded] ELSE Check[dd]; }; ENDLOOP; }; }; checked: RefTab.Ref _ RefTab.Create[]; dList _ SymTab.Create[]; Check[design]; }; DisplayImports: PROC [comm: CDSequencer.Command] = { ListEach: SymTab.EachPairAction = { hasImpDesign _ TRUE; IF val=$notLoaded THEN hasUnloadedDesign _ TRUE; TerminalIO.PutRopes[" ", key, (IF val=$notLoaded THEN " -\n" ELSE " +\n")]; RETURN [FALSE] }; design: CD.Design _ comm.design; hasUnloadedDesign: BOOL _ FALSE; hasImpDesign: BOOL _ FALSE; TerminalIO.PutRopes[design.name, "'s import list: \n"]; [] _ SymTab.Pairs[FindAllImports[design], ListEach]; IF ~hasImpDesign THEN TerminalIO.PutRope[" has no imports\n"]; TerminalIO.PutRope[" --\n"]; DisplayFiles[design]; IF hasImpDesign AND ~hasUnloadedDesign AND CDImports.HasUnloadedImports[design] THEN TerminalIO.PutRope[" **some imported design has unloaded object(s)\n"]; }; <<>> DisplayImportedEntries: PROC [comm: CDSequencer.Command] = { totalCount, unboundCount: INT _ 0; importeeName: ROPE; mdata: ImportEntry; TerminalIO.PutRope["display used entries of imported design\n"]; IF ~HasImports[comm.design] THEN CDSequencer.Quit["no design imported"]; importeeName _ RequestImporteeName[into: comm.design, immediateSingle: TRUE]; IF Rope.IsEmpty[importeeName] THEN CDSequencer.Quit["no design selected"]; mdata _ CDImports.GetImportEntry[comm.design, importeeName, false]; TerminalIO.PutRope[importeeName]; IF mdata=NIL THEN CDSequencer.Quit[" not imported"] ELSE { EachObject: CDDirectory.EachEntryAction = { WITH ob.specific SELECT FROM ip: CDImports.ImportSpecific => IF Rope.Equal[ip.designName, mdata.importeeName] THEN { totalCount _ totalCount+1; TerminalIO.PutF[" %g (%g)", IO.rope[name], IO.rope[ip.objectName]]; IF ip.boundInstance=NIL THEN { unboundCount _ unboundCount+1; TerminalIO.PutRope[" not loaded"]; }; TerminalIO.PutRope["\n"]; }; ENDCASE => NULL }; IF mdata.loaded THEN TerminalIO.PutRope[" loaded\n"] ELSE TerminalIO.PutRope[" not yet loaded\n"]; [] _ CDDirectory.Enumerate[comm.design, EachObject]; IF totalCount=0 THEN TerminalIO.PutRope["--- \n import not used anymore\n"] ELSE { TerminalIO.PutF["--- %g objects imported from %g\n", [integer[totalCount]], [rope[importeeName]]]; IF unboundCount#0 THEN TerminalIO.PutF["=== %g imported objects not loaded\n", [integer[unboundCount]]]; }; }; }; ImportReadCommand: PROC [comm: CDSequencer.Command] = { import: ImportEntry; TerminalIO.PutRope["load (or reload) a design for import\n"]; import _ OptionalLoad[comm.design, NIL, TRUE]; TerminalIO.PutRope[IF import#NIL AND import.loaded THEN "done\n" ELSE "not done\n"]; }; MerginImportCommand: PROC [comm: CDSequencer.Command] = { importeeName: ROPE; mdata: ImportEntry; TerminalIO.PutRope["merge imports into the design\n"]; IF ~HasImports[comm.design] THEN { TerminalIO.PutRope["design has no imports\n"]; RETURN }; importeeName _ RequestImporteeName[into: comm.design, immediateSingle: TRUE]; IF Rope.IsEmpty[importeeName] THEN { TerminalIO.PutRope["no imported design specified\n"]; RETURN }; mdata _ CDImports.GetImportEntry[comm.design, importeeName, false]; IF mdata=NIL THEN { TerminalIO.PutRopes[importeeName, " not imported; not done\n"]; RETURN } ELSE IF ~mdata.loaded THEN { TerminalIO.PutRopes[importeeName, " is not yet loaded\n"]; IF OptionalLoad[comm.design, importeeName]=NIL THEN RETURN; IF ~mdata.loaded THEN RETURN; }; CDImports.MergeInImports[into: comm.design, importeeName: importeeName]; TerminalIO.PutRope["end merge\n"]; }; <<--xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>> <<--multi-design-copy feature>> SelectADesign: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRopes["select ", comm.design.name, " 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]; }; SelectedDesign: PROC [] RETURNS [CD.Design] = { WITH CDProperties.GetProp[$SelectedDesign, $SelectedDesign] SELECT FROM d: CD.Design => RETURN [d]; ENDCASE => RETURN [NIL]; }; InterDesignCopyComm: PROC [comm: CDSequencer.Command] = { inst: CD.Instance; --copy of sourceInst Fail: PROC [r1, r2, r3: Rope.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[" ", CDOps.ObjectRope[ob], " included\n"]; }; }; multiple, always: BOOL _ FALSE; design: CD.Design _ comm.design; obName: Rope.ROPE; ob: CD.Object; sourceDesign: CD.Design _ NIL; sdName: Rope.ROPE; sourceInst: CD.Instance; import: ImportEntry; 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}; <<--Try atomic objects>> IF ~inst.ob.class.inDirectory THEN {IncludeOb[inst.ob]; RETURN}; <<--Object is in directory>> obName _ CDDirectory.Name[inst.ob]; sdName _ sourceDesign.name; Process.Pause[Process.MsecToTicks[200]]; <<--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 >> IF Rope.IsEmpty[obName] THEN {Fail["object not named"]; RETURN}; IF Rope.IsEmpty[sdName] THEN {Fail["can not import from un-named design"]; RETURN}; IF Rope.Equal[sdName, design.name] THEN { <<--Designs have equal names; use matching objects from directory>> TerminalIO.PutRope[" design names match; use object with same name\n"]; ob _ CDDirectory.Fetch[design, obName].object; IF ob=NIL THEN {Fail["object ", obName, " not found in directory"]; RETURN}; IncludeOb[ob]; RETURN }; <<--Designs have different names; try imports>> import _ CDImports.GetImportEntry[into: design, importeeName: sdName]; SELECT TRUE FROM import#NIL AND import.loaded => { --Source design already loaded header: Rope.ROPE _ Rope.Cat["imported ", sdName, " is already loaded"]; headerDoc: Rope.ROPE _ "re importing design ?"; IF sourceDesign.edited THEN { header _ Rope.Concat[header, " but design is EDITED"]; headerDoc _ "cache and design in viewer may differ"; }; SELECT TerminalIO.RequestSelection[header: header, headerDoc: headerDoc, choice: LIST["use cached design", "reload file", "give up"] ] FROM 1 => always _ FALSE; 2 => always _ TRUE; ENDCASE => {Fail["gives up"]; RETURN}; }; sourceDesign.edited => { --Source design not yet loaded but edited SELECT TerminalIO.RequestSelection[ header: Rope.Cat["importing ", sdName, "; but design is edited"], headerDoc: "file might differ from current design", choice: LIST["go ahead and load file", "give up"] ] FROM 1 => always _ TRUE; ENDCASE => {Fail["gives up"]; RETURN}; }; ENDCASE => { --source design not yet loaded nor edited IF ~TerminalIO.Confirm[Rope.Concat["import ", sdName]] THEN { Fail["gives up"]; RETURN }; }; import _ OptionalLoad[design, sdName, always, true]; IF import=NIL OR ~import.loaded THEN {Fail[sdName, " not loaded"]; RETURN}; ob _ CDImports.CreateImport[into: design, objectName: obName, importeeName: sdName]; IF ob=NIL THEN {Fail[obName, " not found"]; RETURN}; IncludeOb[ob]; }; 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 NOT inst.ob.class.inDirectory THEN { object _ inst.ob; foundWithoutChildren _ TRUE; } ELSE { entryName: ROPE = CDDirectory.Name[inst.ob]; 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 { import: ImportEntry _ OptionalLoad[comm.design, moduleName]; IF import#NIL AND import.loaded THEN { referenceOb _ CDImports.CreateImport[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[CDOps.ObjectRope[referenceOb], " included\n"]; } }; <<>> LoadAllImps: PROC [importerDesign: CD.Design, allowConflicts: CDImports.BoolOrInteractive_false] RETURNS [alldone: BOOL] = { <<--Tries to import all designs which are used for importerDesign;>> <<--Does not overload.>> <<--Quite talky on TerminalIO, but not interactive unless parameter specifies>> jobList: SymTab.Ref _ SymTab.Create[]; LoadOneImport: PROC [name: ROPE] = { done: BOOL; CDSequencer.CheckAborted[importerDesign]; done _ CDImportsBackdoor.LoadDesign[into: importerDesign, importeeName: name, overload: false, allowConflicts: allowConflicts, useCache: TRUE]; TerminalIO.PutRopes[" ", name, (IF done THEN " imported\n" ELSE " not imported\n")]; }; SearchDirectImports: PROC [d: CD.Design] = { FOR l: LIST OF CDImports.ImportEntry _ CDImports.GetImportList[d]^, l.rest WHILE l#NIL DO [] _ SymTab.Insert[jobList, l.first.importeeName, $mustLoadAndCheck] ENDLOOP; }; Each: SymTab.EachPairAction = { SELECT val FROM $mustLoadAndCheck => { ie: CDImports.ImportEntry _ CDImports.GetImportEntry[importerDesign, key, true]; IF ~ie.loaded THEN LoadOneImport[key]; [] _ SymTab.Store[jobList, key, $mustCheck]; RETURN [TRUE] }; $mustCheck => { d: CD.Design _ CDRemote.FetchDesign[importerDesign, key]; IF d#NIL THEN SearchDirectImports[d]; [] _ SymTab.Store[jobList, key, $ok]; RETURN [TRUE] }; $ok => RETURN [FALSE]; ENDCASE => ERROR; }; <> <> <> <> <> SearchDirectImports[importerDesign]; WHILE SymTab.Pairs[jobList, Each] DO ENDLOOP; alldone _ ~CDImports.HasUnloadedImports[importerDesign]; }; LoadAllImpsCommand: PROC [comm: CDSequencer.Command] = { <<--Load all imports>> <<--Checks first for an userprofile entry;>> <<--checks then for filename=designname>> b: BOOL; TerminalIO.PutRope["load all imported designs\n"]; b _ LoadAllImps[comm.design, interactive]; IF ~b THEN TerminalIO.PutRope[" **some import not loaded\n"]; TerminalIO.PutRope[" --\n"]; }; UnqueuedLoadAllImps: PROC [comm: CDSequencer.Command] = { <<--hack, called from io commands>> IF ~LoadAllImps[comm.design, false] THEN TerminalIO.PutRope["**some import not loaded\n"]; }; ReplaceIncludesByImportsComm: PROC [comm: CDSequencer.Command] = { FindObjects: CDDirectory.EachEntryAction = { <<--uses global replaceList>> WITH CDProperties.GetObjectProp[ob, $CameFrom] SELECT FROM <<--putting the objectnames in the RefTab keeps them even if replacement is in wrong order>> r: ROPE => [] _ RefTab.Insert[x: replaceList, key: ob, val: CDProperties.GetObjectProp[ob, $OriginalName]]; ENDCASE => NULL }; ReplaceObjects: RefTab.EachPairAction = { <<--uses globals context and design>> quit _ FALSE; WITH val SELECT FROM r: ROPE => { ob: CD.Object _ NARROW[key]; oldName: ROPE _ CDDirectory.Name[ob]; new: CD.Object _ CDGenerate.FetchNCall[context, design, r]; IF new#NIL THEN { msg: ROPE; CDDirectory.ReplaceObject[design, ob, new]; IF ~CDDirectory.Remove[design, oldName, ob] THEN [] _ CDDirectory.Rename[design, ob, Rope.Cat["old-", CDDirectory.Name[ob]], TRUE]; msg _ IF new.bbox=ob.bbox AND CD.InterestRect[new]=CD.InterestRect[ob] THEN " replaced" ELSE " replaced (size conflict)"; TerminalIO.PutF["%g %g by %g\n", IO.rope[msg], IO.rope[oldName], IO.rope[CDDirectory.Name[new]] ]; }; CDSequencer.CheckAborted[design]; }; ENDCASE => NULL }; replaceList: RefTab.Ref _ RefTab.Create[]; import: ImportEntry; context: CDGenerate.Context; design: CD.Design _ comm.design; TerminalIO.PutRope["replace included objects by imports\n"]; import _ OptionalLoad[comm.design]; IF import=NIL THEN {TerminalIO.PutRope[" not loded\n"]; RETURN}; context _ CDGenerateImports.GetImportContext[import.importeeName]; [] _ CDDirectory.Enumerate[comm.design, FindObjects]; [] _ RefTab.Pairs[replaceList, ReplaceObjects]; TerminalIO.PutRope[" --\n"]; }; [] _ CDProperties.RegisterProperty[$SelectedDesign, $chj]; [] _ CDProperties.RegisterProperty[$ImportHints, $chj]; CDSequencer.ImplementCommand[$DrawImported, GetImportedEntryCommand]; CDSequencer.ImplementCommand[$DisplayImports, DisplayImports,, doQueue]; CDSequencer.ImplementCommand[$DisplayImportedEntries, DisplayImportedEntries,, doQueue]; CDSequencer.ImplementCommand[$ImportADesign, ImportReadCommand]; CDSequencer.ImplementCommand[$SelectADesign, SelectADesign,, doQueue]; CDSequencer.ImplementCommand[$DrawCorrespondingObject, DrawImportedCopy]; CDSequencer.ImplementCommand[$MerginImport, MerginImportCommand]; CDSequencer.ImplementCommand[$LoadAllImps, LoadAllImpsCommand,, doQueue]; CDSequencer.ImplementCommand[$UnqueuedLoadAllImps, UnqueuedLoadAllImps,, dontQueue]; CDSequencer.ImplementCommand[$ReplaceByImp, ReplaceIncludesByImportsComm]; CDSequencer.ImplementCommand[$ImportDefaultName, ChangeDefaultFileNameComm]; CDSequencer.ImplementCommand[$UnqueuedCopyInterDesign, InterDesignCopyComm]; END.