-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathvpkResolver.Mod
118 lines (109 loc) · 2.97 KB
/
vpkResolver.Mod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
MODULE vpkResolver;
IMPORT Out, StringList, vpkdepTree;
TYPE
pstr = StringList.pstring;
Tdep = vpkdepTree.Tdep;
Tdeps = vpkdepTree.Tdeps;
TdepTree = vpkdepTree.TdepTree;
VAR rtvr: vpkdepTree.retriever;
PROCEDURE treeContains(VAR d: Tdep; VAR depTree: TdepTree): BOOLEAN;
VAR
res: BOOLEAN;
i: INTEGER;
d2: Tdep;
BEGIN
res := FALSE;
i := 0;
REPEAT
d2 := depTree.Get(depTree, i);
IF d2 # NIL THEN
IF d = d2 THEN res := TRUE END;
(*IF d.name^ = d2.name^ THEN res := TRUE END *)
END;
INC(i)
UNTIL res OR (i >= depTree.Count);
RETURN res;
END treeContains;
PROCEDURE treeContainsByName(VAR d: Tdep; VAR depTree: TdepTree): BOOLEAN;
VAR
res: BOOLEAN;
i: INTEGER;
d2: Tdep;
BEGIN
res := FALSE;
i := 0;
REPEAT
d2 := depTree.Get(depTree, i);
IF d2 # NIL THEN
IF d.name^ = d2.name^ THEN res := TRUE END;
(*IF d.name^ = d2.name^ THEN res := TRUE END *)
END;
INC(i)
UNTIL res OR (i >= depTree.Count);
RETURN res;
END treeContainsByName;
PROCEDURE mkDepTree(VAR d: Tdep; VAR depTree, met: TdepTree);
VAR
depStrs: StringList.TStringList;
t: Tdep;
deps: Tdeps;
p: pstr;
i: INTEGER;
rtrvRes: LONGINT;
BEGIN
vpkdepTree.Add(met, d);
IF d.RetrieveDeps = NIL THEN Out.String("dep retriever method not installed"); Out.Ln; HALT(1) END;
rtrvRes := d.RetrieveDeps(d, depStrs);
IF rtrvRes = -1 THEN
Out.Ln; Out.String("package named "); Out.String(d.name^); Out.String(" not found in the tree"); Out.Ln; HALT(61);
END;
IF rtrvRes = -2 THEN
Out.Ln; Out.String(d.name^); Out.String(".json malformed: no 'Package' section."); Out.Ln;
HALT(62);
END;
IF depStrs # NIL THEN
(*IF rtrvRes > 0 THEN*)
NEW (deps, depStrs.Count);
i := 0;
REPEAT
p := depStrs.GetString(depStrs, i);
IF p # NIL THEN
t := NIL;
t := met.GetByName(met, p^);
IF t = NIL THEN
t := vpkdepTree.CreateDep(p^);
t.InstallRetriever(t, rtvr);
END;
deps[i] := t;
IF ~treeContainsByName(t, depTree) THEN
IF treeContainsByName(t, met) THEN
Out.Ln; Out.String("curcular dependency: ");
Out.String(d.name^); Out.String(" requires "); Out.String(t.name^); Out.Ln;
Out.String("unable to continue."); Out.Ln;
HALT(60)
ELSE
mkDepTree(t, depTree, met);
END;
END;
END;
INC(i);
UNTIL i = depStrs.Count;
d.AssignDeps(d, deps);
END;
vpkdepTree.AddCopy(depTree, d);
END mkDepTree;
PROCEDURE resolve*(first: ARRAY OF CHAR; r: vpkdepTree.retriever): TdepTree;
VAR
depTree: TdepTree;
met: TdepTree;
dep: Tdep;
BEGIN
rtvr := r;
depTree := vpkdepTree.Create();
met := vpkdepTree.Create(); (* for deps that we already met *)
dep := vpkdepTree.CreateDep(first);
dep.InstallRetriever(dep, rtvr);
mkDepTree(dep, depTree, met);
RETURN depTree
END resolve;
END vpkResolver.