÷TextDocs.NewDoc v¤÷F CColor Flat Locked Controls Org ÛBIER` b €3 ðP Oberon10.Scn.Fnt à Oberon12.Scn.Fnt # Ø Ý MODULE DirTools; (* pjm *) (* Directory tools. *) IMPORT FileDir, Fonts, Texts, Oberon, In; CONST SambaHack = TRUE; (* Samba/FAT can only represent even seconds *) IgnoreDot = TRUE; (* Ignore files starting with ".", i.e. temporary and "hidden" files *) TYPE List = POINTER TO RECORD next: List; name: FileDir.FileName; time, date, size: LONGINT; isdir: BOOLEAN; END; VAR w: Texts.Writer; fixed: Fonts.Font; list: List; PROCEDURE InsertFile(path, name: ARRAY OF CHAR; time, date, size: LONGINT; isdir: BOOLEAN); VAR p, n: List; BEGIN IF ~isdir & (~IgnoreDot OR (name[0] # ".")) THEN IF SambaHack THEN DEC(time, time MOD 2) END; (* round seconds down to even *) NEW(n); COPY(name, n.name); n.time := time; n.date := date; n.size := size; n.isdir := isdir; p := list; WHILE (p.next # NIL) & (p.next.name < name) DO p := p.next END; n.next := p.next; p.next := n END END InsertFile; PROCEDURE GetDir(path: ARRAY OF CHAR): List; VAR d: List; BEGIN NEW(list); list.next := NIL; FileDir.EnumerateFiles(path, "*", TRUE, InsertFile); d := list; list := NIL; RETURN d END GetDir; PROCEDURE SameAge(f1, f2: List): BOOLEAN; BEGIN RETURN (f1.time = f2.time) & (f1.date = f2.date) END SameAge; PROCEDURE Younger(f1, f2: List): BOOLEAN; BEGIN RETURN (f1.date > f2.date) OR ((f1.date = f2.date) & (f1.time > f2.time)) END Younger; PROCEDURE CompareLists(d1, d2: List); VAR p1, p2: List; BEGIN p1 := d1; p2 := d2; WHILE (p1.next # NIL) & (p2.next # NIL) DO IF p1.next.name = p2.next.name THEN (* same file *) IF SameAge(p1.next, p2.next) THEN (* exact match *) p1.next := p1.next.next; p2.next := p2.next.next (* delete both from list *) ELSE IF Younger(p1.next, p2.next) THEN p2.next := p2.next.next (* p1 is younger, delete p2 *) ELSE p1.next := p1.next.next (* p2 is younger, delete p1 *) END END ELSE (* mismatch, skip one *) IF p1.next.name < p2.next.name THEN p1 := p1.next (* p1 is smaller, step on *) ELSE p2 := p2.next (* p2 is smaller, step on *) END END END END CompareLists; PROCEDURE WriteList(d: List); BEGIN Texts.SetFont(w, fixed); d := d.next; WHILE d # NIL DO Texts.WriteInt(w, d.size, 10); Texts.WriteDate(w, d.time, d.date); Texts.Write(w, " "); Texts.WriteString(w, d.name); IF d.isdir THEN Texts.WriteString(w, "