<<>> <> <> <> DIRECTORY Commander, CommanderOps, IO, MorePfsEnumeration, PFS, PFSNames, RefTab, Rope, RopeHash, VersionMap2, VersionMap2Binding, VersionMap2BindingByPattern, VersionMap2FromPattern, VersionMap2Pretty; VersionMap2CommandsImpl: CEDAR PROGRAM IMPORTS Commander, CommanderOps, IO, MorePfsEnumeration, PFS, PFSNames, RefTab, Rope, RopeHash, VersionMap2, VersionMap2Binding, VersionMap2BindingByPattern, VersionMap2FromPattern, VersionMap2Pretty = BEGIN OPEN VM2:VersionMap2, VM2BP:VersionMap2BindingByPattern, VM2Pretty:VersionMap2Pretty; ROPE: TYPE ~ Rope.ROPE; VLS: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- ~ { argv: CommanderOps.ArgumentVector _ CommanderOps.Parse[cmd]; map: VM2.Map; pattern: VM2.VersionTuple _ []; IF argv.argc < 3 OR argv.argc > 5 THEN RETURN [$Failure, "Usage: VM2LS [ []]"]; {ENABLE PFS.Error => { msg _ IO.PutFR["Error[%g, %g]", [atom[error.code]], [rope[error.explanation]] ]; GOTO Fail}; PrintMatch: PROC [vt: VM2.VersionTuple] RETURNS [BOOL] ~ { cmd.out.PutRope[VM2Pretty.FormatTuple[vt]]; cmd.out.PutRope["\n"]; RETURN [FALSE]}; IF argv[1].Length[] > 0 AND argv[1].Fetch[0] = '$ THEN map _ VersionMap2Binding.GetMap[argv[1].Substr[1]] ELSE map _ VM2.MapFromFile[PFS.PathFromRope[argv[1]], VM2.nullCreated, TRUE]; pattern.name _ VM2Pretty.ParseName[argv[2]]; IF argv.argc > 3 THEN pattern.created _ VM2Pretty.ParseCreated[argv[3]]; IF argv.argc > 4 THEN pattern.stamp _ VM2Pretty.ParseStamp[argv[4]]; IF map.ScanMatches[PrintMatch, TRUE, pattern].found THEN ERROR; RETURN}; EXITS Fail => result _ $Failure}; ListList: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; PerRoot: PROC [root: ROPE] RETURNS [stop: BOOL] ~ { PerItem: PROC [pattern: VM2.Name] RETURNS [stop: BOOL] ~ { cmd.out.PutF1[" %g", [rope[PFS.RopeFromPath[pattern]]] ]; RETURN[FALSE]}; cmd.out.PutF1["%g =>", [rope[root]] ]; VM2BP.ScanList[root, PerItem]; cmd.out.PutRope["\n"]; RETURN [FALSE]}; IF argv.argc<2 THEN VM2BP.ScanLists[PerRoot] ELSE FOR i: NAT IN (0..argv.argc) DO [] _ PerRoot[argv[i]] ENDLOOP; RETURN}; ListAdd: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; IF argv.argc<2 THEN RETURN [$Failure, "Usage: WatchPatternVersions ..."]; FOR i: NAT IN (1..argv.argc) DO pat: VM2.Name ~ PFS.PathFromRope[argv[i]]; abs: VM2.Name ~ PFS.AbsoluteName[pat]; VM2BP.AddToList[argv[1], abs]; ENDLOOP; RETURN}; Key: TYPE ~ REF KeyPrivate; KeyPrivate: TYPE ~ RECORD [shortName: ROPE, created: VM2.Created]; ListCollisions: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- ~ { argv: CommanderOps.ArgumentVector _ CommanderOps.Parse[cmd]; map: VM2.Map; detect: RefTab.Ref ~ RefTab.Create[hash: Hash, equal: Equal]; doit: RefTab.Ref ~ RefTab.Create[hash: Hash, equal: Equal]; IF argv.argc # 2 THEN RETURN [$Failure, "Usage: VM2LS "]; {ENABLE PFS.Error => { msg _ IO.PutFR["Error[%g, %g]", [atom[error.code]], [rope[error.explanation]] ]; GOTO Fail}; NoteTuple: PROC [vt: VM2.VersionTuple] RETURNS [BOOL] ~ { lc: PFSNames.Component ~ vt.name.ShortName[]; key: Key ~ NEW [KeyPrivate _ [lc.ComponentRope[], vt.created]]; IF NOT detect.Insert[key, $T] THEN [] _ doit.Store[key, $T]; RETURN [FALSE]}; Report: PROC [key, val: REF ANY] RETURNS [quit: BOOL _ FALSE] ~ { k: Key ~ NARROW[key]; PrintCollider: PROC [vt: VM2.VersionTuple] RETURNS [BOOL] ~ { vlc: PFSNames.Component ~ vt.name.ShortName[]; mod: VM2.Name ~ vt.name.ReplaceShortName[[name: [NIL, 0, 0], version: vlc.version]]; cmd.out.PutF["\t%g ver %g\n", [rope[VM2Pretty.FormatName[mod]]], [rope[VM2Pretty.FormatStamp[vt.stamp]]] ]; RETURN [FALSE]}; cmd.out.PutF["%g of %g:", [rope[k.shortName]], [rope[VM2Pretty.FormatCreated[k.created]]] ]; IF map.ScanMatches[PrintCollider, FALSE, [VM2.ShortNameToPattern[k.shortName].name, k.created]].found THEN ERROR; cmd.out.PutRope["\n"]; RETURN}; IF argv[1].Length[] > 0 AND argv[1].Fetch[0] = '$ THEN map _ VersionMap2Binding.GetMap[argv[1].Substr[1]] ELSE map _ VM2.MapFromFile[PFS.PathFromRope[argv[1]], VM2.nullCreated, TRUE]; IF map.Scan[NoteTuple, FALSE].found THEN ERROR; cmd.out.PutF1["%g collisions.\n", [integer[doit.GetSize]] ]; IF doit.Pairs[Report] THEN ERROR; RETURN}; EXITS Fail => result _ $Failure}; TestPSM: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- ~ { argv: CommanderOps.ArgumentVector _ CommanderOps.Parse[cmd]; pat1, pat2, better, worse: VM2.Name; mismatch: BOOL; IF argv.argc#3 THEN RETURN [$Failure, "Usage: test-psm pat1 pat2"]; pat1 _ VM2Pretty.ParseName[argv[1]]; pat2 _ VM2Pretty.ParseName[argv[2]]; [mismatch, better, worse] _ VersionMap2FromPattern.NamePatternSortMerge[pat1, pat2]; cmd.out.PutF["%g, %g => ", [rope[VM2Pretty.FormatName[pat1]]], [rope[VM2Pretty.FormatName[pat2]]] ]; IF mismatch THEN cmd.out.PutRope["mismatch.\n"] ELSE cmd.out.PutF["%g, %g\n", [rope[VM2Pretty.FormatName[better]]], [rope[VM2Pretty.FormatName[worse]]] ]; RETURN}; LS: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- ~ { argv: CommanderOps.ArgumentVector _ CommanderOps.Parse[cmd]; PerInfo: PROC [fullFName, attachedTo: PFS.PATH, uniqueID: PFS.UniqueID, bytes: INT, mutability: PFS.Mutability, fileType: PFS.FileType] RETURNS [continue: BOOL _ TRUE] ~ { cmd.out.PutF["%g %8g %g", [time[uniqueID.egmt.gmt]], [integer[bytes]], [rope[PFS.RopeFromPath[fullFName]]] ]; IF attachedTo#NIL THEN cmd.out.PutF1[" -> %g", [rope[PFS.RopeFromPath[attachedTo]]] ]; cmd.out.PutRope["\n"]; RETURN}; FOR i: NAT IN (0..argv.argc) DO ENABLE PFS.Error => { cmd.err.PutF["%g => PFS.Error[%g, %g]\n", [rope[argv[i]]], [atom[error.code]], [rope[error.explanation]] ]; CONTINUE}; pat: PFS.PATH ~ PFS.PathFromRope[argv[i]]; abs: PFS.PATH ~ PFS.AbsoluteName[pat]; MorePfsEnumeration.EnumerateForInfo[abs, PerInfo]; ENDLOOP; RETURN}; Hash: PROC [key: REF ANY] RETURNS [CARDINAL] ~ { k: Key ~ NARROW[key]; cc: CARD ~ LOOPHOLE[k.created.egmt.gmt]; RETURN [RopeHash.FromRope[rope: k.shortName, case: FALSE, seed: (cc + cc/65536) MOD 65536]]}; Equal: PROC [key1, key2: REF ANY] RETURNS [BOOL] ~ { k1: Key ~ NARROW[key1]; k2: Key ~ NARROW[key2]; RETURN [k1.created=k2.created AND k1.shortName.Equal[k2.shortName, FALSE]]}; Commander.Register["VM2LS", VLS, " [ []] --- lists matching tuples in the indicated map"]; Commander.Register["LS2", LS, "... --- VM2-style file enumeration"]; Commander.Register["ListShortAndCreatedCollisions", ListCollisions, " --- lists sets of tuples with equal shortname & create date"]; Commander.Register["WatchPatternVersions", ListAdd, " * --- be willing to look in files with names matching given patterns for version stamps for lists identified by (for all )"]; Commander.Register["ListPatternVersionsWatches", ListList, "* --- list patterns watched for version map lists identified by (for all ) for each given , or all s if none given"]; Commander.Register["test-psm", TestPSM, " --- sort/merges two VM2 name patterns"]; END.