CDDesignCacheImpl.mesa (part of ChipNDale)
Copyright © 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, April 9, 1987 12:29:43 pm PDT
Last edited by: Christian Jacobi, October 19, 1987 10:49:30 am PDT
DIRECTORY
BasicTime,
CD,
CDDesignCache,
CDEnvironment,
CDIO,
CDOps,
CDPrivate,
CDProperties,
CDValue,
FileNames,
FS,
IO,
RefTab,
Rope,
SymTab,
TerminalIO,
TokenIO,
UserProfile;
CDDesignCacheImpl:
CEDAR
PROGRAM
IMPORTS CD, CDEnvironment, CDIO, CDOps, CDPrivate, CDProperties, CDValue, FileNames, FS, IO, RefTab, Rope, SymTab, TerminalIO, UserProfile
EXPORTS CDDesignCache =
BEGIN
GetSymTab:
PROC [for:
CD.Design]
RETURNS [SymTab.Ref] = {
x: REF ~ CDValue.Fetch[for, $CDDesignCachePrivate];
WITH x
SELECT
FROM
t: SymTab.Ref => RETURN [t];
ENDCASE =>
IF x=
NIL
THEN [] ← CDValue.StoreConditional[for, $CDDesignCachePrivate, SymTab.Create[5]]
ELSE [] ← CDValue.Store[for, $CDDesignCachePrivate, SymTab.Create[5]];
RETURN [GetSymTab[for]]
};
Set:
PUBLIC
PROC [for:
CD.Design, remote:
CD.Design] = {
tab: SymTab.Ref ~ GetSymTab[for];
IF for.technology#remote.technology OR for=remote THEN ERROR CD.Error[calling];
IF remote.mutability#readonly THEN ERROR CD.Error[designMutability];
[] ← SymTab.Store[tab, remote.name, remote];
};
Fetch:
PUBLIC
PROC [for:
CD.Design, remoteName: Rope.
ROPE]
RETURNS [remote:
CD.Design ←
NIL] = {
tab: SymTab.Ref ~ GetSymTab[for];
WITH SymTab.Fetch[tab, remoteName].val
SELECT
FROM
d: CD.Design => IF d.mutability=readonly THEN RETURN [d];
ENDCASE => NULL;
};
IsCached:
PUBLIC
PROC [for:
CD.Design, remoteName: Rope.
ROPE]
RETURNS [
BOOL] = {
RETURN [Fetch[for, remoteName]#NIL]
};
Forget:
PUBLIC
PROC [for:
CD.Design, remoteName: Rope.
ROPE] = {
tab: SymTab.Ref ~ GetSymTab[for];
[] ← SymTab.Delete[tab, remoteName]
};
CameFile:
PROC [d:
CD.Design]
RETURNS [Rope.
ROPE←
NIL] = {
IF d#
NIL
THEN
WITH CDValue.Fetch[d, $CDxCachedFile, design]
SELECT
FROM
r: Rope.ROPE => RETURN [r];
ENDCASE => NULL;
};
CameTime:
PROC [d:
CD.Design]
RETURNS [BasicTime.
GMTsicTime.nullGMT] = {
IF d#
NIL
THEN
WITH CDValue.Fetch[d, $CDxCachedCreated, design]
SELECT
FROM
t: REF INT => RETURN [LOOPHOLE[t^, BasicTime.GMT]];
ENDCASE => NULL;
};
Search:
PUBLIC
PROC [remoteName: Rope.
ROPE, fileName: Rope.
ROPE←
NIL, createdTime: BasicTime.
GMT ← BasicTime.nullGMT, check: CDDesignCache.CheckProc←
NIL, data:
REF←
NIL]
RETURNS [found:
CD.Design←
NIL] = {
Check:
PROC [d:
CD.Design]
RETURNS [ok:
BOOL←
FALSE] = {
IF d#
NIL
AND d.mutability=readonly
THEN
IF fileName=
NIL
OR Rope.Equal[CameFile[d], fileName,
FALSE]
THEN
IF createdTime=BasicTime.nullGMT
OR CameTime[d]=createdTime
THEN
IF check=
NIL
OR check[d, data]
THEN {
ok ← TRUE; found ← d;
};
};
EachDesign: CDPrivate.DesignEnumerator = {
cache: CD.Design;
IF ~RefTab.Insert[seen, design, NIL] THEN RETURN;
IF design.mutability=readonly
AND Rope.Equal[design.name, remoteName]
THEN {
IF Check[design].ok THEN RETURN [quit←TRUE];
RETURN;
};
cache ← Fetch[for: design, remoteName: remoteName];
IF cache#
NIL
AND RefTab.Insert[seen, cache,
NIL]
THEN
IF Check[cache].ok THEN RETURN [quit←TRUE];
};
seen: RefTab.Ref ← RefTab.Create[5];
IF fileName#NIL THEN fileName ← FileNames.ConvertToSlashFormat[fileName];
[] ← CDPrivate.EnumDesigns[EachDesign];
};
GetOrRead:
PUBLIC
PROC [for:
CD.Design, remoteName: Rope.
ROPE, remoteFile: Rope.
ROPE ←
NIL, reload:
BOOL ←
FALSE, checkFile:
BOOL ←
TRUE, check: CDDesignCache.CheckProc←
NIL, data:
REF←
NIL]
RETURNS [remote:
CD.Design←
NIL, different:
BOOL←
FALSE] = {
remote ← Fetch[for, remoteName];
IF remote=
NIL
OR reload
THEN {
d: CD.Design ← DoLoad[for, remoteName, remoteFile, checkFile, check, data];
IF different ← (d#NIL AND remote#d) THEN Set[for, remote𡤍];
};
};
DoLoad:
PROC [for:
CD.Design, remoteName: Rope.
ROPE, fileName: Rope.
ROPE←
NIL, checkFile:
BOOL, check: CDDesignCache.CheckProc, data:
REF]
RETURNS [design:
CD.Design←
NIL] = {
IOCheck:
PROC [h: TokenIO.Handle]
RETURNS [ok:
BOOL] = {
design: CD.Design ← CDIO.DesignInReadOperation[h];
IF design.technology#for.technology
THEN {
TerminalIO.PutF["**technology missmatch: remote design is %g",
IO.rope[design.technology.name]
];
RETURN [FALSE]
};
ok ← Rope.Equal[remoteName, design.name];
IF ~ok
THEN
TerminalIO.PutF["file %g has different design: %g\n",
IO.rope[fileName],
IO.rope[CD.DesignName[design]]
];
};
SearchCheck: CDDesignCache.CheckProc = {
ok ← design.technology=for.technology;
IF ok AND check#NIL THEN ok ← check[design, data];
};
foundFile: Rope.ROPE ← NIL; x: REF;
time: BasicTime.GMT ← BasicTime.nullGMT;
TerminalIO.PutRopes["load remote design ", remoteName, "\n"];
IF Rope.IsEmpty[fileName] THEN fileName ← MakeUpFile[for, remoteName];
IF checkFile
THEN {
foundFile ← CDEnvironment.FindFile[fileName, ".dale", for];
IF Rope.IsEmpty[foundFile]
THEN {
TerminalIO.PutRopes[" not done; file ", fileName, " not found\n"];
RETURN
};
time ← FS.FileInfo[name: foundFile, remoteCheck: FALSE ! FS.Error => CONTINUE].created;
};
design ← Search[remoteName, foundFile, time, SearchCheck, data];
IF design#NIL THEN RETURN [design];
IF foundFile#NIL THEN fileName ← foundFile;
design ← CDIO.ReadDesign[fileName, IOCheck];
IF design#
NIL
THEN {
CDOps.SetMutability[design, readonly];
x ← CDValue.Fetch[design, $CDxFromFile, design];
CDValue.Store[design, $CDxCachedFile, x];
x ← CDValue.Fetch[design, $CDxFileCreated, design];
CDValue.Store[design, $CDxCachedCreated, x];
TerminalIO.PutRopes[" ", remoteName, " loaded\n"];
};
};
MakeUpFile:
PUBLIC
PROC [for:
CD.Design, remoteName: Rope.
ROPE]
RETURNS [fileName: Rope.
ROPE←
NIL] = {
GetHintList:
PROC [for:
CD.Design]
RETURNS [
LIST
OF Rope.
ROPE←
NIL] = {
IF for#
NIL
THEN
WITH CDProperties.GetDesignProp[for, $ImportHints]
SELECT
FROM
rL: LIST OF Rope.ROPE => RETURN [rL];
ENDCASE => NULL;
};
RemSpaces:
PROC [r: Rope.
ROPE]
RETURNS [Rope.
ROPE←
NIL] = {
leng: INT ← Rope.Length[r];
start: INT ← 0;
WHILE start<leng AND Rope.Fetch[r, start]=' DO start ← start+1 ENDLOOP;
WHILE leng>start AND Rope.Fetch[r, leng-1]=' DO leng ← leng-1 ENDLOOP;
IF leng>start THEN RETURN [Rope.Substr[r, start, leng-start]];
};
rl: LIST OF Rope.ROPE ← GetHintList[for];
key, rest: Rope.ROPE ← NIL;
FOR list:
LIST
OF Rope.
ROPE ← rl, list.rest
WHILE list#
NIL
DO
[key, rest] ← CDEnvironment.SplitLine[list.first];
IF Rope.Equal[remoteName, key] THEN RETURN [RemSpaces[rest]];
ENDLOOP;
fileName ← UserProfile.Token[Rope.Cat["ChipNDale.ImportFor.", remoteName], remoteName];
};
END.