VersionMap2FromFile.mesa
Copyright Ó 1990 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer on April 10, 1992 9:55 am PDT
DIRECTORY Atom, BasicTime, MorePfsNames, PFS, PFSNames, Rope, SymTab, VersionMap, VersionMap2, VersionMap2Binding, VersionMap2BindingByPattern, VersionMap2FromPattern, VersionMap2Implr, VersionMapDefaults;
VersionMap2FromFile:
CEDAR
PROGRAM
IMPORTS Atom, MorePfsNames, PFS, PFSNames, Rope, SymTab, VersionMap, VersionMap2, VersionMap2FromPattern, VersionMap2Implr, VersionMapDefaults
EXPORTS VersionMap2, VersionMap2Binding, VersionMap2BindingByPattern
=
BEGIN OPEN VM2:VersionMap2, VM2i:VersionMap2Implr, VM2P:VersionMap2FromPattern, PVM:VersionMap, PVMD:VersionMapDefaults, MPfsN:MorePfsNames;
ROPE: TYPE ~ Rope.ROPE;
allName: VM2.Name ← PFSNames.ConstructName[LIST[MPfsN.ConstructComponent[["**"], [all]], MPfsN.ConstructComponent[["*"], [all]]], TRUE];
class:
VM2.MapClass ~ VM2i.FillinDefaults[
TRUE, constant, [
CreateGenerator: MFFCreateGenerator,
Size: MFFSize,
data: NIL]];
rootToNpl: SymTab.Ref ~ SymTab.Create[case: TRUE];
srcCache: VM2.Map ~ VM2.CreateVariableMap[];
intCache:VM2.Map ~ VM2.CreateVariableMap[];
exlCache: VM2.Map ~ VM2.CreateVariableMap[];
NamePatternList:
TYPE ~
LIST
OF
RECORD [
pat: VM2.Name,
maps: ARRAY VM2P.Kind OF VM2.Map];
ScanLists:
PUBLIC
PROC [
Consume:
PROC [root:
ROPE]
RETURNS [stop:
BOOL]] ~ {
PerPair:
PROC [key:
ROPE, val:
REF
ANY]
RETURNS [quit:
BOOL] ~ {
quit ← Consume[key];
RETURN};
[] ← rootToNpl.Pairs[PerPair];
RETURN};
ScanList:
PUBLIC
PROC [root:
ROPE,
Consume:
PROC [pattern:
VM2.Name]
RETURNS [stop:
BOOL]] ~ {
npl: NamePatternList ← NARROW[rootToNpl.Fetch[root].val];
FOR l: NamePatternList ← npl, l.rest
WHILE l#
NIL
DO
IF Consume[l.first.pat] THEN RETURN;
ENDLOOP;
RETURN};
AddToList:
PUBLIC
PROC [root:
ROPE, pattern:
VM2.Name] ~ {
npl: NamePatternList ← NARROW[rootToNpl.Fetch[root].val];
FOR l: NamePatternList ← npl, l.rest
WHILE l#
NIL
DO
IF VM2.NameEqual[l.first.pat, pattern] THEN RETURN;
ENDLOOP;
npl ←
CONS[
[pattern, [
VM2P.Create[pattern, VM2P.OneKind[source], srcCache, VM2.nullMap, TRUE],
VM2P.Create[pattern, VM2P.OneKind[intermediate], intCache, VM2.nullMap, TRUE],
VM2P.Create[pattern, VM2P.OneKind[executable], exlCache, VM2.nullMap, TRUE] ]],
npl];
[] ← rootToNpl.Store[root, npl];
RETURN};
RemFromList:
PUBLIC
PROC [root:
ROPE, pattern:
VM2.Name] ~ {
head, l: NamePatternList ← NARROW[rootToNpl.Fetch[root].val];
last: NamePatternList ← NIL;
WHILE l#
NIL
DO
IF
VM2.NameEqual[l.first.pat, pattern]
THEN {
IF last=NIL THEN head ← l.rest ELSE last.rest ← l.rest;
}
ELSE last ← l;
l ← l.rest;
ENDLOOP;
[] ← rootToNpl.Store[root, head];
RETURN};
GetMap:
PUBLIC
PROC [key:
ROPE]
RETURNS [
VM2.Map] ~ {
which: ATOM ~ Atom.MakeAtom[key];
all: PVM.MapList ~ PVMD.GetMapList[which];
map: VM2.Map ← VM2.anEmpty;
npl: NamePatternList;
kind: VM2P.Kind;
[npl, kind] ← Factor[key];
FOR list:
PVM.MapList ← all, list.rest
WHILE list#
NIL
DO
map ← map.Union[[class, list.first], other];
ENDLOOP;
FOR l: NamePatternList ← npl, l.rest
WHILE l#
NIL
DO
map ← map.Union[l.first.maps[kind], map];
ENDLOOP;
RETURN [map]};
Factor:
PROC [key:
ROPE]
RETURNS [npl: NamePatternList ←
NIL, kind:
VM2P.Kind ← source] ~ {
kl: INT ~ key.Length[];
Try:
PROC [sfx:
ROPE, k:
VM2P.Kind]
RETURNS [
BOOL] ~ {
sfxl: INT ~ sfx.Length[];
IF sfxl<=kl
AND Rope.EqualSubstrs[key, kl-sfxl, sfxl, sfx, 0, sfxl,
TRUE]
THEN {
npl ← NARROW[rootToNpl.Fetch[key.Substr[0, kl-sfxl]].val];
kind ← k;
RETURN [TRUE]}
ELSE RETURN [FALSE]};
got:
BOOL ← Try["Source", source]
OR Try["Intermediate", intermediate]
OR Try["Executable", executable];
RETURN};
<<GetMap:
PUBLIC
PROC [key:
ROPE]
RETURNS [
VM2.Map] ~ {
found: BOOL;
ma: REF ANY;
[found, ma] ← keyCache.Fetch[key];
IF found THEN RETURN [VM2.DeRefify[ma]^];
{fileNames:
VM2.
LOR ← UserProfile.ListOfTokens[
key: Rope.Cat["VersionMap.", key, "Maps"],
default:
SELECT
TRUE
FROM
key.Equal["Source", FALSE] => LIST["/PCedar/VersionMap/PCedarSource.VersionMap"],
key.Equal["Intermediate", FALSE] => LIST["/PCedar/VersionMap/PCedarIntermediate.VersionMap"],
key.Equal["Executable", FALSE] => LIST["/PCedar/VersionMap/PCedarSparcExecutable.VersionMap", "/PCedar/VersionMap/PCedarSparcOptExecutable.VersionMap"],
ENDCASE => NIL
];
map: VM2.Map ← VM2.anEmpty;
FOR fileNames ← fileNames, fileNames.rest
WHILE fileNames#
NIL
DO
next: VM2.Map ~ MapFromFile[PFS.PathFromRope[fileNames.first !PFS.Error => LOOP], VM2.nullCreated, TRUE];
map ← map.Union[next];
ENDLOOP;
[] ← keyCache.Insert[key, map.Refify[]];
RETURN [map]}};>>
MapFromFile:
PUBLIC
PROC [fileName:
VM2.Name, created:
VM2.Created, assumeImmutable:
BOOL]
RETURNS [
VM2.Map] ~ {
om: PVM.Map ~ PVM.RestoreMapFromFile[fileName, created, assumeImmutable];
RETURN [[class, om]]};
MapIsFromFile:
PUBLIC
PROC [map:
VM2.Map]
RETURNS [
VM2.MaybeFromFile] ~ {
IF map.class=class
THEN {
om: PVM.Map ~ NARROW[map.data];
RETURN [[TRUE, om.fileName, om.askedForUID, om.assumeImmutable]]};
RETURN [[FALSE, VM2.nullName, VM2.nullCreated, FALSE]]};
MFFCreateGenerator:
PROC [map:
VM2.Map, inOrder:
BOOL, pfml: VM2.PatternFactoredMapList]
RETURNS [gen:
VM2.Generator] ~ {
om: PVM.Map ~ NARROW[map.data];
IF pfml.pattern.stamp #
VM2.nullStamp
THEN {
theStamp: VM2.VersionStamp ~ pfml.pattern.stamp;
manl: PVM.MapAndNameList ~ PVM.VersionToAllNames[LIST[om], theStamp];
pfml.pattern.stamp ← VM2.nullStamp;
RETURN CreateManlGenerator[map, inOrder, pfml, manl, theStamp]};
IF pfml.pattern.name = VM2.nullName THEN pfml.pattern.name ← allName;
{shortNameC: PFSNames.Component ~ pfml.pattern.name.ShortName[];
shortNameR: ROPE ~ shortNameC.ComponentRope[--don't want or expect this to include version--];
starp: INT ~ shortNameR.Index[s2: "*"];
dstarp: INT ~ shortNameR.Find["**"];
IF dstarp >= 0
THEN {
--foo/x**y => foo/x*y + foo/x**/*y
path1: VM2.Name ~ pfml.pattern.name.ReplaceShortName[MPfsN.ConsComponent[[shortNameR, 0, dstarp+2], [all]]];
path2: VM2.Name ~ PFSNames.ConstructName[LIST[MPfsN.ConstructComponent[[shortNameR, dstarp+1], shortNameC.version]]];
simpleR: ROPE ~ shortNameR.Replace[dstarp, 1, NIL];
simpleC: PFSNames.Component ~ MPfsN.ConstructComponent[[simpleR], shortNameC.version];
simpleP: VM2.Name ~ pfml.pattern.name.ReplaceShortName[simpleC];
g1: VM2.Generator ~ MFFCreateGenerator[map, inOrder, [[simpleP, pfml.pattern.created, pfml.pattern.stamp], pfml.stampInd, pfml.general]];
g2: VM2.Generator ~ MFFCreateGenerator[map, inOrder, [[path1.Cat[path2], pfml.pattern.created, pfml.pattern.stamp], pfml.stampInd, pfml.general]];
RETURN g1.GeneratorUnion[g2, inOrder]}
ELSE {
prefix: ROPE ~ shortNameR.Substr[len: starp];
rangeList: PVM.RangeList ~ PVM.ShortNameToRanges[LIST[om], prefix];
rg: RangeGenerator ~ NEW [RangeGeneratorPrivate ← [rangeList, prefix, prefix.Length[], pfml]];
FOR rl:
PVM.RangeList ← rangeList, rl.rest
WHILE rl#
NIL
DO
rl.first.len ← rl.first.map.Length[] - rl.first.first;
ENDLOOP;
gen ← NEW [VM2.GeneratorRep ← [RangeNext, VM2i.DullClose, rg]];
IF inOrder THEN gen ← VM2.GeneratorSort[gen];
RETURN};
RangeGenerator: TYPE ~ REF RangeGeneratorPrivate;
RangeGeneratorPrivate:
TYPE ~
RECORD [
rangeList: PVM.RangeList,
prefix: ROPE, prefixLen: INT,
pfml: VM2.PatternFactoredMapList
];
RangeNext:
PROC [gen:
VM2.Generator]
RETURNS [
VM2.VersionTuple] ~ {
rg: RangeGenerator ~ NARROW[gen.data];
DO t:
VM2.VersionTuple;
nameR: ROPE;
gmt: BasicTime.GMT;
stamp: VM2.VersionStamp;
IF rg.rangeList = NIL THEN RETURN [VM2.nullTuple];
IF rg.rangeList.first.len = 0 THEN {rg.rangeList ← rg.rangeList.rest; LOOP};
[nameR, stamp, gmt, rg.rangeList.first] ← PVM.RangeToEntry[rg.rangeList.first];
t ← [PFS.PathFromRope[nameR], VM2.CreatedFromGMT[gmt], stamp];
{snr: ROPE ~ t.name.ShortName[].ComponentRope[--no version part wanted or expected--];
IF NOT rg.prefix.EqualSubstrs[s2: snr, len2: rg.prefixLen, case: FALSE] THEN {rg.rangeList ← rg.rangeList.rest; LOOP};
IF VM2.PfmlHas[rg.pfml, t] THEN RETURN [t];
}ENDLOOP;
};
CreateManlGenerator:
PROC [map:
VM2.Map, inOrder:
BOOL, pfml: VM2.PatternFactoredMapList, manl:
PVM.MapAndNameList, stamp:
VM2.VersionStamp]
RETURNS [gen:
VM2.Generator] ~ {
IF VM2i.NamePatternAcceptsAll[pfml.pattern.name, 2] THEN pfml.pattern.name ← VM2.nullName;
{mg: ManlGenerator ~ NEW [ManlGeneratorPrivate ← [manl, stamp, pfml, pfml.pattern=[] ]];
gen ← NEW [VM2.GeneratorRep ← [ManlNext, VM2i.DullClose, mg]];
IF inOrder THEN gen ← VM2.GeneratorSort[gen];
RETURN}};
ManlGenerator: TYPE ~ REF ManlGeneratorPrivate;
ManlGeneratorPrivate:
TYPE ~
RECORD [
manl: PVM.MapAndNameList,
stamp: VM2.VersionStamp,
pfml: VM2.PatternFactoredMapList,
patternAcceptsAll: BOOL];
ManlNext:
PROC [gen:
VM2.Generator]
RETURNS [
VM2.VersionTuple] ~ {
mg: ManlGenerator ~ NARROW[gen.data];
DO
IF mg.manl=NIL THEN RETURN [VM2.nullTuple];
{t: VM2.VersionTuple ~ [PFS.PathFromRope[mg.manl.first.name], VM2.CreatedFromGMT[mg.manl.first.created], mg.stamp];
mg.manl ← mg.manl.rest;
IF VM2.PfmlHas[mg.pfml, t] THEN RETURN [t];
}ENDLOOP;
};
MFFSize:
PROC [map:
VM2.Map, limit:
INT]
RETURNS [
INT] ~ {
om: PVM.Map ~ NARROW[map.data];
RETURN om.Length[]};
END.