home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Modula / Utilities / Makefiles / MakeForest.MOD < prev    next >
Encoding:
Modula Implementation  |  1988-01-24  |  8.8 KB  |  317 lines  |  [TEXT/????]

  1. IMPLEMENTATION MODULE MakeForest;
  2.   (*
  3.    * MAKEMAKE.  Create a MAKEFILE for a MODULA-2 program.
  4.    *
  5.    * Written by Steve Tynor, 30 September 1986.
  6.    *            UUCP  : tynor@gitpyr
  7.    *            USNAIL: 2550 Akers Mill Rd. T-2, Atlanta GA. 30339
  8.    *
  9.    * Permission is granted to distribute, copy and change this program as long
  10.    * as this notice remains...
  11.    ---
  12.    *
  13.    * Make.
  14.    * Modified and extended for MacMETH by :
  15.    * J?rgen N?rgaard, 23 october 1987.
  16.    *            UUCP  : jnp@daimi.dk
  17.    *            MAIL  : Dybb?lvej 29, v?r. 2+3, 8240 Risskov, DENMARK
  18.    *
  19.    * Essentially only the parser remains from the original.
  20.    * Extensions are a dependency-tree and a make-like facility.
  21.    *
  22.    *)
  23.  
  24.    (* Note : Statements etc. parenthesised by 'Begin Debug/End Debug' comments
  25.     * are for debug use only
  26.     *)
  27.     
  28. IMPORT SYSTEM, System, FileSystem, MakeFileInfo, StringLib0, InOut;
  29.  
  30. (* Begin Debug *) (*
  31. PROCEDURE WriteLong(l : LONGINT);
  32.   VAR
  33.     a, k : CARDINAL;
  34.     digits : ARRAY[0..10] OF CHAR;
  35.     negative,
  36.     special : BOOLEAN;
  37. BEGIN
  38.   negative := (l < 0D);
  39.   special  := (l = MIN(LONGINT) );
  40.   IF special THEN l:= -(l+1D);
  41.   ELSIF negative THEN l:= -l; END;
  42.   k := 0;
  43.   REPEAT
  44.     a := l MOD 10D;
  45.     l := l DIV 10D;
  46.     digits[k] := CHR(SYSTEM.VAL(CARDINAL, ORD('0')) + a);
  47.     INC(k);
  48.   UNTIL l = 0D;
  49.   IF special THEN digits[k] := '-'; digits[0] := '8';
  50.   ELSIF negative THEN digits[k] := '-'; ELSE digits[k] := ' '; END;
  51.   INC(k);
  52.   REPEAT DEC(k); InOut.Write(digits[k]); UNTIL k = 0;
  53. END WriteLong;
  54. *)(* End Debug *)
  55.  
  56.   (*----------------------------------------------------------------------*)
  57.   PROCEDURE FindName (dp       : DepTree;
  58.                       VAR name : ARRAY OF CHAR;
  59.                       VAR entity : EntityPtr) : BOOLEAN;
  60.   VAR
  61.     l : DepList;
  62.     resD,
  63.     resM : BOOLEAN;
  64.     entityD,
  65.     entityM : EntityPtr;
  66.   BEGIN
  67.     IF dp = NIL THEN
  68.       entity := NIL;
  69.       RETURN FALSE;
  70.     ELSE
  71.       l := dp;
  72.       WHILE l # NIL DO
  73.         IF StringLib0.Equal(name, l^.actual^.moduleName) THEN
  74.           entity := l^.actual;
  75.           RETURN TRUE;
  76.         ELSE
  77.           IF NOT l^.actual^.seen THEN
  78.             l^.actual^.seen := TRUE;
  79.             resD := FindName(l^.actual^.DEFDepends, name, entityD);
  80.             resM := FindName(l^.actual^.MODDepends, name, entityM);
  81.             l^.actual^.seen := FALSE;
  82.           ELSE
  83.            resD := FALSE;
  84.            resM := FALSE;
  85.           END;
  86.           IF resD THEN
  87.             entity := entityD;
  88.             RETURN TRUE;
  89.           ELSIF resM THEN
  90.             entity := entityM;
  91.             RETURN TRUE;
  92.           ELSE
  93.             l := l^.next;
  94.           END;
  95.         END;
  96.       END;
  97.       entity := NIL;
  98.       RETURN FALSE;
  99.     END;
  100.   END FindName;
  101.  
  102.   (*----------------------------------------------------------------------*)
  103.   PROCEDURE AddModule (VAR name : NameString;
  104.                        VAR dp : DepTree;
  105.                        VAR de : EntityPtr) : BOOLEAN;
  106.     (* returns TRUE if file added, FALSE if the file was already there, and a
  107.        POINTER to a new entity *)
  108.     VAR
  109.       res : BOOLEAN;
  110.       entity : EntityPtr;
  111.       l : DepList;
  112.   BEGIN
  113.     res := FindName(root, name, entity);
  114.     IF dp = NIL THEN
  115.       System.Allocate(dp, SYSTEM.TSIZE(DepListEntity));
  116.       dp^.next := NIL;
  117.       l := dp;
  118.     ELSE
  119.       l := dp;
  120.       WHILE l^.next # NIL DO l := l^.next END;
  121.       System.Allocate(l^.next, SYSTEM.TSIZE(DepListEntity));
  122.          l := l^.next;
  123.       l^.next := NIL;
  124.     END;
  125.     IF res THEN
  126.       l^.actual := entity;
  127.       de := NIL;
  128.       RETURN FALSE;
  129.     ELSE
  130.       System.Allocate(l^.actual, SYSTEM.TSIZE(DepEntity));
  131.       de := l^.actual;
  132.       WITH de^ DO
  133.         moduleName := name;
  134.         defName := "";
  135.         impName := "";
  136.         seen    := FALSE;
  137.         checked := FALSE;
  138.         library := FALSE;
  139.         date    := 0D;
  140.         DEFDepends := NIL;
  141.         MODDepends := NIL;
  142.       END;
  143.       RETURN TRUE;
  144.     END;
  145.   END AddModule;  
  146.   
  147.   PROCEDURE RemoveTree(VAR dp : DepTree);
  148.     VAR temp : DepTree;
  149.   BEGIN
  150.     WHILE dp # NIL DO
  151.       RemoveTree(dp^.actual^.DEFDepends);
  152.       RemoveTree(dp^.actual^.MODDepends);
  153.       temp := dp^.next;
  154.       System.Deallocate(dp^.actual);
  155.       System.Deallocate(dp);
  156.       dp := temp;
  157.     END;
  158.   END RemoveTree;
  159.  
  160.   PROCEDURE Make(dp : DepTree; VAR fd : FileSystem.File);
  161.     CONST 
  162.       Genesis  = MIN(LONGINT); (* older than any file *)
  163.       Eternity = MAX(LONGINT); (* newer than any file *)
  164.       
  165.     TYPE
  166.       Extension = ARRAY[0..2] OF CHAR;
  167.         
  168.     PROCEDURE Max(l1, l2 : LONGINT) : LONGINT;
  169.     BEGIN
  170.       IF l1 > l2 THEN RETURN l1 ELSE RETURN l2 END;
  171.     END Max;
  172.     
  173.     PROCEDURE FileTime(name : System.Path; ext : Extension) : LONGINT;
  174.       VAR
  175.         i : INTEGER;
  176.         time : LONGINT;
  177.         done : BOOLEAN;
  178.     BEGIN
  179.       i := StringLib0.Length(name) - 1;
  180.       name[i - 2] := ext[0];
  181.       name[i - 1] := ext[1];
  182.       name[i ]    := ext[2];
  183.       MakeFileInfo.ModifiedTime(name, done, time);
  184.       IF NOT done THEN time := Genesis; END;  (* File not found; make it.
  185.                                                  Assumed to be .SBM or .OBM  *)
  186.       RETURN time;
  187.     END FileTime;
  188.     
  189.     PROCEDURE WriteFileName(VAR name : System.Path);
  190.       VAR
  191.         i, top : INTEGER;
  192.     BEGIN
  193.       top := StringLib0.Length(name) - 1;
  194.       FOR i:= 0 TO top DO
  195.         FileSystem.WriteChar(fd, name[i]);
  196.       END;
  197.       FileSystem.WriteChar(fd, InOut.EOL);
  198.     END WriteFileName;
  199.     
  200.     PROCEDURE MakeDEFs(dp : DepTree) : LONGINT;
  201.       PROCEDURE Check(ep : EntityPtr; VAR time : LONGINT);
  202.         VAR
  203.           dateDEF,
  204.           dateSBM : LONGINT;
  205.       BEGIN
  206.         dateDEF := FileTime(ep^.defName, 'DEF');
  207.         dateSBM := FileTime(ep^.defName, 'SBM');
  208. (* Begin Debug *)(*
  209. WriteLong(time); InOut.Write(' '); WriteLong(dateDEF); InOut.WriteLn;
  210. WriteLong(dateDEF); InOut.Write(' '); WriteLong(dateSBM); InOut.WriteLn;
  211. *)(* End Debug *)
  212.         IF (time >= dateDEF) OR (dateDEF >= dateSBM) THEN
  213. (* Begin Debug *)(*
  214. InOut.WriteString("Marked Changed"); InOut.WriteLn;
  215. *)(* End Debug *)
  216.           WriteFileName(ep^.defName);
  217.           ep^.date := Eternity; (* Mark changed *)
  218.         ELSE
  219.           ep^.date := dateSBM;
  220.         END;
  221.         time := ep^.date;
  222.       END Check;
  223.     
  224.       VAR
  225.         res, maximum : LONGINT;
  226.     BEGIN
  227.       res := Genesis;
  228.       maximum := Genesis;
  229.       WHILE dp # NIL DO
  230.            WITH dp^.actual^ DO
  231.           IF NOT checked THEN
  232.             checked := TRUE;
  233.             IF NOT library THEN
  234.               res := MakeDEFs(MODDepends); (* Dummy, just do it *)
  235.               res := MakeDEFs(DEFDepends);
  236. (* Begin Debug *)(*
  237. InOut.WriteString('DEF Checking ');
  238. InOut.WriteString(moduleName); InOut.WriteLn;
  239. *)(* End Debug *)
  240.               Check(dp^.actual, res);
  241.             ELSE
  242.               date := Genesis;
  243.               res := date;
  244.             END;
  245.           ELSE
  246.             res := date;
  247.           END;
  248.         END;
  249.         maximum := Max(maximum, res);
  250.         dp := dp^.next;
  251.       END;
  252.       RETURN maximum;
  253.     END MakeDEFs;
  254.     
  255.     PROCEDURE MakeMODs(dp : DepTree) : LONGINT;
  256.       VAR
  257.         maximum : LONGINT;
  258.         dateDEF,
  259.         dateMOD,
  260.         dateOBM : LONGINT;
  261.     BEGIN
  262.       dateDEF := Genesis;
  263.       maximum := Genesis;
  264.       WHILE dp # NIL DO
  265.            WITH dp^.actual^ DO
  266.           IF NOT library THEN
  267.             dateMOD := FileTime(impName, 'MOD');
  268.             dateOBM := FileTime(impName, 'OBM');
  269.             dateDEF := MakeMODs(MODDepends);
  270. (* Begin Debug *)(*
  271. InOut.WriteString('MOD Checking ');
  272. InOut.WriteString(moduleName);
  273. InOut.WriteLn;
  274. WriteLong(dateDEF); InOut.Write(' '); WriteLong(dateOBM); InOut.WriteLn;
  275. WriteLong(dateMOD); InOut.Write(' '); WriteLong(dateOBM); InOut.WriteLn;
  276. *)(* End Debug *)
  277.             IF (dateDEF >= dateOBM) OR (dateMOD >= dateOBM) THEN
  278. (* Begin Debug *)(*
  279. InOut.WriteString("Marked Changed"); InOut.WriteLn;
  280. *)(* End Debug *)
  281.               WriteFileName(impName);
  282.             END;
  283.             maximum := Max(maximum, date);
  284.           END;
  285.         END;
  286.         dp := dp^.next;
  287.       END;
  288.       RETURN maximum;
  289.     END MakeMODs;
  290.     
  291.     VAR
  292.       dateDEF,
  293.       dateMOD,
  294.       dateOBM : LONGINT;
  295.   BEGIN
  296.     dateDEF := MakeDEFs(dp^.actual^.MODDepends); (* Dummy; just do it *)
  297.     dateDEF := MakeMODs(dp^.actual^.MODDepends);
  298.     dateMOD := FileTime(dp^.actual^.impName, 'MOD');
  299.     dateOBM := FileTime(dp^.actual^.impName, 'OBM');
  300. (* Begin Debug *)(*
  301. InOut.WriteString("Checking ");
  302. InOut.WriteString(dp^.actual^.moduleName); InOut.WriteLn;
  303. WriteLong(dateDEF); InOut.Write(' '); WriteLong(dateOBM); InOut.WriteLn;
  304. WriteLong(dateMOD); InOut.Write(' '); WriteLong(dateOBM); InOut.WriteLn;
  305. *)(* End Debug *)
  306.     IF (dateDEF >= dateOBM) OR (dateMOD >= dateOBM) THEN
  307. (* Begin Debug *)(*
  308. InOut.WriteString("Marked Changed"); InOut.WriteLn;
  309. *)(* End Debug *)
  310.       WriteFileName(dp^.actual^.impName);
  311.     END;
  312.   END Make;
  313.   
  314. BEGIN
  315.   root := NIL;
  316. END MakeForest.
  317.