vipak/src/vpkdepTree.Mod
Norayr Chilingarian c5c999f596 now works!
2022-01-19 04:19:52 +04:00

196 lines
4.2 KiB
Modula-2

MODULE vpkdepTree;
IMPORT Out, Strings, strutils, StringList;
TYPE
pstring = strutils.pstring;
pstrings = strutils.pstrings;
Tdep* = POINTER TO TdepDesc;
Tdeps* = POINTER TO ARRAY OF Tdep;
TdepTree* = POINTER TO TdepTreeDesc;
TdepTreeDesc* = RECORD
First- : Tdep;
Last- : Tdep;
Create* : PROCEDURE () : TdepTree;
Free* : PROCEDURE (VAR l : TdepTree);
Clear* : PROCEDURE (VAR l : TdepTree);
Add* : PROCEDURE (VAR l : TdepTree; VAR s : Tdep);
Get* : PROCEDURE (VAR l : TdepTree; i : LONGINT): Tdep;
GetByName* : PROCEDURE (VAR l : TdepTree; VAR name : ARRAY OF CHAR): Tdep;
Empty* : PROCEDURE (VAR l : TdepTree) : BOOLEAN;
Count* : LONGINT;
END;
retriever- = PROCEDURE (VAR d: Tdep; VAR strlist: StringList.TStringList): LONGINT;
TdepDesc* = RECORD
prev-, next-: Tdep;
name- : pstring;
deps- : Tdeps;
Create* : PROCEDURE (VAR name: ARRAY OF CHAR): Tdep;
AssignDeps* : PROCEDURE (VAR d: Tdep; VAR deps: Tdeps);
RetrieveDeps- : retriever;
InstallRetriever*: PROCEDURE(VAR d: Tdep; r: retriever);
END;
PROCEDURE AssignDeps*(VAR d: Tdep; VAR deps: Tdeps);
BEGIN
d.deps := deps
END AssignDeps;
PROCEDURE InstallRetriever*(VAR d: Tdep; r: retriever);
BEGIN
d.RetrieveDeps := r
END InstallRetriever;
PROCEDURE CreateDep*(VAR name: ARRAY OF CHAR): Tdep;
VAR
dep: Tdep;
BEGIN
NEW(dep);
NEW(dep.name, Strings.Length(name) + 1);
COPY(name, dep.name^);
dep.AssignDeps := AssignDeps;
dep.InstallRetriever := InstallRetriever;
dep.RetrieveDeps := NIL;
RETURN dep
END CreateDep;
PROCEDURE list(VAR s : StringList.TStringList);
VAR e : StringList.Node;
i : INTEGER;
BEGIN
NEW(e);
i := 0;
REPEAT
e := s.Get(s, i);
IF e # NIL THEN Out.String (e.obj(StringList.TString).str^); Out.Ln END;
(*Out.String (e.string); Out.Ln;*)
INC(i);
UNTIL i = s.Count - 1;
END list;
PROCEDURE listDeps*(VAR deps: Tdeps);
VAR
l: LONGINT;
BEGIN
l := 0;
REPEAT
Out.Int(l, 0); Out.String(": "); Out.String(deps[l].name^); Out.Ln;
INC(l);
UNTIL l = LEN(deps^) - 1;
END listDeps;
PROCEDURE Free*(VAR l : TdepTree);
BEGIN
l := NIL
END Free;
PROCEDURE Clear*(VAR l : TdepTree);
BEGIN
l.First := NIL;
l.Count := 0;
END Clear;
PROCEDURE Empty* (VAR l : TdepTree) : BOOLEAN;
BEGIN
RETURN l.First = NIL
END Empty;
PROCEDURE Add* (VAR l : TdepTree; VAR d: Tdep);
BEGIN
IF l.First = NIL THEN
l.First := d;
ELSE
l.Last.next := d;
END;
l.Last := d;
l.Last.next := NIL;
INC(l.Count);
END Add;
PROCEDURE AddCopy* (VAR l : TdepTree; VAR d: Tdep);
VAR
new: Tdep;
ln: INTEGER;
BEGIN
NEW(new);
new.prev := d.prev; new.next := d.next;
ln := Strings.Length(d.name^) + 1; NEW(new.name, ln); COPY(d.name^, new.name^);
new.deps := d.deps;
new.Create := d.Create; new.AssignDeps := d.AssignDeps;
new.RetrieveDeps := d.RetrieveDeps;
new.InstallRetriever := d.InstallRetriever;
IF l.First = NIL THEN
l.First := new;
ELSE
l.Last.next := new;
END;
l.Last := new;
l.Last.next := NIL;
INC(l.Count);
END AddCopy;
PROCEDURE Get*(VAR l: TdepTree; inx: LONGINT): Tdep;
VAR
i: LONGINT;
d: Tdep;
BEGIN
d := NIL;
i := 0;
IF (inx < l.Count) & (inx >= 0) THEN
i := 0;
d := l.First;
WHILE i # inx DO
IF d # NIL THEN d := d.next END;
INC(i);
END;
END;
RETURN d;
END Get;
PROCEDURE GetByName*(VAR l: TdepTree; VAR name: ARRAY OF CHAR): Tdep;
VAR
i: LONGINT;
d: Tdep;
fnd: BOOLEAN;
BEGIN
fnd := FALSE;
i := 0;
d := l.First;
REPEAT
IF d # NIL THEN
IF d.name^ = name THEN
fnd := TRUE;
RETURN d;
ELSE
d := d.next
END
END;
INC(i);
(* UNTIL fnd OR (i >= l.Count );*)
UNTIL fnd OR (d = NIL);
RETURN NIL; (* in case of this UNTIL it seems safe to RETURN d *)
END GetByName;
PROCEDURE Create* () : TdepTree;
VAR l : TdepTree;
BEGIN
NEW(l);
l.First := NIL;
l.Last := NIL;
l.Count := 0;
l.Add := Add;
l.Get := Get;
l.GetByName := GetByName;
l.Clear := Clear;
l.Free := Free;
l.Empty := Empty;
RETURN(l);
END Create;
END vpkdepTree.