DirectoryListImpl.mesa
Michael Plass, May 2, 1983 11:59 am
DIRECTORY ConvertUnsafe, Directory, DirectoryList, Heap, MessageWindow, RefText, Rope, UnsafeSTP, UserCredentials;
DirectoryListImpl: CEDAR PROGRAM
IMPORTS ConvertUnsafe, Directory, Heap, MessageWindow, RefText, Rope, UnsafeSTP, UserCredentials
EXPORTS DirectoryList ~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
PastPattern: PROC [pattern: ROPE, text: REF TEXT, start: INT] RETURNS [BOOLEAN] ~ {
FOR i: INT IN [0..MIN[pattern.Length, text.length - start]) DO
c: CHAR ← Rope.Upper[pattern.Fetch[i]];
t: CHAR ← Rope.Upper[text[start+i]];
IF c = '* THEN RETURN [FALSE];
IF t # c THEN RETURN [t > c];
ENDLOOP;
RETURN [FALSE];
};
NeverAbort: PUBLIC PROC RETURNS [BOOLEAN] ~ {RETURN [FALSE]};
Local: PUBLIC PROC [pattern: ROPE, abortProc: PROC RETURNS [BOOLEAN]] RETURNS [LIST OF ROPE] ~ {
pathNameText: REF TEXT ~ RefText.ObtainScratch[200];
currentNameText: REF TEXT ~ RefText.ObtainScratch[200];
nextNameText: REF TEXT ~ RefText.ObtainScratch[200];
list: LIST OF ROPENIL;
TRUSTED {
nextName: LONG STRING ~ LOOPHOLE[nextNameText];
[] ← Directory.GetNext[pathName: "WorkDir>", currentName: "", nextName: nextName];
};
FOR i: NAT DECREASING IN [0..nextNameText.length) DO
IF nextNameText[i] = '> THEN {nextNameText.length ← i+1; EXIT}
ENDLOOP;
pathNameText.length ← 0; RefText.Append[pathNameText, nextNameText];
currentNameText.length ← 0;
nextNameText.length ← 0;
UNTIL abortProc[] DO
TRUSTED {
pathName: LONG STRING ~ LOOPHOLE[pathNameText];
currentName: LONG STRING ~ LOOPHOLE[currentNameText];
nextName: LONG STRING ~ LOOPHOLE[nextNameText];
[] ← Directory.GetNext[pathName: pathName, currentName: currentName, nextName: nextName];
};
IF nextNameText.length = 0 OR PastPattern[pattern, nextNameText, pathNameText.length] THEN EXIT;
currentNameText.length ← 0; RefText.Append[currentNameText, nextNameText, pathNameText.length];
nextNameText.length ← 0;
TRUSTED {
object: Rope.Text ~ LOOPHOLE[currentNameText];
IF Rope.Match[pattern: pattern, object: object, case: FALSE] THEN
list ← CONS[Rope.FromRefText[currentNameText], list];
};
ENDLOOP;
RefText.ReleaseScratch[pathNameText];
RefText.ReleaseScratch[currentNameText];
RefText.ReleaseScratch[nextNameText];
RETURN[Reverse[list]];
};
Remote: PUBLIC PROC [host: ROPE, pattern: ROPE, abortProc: PROC RETURNS [BOOLEAN]] RETURNS [matchingFiles: LIST OF ROPENIL, errorMsg: ROPENIL] ~ TRUSTED {
name, password: ROPE;
[name, password] ← UserCredentials.GetUserCredentials[]; {
nameText: REF TEXT ~ name.ToRefText;
nameString: LONG STRING ~ LOOPHOLE[nameText];
passwordText: REF TEXT ~ password.ToRefText;
passwordString: LONG STRING ~ LOOPHOLE[passwordText];
hostText: REF TEXT ~ host.ToRefText;
hostString: LONG STRING ~ LOOPHOLE[hostText];
patternText: REF TEXT ~ pattern.ToRefText;
patternString: LONG STRING ~ LOOPHOLE[patternText];
stp: UnsafeSTP.Handle ← UnsafeSTP.Create[];
aborted: BOOLEANFALSE;
herald: LONG STRING ← stp.Open[hostString];
MessageWindow.Append[ConvertUnsafe.ToRope[herald], TRUE];
Heap.systemZone.FREE[@herald]; herald ← NIL;
MessageWindow.Append[" "];
stp.Login[nameString, passwordString]; {
nMod10: NAT ← 0;
Visit: PROCEDURE [file: LONG STRING] RETURNS [continue: UnsafeSTP.Continue] ~ TRUSTED {
matchingFiles ← CONS[ConvertUnsafe.ToRope[file], matchingFiles];
IF nMod10 = 0 THEN MessageWindow.Append["."];
nMod10 ← nMod10 + 1;
IF nMod10 = 10 THEN nMod10 ← 0;
continue ← IF aborted ← abortProc[] THEN no ELSE yes;
};
stp.SetDesiredProperties[desiredProperties];
stp.Enumerate[patternString, Visit ! UnsafeSTP.Error => {errorMsg ← ConvertUnsafe.ToRope[error]; CONTINUE}];
};
stp ← stp.Destroy;
MessageWindow.Append[" Closed."];
IF aborted THEN errorMsg ← errorMsg.Concat[" (List aborted by user request)"];
matchingFiles ← Reverse[matchingFiles];
};
};
Reverse: PROC [list: LIST OF ROPE] RETURNS [reversed: LIST OF ROPENIL] ~ {
WHILE list # NIL DO
t: LIST OF ROPE ← list;
list ← t.rest;
t.rest ← reversed;
reversed ← t;
ENDLOOP;
};
desiredProperties: UnsafeSTP.DesiredProperties ← ALL[FALSE];
desiredProperties[directory] ← TRUE;
desiredProperties[nameBody] ← TRUE;
desiredProperties[version] ← TRUE;
END.