MODULE--------------------------------------------------------------------------; IMPORT Time, TextSeq; IMPORT FileInfo, FileStatus, FindExpr, BoolSeq, RegEx; IMPORT APN AS APN, APNSeq AS APNSeq; DirTree
PROCEDURE--------------------------------------------------------------------------SimpleTextDirLayout (self : SimpleTextLayout; pn : APN.T; time : Time.T; size : LONGINT; <*UNUSED*>level : CARDINAL; lastPrefix : BoolSeq.T) : TEXT = VAR res := ""; ilast := lastPrefix.size() - 1; BEGIN FOR i := 0 TO ilast DO WITH last = lastPrefix.get(i) DO IF i < ilast THEN IF last THEN res := res & " "; ELSE res := res & " | "; END; ELSE IF last THEN res := res & " \\- "; ELSE res := res & " |- "; END; END; END; END; RETURN res & self.fmtDir(pn, time, size) & "\n"; END SimpleTextDirLayout;
PROCEDURE--------------------------------------------------------------------------SimpleTextFileLayout (self : SimpleTextLayout; pn : APN.T; time : Time.T; size : LONGINT; <*UNUSED*>level : CARDINAL; lastPrefix : BoolSeq.T) : TEXT = VAR res := ""; ilast := lastPrefix.size() - 1; BEGIN FOR i := 0 TO ilast DO WITH last = lastPrefix.get(i) DO IF i < ilast THEN IF last THEN res := res & " "; ELSE res := res & " | "; END; ELSE IF last THEN res := res & " \\- "; ELSE res := res & " |- "; END; END; END; END; RETURN res & self.fmtFile(pn, time, size) & "\n"; END SimpleTextFileLayout;
PROCEDURE--------------------------------------------------------------------------SimpleTextFmtDir (<*UNUSED*>self : SimpleTextLayout; pn : APN.T; <*UNUSED*>time : Time.T; <*UNUSED*>size : LONGINT) : TEXT = BEGIN RETURN APN.Last(pn).denotation(); END SimpleTextFmtDir;
PROCEDURE--------------------------------------------------------------------------SimpleTextFmtFile (<*UNUSED*>self : SimpleTextLayout; pn : APN.T; <*UNUSED*>time : Time.T; <*UNUSED*>size : LONGINT) : TEXT = BEGIN RETURN APN.Last(pn).denotation(); END SimpleTextFmtFile;
PROCEDURE--------------------------------------------------------------------------SimpleTextNoSort (<*UNUSED*>self : SimpleTextLayout; list : APNSeq.T) : APNSeq.T = BEGIN RETURN list; END SimpleTextNoSort;
PROCEDURELayout (cache : FileInfo.T; root : APN.T; lfuns : LayoutClosure := NIL; ignDir : FindExpr.T := NIL; ignFile : FindExpr.T := NIL; sc := SortCriterion.None; update := FALSE) : TEXT = PROCEDURE L(p : APN.T; level : CARDINAL; lastPrefix : BoolSeq.T) : TEXT = PROCEDURE LevelLayout(list : APNSeq.T) : TEXT = VAR fn : APN.T; res := ""; BEGIN list := lfuns.sort(list); FOR i := 0 TO list.size() - 1 DO fn := list.get(i); VAR lp := NEW(BoolSeq.T).init(); BEGIN lp := BoolSeq.Cat(lp, lastPrefix); lp.addhi(i = list.size() - 1); res := res & L(fn, level + 1, lp); END; END; RETURN res; END LevelLayout; VAR dir : APNSeq.T; dirs : APNSeq.T; files : APNSeq.T; fn : APN.T; s, fstat : FileStatus.T; base : TEXT; base2 : TEXT; ignoreDir : BOOLEAN; ignoreFile : BOOLEAN; itemLayout : TEXT := ""; partLayout : TEXT := ""; BEGIN s := cache.getStatus(p); IF NOT s.exists THEN RETURN "not found: " & p.denotation() END; base := APN.Last(p).denotation(); TRY ignoreDir := ignDir # NIL AND ignDir.test(base); EXCEPT ELSE ignoreDir := FALSE; END; TRY ignoreFile := ignFile # NIL AND ignFile.test(base); EXCEPT ELSE ignoreFile := FALSE; END; IF s.isFile AND NOT ignoreFile THEN itemLayout := lfuns.file(p, s.modified, s.size, level, lastPrefix); ELSIF s.isDir AND NOT ignoreDir THEN itemLayout := lfuns.dir(p, s.modified, s.size, level, lastPrefix); dir := cache.getDir(p); IF sc # SortCriterion.None THEN dirs := NEW(APNSeq.T).init(); files := NEW(APNSeq.T).init(); FOR i := 0 TO dir.size() - 1 DO fn := dir.get(i); base2 := APN.Last(fn).denotation(); fstat := cache.getStatus(fn); TRY IF fstat.isDir AND (ignDir = NIL OR NOT ignDir.test(base2)) THEN dirs.addhi(fn); ELSIF fstat.isFile AND (ignFile = NIL OR NOT ignFile.test(base2)) THEN files.addhi(fn); END; EXCEPT RegEx.Error => IF fstat.isDir THEN dirs.addhi(fn); ELSIF fstat.isFile THEN files.addhi(fn); END; END; END; IF sc = SortCriterion.DirsFirst THEN partLayout := LevelLayout(APNSeq.Cat(dirs, files)); ELSIF sc = SortCriterion.FilesFirst THEN partLayout := LevelLayout(APNSeq.Cat(files, dirs)); END; ELSE partLayout := LevelLayout(dir); END; ELSIF NOT ignoreDir AND NOT ignoreFile THEN itemLayout := lfuns.file(p, s.modified, s.size, level, lastPrefix) & " (unknown file type)\n"; END; RETURN itemLayout & partLayout; END L; VAR last : BoolSeq.T; BEGIN (* Layout *) IF cache = NIL THEN RETURN NIL END; IF update THEN cache.updateRec(root, emptyTextSeq, emptyAPNSeq, ignDir, ignFile); END; IF lfuns = NIL THEN lfuns := simpleTextLayout; END; last := NEW(BoolSeq.T).init(); last.addhi(TRUE); RETURN L(root, 0, last); END Layout; VAR emptyTextSeq := NEW (TextSeq.T).init(); emptyAPNSeq := NEW (APNSeq.T).init(); BEGIN simpleTextLayout := NEW(SimpleTextLayout); END DirTree.