Recent

Author Topic: How to find out if a Unit is in Uses-Clause?  (Read 1989 times)

Zvoni

  • Hero Member
  • *****
  • Posts: 2300
How to find out if a Unit is in Uses-Clause?
« 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
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: How to find out if a Unit is in Uses-Clause?
« Reply #1 on: October 20, 2020, 10:48:38 pm »
scope of defines are per unit (or the main program).

Zvoni

  • Hero Member
  • *****
  • Posts: 2300
Re: How to find out if a Unit is in Uses-Clause?
« Reply #2 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?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4458
  • I like bugs.
Re: How to find out if a Unit is in Uses-Clause?
« Reply #3 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.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

Zvoni

  • Hero Member
  • *****
  • Posts: 2300
Re: How to find out if a Unit is in Uses-Clause?
« Reply #4 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?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4458
  • I like bugs.
Re: How to find out if a Unit is in Uses-Clause?
« Reply #5 on: October 21, 2020, 02:03:20 am »
Opinion?
A weird strategy IMO. However I don't know details of your use case.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

jamie

  • Hero Member
  • *****
  • Posts: 6077
Re: How to find out if a Unit is in Uses-Clause?
« Reply #6 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.

The only true wisdom is knowing you know nothing

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1311
    • Lebeau Software
Re: How to find out if a Unit is in Uses-Clause?
« Reply #7 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(...)}).
« Last Edit: October 21, 2020, 03:43:55 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: How to find out if a Unit is in Uses-Clause?
« Reply #8 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.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Zvoni

  • Hero Member
  • *****
  • Posts: 2300
Re: How to find out if a Unit is in Uses-Clause?
« Reply #9 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.
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Zvoni

  • Hero Member
  • *****
  • Posts: 2300
Re: How to find out if a Unit is in Uses-Clause?
« Reply #10 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
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Zvoni

  • Hero Member
  • *****
  • Posts: 2300
Re: How to find out if a Unit is in Uses-Clause?
« Reply #11 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!
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: How to find out if a Unit is in Uses-Clause?
« Reply #12 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.

Zvoni

  • Hero Member
  • *****
  • Posts: 2300
Re: How to find out if a Unit is in Uses-Clause?
« Reply #13 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.
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

 

TinyPortal © 2005-2018