home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / dev / obero / oberon-a / source / oru / oru.mod < prev    next >
Text File  |  1994-09-03  |  22KB  |  737 lines

  1. (***************************************************************************
  2.  
  3.      $RCSfile: ORU.mod $
  4.   Description: Generates a script file that will recompile modules dependant
  5.                on a given module.
  6.  
  7.    Created by: fjc (Frank Copeland)
  8.     $Revision: 2.6 $
  9.       $Author: fjc $
  10.         $Date: 1994/09/03 16:32:01 $
  11.  
  12.   Copyright © 1993-1994, Frank Copeland
  13.   This module forms part of the ORU program
  14.   See ORU.doc for conditions of use and distribution
  15.  
  16.   Log entries are at the end of the file.
  17.  
  18. ***************************************************************************)
  19.  
  20. MODULE ORU;
  21.  
  22. (*
  23. ** $C= CaseChk       $I= IndexChk  $L= LongAdr   $N= NilChk
  24. ** $P- PortableCode  $R= RangeChk  $S= StackChk  $T= TypeChk
  25. ** $V= OvflChk       $Z= ZeroVars
  26. *)
  27.  
  28. IMPORT
  29.   SYS := SYSTEM, ORURev, Errors, E := Exec, D := Dos, IU := IntuiUtil,
  30.   Args, IO := StdIO, Str := Strings, L := Lists, Files;
  31.  
  32. CONST
  33.   CopyrightStr = "Copyright © 1993-1994 Frank Copeland\n";
  34.   UsageStr = "See ORU.doc for conditions of use\n";
  35.  
  36. CONST
  37.   MaxPaths         = 32;        (* Maximum number of search paths. *)
  38.   SymExtension     = ".Sym";    (* File extension for symbol files. *)
  39.   DefaultExtension = ".mod";    (* Default extension for source files. *)
  40.   DefaultPath      = "OLIB:";   (* Default path for symbols *)
  41.  
  42.   SymFileTag       = 53594D07H; (* "SYM" + version # *)
  43.   eMod = 22; eMod0 = 25;        (* Symbol file internal tags *)
  44.  
  45.   (* Error messages *)
  46.   OutOfMem  = " !! Out of memory\n";
  47.   OpenError = "\x9B\x4B !! Could not open %s\n";
  48.  
  49. VAR
  50.   NotCD       : BOOLEAN;  (* Don't search current directory if TRUE. *)
  51.   All         : BOOLEAN;  (* Process all modules in search directories. *)
  52.   Symbols     : ARRAY MaxPaths + 1 OF E.STRPTR;
  53.                           (* Search paths for symbol files. *)
  54.   NumSymbols  : INTEGER;  (* Number of paths specified. *)
  55.   Source      : ARRAY MaxPaths + 1 OF E.STRPTR;
  56.                           (* Search paths for source files. *)
  57.   NumSources  : INTEGER;  (* Number of paths specified. *)
  58.   Destination : E.STRPTR; (* Destination directory for batch file. *)
  59.   Extension   : E.STRPTR; (* File extension for source files. *)
  60.   Module      : E.STRPTR; (* Name of redefined module. *)
  61.   ModuleList  : L.List;   (* List of modules discovered. *)
  62.   Dependants  : L.List;   (* List of dependant modules. *)
  63.  
  64. CONST
  65.   MaxName = 31;
  66.  
  67. TYPE
  68.  
  69.   ModName = ARRAY MaxName + 1 OF CHAR;
  70.  
  71.   MNodePtr = POINTER TO MNode;
  72.   MNode = RECORD (L.ExtNode)
  73.     symbols : E.STRPTR;
  74.     imports : L.List;
  75.     path    : E.STRPTR;
  76.   END; (* MNode *)
  77.  
  78.  
  79. (*------------------------------------*)
  80. PROCEDURE Init ();
  81. (*
  82.  *  Simply initialises global variables.
  83.  *)
  84.  
  85. BEGIN (* Init *)
  86.   Extension := SYS.ADR (DefaultExtension);
  87.   L.NewList (ModuleList);
  88.   L.NewList (Dependants);
  89. END Init;
  90.  
  91.  
  92. (*------------------------------------*)
  93. PROCEDURE GetArgs ();
  94. (*
  95.  *  Parses the command line arguments.
  96.  *)
  97.  
  98.   CONST DuplicateArg = " !! Argument duplicated\n\n";
  99.         PathMissing  = " !! <path> missing\n\n";
  100.         ModAndAll    = " !! both <module> and ALL specified\n\n";
  101.         TooManySyms  = " !! Too many symbol file search paths\n";
  102.         TooManySrcs  = " !! Too many source file search paths\n";
  103.         CmdMissing   = " !! <command> missing\n\n";
  104.         ExtMissing   = " !! <extension> missing\n\n";
  105.         WithMissing  = " !! <file> missing\n\n";
  106.         ArgTooLong   = " !! Argument in WITH file too long\n";
  107.         BadArg       = " !! Unrecognised argument in WITH file\n";
  108.  
  109.   VAR moduleFound, destFound, cmdFound, extFound : BOOLEAN; arg : INTEGER;
  110.       argStr : ARRAY 256 OF CHAR;
  111.  
  112.   (*------------------------------------*)
  113.   PROCEDURE Greeting ();
  114.  
  115.   BEGIN (* Greeting *)
  116.     IO.WriteStr (ORURev.vString);
  117.     IO.WriteStr (CopyrightStr);
  118.     IO.WriteStr (UsageStr);
  119.     IO.WriteLn ();
  120.   END Greeting;
  121.  
  122.   (*------------------------------------*)
  123.   PROCEDURE Usage ();
  124.  
  125.   BEGIN (* Usage *)
  126.     IO.WriteStr ("Usage:   ORU {option} <module>|ALL\n\n");
  127.     IO.WriteStr ("Options: NOTCD {WITH <file>}\n");
  128.     IO.WriteStr ("         {SYM | SYMBOLS <path>}\n");
  129.     IO.WriteStr ("         {SRC | SOURCE} <path>}\n");
  130.     IO.WriteStr ("         DST | DESTINATION <path>\n");
  131.     IO.WriteStr ("         EXT | EXTENSION <extension>\n\n");
  132.   END Usage;
  133.  
  134.   (*------------------------------------*)
  135.   PROCEDURE ParseWithFile (VAR fileName : ARRAY OF CHAR);
  136.  
  137.     VAR file : Files.File; r : Files.Rider; argStr : ARRAY 256 OF CHAR;
  138.  
  139.     (*------------------------------------*)
  140.     (* $D- disable copying of open arrays *)
  141.     PROCEDURE BailOut (msg : ARRAY OF CHAR);
  142.  
  143.     BEGIN (* BailOut *)
  144.       IO.WriteStr (msg); Usage (); Files.Close (file); HALT (10)
  145.     END BailOut;
  146.  
  147.     (*------------------------------------*)
  148.     (* $D- disable copying of open arrays *)
  149.     PROCEDURE BailOut2 (msg : ARRAY OF CHAR);
  150.  
  151.     BEGIN (* BailOut2 *)
  152.       IO.WriteStr (msg); Files.Close (file); HALT (10)
  153.     END BailOut2;
  154.  
  155.     (*------------------------------------*)
  156.     PROCEDURE GetNextArg ();
  157.  
  158.       VAR i : LONGINT; ch : CHAR;
  159.  
  160.     BEGIN (* GetNextArg *)
  161.       Files.Read (r, ch);
  162.       (* Skip white space *)
  163.       WHILE (ch <= " ") & ~r.eof DO Files.Read (r, ch) END;
  164.       IF r.eof THEN
  165.         RETURN
  166.       ELSIF ch = 22X THEN
  167.         (* Quoted argument *)
  168.         i := 0; Files.Read (r, ch);
  169.         WHILE (i < 255) & (ch # 22X) & ~r.eof DO
  170.           argStr [i] := ch; INC (i); Files.Read (r, ch)
  171.         END;
  172.         argStr [i] := 0X;
  173.         IF ch = 22X THEN Files.Read (r, ch)
  174.         ELSIF ~r.eof THEN BailOut2 (ArgTooLong)
  175.         END;
  176.       ELSE
  177.         i := 0;
  178.         WHILE (i < 255) & (ch > " ") & ~r.eof DO
  179.           argStr [i] := ch; INC (i); Files.Read (r, ch)
  180.         END;
  181.         argStr [i] := 0X;
  182.         IF (ch > " ") & ~r.eof THEN BailOut2 (ArgTooLong) END
  183.       END; (* ELSE *)
  184.     END GetNextArg;
  185.  
  186.     (*------------------------------------*)
  187.     PROCEDURE CopyArg () : E.STRPTR;
  188.  
  189.       VAR copy : E.STRPTR;
  190.  
  191.     BEGIN (* CopyArg *)
  192.       SYS.NEW (copy, SYS.STRLEN (argStr) + 1);
  193.       COPY (argStr, copy^);
  194.       RETURN copy
  195.     END CopyArg;
  196.  
  197.   BEGIN (* ParseWithFile *)
  198.     file := Files.Old (fileName);
  199.     IF file # NIL THEN
  200.       Files.Set (r, file, 0); GetNextArg ();
  201.       WHILE ~r.eof DO
  202.         Str.ToUpper (argStr);
  203.         IF argStr = "NOTCD" THEN
  204.           IF NotCD THEN BailOut (DuplicateArg) END;
  205.           NotCD := TRUE
  206.         ELSIF (argStr = "SYM") OR (argStr = "SYMBOLS") THEN
  207.           GetNextArg ();
  208.           IF r.eof THEN BailOut (PathMissing)
  209.           ELSIF NumSymbols >= MaxPaths THEN
  210.           BailOut2 (TooManySyms)
  211.           END;
  212.           Symbols [NumSymbols] := CopyArg ();
  213.           INC (NumSymbols); Symbols [NumSymbols] := NIL;
  214.         ELSIF (argStr = "SRC") OR (argStr = "SOURCE") THEN
  215.           GetNextArg ();
  216.           IF r.eof THEN BailOut (PathMissing)
  217.           ELSIF NumSources >= MaxPaths THEN BailOut2 (TooManySrcs)
  218.           END;
  219.           Source [NumSources] := CopyArg ();
  220.           INC (NumSources); Source [NumSources] := NIL;
  221.         ELSIF (argStr = "EXT") OR (argStr = "EXTENSION") THEN
  222.           GetNextArg ();
  223.           IF r.eof OR extFound THEN
  224.             IF extFound THEN BailOut (DuplicateArg)
  225.             ELSE BailOut (ExtMissing)
  226.             END;
  227.           END;
  228.           Extension := CopyArg (); extFound := TRUE
  229.         ELSE
  230.           BailOut (BadArg)
  231.         END; (* ELSE *)
  232.         GetNextArg ();
  233.       END; (* WHILE *)
  234.       Files.Close (file);
  235.     ELSE
  236.       IO.WriteF1 (" !! Could not open %s\n", SYS.ADR (fileName))
  237.     END; (* ELSE *)
  238.   END ParseWithFile;
  239.  
  240.   (*------------------------------------*)
  241.   (* $D- disable copying of open arrays *)
  242.   PROCEDURE BailOut (msg : ARRAY OF CHAR);
  243.  
  244.   BEGIN (* BailOut *)
  245.     IO.WriteStr (msg); Usage ();  HALT (10)
  246.   END BailOut;
  247.  
  248.   (*------------------------------------*)
  249.   (* $D- disable copying of open arrays *)
  250.   PROCEDURE BailOut2 (msg : ARRAY OF CHAR);
  251.  
  252.   BEGIN (* BailOut2 *)
  253.     IO.WriteStr (msg); HALT (10)
  254.   END BailOut2;
  255.  
  256. BEGIN (* GetArgs *)
  257.   moduleFound := FALSE; destFound := FALSE; cmdFound := FALSE;
  258.   extFound := FALSE;
  259.   IF Args.IsCLI THEN
  260.     Greeting ();
  261.     IF Args.argc < 2 THEN
  262.       (* Minimum of one argument needed *)
  263.       BailOut (" !! Arguments missing\n\n")
  264.     END;
  265.     Symbols [0] := SYS.ADR (DefaultPath);
  266.     NumSymbols := 1; Symbols [1] := NIL;
  267.     arg := 1; (* first argument is the program name, so ignore it. *)
  268.     WHILE arg < Args.argc DO
  269.       COPY (Args.argv [arg]^, argStr); Str.ToUpper (argStr);
  270.       IF argStr = "NOTCD" THEN
  271.         IF NotCD THEN BailOut (DuplicateArg) END;
  272.         NotCD := TRUE
  273.       ELSIF (argStr = "SYM") OR (argStr = "SYMBOLS") THEN
  274.         INC (arg);
  275.         IF arg >= Args.argc THEN BailOut (PathMissing)
  276.         ELSIF NumSymbols >= MaxPaths THEN BailOut2 (TooManySyms)
  277.         END;
  278.         Symbols [NumSymbols] := Args.argv [arg];
  279.         INC (NumSymbols); Symbols [NumSymbols] := NIL;
  280.       ELSIF (argStr = "SRC") OR (argStr = "SOURCE") THEN
  281.         INC (arg);
  282.         IF arg >= Args.argc THEN BailOut (PathMissing)
  283.         ELSIF NumSources >= MaxPaths THEN BailOut2 (TooManySrcs)
  284.         END;
  285.         Source [NumSources] := Args.argv [arg];
  286.         INC (NumSources); Source [NumSources] := NIL;
  287.       ELSIF (argStr = "DST") OR (argStr = "DESTINATION") THEN
  288.         INC (arg);
  289.         IF (arg >= Args.argc) OR destFound THEN
  290.           IF destFound THEN BailOut (DuplicateArg)
  291.           ELSE BailOut (PathMissing)
  292.           END;
  293.         END;
  294.         Destination := Args.argv [arg]; destFound := TRUE
  295.       ELSIF (argStr = "EXT") OR (argStr = "EXTENSION") THEN
  296.         INC (arg);
  297.         IF (arg >= Args.argc) OR extFound THEN
  298.           IF extFound THEN BailOut (DuplicateArg)
  299.           ELSE BailOut (ExtMissing)
  300.           END;
  301.         END;
  302.         Extension := Args.argv [arg]; extFound := TRUE
  303.       ELSIF argStr = "ALL" THEN
  304.         IF All THEN BailOut (DuplicateArg)
  305.         ELSIF moduleFound THEN BailOut (ModAndAll)
  306.         END;
  307.         Module := SYS.ADR("All"); All := TRUE
  308.       ELSIF argStr = "WITH" THEN
  309.         INC (arg);
  310.         IF arg >= Args.argc THEN BailOut (WithMissing) END;
  311.         ParseWithFile (Args.argv [arg]^)
  312.       ELSE
  313.         IF moduleFound THEN BailOut (DuplicateArg)
  314.         ELSIF All THEN BailOut (ModAndAll)
  315.         END;
  316.         Module := Args.argv [arg]; moduleFound := TRUE
  317.       END; (* ELSE *)
  318.       INC (arg)
  319.     END; (* WHILE *)
  320.     IF ~moduleFound & ~All THEN BailOut (" !! <module> missing\n\n") END;
  321.   ELSE
  322.     IU.SimpleNotice
  323.       (NIL, SYS.ADR ("Sorry, no support for Workbench yet :-("));
  324.     HALT (10)
  325.   END; (* ELSE *)
  326. END GetArgs;
  327.  
  328.  
  329. (*------------------------------------*)
  330. PROCEDURE SearchSymbolFile (directory : E.STRPTR; fileName : ARRAY OF CHAR);
  331.  
  332.   CONST
  333.     NotSymFile = "\x9B\x4B !! %s is obsolete, or is not a symbol file\n";
  334.  
  335.   VAR
  336.     F : Files.File; R : Files.Rider; tag : LONGINT; modName : ModName;
  337.     module : MNodePtr; import : L.ExtNodePtr;
  338.  
  339.   (*------------------------------------*)
  340.   PROCEDURE ReadModAnchor (VAR n : ARRAY OF CHAR) : BOOLEAN;
  341.  
  342.     CONST
  343.       BadName = "\x9B\x4B !! Bad name in symbol file %s\n";
  344.  
  345.     VAR s : SHORTINT; ch : CHAR; key : LONGINT;
  346.  
  347.   BEGIN (* ReadModAnchor *)
  348.     Files.Read (R, s); (* modAnchor *)
  349.     IF (s = eMod) OR (s = eMod0) THEN
  350.       Files.ReadBytes (R, key, 4); s := 0;
  351.       LOOP
  352.         Files.Read (R, ch); n [s] := ch;
  353.         IF ch = 0X THEN EXIT END;
  354.         INC (s);
  355.         IF s > MaxName THEN
  356.           n [MaxName] := 0X;
  357.           IO.WriteF1 (BadName, SYS.ADR (fileName));
  358.           WHILE ch # 0X DO Files.Read (R, ch) END;
  359.           RETURN FALSE
  360.         END; (* IF *)
  361.       END; (* LOOP *)
  362.       RETURN TRUE
  363.     END; (* IF *)
  364.     RETURN FALSE
  365.   END ReadModAnchor;
  366.  
  367. (* $D- disable copying of open arrays *)
  368. BEGIN (* SearchSymbolFile *)
  369.   IO.WriteF1 ("\x9B\x4B << %s\r", SYS.ADR (fileName));
  370.   F := Files.Old (fileName);
  371.   IF F = NIL THEN IO.WriteF1 (OpenError, SYS.ADR (fileName))
  372.   ELSE
  373.     Files.Set (R, F, 0); Files.ReadBytes (R, tag, 4);
  374.     IF tag # SymFileTag THEN
  375.       IO.WriteF1 (NotSymFile, SYS.ADR (fileName))
  376.     ELSE
  377.       IF ReadModAnchor (modName) THEN
  378.         NEW (module);
  379.         L.AttachName (module^, modName); module.key := 0;
  380.         module.symbols := directory; L.NewList (module.imports);
  381.         L.AddTail (ModuleList, module);
  382.         WHILE ReadModAnchor (modName) DO
  383.           NEW (import);
  384.           L.AttachName (import^, modName);
  385.           L.AddTail (module.imports, import);
  386.         END;
  387.       END;
  388.     END;
  389.     Files.Close (F); SYS.DISPOSE (F)
  390.   END;
  391. END SearchSymbolFile;
  392.  
  393.  
  394. (*------------------------------------*)
  395. PROCEDURE ScanForSymbols (directory : E.STRPTR);
  396.  
  397.   CONST
  398.     LockError    = " !! Failed to lock %s\n";
  399.     ExamineError = " !! Examine () failed\n";
  400.     NotDirectory = " !! %s is not a directory\n";
  401.  
  402.   VAR
  403.     lock, oldLock : D.FileLockPtr; fib : D.FileInfoBlockPtr;
  404.     success : BOOLEAN; len : LONGINT; extension : ARRAY 5 OF CHAR;
  405.  
  406. BEGIN (* ScanForSymbols *)
  407.   IF directory = NIL THEN directory := SYS.ADR ("") END;
  408.   lock := D.base.Lock (directory^, D.sharedLock);
  409.   IF lock = NIL THEN IO.WriteF1 (LockError, directory); RETURN END;
  410.  
  411.   NEW (fib);
  412.   oldLock := D.base.CurrentDir (lock);
  413.   success := D.base.Examine (lock, fib^);
  414.  
  415.   IF ~success THEN IO.WriteStr (ExamineError)
  416.   ELSE
  417.     IF fib.dirEntryType <= 0 THEN IO.WriteF1 (NotDirectory, directory)
  418.     ELSE
  419.       WHILE D.base.ExNext (lock, fib^) DO
  420.         IF fib.dirEntryType < 0 THEN
  421.           len := Str.Length (fib.fileName);
  422.           IF (len > 3) & (fib.fileName [len - 4] = ".") THEN
  423.             Str.CopySubString (extension, fib.fileName, len - 4, 4);
  424.             IF extension = SymExtension THEN
  425.               SearchSymbolFile (directory, fib.fileName)
  426.             END;
  427.           END;
  428.         END;
  429.       END;
  430.     END;
  431.   END;
  432.  
  433.   SYS.DISPOSE (fib);
  434.   oldLock := D.base.CurrentDir (oldLock);
  435.   D.base.UnLock (lock)
  436. END ScanForSymbols;
  437.  
  438.  
  439. (*------------------------------------*)
  440. (* $D- disable copying of open arrays *)
  441. PROCEDURE SearchForDependants (modName : ARRAY OF CHAR; level : LONGINT);
  442.  
  443.   CONST ModuleMissing = " !! Module %s not found\n";
  444.  
  445.   VAR node, module, import : L.NodePtr;
  446.  
  447. BEGIN (* SearchForDependants *)
  448.   module := L.FindNameNoCase (ModuleList, modName);
  449.   IF module = NIL THEN IO.WriteF1 (ModuleMissing, SYS.ADR (modName))
  450.   ELSE
  451.     IF module(MNodePtr).key > level THEN
  452.       module(MNodePtr).key := level;
  453.       node := ModuleList.head;
  454.       WHILE node # NIL DO
  455.         WITH node : MNodePtr DO
  456.           import := L.FindNameNoCase (node.imports, modName);
  457.           IF import # NIL THEN
  458.             SearchForDependants (node.name^, level - 1)
  459.           END;
  460.         END;
  461.         node := node.succ
  462.       END;
  463.     END;
  464.   END;
  465. END SearchForDependants;
  466.  
  467.  
  468. (*------------------------------------*)
  469. PROCEDURE SearchForAll ();
  470.  
  471.   VAR node, module, import : L.NodePtr;
  472.  
  473. BEGIN (* SearchForAll *)
  474.   module := ModuleList.head;
  475.   WHILE module # NIL DO
  476.     IF module(MNodePtr).key = 0 THEN
  477.       module(MNodePtr).key := -1;
  478.       node := ModuleList.head;
  479.       WHILE node # NIL DO
  480.         WITH node : MNodePtr DO
  481.           import := L.FindName (node.imports, module(L.ExtNodePtr).name^);
  482.           IF import # NIL THEN
  483.             SearchForDependants (node.name^, -2)
  484.           END;
  485.         END; (* WITH node *)
  486.         node := node.succ
  487.       END; (* WHILE *)
  488.     END;
  489.     module := module.succ;
  490.   END; (* WHILE *)
  491. END SearchForAll;
  492.  
  493.  
  494. (*------------------------------------*)
  495. PROCEDURE SortDependants ();
  496.  
  497.   VAR node : L.NodePtr;
  498.  
  499. BEGIN (* SortDependants *)
  500.   LOOP
  501.     node := L.RemHead (ModuleList);
  502.     IF node = NIL THEN EXIT END;
  503.     WITH node : MNodePtr DO
  504.       IF node.key < 0 THEN L.Enqueue (Dependants, node) END
  505.     END; (* WITH *)
  506.   END; (* LOOP *)
  507. END SortDependants;
  508.  
  509.  
  510. (*------------------------------------*)
  511. (* $D- disable copying of open arrays *)
  512. PROCEDURE FileExists (path : ARRAY OF CHAR) : BOOLEAN;
  513.  
  514.   VAR lock : D.FileLockPtr; result : BOOLEAN;
  515.  
  516. BEGIN (* FileExists *)
  517.   result := FALSE;
  518.   lock := D.base.Lock (path, D.sharedLock);
  519.   IF lock # NIL THEN result := TRUE; D.base.UnLock (lock) END;
  520.   RETURN result
  521. END FileExists;
  522.  
  523. (*------------------------------------*)
  524. (* $D- disable copying of open arrays *)
  525. PROCEDURE Search (file : ARRAY OF CHAR; VAR path : E.STRPTR) : BOOLEAN;
  526.  
  527.   VAR
  528.     index : INTEGER; fullPath : ARRAY 256 OF CHAR;
  529.     len : LONGINT; ch : CHAR;
  530.  
  531. BEGIN (* Search *)
  532.   path := NIL;
  533.   IF NotCD THEN
  534.     IF Source [0] = NIL THEN RETURN FALSE END;
  535.     COPY (Source [0]^, fullPath); index := 0
  536.   ELSE
  537.     fullPath [0] := 0X; index := -1
  538.   END;
  539.   LOOP
  540.     len := Str.Length (fullPath);
  541.     IF len > 0 THEN
  542.       ch := fullPath [len - 1];
  543.       IF (ch # "/") & (ch # ":") THEN Str.Append (fullPath, "/") END
  544.     END;
  545.     Str.Append (fullPath, file); Str.Append (fullPath, Extension^);
  546.     IF FileExists (fullPath) THEN
  547.       IF index >= 0 THEN path := Source [index] END;
  548.       RETURN TRUE
  549.     END;
  550.     INC (index);
  551.     IF Source [index] = NIL THEN RETURN FALSE
  552.     ELSE COPY (Source [index]^, fullPath)
  553.     END
  554.   END
  555. END Search;
  556.  
  557. (*------------------------------------*)
  558. PROCEDURE SearchForSources ();
  559.  
  560.   VAR node, succ : L.NodePtr;
  561.  
  562. BEGIN (* SearchForSources *)
  563.   node := Dependants.head;
  564.   WHILE node # NIL DO
  565.     succ := node.succ;
  566.     WITH node : MNodePtr DO
  567.       IF ~Search (node.name^, node.path) THEN
  568.         L.Remove (Dependants, node)
  569.       END
  570.     END;
  571.     node := succ
  572.   END;
  573. END SearchForSources;
  574.  
  575.  
  576. (*------------------------------------*)
  577. (* $D- disable copying of open arrays *)
  578. PROCEDURE OutputModules (batchFile : ARRAY OF CHAR);
  579.  
  580.   VAR
  581.     F : Files.File; R : Files.Rider; module : L.NodePtr;
  582.     len : LONGINT; ch : CHAR;
  583.  
  584. BEGIN (* OutputModules *)
  585.   F := Files.New (batchFile);
  586.   IF F = NIL THEN IO.WriteF1 (OpenError, SYS.ADR (batchFile))
  587.   ELSE
  588.     Files.Set (R, F, 0);
  589.     module := Dependants.head;
  590.     WHILE module # NIL DO
  591.       WITH module : MNodePtr DO
  592.         IF module.path # NIL THEN
  593.           len := Str.Length (module.path^);
  594.           IF len > 0 THEN
  595.             Files.WriteBytes (R, module.path^, len);
  596.             ch := module.path^ [len - 1];
  597.             IF (ch # "/") & (ch # ":") THEN Files.Write (R, "/") END;
  598.           END
  599.         END;
  600.         Files.WriteBytes (R, module.name^, Str.Length (module.name^));
  601.       END;
  602.       Files.WriteBytes (R, Extension^, Str.Length (Extension^));
  603.       Files.Write (R, "\n");
  604.       module := module.succ
  605.     END;
  606.     Files.Register (F)
  607.   END;
  608. END OutputModules;
  609.  
  610.  
  611. (*------------------------------------*)
  612. PROCEDURE Main ();
  613. (*
  614.  *  The main body of the program.
  615.  *
  616.  *  The basic sequence is:
  617.  *
  618.  *    * Scan the current directory and the Symbols list.  With each symbol
  619.  *      file found:
  620.  *        * Add the module to the list of modules found.
  621.  *        * Open the symbol file and create a list of the modules it
  622.  *          imports.
  623.  *    * Search the module list for modules that import the redefined module
  624.  *      and add them to a list of dependant modules.
  625.  *    * Search the current directory and the Sources list for the source
  626.  *      files of the dependant modules.
  627.  *    * Output the list to the script file using the command template.
  628.  *)
  629.  
  630.   VAR index : INTEGER; batchFile : ARRAY 256 OF CHAR;
  631.     len : LONGINT; ch : CHAR;
  632.  
  633. BEGIN (* Main *)
  634.   IO.WriteStr (" !! Scanning for symbol files\n");
  635.   IF ~NotCD THEN
  636.     IO.WriteStr ("    Scanning current directory\n"); ScanForSymbols (NIL)
  637.   END;
  638.  
  639.   index := 0;
  640.   WHILE Symbols [index] # NIL DO
  641.     IO.WriteF1 ("\x9B\x4B    Scanning %s\n", Symbols [index]);
  642.     ScanForSymbols (Symbols [index]); INC (index)
  643.   END;
  644.  
  645.   IF All THEN
  646.     IO.WriteStr ("\x9B\x4B !! Searching for all dependant modules\n");
  647.     SearchForAll ()
  648.   ELSE
  649.     IO.WriteF1 ("\x9B\x4B !! Searching for dependants of %s\n", Module);
  650.     SearchForDependants (Module^, -1);
  651.   END; (* ELSE *)
  652.  
  653.   IO.WriteStr ("\x9B\x4B !! Sorting dependant modules\n");
  654.   SortDependants ();
  655.  
  656.   IO.WriteStr ("\x9B\x4B !! Searching for source files\n");
  657.   SearchForSources ();
  658.  
  659.   (*
  660.   IO.WriteStr ("\nDependant modules:\n");
  661.   module := Dependants.head;
  662.   WHILE module # NIL DO
  663.     WITH module : MNodePtr DO
  664.       IO.WriteF3 ("  %s %s : %ld\n", module.path, module.name, module.key);
  665.     END; (* WITH module *)
  666.     module := module.succ
  667.   END; (* WHILE *)
  668.   IO.WriteLn ();
  669.   *)
  670.  
  671.   IF Destination = NIL THEN
  672.     batchFile := ""
  673.   ELSE
  674.     COPY (Destination^, batchFile); len := Str.Length (batchFile);
  675.     IF len > 0 THEN
  676.       ch := batchFile [len - 1];
  677.       IF (ch # "/") & (ch # ":") THEN Str.Append (batchFile, "/") END
  678.     END
  679.   END;
  680.   Str.Append (batchFile, Module^); Str.Append (batchFile, ".bat");
  681.   IO.WriteF1
  682.     ("\x9B\x4B !! Creating batch file %s\n", SYS.ADR (batchFile));
  683.   OutputModules (batchFile)
  684. END Main;
  685.  
  686.  
  687. BEGIN (* ORU *)
  688.   Init ();
  689.   GetArgs ();
  690.   Main ();
  691. END ORU.
  692.  
  693. (***************************************************************************
  694.  
  695.   $Log: ORU.mod $
  696.   Revision 2.6  1994/09/03  16:32:01  fjc
  697.   - Gets version string from ORURev.
  698.  
  699.   Revision 2.5  1994/08/08  16:38:47  fjc
  700.   Release 1.4
  701.  
  702.   Revision 2.4  1994/06/17  18:09:17  fjc
  703.   - Updated for release
  704.  
  705.   Revision 2.3  1994/06/05  00:11:07  fjc
  706.   - Updated symbol file tag to new version
  707.   - Changed to use new Amiga interface
  708.  
  709.   Revision 2.2  1994/05/21  22:47:40  fjc
  710.   - Removed case-sensitivity of module parameter
  711.   - Appends "/" to paths not ending in "/" or ":"
  712.  
  713.   Revision 2.1  1994/05/19  23:23:19  fjc
  714.   - Bumped version number.
  715.   - Changed to generate a batch file to be used with the BATCH
  716.     option of the compiler.
  717.   - OLIB: is now the default symbol file search path.
  718.  
  719.   Revision 1.3  1994/05/11  23:40:54  fjc
  720.   - Added copyright notice to file header
  721.   - Changed greeting
  722.  
  723.   Revision 1.2  1994/01/25  10:07:37  fjc
  724.   - Updated greeting
  725.  
  726.   Revision 1.1  1994/01/15  19:02:30  fjc
  727.   - Start of revision control
  728.  
  729.   0.4  (02-Jan-94)  Recognises new symbol file tags.
  730.   0.3  (28-Dec-93)  Increased MaxPaths.
  731.   0.2  (30-Sep-93)  Add ALL and WITH options.
  732.   0.1  (06-Sep-93)  First public release.
  733.   0.0  (27-Aug-93)  Initial version.
  734.  
  735. ***************************************************************************)
  736.  
  737.