DListCommandProc: Commander.CommandProc = {
[cmd: Handle] RETURNS [result: REF ← NIL, msg: ROPE ← NIL]
CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...]
EachFileInfo:
PFS.InfoProc = {
item: FileItem ¬ NIL;
continue ¬ TRUE;
Process.CheckForAbort[];
item ¬ NEW[FileItemRep ¬ [fullFName, attachedTo, uniqueID.egmt.gmt, bytes, fileType]];
filesSeen ¬ filesSeen + 1;
IF bytes > 0 THEN bytesTotal ¬ bytesTotal + bytes;
PriorityQueue.Insert[pq, item];
};
PrintOneFile:
PROC [item: FileItem] = {
item: REF [fullUName, attachedTo: PATH, created: GMT, bytes: INT, keep: CARDINAL, PFS.FileType]
oldLag: PATH ¬ lagPrefix;
printName: ROPE ¬ PFS.RopeFromPath[item.fullUName];
Process.CheckForAbort[];
Factor out the directories
SetLagPrefix[item.fullUName];
IF oldLag # lagPrefix
THEN {
IO.PutRope[out, PFS.RopeFromPath[lagPrefix]];
IO.PutChar[out, '\n];
};
printName ¬ PFS.RopeFromPath[PFSNames.SubName[item.fullUName, lagPrefixLen]];
IO.PutRope[out, " "];
IO.PutF1[out, "%-24g ", [rope[printName]] ];
IF item.created = BasicTime.nullGMT
THEN IO.PutRope[out, "??"]
ELSE DateToStream[out, [explicit, item.created] ];
IO.PutChar[out, '\n];
};
AddFile:
PROC [pattern:
PATH, allVersions:
BOOL] = {
Do:
PROC [] ~ {
ENABLE
PFS.Error =>
IF error.group # $bug
THEN {
IO.PutRope[cmd.err, " -- "];
IO.PutRope[cmd.err, error.explanation];
IO.PutRope[cmd.err, "\n"];
GO TO err};
patternsTried ¬ patternsTried + 1;
PFS.EnumerateForInfo[pattern, EachFileInfo];
In these cases it is better to enumerate for info, to reduce server traffic
EXITS
err => {IO.PutRope[cmd.err, "\n"]; RETURN};
};
wDir: ROPE ~ NARROW[ProcessProps.GetProp[$WorkingDirectory]];
newProp: List.AList ~ List.PutAssoc[$WDir, PFS.PathFromRope[wDir], NIL];
ProcessProps.AddPropList[newProp, Do];
};
SetLagPrefix:
PROC [fileName:
PATH] = {
... sets the lagging prefix from the given file name, which is presumed to be syntactically correct, although it need not be complete. A file name without a prefix will set the lagPrefix to NIL. We also enforce lagPrefixLen = Rope.Length[lagPrefix] at exit, assuming that no other routine sets lagPrefix.
newPrefix: PATH ¬ IF fileName# NIL THEN PFSNames.Parent[fileName] ELSE NIL;
IF lagPrefix #
NIL
THEN {
do we have a new prefix?
IF PFSNames.Equal[lagPrefix, newPrefix] THEN RETURN;
};
We have a new lagging prefix, so scan backwards for the LAST directory
lagPrefix ¬ newPrefix;
lagPrefixLen ¬ PFSNames.ComponentCount[newPrefix];
};
AddSortOption:
PROC [option:
ATOM] = {
new: LORA ¬ LIST[option];
IF sortDataTail = NIL THEN sortData ¬ new ELSE sortDataTail.rest ¬ new;
sortDataTail ¬ new;
};
out: STREAM = cmd.out;
lagPrefix: PATH ¬ NIL;
lagPrefixLen: INT ¬ 0;
patternsTried, filesSeen, bytesTotal: INT ¬ 0;
complexSorting: BOOL ¬ TRUE;
sortData: LORA ¬ NIL;
sortDataTail: LORA ¬ NIL;
pq: PriorityQueue.Ref;
AddSortOption[$MoreRecent];
pq ¬ PriorityQueue.Create[SortPred, sortData];
DO
arg: ROPE = CommanderOps.NextArgument[cmd];
IF arg = NIL THEN EXIT;
the argument is assumed to be a file name.
AddFile[
PFS.PathFromRope[arg !
PFS.Error =>
IF error.group # $bug
THEN {
IO.PutRope[cmd.err, " -- "];
IO.PutRope[cmd.err, error.explanation];
IO.PutRope[cmd.err, "\n"];
GO TO failed}], FALSE];
ENDLOOP;
IF filesSeen > 0
THEN {
out: IO.STREAM ~ IO.ROS[];
IF pq #
NIL
THEN {
lagName: PATH ¬ NIL;
THROUGH [0..PriorityQueue.Size[pq])
DO
item: FileItem = NARROW[PriorityQueue.Remove[pq]];
PrintOneFile[item];
ENDLOOP;
};
IO.PutF1[out, "-- %g files", [integer[filesSeen]] ];
IF bytesTotal > 0 THEN IO.PutF1[out, ", %g total bytes", [integer[bytesTotal]] ];
IO.PutChar[out, '\n];
msg ¬ IO.RopeFromROS[out];
};
EXITS
failed => {result ¬ $Failure};
};
FileItem: TYPE = REF FileItemRep;
FileItemRep:
TYPE =
RECORD [fullUName, attachedTo:
PATH, created:
GMT, bytes:
INT, fileType:
PFS.FileType];
SortPred: PriorityQueue.SortPred = {
[x: Item, y: Item, data: REF] RETURNS [BOOL]
xx: FileItem = NARROW[x];
yy: FileItem = NARROW[y];
options: LORA = NARROW[data];
FOR each:
LORA ¬ options, each.rest
WHILE each #
NIL
DO
SELECT each.first
FROM
$MoreRecent => {
IF xx.created = yy.created THEN LOOP;
RETURN [BasicTime.Period[xx.created, yy.created] < 0];
};
$LessRecent => {
IF xx.created = yy.created THEN LOOP;
RETURN [BasicTime.Period[xx.created, yy.created] > 0];
};
$Larger => {
IF xx.bytes = yy.bytes THEN LOOP;
RETURN [xx.bytes > yy.bytes];
};
$Smaller => {
IF xx.bytes = yy.bytes THEN LOOP;
RETURN [xx.bytes < yy.bytes];
};
ENDCASE;
ENDLOOP;
RETURN [PFSNames.Compare[xx.fullUName, yy.fullUName, FALSE] = less];
};