DIRECTORY CD, CDGenerate, CDGenerateBackdoor, CDDirectory, CDEnvironment, CDIO, CDProperties, CDRemote, CDSequencer, CDValue, FileNames, RefTab, Rope, SymTab, TerminalIO, TokenIO, UserProfile; CDRemoteImpl: CEDAR PROGRAM IMPORTS CD, CDGenerate, CDGenerateBackdoor, CDDirectory, CDEnvironment, CDIO, CDProperties, CDSequencer, CDValue, FileNames, RefTab, Rope, SymTab, TerminalIO, UserProfile EXPORTS CDRemote = BEGIN ROPE: TYPE = Rope.ROPE; dummy: CDGenerate.Context _ CDGenerate.Create[]; contextToName: RefTab.Ref _ RefTab.Create[]; NameRec: TYPE = RECORD [name: ROPE, key: REF]; nameToContext: SymTab.Ref _ SymTab.Create[]; 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]; }; }; GetOver: PROC [into: CD.Design, from: CD.Design, ob: CD.Object, key: REF_NIL] RETURNS [ob1: CD.Object_NIL] = { replaceList: CDDirectory.ReplaceList _ NIL; EachChild: CDDirectory.EachObjectProc = { IF me.class.composed THEN { replaceRec: REF CDDirectory.ReplaceRec; ob1: CD.Object; IF CDDirectory.IsIncluded[from, me] THEN { ob1 _ CDGenerate.FetchNCall[realContext, design, CDDirectory.Name[me, from]]; }; IF ob1=NIL THEN ob1 _ GetOver[into, from, me, NIL]; IF ob1=NIL THEN ERROR; replaceRec _ NEW[CDDirectory.ReplaceRec _ [old: me, new: ob1]]; replaceList _ CONS[replaceRec, replaceList]; } }; ca: BOOL; [ob1, ca] _ CDDirectory.Another1[me: ob, fromOrNil: from, into: into]; IF ob1#NIL THEN { IF ~ca THEN { [] _ CDDirectory.EnumerateChildObjects[me: ob1, proc: EachChild]; IF replaceList#NIL THEN [] _ CDDirectory.ReplaceDirectChild[me: ob1, design: into, replace: replaceList, propagate: FALSE]; }; IF CDDirectory.IsIncluded[from, ob] THEN [] _ CDDirectory.Include[design: into, object: ob1, name: CDDirectory.Name[ob, from]]; CDProperties.PutObjectProp[ob1, $CameFrom, from.name]; IF key=NIL THEN key _ CDDirectory.Name[ob, from]; CDProperties.PutObjectProp[ob1, $OriginalName, key]; }; }; 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 RETURN [GetOver[into: design, from: remoteDesign, ob: rob, key: key]]; }; }; CacheDesign: PUBLIC PROC [for: CD.Design, remote: CD.Design] = { rn: REF NameRec _ RemoteInfo[GetContext[remote.name]]; IF for.technology#remote.technology THEN ERROR CD.Error[calling]; IF remote.mutability#readonly THEN ERROR CD.Error[designMutability]; 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] = { Check: PROC [h: TokenIO.Handle] RETURNS [ok: BOOL] = { design: CD.Design _ CDIO.DesignInReadOperation[h]; 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: """, CD.DesignName[design], """\n"]]; } ELSE TerminalIO.PutRopes["**technology missmatch: remote design is ", design.technology.name, "\n"]; }; name1: ROPE; x: Rope.ROPE _ " not done"; TerminalIO.PutRopes["load remote design ", remoteName, "\n"]; IF Rope.IsEmpty[fileName] THEN fileName _ MakupName[importer, remoteName]; name1 _ CDEnvironment.FindFile[fileName, ".dale", importer]; IF Rope.IsEmpty[name1] THEN x _ Rope.Cat[" not done; file ", fileName, " not found"] ELSE { design _ CDIO.ReadDesign[name1, Check]; IF design#NIL THEN { ref: REF; CDSequencer.SetMutability[design, readonly]; ref _ CDValue.Fetch[design, $CDxFromFile, design]; CDValue.Store[design, $CDxCachedFile, ref]; ref _ CDValue.Fetch[design, $CDxFileCreated, design]; CDValue.Store[design, $CDxCachedCreated, ref]; x _ Rope.Cat[" ", remoteName, " loaded\n"]; }; }; TerminalIO.PutRope[x]; }; unspecRemoteContext: CDGenerate.Context _ CDGenerateBackdoor.CreateIndirect[ onTopOf: dummy, iGenerator: UnspecRemoteIGenerator, selector: UnspecSelector ]; [] _ SymTab.Insert[CDGenerateBackdoor.publicContexts, "INCLUDE", unspecRemoteContext]; [] _ CDProperties.Register[$CameFrom, [autoRem: TRUE, exclusive: TRUE]]; [] _ CDProperties.Register[$OriginalName, [autoRem: TRUE, exclusive: TRUE]]; END. LCDRemoteImpl.mesa (part of ChipNDale) Copyright c 1985, 1987 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, June 5, 1985 8:02:35 pm PDT Last edited by: Christian Jacobi, February 26, 1987 11:21:26 am PST --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 context ==> remote design name -- entries of type REF NameRec remote design name ==> context --this one even does not know what design to use --will be cached !! --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 Ê r˜codešœ%™%Kšœ Ïmœ7™BKšœ5Ïk™8KšœC™CK˜—šž œ˜ Kšžœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšžœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ —K˜šÏn œžœž˜Kšžœžœ>žœ^˜ªKšžœ ˜—Kšž˜K˜šÏc.™.Kš Y™YKš O™O—K˜Kšžœžœžœ˜K˜Kšœ0˜0šœ-˜-Kšœ™Kš ™Kš œ žœžœžœžœ˜.—šœ,˜,Kšœ™—K˜šÐbnœ%˜3Kšœ:˜:Kšœ˜K˜—š¡œ%˜-Kšœžœ˜"KšœS˜SKšœ˜K˜—š¡œ'˜=Kš 0™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˜šŸœžœžœžœ žœžœžœžœžœžœ˜nKšœ'žœ˜+K˜š¡ œ"˜+šžœžœ˜Kšœ žœžœ˜7šžœ"žœ˜*šœN˜NKš ™—K˜—šžœžœžœ˜Kšœžœ˜#—Kšžœžœžœžœ˜Kšœ žœ/˜?Kšœžœ˜,K˜—Kšœ˜—K˜Kšœžœ˜ KšœF˜Fšžœžœžœ˜šžœžœ˜ KšœA˜Ašžœ žœžœ˜Kšœ\žœ˜c—Kšœ˜—šžœ"žœ˜)KšœV˜V—Kšœ6˜6Kšžœžœžœ"˜1Kšœ4˜4K˜—K˜—K˜Kšœžœ˜Kšœ žœ#˜2Kš /™/šžœ*žœ˜2Kšœ+˜+Kšž˜K˜—Kšœ-˜-šžœžœžœ˜Kšœžœ6˜=Kšžœžœžœžœ@˜VK˜—Kšœ˜—K˜š Ÿ œžœžœžœžœ ˜@Kš 5™5Kš H™HKš 4™4Kšœžœ/˜6Kšžœ"žœžœžœ˜AKšžœžœžœžœ˜DKšžœžœžœ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˜šŸœžœžœžœ˜6Kšœžœ žœ˜2šžœ,žœ˜4Kšœ)˜)KšžœžœžœRžœ˜€K˜—Kšžœ`˜dKšœ˜—K˜Kšœžœ˜ Kšœžœ˜Kšœ=˜=Kšžœžœ,˜JKšœ<˜