home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1988-01-24 | 8.8 KB | 317 lines | [TEXT/????] |
- IMPLEMENTATION MODULE MakeForest;
- (*
- * MAKEMAKE. Create a MAKEFILE for a MODULA-2 program.
- *
- * Written by Steve Tynor, 30 September 1986.
- * UUCP : tynor@gitpyr
- * USNAIL: 2550 Akers Mill Rd. T-2, Atlanta GA. 30339
- *
- * Permission is granted to distribute, copy and change this program as long
- * as this notice remains...
- ---
- *
- * Make.
- * Modified and extended for MacMETH by :
- * J?rgen N?rgaard, 23 october 1987.
- * UUCP : jnp@daimi.dk
- * MAIL : Dybb?lvej 29, v?r. 2+3, 8240 Risskov, DENMARK
- *
- * Essentially only the parser remains from the original.
- * Extensions are a dependency-tree and a make-like facility.
- *
- *)
-
- (* Note : Statements etc. parenthesised by 'Begin Debug/End Debug' comments
- * are for debug use only
- *)
-
- IMPORT SYSTEM, System, FileSystem, MakeFileInfo, StringLib0, InOut;
-
- (* Begin Debug *) (*
- PROCEDURE WriteLong(l : LONGINT);
- VAR
- a, k : CARDINAL;
- digits : ARRAY[0..10] OF CHAR;
- negative,
- special : BOOLEAN;
- BEGIN
- negative := (l < 0D);
- special := (l = MIN(LONGINT) );
- IF special THEN l:= -(l+1D);
- ELSIF negative THEN l:= -l; END;
- k := 0;
- REPEAT
- a := l MOD 10D;
- l := l DIV 10D;
- digits[k] := CHR(SYSTEM.VAL(CARDINAL, ORD('0')) + a);
- INC(k);
- UNTIL l = 0D;
- IF special THEN digits[k] := '-'; digits[0] := '8';
- ELSIF negative THEN digits[k] := '-'; ELSE digits[k] := ' '; END;
- INC(k);
- REPEAT DEC(k); InOut.Write(digits[k]); UNTIL k = 0;
- END WriteLong;
- *)(* End Debug *)
-
- (*----------------------------------------------------------------------*)
- PROCEDURE FindName (dp : DepTree;
- VAR name : ARRAY OF CHAR;
- VAR entity : EntityPtr) : BOOLEAN;
- VAR
- l : DepList;
- resD,
- resM : BOOLEAN;
- entityD,
- entityM : EntityPtr;
- BEGIN
- IF dp = NIL THEN
- entity := NIL;
- RETURN FALSE;
- ELSE
- l := dp;
- WHILE l # NIL DO
- IF StringLib0.Equal(name, l^.actual^.moduleName) THEN
- entity := l^.actual;
- RETURN TRUE;
- ELSE
- IF NOT l^.actual^.seen THEN
- l^.actual^.seen := TRUE;
- resD := FindName(l^.actual^.DEFDepends, name, entityD);
- resM := FindName(l^.actual^.MODDepends, name, entityM);
- l^.actual^.seen := FALSE;
- ELSE
- resD := FALSE;
- resM := FALSE;
- END;
- IF resD THEN
- entity := entityD;
- RETURN TRUE;
- ELSIF resM THEN
- entity := entityM;
- RETURN TRUE;
- ELSE
- l := l^.next;
- END;
- END;
- END;
- entity := NIL;
- RETURN FALSE;
- END;
- END FindName;
-
- (*----------------------------------------------------------------------*)
- PROCEDURE AddModule (VAR name : NameString;
- VAR dp : DepTree;
- VAR de : EntityPtr) : BOOLEAN;
- (* returns TRUE if file added, FALSE if the file was already there, and a
- POINTER to a new entity *)
- VAR
- res : BOOLEAN;
- entity : EntityPtr;
- l : DepList;
- BEGIN
- res := FindName(root, name, entity);
- IF dp = NIL THEN
- System.Allocate(dp, SYSTEM.TSIZE(DepListEntity));
- dp^.next := NIL;
- l := dp;
- ELSE
- l := dp;
- WHILE l^.next # NIL DO l := l^.next END;
- System.Allocate(l^.next, SYSTEM.TSIZE(DepListEntity));
- l := l^.next;
- l^.next := NIL;
- END;
- IF res THEN
- l^.actual := entity;
- de := NIL;
- RETURN FALSE;
- ELSE
- System.Allocate(l^.actual, SYSTEM.TSIZE(DepEntity));
- de := l^.actual;
- WITH de^ DO
- moduleName := name;
- defName := "";
- impName := "";
- seen := FALSE;
- checked := FALSE;
- library := FALSE;
- date := 0D;
- DEFDepends := NIL;
- MODDepends := NIL;
- END;
- RETURN TRUE;
- END;
- END AddModule;
-
- PROCEDURE RemoveTree(VAR dp : DepTree);
- VAR temp : DepTree;
- BEGIN
- WHILE dp # NIL DO
- RemoveTree(dp^.actual^.DEFDepends);
- RemoveTree(dp^.actual^.MODDepends);
- temp := dp^.next;
- System.Deallocate(dp^.actual);
- System.Deallocate(dp);
- dp := temp;
- END;
- END RemoveTree;
-
- PROCEDURE Make(dp : DepTree; VAR fd : FileSystem.File);
- CONST
- Genesis = MIN(LONGINT); (* older than any file *)
- Eternity = MAX(LONGINT); (* newer than any file *)
-
- TYPE
- Extension = ARRAY[0..2] OF CHAR;
-
- PROCEDURE Max(l1, l2 : LONGINT) : LONGINT;
- BEGIN
- IF l1 > l2 THEN RETURN l1 ELSE RETURN l2 END;
- END Max;
-
- PROCEDURE FileTime(name : System.Path; ext : Extension) : LONGINT;
- VAR
- i : INTEGER;
- time : LONGINT;
- done : BOOLEAN;
- BEGIN
- i := StringLib0.Length(name) - 1;
- name[i - 2] := ext[0];
- name[i - 1] := ext[1];
- name[i ] := ext[2];
- MakeFileInfo.ModifiedTime(name, done, time);
- IF NOT done THEN time := Genesis; END; (* File not found; make it.
- Assumed to be .SBM or .OBM *)
- RETURN time;
- END FileTime;
-
- PROCEDURE WriteFileName(VAR name : System.Path);
- VAR
- i, top : INTEGER;
- BEGIN
- top := StringLib0.Length(name) - 1;
- FOR i:= 0 TO top DO
- FileSystem.WriteChar(fd, name[i]);
- END;
- FileSystem.WriteChar(fd, InOut.EOL);
- END WriteFileName;
-
- PROCEDURE MakeDEFs(dp : DepTree) : LONGINT;
- PROCEDURE Check(ep : EntityPtr; VAR time : LONGINT);
- VAR
- dateDEF,
- dateSBM : LONGINT;
- BEGIN
- dateDEF := FileTime(ep^.defName, 'DEF');
- dateSBM := FileTime(ep^.defName, 'SBM');
- (* Begin Debug *)(*
- WriteLong(time); InOut.Write(' '); WriteLong(dateDEF); InOut.WriteLn;
- WriteLong(dateDEF); InOut.Write(' '); WriteLong(dateSBM); InOut.WriteLn;
- *)(* End Debug *)
- IF (time >= dateDEF) OR (dateDEF >= dateSBM) THEN
- (* Begin Debug *)(*
- InOut.WriteString("Marked Changed"); InOut.WriteLn;
- *)(* End Debug *)
- WriteFileName(ep^.defName);
- ep^.date := Eternity; (* Mark changed *)
- ELSE
- ep^.date := dateSBM;
- END;
- time := ep^.date;
- END Check;
-
- VAR
- res, maximum : LONGINT;
- BEGIN
- res := Genesis;
- maximum := Genesis;
- WHILE dp # NIL DO
- WITH dp^.actual^ DO
- IF NOT checked THEN
- checked := TRUE;
- IF NOT library THEN
- res := MakeDEFs(MODDepends); (* Dummy, just do it *)
- res := MakeDEFs(DEFDepends);
- (* Begin Debug *)(*
- InOut.WriteString('DEF Checking ');
- InOut.WriteString(moduleName); InOut.WriteLn;
- *)(* End Debug *)
- Check(dp^.actual, res);
- ELSE
- date := Genesis;
- res := date;
- END;
- ELSE
- res := date;
- END;
- END;
- maximum := Max(maximum, res);
- dp := dp^.next;
- END;
- RETURN maximum;
- END MakeDEFs;
-
- PROCEDURE MakeMODs(dp : DepTree) : LONGINT;
- VAR
- maximum : LONGINT;
- dateDEF,
- dateMOD,
- dateOBM : LONGINT;
- BEGIN
- dateDEF := Genesis;
- maximum := Genesis;
- WHILE dp # NIL DO
- WITH dp^.actual^ DO
- IF NOT library THEN
- dateMOD := FileTime(impName, 'MOD');
- dateOBM := FileTime(impName, 'OBM');
- dateDEF := MakeMODs(MODDepends);
- (* Begin Debug *)(*
- InOut.WriteString('MOD Checking ');
- InOut.WriteString(moduleName);
- InOut.WriteLn;
- WriteLong(dateDEF); InOut.Write(' '); WriteLong(dateOBM); InOut.WriteLn;
- WriteLong(dateMOD); InOut.Write(' '); WriteLong(dateOBM); InOut.WriteLn;
- *)(* End Debug *)
- IF (dateDEF >= dateOBM) OR (dateMOD >= dateOBM) THEN
- (* Begin Debug *)(*
- InOut.WriteString("Marked Changed"); InOut.WriteLn;
- *)(* End Debug *)
- WriteFileName(impName);
- END;
- maximum := Max(maximum, date);
- END;
- END;
- dp := dp^.next;
- END;
- RETURN maximum;
- END MakeMODs;
-
- VAR
- dateDEF,
- dateMOD,
- dateOBM : LONGINT;
- BEGIN
- dateDEF := MakeDEFs(dp^.actual^.MODDepends); (* Dummy; just do it *)
- dateDEF := MakeMODs(dp^.actual^.MODDepends);
- dateMOD := FileTime(dp^.actual^.impName, 'MOD');
- dateOBM := FileTime(dp^.actual^.impName, 'OBM');
- (* Begin Debug *)(*
- InOut.WriteString("Checking ");
- InOut.WriteString(dp^.actual^.moduleName); InOut.WriteLn;
- WriteLong(dateDEF); InOut.Write(' '); WriteLong(dateOBM); InOut.WriteLn;
- WriteLong(dateMOD); InOut.Write(' '); WriteLong(dateOBM); InOut.WriteLn;
- *)(* End Debug *)
- IF (dateDEF >= dateOBM) OR (dateMOD >= dateOBM) THEN
- (* Begin Debug *)(*
- InOut.WriteString("Marked Changed"); InOut.WriteLn;
- *)(* End Debug *)
- WriteFileName(dp^.actual^.impName);
- END;
- END Make;
-
- BEGIN
- root := NIL;
- END MakeForest.
-