Lazarus

Free Pascal => General => Topic started by: Zvoni on October 20, 2020, 10:09:52 pm

Title: How to find out if a Unit is in Uses-Clause?
Post by: Zvoni on October 20, 2020, 10:09:52 pm
Hi Folks,

is there a way to find out, if a Unit is in the Uses-Clause?

For discussions sake:
I have a Unit "MainUnit.pas".
In its Uses-clause under Interface i have some other units included (e.g. "Uses classes, sysutils, MyUnitDB, MyOtherUnit").
Now, i'm using inc-files to structure my code, and i want to implement functionality depending on which Unit is in the Uses-clause.
Those inc-files are being included via Directive in my "MainUnit.pas"-File

I was thinking about being smart, and just set a {$DEFINE MyUnitDB} at the top of Unit "MyUnitDB", so i could use in my code in the inc-files
{$IFDEF MyUnitDB}
...use code
{$ENDIF}

But that doesn't seem to work.
Scope of Defines are per File?

I hope i'm clear with what i'm asking/trying to achieve.

Yes, i know i can set defines in Project-Properties, but i'd like to avoid that, because it's a dynamic functionality:
Use a Unit --> Inherit the Define --> Functionality becomes available
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: marcov on October 20, 2020, 10:48:38 pm
scope of defines are per unit (or the main program).
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: Zvoni on October 20, 2020, 11:06:54 pm
scope of defines are per unit (or the main program).
Damn!
Any idea if it's in the plans?
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: JuhaManninen on October 21, 2020, 12:14:18 am
Yes, i know i can set defines in Project-Properties, but i'd like to avoid that, because it's a dynamic functionality:
Use a Unit --> Inherit the Define --> Functionality becomes available
If you use Lazarus IDE, you can use Build Modes for different defines.
Then instead of editing a uses section, switch a Build Mode.
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: Zvoni on October 21, 2020, 12:24:29 am
Juha,
good Idea, but my goal is to have that dynamic functionality without resorting to "global" defines.

But i have thought of a workaround:
Just declaring a regular Const at the Top of the Unit, and then in my other units just encase the whole Function-Body in a
"If MyConst Then Begin ..... End" as first/last line of code inside the functions.
It would still get compiled in, but from the outside it would be an empty function.

Opinion?
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: JuhaManninen on October 21, 2020, 02:03:20 am
Opinion?
A weird strategy IMO. However I don't know details of your use case.
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: jamie on October 21, 2020, 02:07:36 am
yes a {$DEFine xxXXXX} at the top will work..

{$IFDEF xxXXXX}
   
 ……

{$IFend}
 
 but you can also do this in your project and make it appear in all of your unit files, just add a define the compile knows about through out and simple change that.

Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: Remy Lebeau on October 21, 2020, 03:41:45 am
Just declaring a regular Const at the Top of the Unit, and then in my other units just encase the whole Function-Body in a
"If MyConst Then Begin ..... End" as first/last line of code inside the functions.

I don't think that will work, since the const will fail to compile if it hasn't been declared yet.

Delphi has {$IF (NOT) DECLARED(...)} that would be suitable for this task, but I don't know if FreePascal has that (I can't find it documented anywhere, only {$IF (NOT) DEFINED(...)}).
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: Blaazen on October 21, 2020, 04:26:46 am
Can't you use this:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. {$DEFINE UseUnit2}
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, {$IFDEF UseUnit2}unit2{$ENDIF};
  8.  
  9. type
  10.   { TForm1 }
  11.   TForm1 = class(TForm)
  12.     procedure FormCreate(Sender: TObject);
  13.   private
  14.  
  15.   public
  16.  
  17.   end;
  18.  
  19. var
  20.   Form1: TForm1;
  21.  
  22. implementation
  23.  
  24. {$R *.lfm}
  25.  
  26. { TForm1 }
  27.  
  28. {$IFDEF UseUnit2}
  29.   {$INCLUDE Unit2related.inc}
  30. {$ENDIF}
  31.  
  32. procedure TForm1.FormCreate(Sender: TObject);
  33. begin
  34.   {$IFDEF UseUnit2} writeln('unit2 activated' );{$ENDIF}
  35. end;
  36.  
  37. end.

i.e. if you will want to disable unit2 in your app you will just comment the $define (line 3) and unit2 nor include file won't be added.
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: Zvoni on October 21, 2020, 07:49:43 am
Blaazen,
that's basically the other way around.
My Goal:
Code: Pascal  [Select][+][-]
  1. // In Unit1
  2. {$DEFINE UseUnit1}
  3. Interface
  4. Procedure DoSomeThing;
  5.  
  6. Implementation
  7.  
  8. Procedure DoSomeThing;
  9. Begin
  10.  
  11. .....
  12. End;
  13.  
Code: Pascal  [Select][+][-]
  1. //In Unit2
  2. Interface
  3.  
  4. Uses Unit1;
  5.  
  6. Implementation
  7.  
  8. {$IFDEF UseUnit1}
  9. Procedure AccessProcInUnit1;
  10. Begin
  11.    DoSomeThing;
  12. End;
  13. {$ENDIF}
  14.  

The thing is: I have different units accessing different c-libraries (one unit per library containing the external function prototypes), and i want the functionality be dynamically available depending on which Units are used in the main project.
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: Zvoni on October 21, 2020, 07:51:32 am
I don't think that will work, since the const will fail to compile if it hasn't been declared yet.
Damn! didn't think of that.
True. I cannot check for a constant which is "exported" from a not used Unit
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: Zvoni on October 21, 2020, 08:06:32 am
Delphi has {$IF (NOT) DECLARED(...)} that would be suitable for this task, but I don't know if FreePascal has that (I can't find it documented anywhere, only {$IF (NOT) DEFINED(...)}).

Bingo!
https://www.freepascal.org/docs-html/prog/progsu127.html#x140-1410002.4.1
Quote
DECLARED(passym)
    Evaluates to TRUE if the pascal symbol is declared at this point in the sources, or FALSE if it is not yet defined.
Will try that one!
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: PascalDragon on October 21, 2020, 09:18:29 am
Delphi has {$IF (NOT) DECLARED(...)} that would be suitable for this task, but I don't know if FreePascal has that (I can't find it documented anywhere, only {$IF (NOT) DEFINED(...)}).

Bingo!
https://www.freepascal.org/docs-html/prog/progsu127.html#x140-1410002.4.1
Quote
DECLARED(passym)
    Evaluates to TRUE if the pascal symbol is declared at this point in the sources, or FALSE if it is not yet defined.
Will try that one!

Please note that it currently does not work with namespaced units. So if you have e.g. a unit UUnit.Test then using DECLARED(UUnit.Test) fails to compile. Even if you use the default namespace option -FNuunit, only use Test in the program and DECLARED(Test) for your include it will evaluate to False.

With non-namespaced units it will work however.
Title: Re: How to find out if a Unit is in Uses-Clause?
Post by: Zvoni on October 21, 2020, 10:55:30 am
Please note that it currently does not work with namespaced units. So if you have e.g. a unit UUnit.Test then using DECLARED(UUnit.Test) fails to compile. Even if you use the default namespace option -FNuunit, only use Test in the program and DECLARED(Test) for your include it will evaluate to False.

With non-namespaced units it will work however.

PD,
thx for the Info.
non-namespaced is sufficient for me.
TinyPortal © 2005-2018