DEADSOFTWARE

cpmake: add options for bootstrapping
[cpc.git] / src / generic / Dsw / Mod / MakeMain.cp
1 MODULE DswMakeMain;
3 IMPORT Kernel, Files, Log, Strings, DswOpts, DswProcs, DswDocuments, DevCPM, DevCPT, DevCPR, DevCPS;
5 CONST
6 version = "0.3";
8 modDir = "Mod";
9 sysDir = "System";
11 maxImps = 127;
12 maxJobs = maxImps;
14 (* symbol values *)
15 null = 0; times = 1; slash = 2; div = 3; mod = 4;
16 and = 5; plus = 6; minus = 7; or = 8; eql = 9;
17 neq = 10; lss = 11; leq = 12; gtr = 13; geq = 14;
18 in = 15; is = 16; arrow = 17; dollar = 18; period = 19;
19 comma = 20; colon = 21; upto = 22; rparen = 23; rbrak = 24;
20 rbrace = 25; of = 26; then = 27; do = 28; to = 29;
21 by = 30; not = 33;
22 lparen = 40; lbrak = 41; lbrace = 42; becomes = 44;
23 number = 45; nil = 46; string = 47; ident = 48; semicolon = 49;
24 bar = 50; end = 51; else = 52; elsif = 53; until = 54;
25 if = 55; case = 56; while = 57; repeat = 58; for = 59;
26 loop = 60; with = 61; exit = 62; return = 63; array = 64;
27 record = 65; pointer = 66; begin = 67; const = 68; type = 69;
28 var = 70; out = 71; procedure = 72; close = 73; import = 74;
29 module = 75; eof = 76;
31 (* module state flags *)
32 imported = 0; trace = 1; hasObj = 2; hasSym = 3; hasErrors = 4;
33 library = 5; force = 6;
35 debugImport = FALSE;
36 debugOrder = FALSE;
37 debugJobs = FALSE;
39 TYPE
40 String = POINTER TO ARRAY OF CHAR;
42 Selector = POINTER TO RECORD
43 name: DevCPT.Name;
44 value: BOOLEAN;
45 next: Selector
46 END;
48 Module = POINTER TO RECORD
49 name: DevCPT.Name;
50 odc: Files.Name;
51 depth: INTEGER; (* 0: leaf, MAX: root *)
52 dir: DevCPM.Directory;
53 mno: INTEGER;
54 imp: ARRAY maxImps OF Module;
55 flags: SET;
56 worker: DswProcs.Process;
57 END;
59 VAR (* options *)
60 auto, trap, clean, symonly, nocode1, nocode2: BOOLEAN;
61 exe, target, base: String;
62 jobs: INTEGER;
64 VAR
65 werr, err: INTEGER;
66 mno, rno: INTEGER; (* num modules *)
67 modList, lnkList, cmpList: ARRAY maxImps OF Module;
68 def: Selector; (* with head, global list of selectors *)
69 dirList: DevCPM.Directory;
71 PROCEDURE Error (IN str, p0, p1: ARRAY OF CHAR; i2: INTEGER);
72 VAR p2: ARRAY 32 OF CHAR;
73 BEGIN
74 Strings.IntToString(i2, p2);
75 Log.String("cpmake: "); Log.ParamMsg(str, p0, p1, p2); Log.Ln;
76 INC(err);
77 IF trap THEN
78 HALT(100)
79 END
80 END Error;
82 (* --------- options --------- *)
84 PROCEDURE IdentLen (IN s: ARRAY OF CHAR): INTEGER;
85 VAR i: INTEGER;
86 BEGIN
87 i := 0;
88 IF Strings.IsIdentStart(s[0]) THEN
89 REPEAT INC(i) UNTIL ~Strings.IsIdent(s[i])
90 END;
91 RETURN i
92 END IdentLen;
94 PROCEDURE Define (n: ARRAY OF CHAR; overwrite: BOOLEAN);
95 VAR i: INTEGER; v: BOOLEAN; s: Selector;
96 BEGIN
97 i := IdentLen(n);
98 IF i # 0 THEN
99 IF ~((n[i] = 0X) OR (((n[i] = "+") OR (n[i] = "-")) & (n[i + 1] = 0X))) THEN
100 Error("expectd + or - after selector identifier (^0)", n, "", 0)
101 END;
102 v := n[i] # "-"; n[i] := 0X; s := def;
103 WHILE (s.next # NIL) & (s.next.name$ # n$) DO s := s.next END;
104 IF s.next = NIL THEN
105 NEW(s.next);
106 Strings.StringToUtf8(n, s.next.name, i);
107 ASSERT(i = 0);
108 s.next.value := v
109 ELSIF overwrite THEN
110 s.next.value := v
111 END
112 ELSE Error("selector '^0' have invalid identifier", n, "", 0)
113 END
114 END Define;
116 PROCEDURE AddModule (IN n: ARRAY OF CHAR; selectors: Selector; dir: DevCPM.Directory);
117 VAR i, res: INTEGER; m: Module;
118 BEGIN
119 i := IdentLen(n);
120 IF (i # 0) & (n[i] = 0X) THEN
121 i := 0;
122 WHILE (i < mno) & (modList[i].name$ # n$) DO INC(i) END;
123 IF i >= mno THEN
124 NEW(m);
125 Strings.StringToUtf8(n, m.name, res);
126 ASSERT(res = 0);
127 m.dir := dir;
128 modList[i] := m;
129 INC(mno)
130 END
131 ELSE
132 Error("invalid module name", "", "", 0)
133 END
134 END AddModule;
136 PROCEDURE StrToInt (IN s: ARRAY OF CHAR; def: INTEGER): INTEGER;
137 VAR x, res: INTEGER;
138 BEGIN
139 Strings.StringToInt(s, x, res);
140 IF res # 0 THEN
141 Error("invalid integer value", s, "", 0);
142 x := def
143 END;
144 RETURN x
145 END StrToInt;
147 PROCEDURE NewStr (IN s: ARRAY OF CHAR): String;
148 VAR p: String;
149 BEGIN
150 NEW(p, LEN(s$) + 1); p^ := s$;
151 RETURN p
152 END NewStr;
154 PROCEDURE Help;
155 BEGIN
156 Log.String("Usage: cpmake [options] module..."); Log.Ln;
157 Log.String("Options:"); Log.Ln;
158 Log.String(" -a Enable automatic dependency resolution"); Log.Ln;
159 Log.String(" -b Do not compile modules"); Log.Ln;
160 Log.String(" -x Do not link objects"); Log.Ln;
161 Log.String(" -c Remove all generated files"); Log.Ln;
162 Log.String(" -s Generate symbol files only"); Log.Ln;
163 Log.String(" -d selector Add selector"); Log.Ln;
164 Log.String(" -t target Specify target rules"); Log.Ln;
165 Log.String(" -o file Generate object file"); Log.Ln;
166 Log.String(" -j num Specifies the number of jobs to run simultaneously"); Log.Ln;
167 Log.String(" -f path Specifies path to directory with targets"); Log.Ln;
168 Log.String(" -h Print help"); Log.Ln;
169 Log.String(" -v Print version"); Log.Ln;
170 Kernel.Quit(0)
171 END Help;
173 PROCEDURE ParseArgs;
174 BEGIN
175 exe := NIL; auto := FALSE; jobs := 1; def.next := NIL; mno := 0; rno := 0;
176 target := NewStr("default"); base := NewStr("cprules");
177 LOOP
178 CASE DswOpts.GetOpt("acbxd:sgGo:t:j:f:") OF
179 | "a": auto := TRUE
180 | "b": nocode1 := TRUE
181 | "x": nocode2 := TRUE
182 | "c": clean := TRUE
183 | "g": trap := TRUE
184 | "G": Kernel.intTrap := TRUE
185 | "s": symonly := TRUE
186 | "f": base := DswOpts.str
187 | "d": Define(DswOpts.str, TRUE)
188 | "h": Help
189 | "j": jobs := MIN(MAX(StrToInt(DswOpts.str, 1), 1), maxJobs)
190 | "o": exe := DswOpts.str
191 | "t": target := DswOpts.str
192 | "v": Log.String(version); Log.Ln; Kernel.Quit(0)
193 | ":": Error("missing argument for option -^0", DswOpts.str, "", 0)
194 | "?": Error("unknown option -^0", DswOpts.str, "", 0)
195 | "$": AddModule(DswOpts.str, def, dirList)
196 | 00X: EXIT
197 END
198 END
199 END ParseArgs;
201 PROCEDURE ReadDefines;
202 VAR loc: Files.Locator; name: Files.Name; m: DswDocuments.Model; r: DswDocuments.Reader; i, res: INTEGER;
203 BEGIN
204 loc := Files.dir.This(base).This(target);
205 DswDocuments.Open(loc, "defines", m, res);
206 IF res = 0 THEN
207 r := m.NewReader(NIL);
208 r.SetPos(0);
209 r.Read;
210 WHILE ~r.eot DO
211 i := 0;
212 WHILE ~r.eot & (r.char <= 20X) DO r.Read END;
213 WHILE ~r.eot & (r.char > 20X) DO name[i] := r.char; r.Read; INC(i) END;
214 IF i # 0 THEN name[i] := 0X; Define(name, FALSE) END
215 END
216 END
217 END ReadDefines;
219 PROCEDURE CheckParams;
220 BEGIN
221 IF (exe # NIL) & (exe^ = "") THEN
222 Error("specified empty file name for exe", "", "", 0)
223 END;
224 IF target^ = "" THEN
225 Error("specified empty rule", "", "", 0)
226 END;
227 IF base^ = "" THEN
228 Error("specified empty path to cpmake rules", "", "", 0)
229 END;
230 ReadDefines
231 END CheckParams;
233 (* --------- loader --------- *)
235 PROCEDURE Import (m: Module; IN name: DevCPT.Name);
236 VAR i, j: INTEGER; imp: Module;
237 BEGIN
238 ASSERT(m # NIL, 20);
239 ASSERT(name # "", 21);
240 IF debugImport THEN Log.String(" import "); Log.String(name$) END;
241 IF name = "SYSTEM" THEN INCL(DevCPM.options, DevCPM.sysImp)
242 ELSIF name = "COM" THEN INCL(DevCPM.options, DevCPM.com)
243 ELSIF name = "JAVA" THEN INCL(DevCPM.options, DevCPM.java)
244 ELSE
245 IF debugImport THEN Log.Char(" ") END;
246 i := 0; (* find module in local list *)
247 WHILE (i < m.mno) & (m.imp[i].name$ # name$) DO INC(i) END;
248 IF i >= m.mno THEN
249 j := 0; (* find module in global list *)
250 WHILE (j < mno) & (modList[j].name$ # name$) DO INC(j) END;
251 IF j >= mno THEN
252 IF ~auto THEN
253 Log.String("module " + name + " required before " + m.name); Log.Ln; INC(werr)
254 END;
255 NEW(imp); imp.name := name$;
256 modList[mno] := imp; INC(mno)
257 ELSE
258 imp := modList[j]
259 END;
260 m.imp[m.mno] := imp; INC(m.mno)
261 ELSE DevCPM.err(1)
262 END
263 END;
264 IF debugImport THEN Log.Ln END;
265 END Import;
267 PROCEDURE ParseModule (m: Module);
268 VAR sym: BYTE; SelfName, impName, aliasName: DevCPT.Name;
270 PROCEDURE err (n: SHORTINT);
271 BEGIN DevCPM.err(n)
272 END err;
274 PROCEDURE CheckSym(s: SHORTINT);
275 BEGIN
276 IF sym = s THEN DevCPS.Get(sym) ELSE DevCPM.err(s) END
277 END CheckSym;
279 BEGIN
280 IF debugImport THEN Log.String("module " + m.name); Log.Ln END;
281 DevCPS.Init; DevCPS.Get(sym);
282 IF sym = module THEN DevCPS.Get(sym) ELSE err(16) END;
283 IF sym = ident THEN
284 SelfName := DevCPS.name$; DevCPS.Get(sym);
285 IF sym = lbrak THEN
286 INCL(DevCPM.options, DevCPM.interface); DevCPS.Get(sym);
287 IF sym = eql THEN DevCPS.Get(sym)
288 ELSE INCL(DevCPM.options, DevCPM.noCode)
289 END;
290 IF sym = string THEN INCL(m.flags, library); DevCPS.Get(sym)
291 ELSE err(string)
292 END;
293 CheckSym(rbrak)
294 END;
295 CheckSym(semicolon);
296 IF sym = import THEN DevCPS.Get(sym);
297 LOOP
298 IF sym = ident THEN
299 aliasName := DevCPS.name$; impName := aliasName$; DevCPS.Get(sym);
300 IF sym = becomes THEN DevCPS.Get(sym);
301 IF sym = ident THEN impName := DevCPS.name$; DevCPS.Get(sym) ELSE err(ident) END
302 END;
303 Import(m, impName)
304 ELSE err(ident)
305 END;
306 IF sym = comma THEN DevCPS.Get(sym)
307 ELSIF sym = ident THEN err(comma)
308 ELSE EXIT
309 END
310 END;
311 CheckSym(semicolon)
312 END;
313 LOOP (* preprocessor must read module fully *)
314 IF sym = end THEN
315 DevCPS.Get(sym);
316 IF sym = ident THEN
317 DevCPS.Get(sym);
318 IF sym = period THEN
319 IF DevCPS.name # SelfName THEN err(4) END;
320 EXIT
321 ELSIF sym = eof THEN
322 err(period);
323 EXIT
324 END
325 ELSIF sym = eof THEN
326 err(ident);
327 EXIT
328 END;
329 ELSIF sym = eof THEN
330 err(end);
331 EXIT
332 ELSE
333 DevCPS.Get(sym);
334 END
335 END
336 ELSE err(ident)
337 END;
338 DevCPS.str := NIL
339 END ParseModule;
341 PROCEDURE CheckModule (m: Module; source: String; OUT ok: BOOLEAN);
342 VAR s: Selector;
343 BEGIN
344 DevCPM.Init(source);
345 DevCPM.symList := m.dir;
346 (*DevCPM.codePath := m.outcode;*)
347 (*DevCPM.symPath := m.outsym;*)
348 DevCPM.name := m.name$;
349 INCL(DevCPM.options, DevCPM.comAware);
350 IF trap THEN
351 INCL(DevCPM.options, DevCPM.trap)
352 END;
353 (*IF oberon IN m.opts THEN INCL(DevCPM.options, DevCPM.oberon) END;*)
354 DevCPR.Init;
355 s := def.next;
356 WHILE s # NIL DO
357 DevCPR.Set(s.name, s.value);
358 s := s.next
359 END;
360 ParseModule(m);
361 DevCPR.Check;
362 ok := DevCPM.noerr;
363 IF DevCPR.used THEN INCL(m.flags, force) END;
364 DevCPR.Close;
365 DevCPM.InsertMarks;
366 DevCPM.Close;
367 Kernel.FastCollect
368 END CheckModule;
370 PROCEDURE MakePath (IN dir, name: Files.Name; IN type: Files.Type; OUT path: Files.Name);
371 BEGIN
372 ASSERT(name # "", 21);
373 IF dir = "" THEN path := modDir + "/" + name
374 ELSE path := dir + "/" + modDir + "/" + name
375 END;
376 Kernel.MakeFileName(path, type)
377 END MakePath;
379 PROCEDURE Open (loc: Files.Locator; IN sub, name: Files.Name; OUT path: Files.Name; OUT text: DswDocuments.Model);
380 VAR res: INTEGER;
381 BEGIN
382 ASSERT(loc # NIL, 20);
383 ASSERT(name # "", 21);
384 (* !!! use Kernel.MakeFileName instead ".ext" concat !!! *)
385 MakePath(sub, name, "cp", path);
386 DswDocuments.Open(loc, name + ".cp", text, res);
387 IF text = NIL THEN
388 MakePath(sub, name, "odc", path);
389 DswDocuments.Open(loc, name + ".odc", text, res);
390 IF (text = NIL) & (sub = "") THEN
391 MakePath(sysDir, name, "cp", path);
392 loc := Files.dir.This(sysDir).This(modDir);
393 DswDocuments.Open(loc, name + ".cp", text, res);
394 IF text = NIL THEN
395 MakePath(sysDir, name, "odc", path);
396 DswDocuments.Open(loc, name + ".odc", text, res);
397 IF text = NIL THEN
398 path := ""
399 END
400 END
401 END
402 END
403 END Open;
405 PROCEDURE GetSource (IN modName: ARRAY OF CHAR; list: DevCPM.Directory; OUT path: Files.Name; OUT s: String);
406 VAR
407 sub, name: Files.Name; loc: Files.Locator; base: DevCPM.Directory;
408 text: DswDocuments.Model; r: DswDocuments.Reader; i, res: INTEGER;
409 BEGIN
410 s := NIL; path := ""; base := list;
411 Kernel.SplitName(modName, sub, name);
412 loc := Files.dir.This(sub).This(modDir);
413 Open(loc, sub, name, path, text);
414 WHILE (text = NIL) & (base # NIL) DO
415 ASSERT(base.legacy, 100);
416 loc := Files.dir.This(base.path).This(sub).This(modDir);
417 Open(loc, sub, name, path, text);
418 base := base.next
419 END;
420 IF text # NIL THEN
421 NEW(s, text.Length() + 1);
422 IF s # NIL THEN
423 r := text.NewReader(NIL);
424 FOR i := 0 TO text.Length() - 1 DO
425 r.Read; s[i] := r.char
426 END
427 END
428 END
429 END GetSource;
431 PROCEDURE Trace (m, parent: Module; VAR lno: INTEGER);
432 VAR i: INTEGER;
433 BEGIN
434 IF ~(trace IN m.flags) THEN
435 INCL(m.flags, trace);
436 FOR i := 0 TO m.mno - 1 DO
437 Trace(m.imp[i], m, lno);
438 m.depth := MAX(m.depth, m.imp[i].depth + 1)
439 END;
440 IF ~(imported IN m.flags) THEN
441 INCL(m.flags, imported);
442 lnkList[lno] := m;
443 INC(lno)
444 END;
445 EXCL(m.flags, trace)
446 ELSE
447 Error("recursive import of ^0 in ^1", m.name$, parent.name$, 0)
448 END
449 END Trace;
451 PROCEDURE Sort;
452 VAR i, j: INTEGER; m: Module;
453 BEGIN
454 ASSERT((mno = 0) OR (lnkList[0] # NIL), 20);
455 cmpList := lnkList;
456 i := 1;
457 WHILE i < mno DO
458 m := cmpList[i];
459 j := i - 1;
460 WHILE (j >= 0) & (cmpList[j].depth > m.depth) DO
461 cmpList[j + 1] := cmpList[j];
462 DEC(j)
463 END;
464 cmpList[j + 1] := m;
465 INC(i)
466 END
467 END Sort;
469 PROCEDURE CheckDeps;
470 VAR i, j, num: INTEGER; m: Module; src: String; ok: BOOLEAN;
471 BEGIN
472 i := 0; rno := mno;
473 WHILE (err = 0) & (i < mno) DO
474 m := modList[i];
475 GetSource(m.name$, m.dir, m.odc, src);
476 IF src # NIL THEN
477 CheckModule(m, src, ok);
478 IF ~ok THEN INC(err) END
479 ELSE
480 Error("unable to open module ^1", m.name$, "", 0)
481 END;
482 INC(i)
483 END;
484 INC(err, werr);
485 num := 0;
486 FOR i := 0 TO rno - 1 DO
487 Trace(modList[i], modList[i], num)
488 END;
489 ASSERT((err # 0) OR (num = mno), 100);
490 Sort;
491 IF debugOrder THEN
492 Log.String("Parallel depth:"); Log.Ln;
493 FOR i := 0 TO mno - 1 DO
494 Log.String(" " + cmpList[i].name); Log.Int(cmpList[i].depth); Log.Ln;
495 END
496 END
497 END CheckDeps;
499 PROCEDURE IsCompiled (m: Module): BOOLEAN;
500 CONST target = {hasSym, hasObj};
501 VAR i: INTEGER; ready: BOOLEAN;
502 BEGIN
503 ASSERT(m # NIL, 20);
504 i := 0;
505 ready := ~(hasErrors IN m.flags) & (m.flags * target = target);
506 WHILE ready & (i < m.mno) DO
507 ready := IsCompiled(m.imp[i]);
508 INC(i)
509 END;
510 RETURN ready
511 END IsCompiled;
513 PROCEDURE Ready (m: Module): BOOLEAN;
514 CONST target = {hasSym, hasObj};
515 VAR i: INTEGER; ready: BOOLEAN;
516 BEGIN
517 i := 0;
518 ready := ~(hasErrors IN m.flags) & (m.flags * target # target) & (m.worker = NIL);
519 WHILE ready & (i < m.mno) DO
520 ready := IsCompiled(m.imp[i]);
521 INC(i)
522 END;
523 RETURN ready
524 END Ready;
526 PROCEDURE PrepareCompiler (m: Module): DswProcs.Process;
527 VAR p: DswProcs.Process; s: Selector;
528 BEGIN
529 ASSERT(m # NIL, 20);
530 ASSERT(m.odc # "", 21);
531 ASSERT(m.worker = NIL, 22);
532 p := DswProcs.dir.New();
533 p.Program(base + "/" + target + "/" + "build");
534 p.PutParam(m.odc);
535 IF nocode1 THEN p.PutParam("-b") END;
536 IF nocode2 THEN p.PutParam("-x") END;
537 IF force IN m.flags THEN p.PutParam("-f") END;
538 IF symonly OR (library IN m.flags) THEN p.PutParam("-s") END;
539 s := def.next;
540 WHILE s # NIL DO
541 IF s.value THEN p.PutParam("-D") ELSE p.PutParam("-d") END;
542 p.PutParam(s.name$);
543 s := s.next
544 END;
545 RETURN p
546 END PrepareCompiler;
548 PROCEDURE Compile;
549 VAR i, j, num, res: INTEGER; ok: BOOLEAN; m: Module; w: DswProcs.Process;
550 BEGIN
551 IF mno = 0 THEN RETURN END;
552 num := 0; j := 0;
553 WHILE (err = 0) & (num < mno) OR (j > 0) DO
554 i := 0;
555 WHILE (err = 0) & (i < mno) & (j < jobs) DO
556 m := cmpList[i];
557 IF Ready(m) THEN
558 w := PrepareCompiler(m);
559 IF debugJobs THEN Log.String("Start job " + m.name) END;
560 w.Execute(ok);
561 IF ok THEN
562 IF debugJobs THEN Log.String(" ok") END;
563 m.worker := w;
564 INC(j)
565 ELSE
566 IF debugJobs THEN Log.String(" fail") END;
567 INCL(m.flags, hasErrors);
568 INC(err)
569 END;
570 IF debugJobs THEN Log.Ln END
571 END;
572 INC(i)
573 END;
574 WHILE (err = 0) & (j >= jobs) OR (j > 0) DO
575 i := 0;
576 WHILE (j > 0) & (i < mno) DO
577 m := cmpList[i];
578 w := m.worker;
579 IF (w # NIL) & w.IsTerminated() THEN
580 res := w.Result();
581 IF debugJobs THEN Log.String("Stop job " + m.name); Log.Int(res); Log.Ln END;
582 IF res = 0 THEN
583 INCL(m.flags, hasObj);
584 INCL(m.flags, hasSym);
585 INC(num)
586 ELSE
587 INCL(m.flags, hasErrors);
588 INC(err)
589 END;
590 m.worker := NIL;
591 DEC(j)
592 END;
593 INC(i)
594 END
595 END
596 END
597 END Compile;
599 PROCEDURE Link;
600 VAR p: DswProcs.Process; ok: BOOLEAN; i, res: INTEGER;
601 BEGIN
602 IF ~symonly & (exe # NIL) THEN
603 p := DswProcs.dir.New();
604 p.Program(base + "/" + target + "/" + "link");
605 p.PutParam(exe$);
606 FOR i := 0 TO mno - 1 DO
607 IF ~(library IN lnkList[i].flags) THEN
608 p.PutParam(lnkList[i].name$)
609 END
610 END;
611 p.Execute(ok);
612 IF ok THEN
613 p.Wait;
614 res := p.Result();
615 IF res # 0 THEN
616 Error("link failed with code ^2", "", "", res)
617 END
618 ELSE Error("link failed: unable to execute script", "", "", 0)
619 END
620 END
621 END Link;
623 PROCEDURE Cleanup;
624 VAR p: DswProcs.Process; ok: BOOLEAN; res: INTEGER;
625 BEGIN
626 IF clean THEN
627 p := DswProcs.dir.New();
628 p.Program(base + "/" + target + "/" + "clean");
629 p.Execute(ok);
630 IF ok THEN
631 p.Wait;
632 res := p.Result();
633 IF res # 0 THEN
634 Error("cleanup failed with code ^2", "", "", res)
635 END
636 ELSE Error("cleanup failed: unable to execute script", "", "", 0)
637 END
638 END
639 END Cleanup;
641 PROCEDURE Main;
642 BEGIN
643 IF Kernel.trapCount = 0 THEN
644 ParseArgs;
645 IF err = 0 THEN
646 CheckParams;
647 IF err = 0 THEN
648 CheckDeps;
649 IF err = 0 THEN
650 Cleanup;
651 IF err = 0 THEN
652 Compile;
653 IF err = 0 THEN
654 Link
655 END
656 END
657 END
658 END
659 END
660 ELSE Error("trap occured", "", "", 0)
661 END;
662 IF err = 0 THEN Kernel.Quit(0)
663 ELSE Kernel.Quit(1)
664 END
665 END Main;
667 BEGIN
668 NEW(def);
669 ASSERT(def # NIL, 100);
670 Kernel.intTrap := FALSE;
671 Kernel.Start(Main)
672 END DswMakeMain.