<> <> <> <> DIRECTORY CD, CDGenerate, CDGenerateBackdoor, CDGenerateImports, CDIO, CDImports, RefTab, Rope, SymTab, TerminalIO; CDGenerateImportsImpl: CEDAR PROGRAM IMPORTS CDGenerate, CDGenerateBackdoor, CDIO, CDImports, RefTab, Rope, SymTab, TerminalIO EXPORTS CDGenerateImports = BEGIN dummy: CDGenerate.Table _ CDGenerate.Create[]; tableToName: RefTab.Ref _ RefTab.Create[]; nameToTable: SymTab.Ref _ SymTab.Create[]; UnspecSelector: CDGenerateBackdoor.SelectorProc = BEGIN key _ TerminalIO.RequestRope[label, " import [design.oject] >"]; END; Selector: CDGenerateBackdoor.SelectorProc = { dName: Rope.ROPE = ImporteeName[table]; key _ TerminalIO.RequestRope[Rope.Cat[label, " import oject from ", dName, " >"]]; }; ImportIGenerator: CDGenerateBackdoor.IGeneratorProc = BEGIN importeeName: Rope.ROPE _ ImporteeName[realTable]; imp: REF CDImports.Import; IF Rope.IsEmpty[importeeName] THEN { TerminalIO.WriteRope["**generate with bad importee name\n"]; RETURN }; imp _ CDImports.GetImport[design, importeeName]; IF imp=NIL OR imp.importee=NIL THEN DoImport[design, importeeName]; ob _ CDImports.GetReference[design, key, importeeName]; END; UnspecImportIGenerator: CDGenerateBackdoor.IGeneratorProc = BEGIN dot: INT = TrailingDot[key]; importeeName: Rope.ROPE_NIL; objectName: Rope.ROPE_NIL; table: CDGenerate.Table; IF dot < Rope.Length[key] THEN { objectName _ Rope.Substr[key, dot+1]; importeeName _ Rope.Substr[key, 0, dot] }; IF ~Rope.IsEmpty[importeeName] AND ~Rope.IsEmpty[objectName] THEN { table _ GetImportTable[importeeName]; ob _ CDGenerate.FetchNCall[table, design, objectName]; } ELSE TerminalIO.WriteRope["**tried to import with bad syntax\n"]; END; TrailingDot: PROC [base: Rope.ROPE] RETURNS [INT] = { <<--position of last dot>> len: INT _ Rope.Length[base]; pos: INT _ len; WHILE pos > 0 DO SELECT Rope.Fetch[base, pos _ pos - 1] FROM '. => RETURN [pos]; '!, '], '>, '/ => EXIT; ENDCASE; ENDLOOP; RETURN [len]; }; ImporteeName: PUBLIC PROC [table: CDGenerate.Table] RETURNS [r: Rope.ROPE_NIL] = TRUSTED BEGIN WITH tableToName.Fetch[LOOPHOLE[table]].val SELECT FROM n: Rope.ROPE => r _ n ENDCASE => { table _ CDGenerateBackdoor.Indiretee[table]; IF table#NIL THEN RETURN[ImporteeName[table]] }; END; GetImportTable: PUBLIC PROC [designName: Rope.ROPE] RETURNS [table: CDGenerate.Table_NIL] = TRUSTED BEGIN WITH nameToTable.Fetch[designName].val SELECT FROM t: CDGenerate.Table => RETURN [t] ENDCASE => NULL; table _ CDGenerateBackdoor.CreateIndirect[onTopOf: dummy, iGenerator: ImportIGenerator, selector: Selector, cache: TRUE, flushThrough: FALSE, clearThrough: FALSE, registerThrough: FALSE]; [] _ tableToName.Insert[LOOPHOLE[table], designName]; IF nameToTable.Insert[designName, LOOPHOLE[table]] THEN RETURN; RETURN [GetImportTable[designName]] --indirection for concurrency problems END; DoImport: PROC [importer: CD.Design, importeeName: Rope.ROPE] = BEGIN Check: PROC [design: CD.Design] RETURNS [ok: BOOL] = BEGIN ok _ design.technology=importer.technology; IF NOT ok THEN { TerminalIO.WriteRope["Technology missmatch: includee is "]; TerminalIO.WriteRope[design.technology.name]; TerminalIO.WriteRope["\n"]; RETURN }; ok _ Rope.Equal[importeeName, CDIO.DesignInReadOperation[].name]; IF NOT ok THEN { TerminalIO.WriteRope["import failed, file has design with different name\n"]; }; END; done: BOOL _ FALSE; design: CD.Design; TerminalIO.WriteRope["load a design to generate imports\n"]; [] _ CDIO.UseWorkingDirectory[importer]; design _ CDIO.ReadDesign[CDIO.MakeName[ base: importeeName, ext: "dale", wDir: CDIO.GetWorkingDirectory[importer]], Check]; IF design#NIL THEN { done _ CDImports.DoImport[design: importer, importee: design, allowOverload: interactive, allowConflicts: interactive]; }; TerminalIO.WriteRope[IF done THEN "import done\n" ELSE "import not done\n"]; END; unspecImportTable: CDGenerate.Table _ CDGenerateBackdoor.CreateIndirect[ onTopOf: dummy, iGenerator: UnspecImportIGenerator, selector: UnspecSelector ]; TRUSTED { [] _ SymTab.Insert[CDGenerateBackdoor.publicTables, "IMPORT", LOOPHOLE[unspecImportTable]]; }; END.