DIRECTORY CD, CDGenerate, CDGenerateBackdoor, CDDirectory, CDEnvironment, CDIO, CDProperties, CDRemote, CDValue, FileNames, RefTab, Rope, SymTab, TerminalIO, TokenIO, UserProfile; CDRemoteImpl: CEDAR PROGRAM IMPORTS CDGenerate, CDGenerateBackdoor, CDDirectory, CDEnvironment, CDIO, CDProperties, CDValue, FileNames, RefTab, Rope, SymTab, TerminalIO, UserProfile EXPORTS CDRemote = BEGIN ROPE: TYPE = Rope.ROPE; dummy: CDGenerate.Context _ CDGenerate.Create[]; contextToName: RefTab.Ref _ RefTab.Create[]; -- context ==> remote design name NameRec: TYPE = RECORD [name: ROPE, key: REF]; nameToContext: SymTab.Ref _ SymTab.Create[]; -- remote design name ==> context UnspecSelector: CDGenerateBackdoor.SelectorProc = { key _ TerminalIO.RequestRope[" include [design.oject] >"]; }; Selector: CDGenerateBackdoor.SelectorProc = { dName: ROPE = DesignName[context]; key _ TerminalIO.RequestRope[Rope.Cat[label, " include oject from ", dName, " >"]]; }; UnspecRemoteIGenerator: CDGenerateBackdoor.IGeneratorProc = { dotIndex: INT; remoteName, objectName: ROPE _ NIL; name: ROPE _ FileNames.GetShortName[key]; dotIndex _ Rope.Index[name, 0, "."]; --the first dot! multiple dots belong to the object name IF dotIndex < Rope.Length[name] THEN { objectName _ Rope.Substr[name, dotIndex+1]; remoteName _ Rope.Substr[name, 0, dotIndex] }; IF ~Rope.IsEmpty[remoteName] AND ~Rope.IsEmpty[objectName] THEN { context: CDGenerate.Context _ GetContext[remoteName]; ob _ CDGenerate.FetchNCall[context, design, objectName]; } ELSE TerminalIO.PutRopes["**tried to access remote with bad syntax; [", key, "]\n"]; }; GetContext: PUBLIC PROC [remoteDesign: ROPE] RETURNS [context: CDGenerate.Context_NIL] = { IF Rope.IsEmpty[remoteDesign] THEN ERROR; WITH nameToContext.Fetch[remoteDesign].val SELECT FROM t: CDGenerate.Context => RETURN [t] ENDCASE => NULL; context _ CDGenerateBackdoor.CreateIndirect[onTopOf: dummy, iGenerator: RemoteIGenerator, selector: Selector, cache: TRUE, flushThrough: FALSE, clearThrough: FALSE, registerThrough: FALSE]; [] _ contextToName.Insert[context, NEW[NameRec _ [name: remoteDesign, key: NEW[INT]] ] ]; IF nameToContext.Insert[remoteDesign, context] THEN RETURN; RETURN [GetContext[remoteDesign]] --indirection for concurrency problems }; Get: PUBLIC PROC [for: CD.Design, remoteDesign: ROPE, object: ROPE] RETURNS [ob: CD.Object] = { context: CDGenerate.Context = GetContext[remoteDesign]; ob _ CDGenerate.FetchNCall[context, for, object]; }; RemoteInfo: PROC [context: CDGenerate.Context] RETURNS [r: REF NameRec_NIL] = { WITH contextToName.Fetch[context].val SELECT FROM rn: REF NameRec => RETURN [rn]; ENDCASE => { context _ CDGenerateBackdoor.Indiretee[context]; IF context#NIL THEN RETURN[RemoteInfo[context]] }; }; DesignName: PUBLIC PROC [context: CDGenerate.Context] RETURNS [r: ROPE_NIL] = { rn: REF NameRec _ RemoteInfo[context]; IF rn#NIL THEN RETURN [rn.name] }; RemoteIGenerator: CDGenerateBackdoor.IGeneratorProc = { replaceList: CDDirectory.ReplaceList _ NIL; GetOrLoad: PROC [importer: CD.Design, remoteInfo: REF NameRec] RETURNS [design: CD.Design_NIL] = { IF remoteInfo=NIL OR Rope.IsEmpty[remoteInfo.name] THEN { TerminalIO.PutRope["**generate with bad remote name\n"]; RETURN }; WITH CDValue.Fetch[boundTo: importer, key: remoteInfo.key] SELECT FROM d: CD.Design => design _ d; ENDCASE => NULL; IF design=NIL THEN { design _ DoLoad[importer, remoteInfo.name]; CacheDesign[importer, design]; }; }; EachChild: CDDirectory.EnumerateObjectsProc = { -- PROC [me: CD.Object, x: REF] -- IF me.class.inDirectory THEN { name: ROPE _ CDDirectory.Name[me]; ob1: CD.Object _ CDGenerate.FetchNCall[realContext, design, name];--will be cached! replaceRec: REF CDDirectory.ReplaceRec _ NEW[CDDirectory.ReplaceRec _ [old: me, new: ob1]]; replaceList _ CONS[replaceRec, replaceList]; } }; remoteDesign: CD.Design; remoteInfo: REF NameRec _ RemoteInfo[passContext]; IF Rope.Equal[remoteInfo.name, design.name] THEN { ob _ CDDirectory.Fetch[design, key].object; RETURN }; remoteDesign _ GetOrLoad[design, remoteInfo]; IF remoteDesign#NIL THEN { rob: CD.Object _ CDDirectory.Fetch[remoteDesign, key].object; IF rob#NIL THEN { tm, cm: CDDirectory.DMode; [ob, tm, cm] _ CDDirectory.Another[me: rob, fromOrNil: remoteDesign, into: design]; IF ob#NIL THEN { IF cm=immutable THEN { CDDirectory.EnumerateChildObjects[me: ob, p: EachChild]; IF replaceList#NIL THEN [] _ CDDirectory.ReplaceDirectChild[me: ob, design: design, replace: replaceList]; }; IF tm=ready THEN [] _ CDDirectory.Include[design: design, object: ob]; CDProperties.PutObjectProp[ob, $CameFrom, remoteDesign.name]; CDProperties.PutObjectProp[ob, $OriginalName, key]; RETURN [ob] }; }; }; }; CacheDesign: PUBLIC PROC [for: CD.Design, remote: CD.Design] = { rn: REF NameRec _ RemoteInfo[GetContext[remote.name]]; IF for.technology#remote.technology THEN ERROR; IF rn#NIL THEN CDValue.Store[boundTo: for, key: rn.key, value: remote] ELSE TerminalIO.PutRope["**CacheRemoteDesign failed; debugging is appropriate\n"]; }; FetchDesign: PUBLIC PROC [for: CD.Design, name: ROPE] RETURNS [remote: CD.Design _ NIL] = { rn: REF NameRec _ RemoteInfo[GetContext[name]]; WITH CDValue.Fetch[boundTo: for, key: rn.key, propagation: design] SELECT FROM d: CD.Design => remote _ d ENDCASE => NULL; }; IsCached: PUBLIC PROC [for: CD.Design, remoteDesign: ROPE] RETURNS [BOOL] = { RETURN [FetchDesign[for, remoteDesign]#NIL] }; ForgetCache: PUBLIC PROC [for: CD.Design, remoteDesign: ROPE] = { rn: REF NameRec _ RemoteInfo[GetContext[remoteDesign]]; CDValue.Store[boundTo: for, key: rn.key, value: NIL] }; LoadCache: PUBLIC PROC [for: CD.Design, remoteDesign: ROPE, remoteFile: ROPE _ NIL, reload: BOOL _ FALSE] RETURNS [loaded: BOOL] = { d: CD.Design; IF ~reload AND IsCached[for, remoteDesign] THEN RETURN [TRUE]; d _ DoLoad[for, remoteDesign, remoteFile]; IF loaded_(d#NIL) THEN CacheDesign[for, d]; }; MakupName: PUBLIC PROC [for: CD.Design, remoteDesign: ROPE] RETURNS [f: ROPE_NIL] = { 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; }; RemSpaces: PROC [r: ROPE] RETURNS [ROPE_NIL] = { leng: INT _ Rope.Length[r]; start: INT _ 0; WHILE startstart THEN RETURN [Rope.Substr[r, start, leng-start]]; }; rl: LIST OF ROPE _ GetHintList[for]; key, rest: ROPE _ NIL; FOR list: LIST OF ROPE _ rl, list.rest WHILE list#NIL DO [key, rest] _ CDEnvironment.SplitLine[list.first]; IF Rope.Equal[remoteDesign, key] THEN RETURN [RemSpaces[rest]]; ENDLOOP; f _ UserProfile.Token[Rope.Cat["ChipNDale.ImportFor.", remoteDesign], remoteDesign]; }; DoLoad: PROC [importer: CD.Design, remoteName: ROPE, fileName: ROPE_NIL] RETURNS [design: CD.Design_NIL] = { checkWasCalled: BOOL _ FALSE; Check: PROC [h: TokenIO.Handle] RETURNS [ok: BOOL] = { design: CD.Design _ CDIO.DesignInReadOperation[h]; checkWasCalled _ TRUE; IF ok _ design.technology=importer.technology THEN { ok _ Rope.Equal[remoteName, design.name]; IF NOT ok THEN TerminalIO.PutRope[Rope.Cat["file """, fileName, """ has different design: """, design.name, """\n"]]; } ELSE TerminalIO.PutRopes["**technology missmatch: remote design is ", design.technology.name, "\n"]; }; name1: ROPE; TerminalIO.PutRopes["load remote design ", remoteName, "\n"]; IF Rope.IsEmpty[fileName] THEN fileName _ MakupName[importer, remoteName]; name1 _ CDIO.MakeName[base: fileName, ext: "dale", wDir: CDIO.GetWorkingDirectory[importer]]; design _ CDIO.ReadDesign[name1, Check]; IF ~checkWasCalled AND design=NIL THEN { name2: ROPE _ CDIO.MakeName[base: fileName, ext: "dale", wDir: CDIO.GetWorkingDirectory[NIL]]; IF ~Rope.Equal[name1, name2, FALSE] THEN design _ CDIO.ReadDesign[name2, Check]; }; TerminalIO.PutRopes["loading remote design ", (IF design#NIL THEN "done\n" ELSE "not done\n")]; }; unspecRemoteContext: CDGenerate.Context _ CDGenerateBackdoor.CreateIndirect[ onTopOf: dummy, iGenerator: UnspecRemoteIGenerator, selector: UnspecSelector ]; [] _ SymTab.Insert[CDGenerateBackdoor.publicContexts, "INCLUDE", unspecRemoteContext]; [] _ CDProperties.Register[$CameFrom, [autoRem: TRUE]]; [] _ CDProperties.Register[$OriginalName, [autoRem: TRUE]]; END. ψCDRemoteImpl.mesa (part of ChipNDale) Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, June 5, 1985 8:02:35 pm PDT Last edited by: Christian Jacobi, October 20, 1986 12:56:51 pm PDT --implements two methods of generator contexts --contexts as exported from CDRemote: selecting an object from one specific remote design --context "INCLUDE": generator key is designName.objectName; for any designName -- entries of type REF NameRec --this one even does not know what design to use --test for silly case of using same design name --caller MUST guarantee: remote will NEVER be changed -- (but a different design with the same name might be cached later...) --CDRemote guarantees: it will never change remote Κ {˜codešœ%™%Kšœ Οmœ7™BKšœ8™8K™BK˜—šΟk œ˜ Kšžœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ —K˜šΟn œžœž˜Kšžœ;žœQ˜™Kšžœ ˜—Kšž˜K˜šœ.™.KšœY™YKšœO™O—K˜Kšžœžœžœ˜K˜Kšœ0˜0šœ-˜-KšΟc!˜!Kšœ™Kš œ žœžœžœžœ˜.—šœ,˜,Kš !˜!—K˜šΟbœ%˜3Kšœ:˜:Kšžœ˜K˜—š‘œ%˜-Kšœ"˜"KšœS˜SKšœ˜K˜—š‘œ'˜=K™0Kšœ žœžœžœ˜2Kšœ žœ˜)Kšœ& 8˜^šžœžœ˜&Kšœ+˜+Kšœ+˜+K˜—šžœžœžœ˜AKšœ5˜5Kšœ8˜8K˜—KšžœQ˜UKšœ˜—K˜šŸ œž œžœžœ˜ZKšžœžœžœ˜*šžœ'žœž˜6Kšœžœ˜#Kšžœžœ˜—šœZ˜ZKš œžœžœžœžœ˜c—šœ#˜#Kšžœ%žœžœ˜3Kšœ˜—Kšžœ-žœžœ˜;Kšžœ &˜HKšœ˜—K˜š Ÿœžœžœžœ+žœžœ ˜_Kšœ7˜7Kšœ1˜1Kšœ˜—K˜š Ÿ œžœžœžœ žœ˜Ošžœ"žœž˜1Kšœžœ žœ˜šžœ˜ Kšœ0˜0Kšžœ žœžœžœ˜/Kšœ˜——Kšœ˜—K˜š Ÿ œžœžœžœ žœ˜OKšœžœ˜&Kšžœžœžœžœ ˜Kšœ˜—K˜š‘œ'˜7Kšœ'žœ˜+K˜šŸ œžœ žœžœ žœ žœžœ˜bšžœ žœžœžœ˜9Kšœ8˜8Kšž˜Kšœ˜—šžœ7žœž˜FKšœžœ˜Kšžœžœ˜—šžœžœžœ˜Kšœ+˜+Kšœ˜K˜—Kšœ˜—K˜šΠbn œ' "œ˜Sšžœžœ˜Kšœžœ˜"Kšœžœ; ˜SKšœ žœžœ/˜[Kšœžœ˜,K˜—Kšœ˜—K˜Kšœžœ˜Kšœ žœ#˜2K™/šžœ*žœ˜2Kšœ+˜+Kšž˜K˜—Kšœ-˜-šžœžœžœ˜Kšœžœ6˜=šžœžœžœ˜Kšœ˜KšœS˜Sšžœžœžœ˜šžœžœ˜Kšœ8˜8šžœ žœžœ˜KšœR˜R—Kšœ˜—Kšžœ žœ6˜FKšœ=˜=Kšœ3˜3Kšžœ˜ K˜—K˜—K˜—Kšœ˜—K˜š Ÿ œžœžœžœžœ ˜@Kšœ5™5KšœH™HKšœ4™4Kšœžœ/˜6Kšžœ"žœžœ˜/Kšžœžœžœ8˜Fšžœ˜KšœM˜M—Kšœ˜K˜—šŸ œžœžœžœžœ žœ žœ˜[Kšœžœ(˜/šžœ?žœž˜NKšœžœ˜Kšžœžœ˜—Kšœ˜K˜—K˜š Ÿœž œžœžœžœ˜MKšžœ!žœ˜+K˜—K˜šŸ œž œžœ ˜AKšœžœ0˜7Kšœ0žœ˜4Kšœ˜—K˜šŸ œžœžœžœ-žœžœ žœžœžœ žœ˜„Kšœžœ˜ Kš žœ žœžœžœžœ˜>Kšœ*˜*Kšžœ žœžœ˜,K˜—K˜šŸ œž œžœžœžœžœžœ˜UšŸ œžœžœ žœžœžœžœžœ˜Ašžœžœž˜šžœ/žœž˜>Kš œžœžœžœžœ˜ Kšžœžœ˜——K˜—š Ÿ œžœžœžœžœžœ˜0Kšœžœ˜Kšœžœ˜Kšžœ žœžœžœ˜HKšžœ žœžœžœ˜GKšžœ žœžœ%˜>Kšœ˜—Kšœžœžœžœ˜$Kšœ žœžœ˜š žœžœžœžœžœžœž˜8Kšœ2˜2Kšžœžœžœ˜?Kšžœ˜—KšœV˜VKšœ˜—K˜šŸœžœ žœžœ žœžœžœ žœžœ˜lKšœžœžœ˜K˜šŸœžœžœžœ˜6Kšœžœ žœ˜2Kšœžœ˜šžœ,žœ˜4Kšœ)˜)Kšžœžœžœh˜vK˜—Kšžœ`˜dKšœ˜—K˜Kšœžœ˜ Kšœ=˜=Kšžœžœ,˜JKšœžœ-žœ ˜]Kšœ žœ˜'šžœžœžœžœ˜)Kš œžœžœ-žœžœ˜^Kšžœžœžœ žœ˜PK˜—Kš œ/žœžœžœ žœ˜_Kšœ˜—K˜K˜Kšœž˜žKšœV˜VKšœ0žœ˜7Kšœ4žœ˜;Kšžœ˜K˜—…— Ύ.1