VersionMap2FromPatternImpl.mesa
Copyright Ó 1990 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer on April 10, 1992 9:37 am PDT
DIRECTORY PFS, Rope, SimpleFeedback, VersionMap2, VersionMap2FromPattern, VersionMap2Implr, VersionMap2Pretty, VersionMapClassify;
VersionMap2FromPatternImpl: CEDAR PROGRAM
IMPORTS PFS, Rope, SimpleFeedback, VersionMap2, VersionMap2FromPattern, VersionMap2Implr, VersionMap2Pretty, VersionMapClassify
EXPORTS VersionMap2FromPattern
=
BEGIN OPEN VersionMap2, VersionMap2FromPattern, PVMC:VersionMapClassify, VM2i:VersionMap2Implr, VM2Pretty:VersionMap2Pretty;
ROPE: TYPE ~ Rope.ROPE;
class: MapClass ~ VM2i.FillinDefaults[FALSE, readonly, [
Scan: Scan]];
PatDat: TYPE ~ REF PatDatPrivate;
PatDatPrivate: TYPE ~ RECORD [
name: Name,
kinds: KindSet,
cache, hints, namePatMap: Map,
cg, hg, cl, hl, rtd: BOOL
];
Create: PUBLIC PROC [name: Name, kinds: KindSet ← allKinds, cache, hints: Map ← nullMap, restrictedCache, restrictedHints: BOOLFALSE] RETURNS [Map] ~ {
pd: PatDat ~ NEW[PatDatPrivate ← [name, kinds, cache, hints, CreateMatcher[[name]], cache#nullMap, hints#nullMap, restrictedCache, restrictedHints, kinds#allKinds]];
RETURN [[class, pd]]};
debug: BOOLFALSE;
Scan: PROC [map: Map, Consume: TupleConsumer, inOrder: BOOL, pfml: PatternFactoredMapList] RETURNS [mt: MaybeTuple ← noMaybe] ~ {
pd: PatDat ~ NARROW[map.data];
better, worse: Name;
mismatch, testWorse: BOOL;
PerName: PROC [name: Name] RETURNS [continue: BOOLTRUE] ~ {
IF NameMatch[name, worse]
THEN PFS.EnumerateForInfo[name, PerInfo];
RETURN[NOT mt.found]};
PerInfo: PROC [fullFName, attachedTo: Name, uniqueID: Created, bytes: INT, mutability: PFS.Mutability, fileType: PFS.FileType] RETURNS [continue: BOOLTRUE] --PFS.InfoProc-- ~ {
IF CreatedMatch[uniqueID, pfml.pattern.created] AND AllHave[pfml.stampInd, [fullFName, uniqueID]] THEN {
kindTested: BOOLFALSE;
nameR: ROPENIL;
ck: PVMC.Kind ← unknown;
PerMatch: PROC [vt: VersionTuple] RETURNS [BOOL] ~ {
IF StampMatch[vt.stamp, pfml.pattern.stamp] AND AllHave[pfml.general, vt] AND Consume[vt]
THEN mt ← [TRUE, vt];
RETURN [TRUE]};
RightKind: PROC RETURNS [BOOL] ~ INLINE {
IF kindTested THEN RETURN [TRUE];
kindTested ← TRUE;
nameR ← PFS.RopeFromPath[fullFName];
ck ← PVMC.Classify[nameR];
IF ck=unknown THEN RETURN [TRUE];
RETURN [pd.kinds[SELECT ck FROM source=>source, intermediate=>intermediate, sparc, sparcOpt=>executable, ENDCASE => ERROR]]};
IF pd.cg THEN {
IF pd.rtd AND (NOT pd.cl) AND (NOT RightKind[]) THEN RETURN;
IF pd.cache.ScanMatches[PerMatch, FALSE, [fullFName, uniqueID]].found THEN RETURN};
IF pd.hg THEN {
IF pd.rtd AND (NOT pd.hl) AND (NOT RightKind[]) THEN RETURN;
IF pd.hints.ScanMatches[PerMatch, FALSE, [fullFName, uniqueID]].found THEN RETURN};
IF NOT RightKind[] THEN RETURN;
{stamp: VersionStamp;
IF nameR=NIL THEN nameR ← PFS.RopeFromPath[fullFName];
IF debug THEN SimpleFeedback.PutF[$VersionMap2, oneLiner, $Debug,
"Reading stamp from %g.", [rope[nameR]] ];
stamp ← PVMC.ReadVersionStamp[ck, nameR, uniqueID.egmt.gmt, FALSE].stamp;
IF pd.cg THEN [] ← pd.cache.AddTuple[[fullFName, uniqueID, stamp]];
IF StampMatch[stamp, pfml.pattern.stamp] AND AllHave[pfml.general, [fullFName, uniqueID, stamp]] AND Consume[[fullFName, uniqueID, stamp]] THEN {
mt ← [TRUE, [fullFName, uniqueID, stamp]];
RETURN [FALSE]}
ELSE RETURN}};
RETURN [TRUE]};
IF pfml.stampInd=listOfEmpty THEN RETURN;
[mismatch, better, worse] ← NamePatternSortMerge[pfml.pattern.name, pd.name];
<<until we can enumerate one of our patterns, we wimp out:>>
better ← pd.name;
worse ← pfml.pattern.name;
testWorse ← NOT (mismatch OR worse=nullName OR NameEqual[better, worse]);
IF debug THEN SimpleFeedback.PutFL[$VersionMap2, oneLiner, $Debug,
"Scanning %g in %g, enumerating %g%g.", LIST[
[rope[VM2Pretty.FormatTuple[pfml.pattern]]],
[rope[VM2Pretty.FormatName[pd.name]]],
[rope[IF mismatch THEN "<nothing>" ELSE VM2Pretty.FormatName[better]]],
[rope[IF testWorse THEN Rope.Concat[" and ", VM2Pretty.FormatName[worse]] ELSE NIL]] ]];
IF mismatch THEN RETURN;
IF better=nullName THEN VM2i.Cant[LIST[pd, NEW[PatternFactoredMapList ← pfml]], "A map from pattern can't Scan (better is null)"];
IF testWorse
THEN PFS.EnumerateForNames[better, PerName]
ELSE PFS.EnumerateForInfo[better, PerInfo];
RETURN};
END.