|
@@ -0,0 +1,60 @@
|
|
|
+MODULE DependencyWalker;
|
|
|
+
|
|
|
+IMPORT Commands, Diagnostics, Files, Options, Streams, FoxBasic, FoxGlobal, FoxParser, FoxScanner, FoxSyntaxTree;
|
|
|
+
|
|
|
+PROCEDURE Process (CONST moduleName, fileExtension: ARRAY OF CHAR; diagnostics: Diagnostics.Diagnostics; writer: Streams.Writer): BOOLEAN;
|
|
|
+VAR reader: Streams.Reader; scanner: FoxScanner.Scanner; parser: FoxParser.Parser;
|
|
|
+VAR module: FoxSyntaxTree.Module; import: FoxSyntaxTree.Import; string: ARRAY 64 OF CHAR;
|
|
|
+BEGIN
|
|
|
+ reader := FoxBasic.GetFileReader (moduleName);
|
|
|
+ IF reader = NIL THEN diagnostics.Error (moduleName, Diagnostics.Invalid, Diagnostics.Invalid, "Failed to open module"); RETURN FALSE END;
|
|
|
+ scanner := FoxScanner.NewScanner (moduleName, reader, 0, diagnostics);
|
|
|
+ NEW (parser, scanner, diagnostics);
|
|
|
+ module := parser.Module ();
|
|
|
+ IF parser.error THEN RETURN FALSE END;
|
|
|
+ FoxGlobal.ModuleFileName (module.name, module.context, string);
|
|
|
+ writer.String (string);
|
|
|
+ writer.String (fileExtension);
|
|
|
+ writer.String (": ");
|
|
|
+ writer.String (moduleName);
|
|
|
+ import := module.moduleScope.firstImport;
|
|
|
+ WHILE import # NIL DO
|
|
|
+ IF import.moduleName # FoxGlobal.SystemName THEN
|
|
|
+ writer.Char (' ');
|
|
|
+ IF import.context # FoxSyntaxTree.invalidIdentifier THEN
|
|
|
+ FoxGlobal.ModuleFileName (import.moduleName, import.context, string);
|
|
|
+ ELSE
|
|
|
+ FoxGlobal.ModuleFileName (import.moduleName, module.context, string);
|
|
|
+ END;
|
|
|
+ writer.String (string);
|
|
|
+ writer.String (fileExtension);
|
|
|
+ END;
|
|
|
+ import := import.nextImport;
|
|
|
+ END;
|
|
|
+ writer.Ln;
|
|
|
+ RETURN TRUE;
|
|
|
+END Process;
|
|
|
+
|
|
|
+PROCEDURE Walk* (context: Commands.Context);
|
|
|
+VAR options : Options.Options; diagnostics : Diagnostics.StreamDiagnostics;
|
|
|
+VAR fileExtension: Options.Parameter; moduleName: Files.FileName;
|
|
|
+BEGIN
|
|
|
+ NEW (options);
|
|
|
+ options.Add ('e', "fileExtension", Options.String);
|
|
|
+ IF ~options.Parse (context.arg, context.error) THEN
|
|
|
+ context.result := Commands.CommandParseError; RETURN;
|
|
|
+ END;
|
|
|
+ IF ~options.GetString ("fileExtension", fileExtension) THEN fileExtension := ".Sym" END;
|
|
|
+
|
|
|
+ NEW (diagnostics, context.error);
|
|
|
+ LOOP
|
|
|
+ context.arg.SkipWhitespace;
|
|
|
+ context.arg.String (moduleName);
|
|
|
+ IF moduleName = "" THEN EXIT END;
|
|
|
+ IF ~Process (moduleName, fileExtension, diagnostics, context.out) THEN
|
|
|
+ context.result := Commands.CommandError; RETURN;
|
|
|
+ END;
|
|
|
+ END;
|
|
|
+END Walk;
|
|
|
+
|
|
|
+END DependencyWalker.
|