<<>> <> <> <> 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}; < 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.