showdeps.pp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. {
  2. This file is part of the Free Component Library
  3. Copyright (c) 2022 by Michael Van Canneyt, [email protected]
  4. Display unit/program dependencies.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. program showdeps;
  12. {$mode objfpc}
  13. {$H+}
  14. uses SysUtils, Classes, PParser, PasTree;
  15. type
  16. { We have to override abstract TPasTreeContainer methods.
  17. See utils/fpdoc/dglobals.pp for an implementation of TFPDocEngine,
  18. a "real" engine. }
  19. TSimpleEngine = class(TPasTreeContainer)
  20. public
  21. function CreateElement(AClass: TPTreeElement; const AName: String;
  22. AParent: TPasElement; AVisibility: TPasMemberVisibility;
  23. const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
  24. override;
  25. function FindElement(const AName: String): TPasElement; override;
  26. end;
  27. function TSimpleEngine.CreateElement(AClass: TPTreeElement; const AName: String;
  28. AParent: TPasElement; AVisibility: TPasMemberVisibility;
  29. const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
  30. begin
  31. // Writeln(AName,' : ',AClass.ClassName,' at ',ASourceFilename,':',ASourceLinenumber);
  32. Result := AClass.Create(AName, AParent);
  33. Result.Visibility := AVisibility;
  34. Result.SourceFilename := ASourceFilename;
  35. Result.SourceLinenumber := ASourceLinenumber;
  36. end;
  37. function TSimpleEngine.FindElement(const AName: String): TPasElement;
  38. begin
  39. { dummy implementation, see TFPDocEngine.FindElement for a real example }
  40. Result := nil;
  41. end;
  42. Procedure PrintUses(aSection : TPasSection; aShowFileName : Boolean = false);
  43. Var
  44. i : integer;
  45. aUses : TPasUsesUnit;
  46. aName : string;
  47. begin
  48. if aSection=Nil then
  49. exit;
  50. for aUses in aSection.UsesClause do
  51. begin
  52. aName:='';
  53. if aShowFileName and assigned(aUses.InFileName) then
  54. aName:=AnsiDequotedStr(aUses.InFileName.Value,'''');
  55. if (aName='') and assigned(aUses.Expr) then
  56. aName:=aUses.Expr.GetDeclaration(False);
  57. if aName='' then
  58. aName:=aUses.Name;
  59. Writeln(aName);
  60. end;
  61. end;
  62. Procedure Usage;
  63. begin
  64. Writeln('Usage : ',ExtractFileName(Paramstr(0)),' [OPTIONS] options ');
  65. Writeln('Where options is exactly one of');
  66. Writeln('-h or --help shows this help');
  67. Writeln('-f or --filename show actual unit filename, if available');
  68. Writeln('-s or --skip-implementation Do not show implementation dependencies');
  69. Writeln('All other options are passed as-is to the parser');
  70. Halt(0);
  71. end;
  72. var
  73. M: TPasModule;
  74. P : TPasProgram absolute M;
  75. E: TPasTreeContainer;
  76. First : String;
  77. Offset,I: Integer;
  78. Decls: TFPList;
  79. cmdline : String;
  80. SkipImplementation,
  81. ShowFileName : Boolean;
  82. begin
  83. cmdline:='';
  84. SkipImplementation:=False;
  85. ShowFileName:=False;
  86. First:=ParamStr(1);
  87. if (ParamCount=0) or (First='-h') or (First='--help') then
  88. Usage;
  89. Offset:=1;
  90. Case first of
  91. '-f',
  92. '--filename':
  93. ShowFileName:=True;
  94. '-s',
  95. '--skip-implementation':
  96. SkipImplementation:=True;
  97. else
  98. Offset:=0;
  99. end;
  100. For I:=1+Offset to ParamCount do
  101. CmdLine:=CmdLine+' '+Paramstr(i);
  102. E := TSimpleEngine.Create;
  103. M := nil;
  104. try
  105. M := ParseSource(E, cmdline, 'linux', 'i386');
  106. PrintUses(M.InterfaceSection);
  107. if not SkipImplementation then
  108. PrintUses(M.ImplementationSection);
  109. if M is TPasProgram then
  110. PrintUses(P.ProgramSection,ShowFilename);
  111. finally
  112. FreeAndNil(M);
  113. FreeAndNil(E)
  114. end;
  115. end.