Recent

Author Topic: System.SysUtils, System.Classes....  (Read 3043 times)

Molochnik

  • Jr. Member
  • **
  • Posts: 79
System.SysUtils, System.Classes....
« on: May 17, 2024, 11:08:54 am »
I keep replacing such unit names removing namespace prefix, cause otherwise they cannot be found, but am I right?

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: System.SysUtils, System.Classes....
« Reply #1 on: May 17, 2024, 11:24:35 am »
When programming parallel (Delphi and Lazarus) on same units, than I prefer conditional compiling so Delphi is happy with its namespace and Lazarus is happy too :D
Code: Pascal  [Select][+][-]
  1. {$IFDEF FPC}
  2. uses SysUtils, Classes....
  3. {$ELSE FPC}
  4. // in here you could also add a second condition for older Delphi versions
  5. uses System.SysUtils, System.Classes....
  6. {$ENDIF FPC}
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Wallaby

  • Full Member
  • ***
  • Posts: 104
Re: System.SysUtils, System.Classes....
« Reply #2 on: May 17, 2024, 11:51:48 am »
The name spaced approach will soon work with FPC as well.

Most units have been converted to name-spaced versions, e.g. https://gitlab.com/freepascal.org/fpc/source/-/blob/main/rtl/namespaced/common/System.SysUtils.pp

Molochnik

  • Jr. Member
  • **
  • Posts: 79
Re: System.SysUtils, System.Classes....
« Reply #3 on: May 17, 2024, 12:10:36 pm »
KodeZwerg
That's cool! With such approach its easy to make even gcc happy.  :D

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: System.SysUtils, System.Classes....
« Reply #4 on: May 17, 2024, 01:11:42 pm »
I am glad you liking it.
Here is a more comprehensive approach:
(the content of this i put into a file called "kz.inc")
Code: Pascal  [Select][+][-]
  1. {$IF Defined(DCC) or Defined(VER210) or Defined(VER200) or Defined(VER190) or Defined(VER185) or Defined(VER180) or Defined(VER170) or Defined(VER160) or Defined(VER150) or Defined(VER140) or Defined(VER130) or Defined(VER120) or Defined(VER100) or Defined(VER90) or Defined(VER80)}
  2.   {$DEFINE Delphi} { Delphi }
  3. {$IFEND}
  4.  
  5. {$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 25)}
  6.   {$LEGACYIFEND ON}
  7. {$IFEND}
  8.  
  9. {$IF Defined(FPC)}
  10.   {$DEFINE Lazarus} { Lazarus and Free Pascal }
  11. {$IFEND}
  12.  
  13. {$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 23)}
  14.   {$DEFINE NameSpace} { Delphis NameSpace feature (eg Winapi.Windows instead of Windows) }
  15. {$IFEND}
  16.  
  17. {$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 20)}
  18.   {$DEFINE UniCode} { Delphis UniCode support }
  19. {$IFEND}
  20.  
  21. {$IF Defined(WIN32) or Defined(WIN64) or Defined(MSWindows)}
  22.   {$DEFINE Windows} { We are on Windows }
  23. {$IFEND Windows}
  24.  
  25. {$IF Defined(FPC) and Declared(FPC_VERSION) and (FPC_VERSION >= 3)}
  26.   {$DEFINE UniCode} { FreePascal UniCode support }
  27. {$IFEND}
and here is an example how to use it:
Code: Pascal  [Select][+][-]
  1. {$I '.\kz.inc'}
  2.  
  3. {$IFDEF FPC}
  4. {$mode objfpc}{$H+}
  5. {$ENDIF FPC}
  6.  
  7. interface
  8.  
  9. uses
  10. {$IFDEF DELPHI}
  11.   {$IFDEF NameSpace}
  12.     {$IFDEF Windows}
  13.       Winapi.Windows,
  14.     {$ENDIF Windows}
  15.     System.SysUtils, System.Classes,
  16.     Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
  17.   {$ELSE NameSpace}
  18.     {$IFDEF Windows}
  19.       Windows,
  20.     {$ENDIF Windows}
  21.     SysUtils, Classes,
  22.     Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
  23.   {$ENDIF NameSpace}
  24. {$ENDIF DELPHI}
  25. {$IFDEF FPC}
  26.   {$IFDEF Windows}
  27.     Windows,
  28.   {$ENDIF Windows}
  29.   SysUtils, Classes,
  30.   Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
  31. {$ENDIF FPC}
  32. // here you can add custom units that always named same way
  33. MyUnit
  34. ; // <- important!
and to load the correct form data:
Code: Pascal  [Select][+][-]
  1. implementation
  2.  
  3. {$IFDEF DELPHI}
  4. {$R *.dfm}
  5. {$ENDIF DELPHI}
  6. {$IFDEF FPC}
  7. {$R *.lfm}
  8. {$ENDIF FPC}
For the last one (load form) you will need to have same formdata for Delphi and Lazarus.
In many cases it is enough to copy the lfm or dfm to the other extension, load it once into IDE and watch if it throw errors because Delphi and Lazarus got differences in property names.
After fixing errors with any texteditor (remove the errors by hand) you will have a project that works and compiles for both Pascal Interpreters.
« Last Edit: May 17, 2024, 01:37:44 pm by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: System.SysUtils, System.Classes....
« Reply #5 on: May 17, 2024, 01:15:56 pm »
The name spaced approach will soon work with FPC as well.

Most units have been converted to name-spaced versions, e.g. https://gitlab.com/freepascal.org/fpc/source/-/blob/main/rtl/namespaced/common/System.SysUtils.pp
I pray that the FPC team makes it better than the Delphi team was doing.

example that break old code:
Code: Pascal  [Select][+][-]
  1. uses WinApi.Windows;
  2. begin
  3.   Windows.CloseHandle(); // <- can't find closehandle since unit is included by namespace
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11944
  • FPC developer.
Re: System.SysUtils, System.Classes....
« Reply #6 on: May 17, 2024, 01:30:52 pm »
In Delphi I simply add all common prefixes to the project namespace path and then use the old names.

IMHO the implementation is toothless in the first place, so you don't miss much.


Molochnik

  • Jr. Member
  • **
  • Posts: 79
Re: System.SysUtils, System.Classes....
« Reply #7 on: May 17, 2024, 06:22:45 pm »
KodeZwerg
I often use {$IFDEF FPC} constructions but try to do them as small as possible. It works good with non visual code, but I couldnt get it worked with Data Modules particularly with Delphi realization of TService, if you place all form definition under IFDEF Delphi cannot open it

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1430
    • Lebeau Software
Re: System.SysUtils, System.Classes....
« Reply #8 on: May 17, 2024, 08:01:47 pm »
Code: Pascal  [Select][+][-]
  1. {$IF Defined(DCC) or Defined(VER210) or Defined(VER200) or Defined(VER190) or Defined(VER185) or Defined(VER180) or Defined(VER170) or Defined(VER160) or Defined(VER150) or Defined(VER140) or Defined(VER130) or Defined(VER120) or Defined(VER100) or Defined(VER90) or Defined(VER80)}
  2.   {$DEFINE Delphi} { Delphi }
  3. {$IFEND}

You can't use {$IF} to check for Delphi versions earlier than VER140 (Delphi 6) since {$IF} doesn't exist in earlier versions.  You have to check {$IFDEF CONDITIONALEXPRESSIONS} to know if {$IF} is available to use.

Also, you are missing VER220 for Delphi XE (VER210 is Delphi 2010). The DCC conditional was introduced in VER230 (Delphi XE2).

A simpler way to detect Delphi 6-XE is to check for CompilerVersion < 23 instead of checking each VERxxx individually.

Code: Pascal  [Select][+][-]
  1. {$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 25)}
  2.   {$LEGACYIFEND ON}
  3. {$IFEND}

{$LEGACYIFEND} was introduced in CompilerVersion 24 (XE3), not 25 (XE4).

This is what I would probably use:

Code: Pascal  [Select][+][-]
  1. {$IFNDEF FPC}
  2.   {$IFDEF CONDITIONALEXPRESSIONS} // Delphi 6+
  3.     {$IF CompilerVersion >= 24} // Delphi XE3+
  4.       {$LEGACYIFEND ON}
  5.     {$IFEND}
  6.   {$ENDIF}
  7.   {$IFNDEF DCC}
  8.     {$IFDEF CONDITIONALEXPRESSIONS} // Delphi 6+
  9.       {$IF CompilerVersion < 23} // Delphi 6-XE
  10.         {$DEFINE DCC}
  11.       {$IFEND}
  12.     {$ELSE}
  13.       {$IFDEF VER130} // Delphi 5
  14.         {$DEFINE DCC}
  15.       {$ENDIF}
  16.       {$IFDEF VER120} // Delphi 4
  17.         {$DEFINE DCC}
  18.       {$ENDIF}
  19.       {$IFDEF VER100} // Delphi 3
  20.         {$DEFINE DCC}
  21.       {$ENDIF}
  22.       {$IFDEF VER90} // Delphi 2
  23.         {$DEFINE DCC}
  24.       {$ENDIF}
  25.       {$IFDEF VER80} // Delphi 1
  26.         {$DEFINE DCC}
  27.       {$ENDIF}
  28.     {$ENDIF}
  29.   {$ENDIF}
  30.   {$IFDEF DCC}
  31.     {$DEFINE Delphi}
  32.   {$ENDIF}
  33. {$ENDIF}

Code: Pascal  [Select][+][-]
  1. {$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 23)}
  2.   {$DEFINE NameSpace} { Delphis NameSpace feature (eg Winapi.Windows instead of Windows) }
  3. {$IFEND}

Technically, they are called Unit Scope Names, not Namespaces.  They have similar syntax, but they are different features with different semantics.

Code: Pascal  [Select][+][-]
  1. {$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 20)}
  2.   {$DEFINE UniCode} { Delphis UniCode support }
  3. {$IFEND}

You might want to re-think that symbol name.  The Win32 API has its own UNICODE conditional, which Delphi and FreePascal can utilize even if they don't use the UnicodeString type.

Code: Pascal  [Select][+][-]
  1. {$IF Defined(FPC) and Declared(FPC_VERSION) and (FPC_VERSION >= 3)}
  2.   {$DEFINE UniCode} { FreePascal UniCode support }
  3. {$IFEND}

Likewise.

Also, if you want to detect if UnicodeString is available in FreePascal, you can use {$IFDEF FPC_HAS_UNICODESTRING} instead of checking the FPC compiler version.  But, even if UnicodeString is available, that doesn't guarantee the String type maps to it (which it doesn't by default - you have to use {$Mode DelphiUnicode} or {$ModeSwitch UnicodeStrings} for that).

Code: Pascal  [Select][+][-]
  1. uses
  2. {$IFDEF DELPHI}
  3.   {$IFDEF NameSpace}
  4.     {$IFDEF Windows}
  5.       Winapi.Windows,
  6.     {$ENDIF Windows}
  7.     System.SysUtils, System.Classes,
  8.     Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
  9.   {$ELSE NameSpace}
  10.     {$IFDEF Windows}
  11.       Windows,
  12.     {$ENDIF Windows}
  13.     SysUtils, Classes,
  14.     Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
  15.   {$ENDIF NameSpace}
  16. {$ENDIF DELPHI}
  17. {$IFDEF FPC}
  18.   {$IFDEF Windows}
  19.     Windows,
  20.   {$ENDIF Windows}
  21.   SysUtils, Classes,
  22.   Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
  23. {$ENDIF FPC}
  24. // here you can add custom units that always named same way
  25. MyUnit
  26. ; // <- important!

Wow, that's certainly an eyesore!

You could simply add the System, Vcl, and Winapi Unit Scopes to the Delphi project's options (which they should be by default) and then you can omit the Unit Scopes from the code.  In which case, the two branches for Delphi and FPC units can be consolidated:

Code: Pascal  [Select][+][-]
  1. uses
  2.   {$IFDEF Windows}
  3.   Windows,
  4.   {$ENDIF Windows}
  5.   SysUtils, Classes,
  6.   Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
  7.   MyUnit;

But, if you don't want to do that, your example could still be simplified a little to reduce duplication:

Code: Pascal  [Select][+][-]
  1. uses
  2. {$IFDEF NameSpace}
  3.   {$IFDEF Windows}
  4.   Winapi.Windows,
  5.   {$ENDIF Windows}
  6.   System.SysUtils, System.Classes,
  7.   Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
  8. {$ELSE NameSpace}
  9.   {$IFDEF Windows}
  10.   Windows,
  11.   {$ENDIF Windows}
  12.   SysUtils, Classes,
  13.   Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
  14. {$ENDIF NameSpace}
  15.   MyUnit;
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: System.SysUtils, System.Classes....
« Reply #9 on: May 21, 2024, 04:49:24 pm »
Many kudos Remy, your input is very appreciated! Sorry for late reply, I've had "Pfingsten"-vacation  :-*
The version numbers I've took from an Embarcadero site, when something is here missing than its also there not visible :D but forgot the address :-/ thank you for your input on that!
I will rename UNICODE to something better, didn't knew it was in use, so thanks!
Blame on me, I just checked for what I could test if it is Delphi but was not checking since when {$IF} is available :-[ Thank you for that updates!
LEGACYIFEND thank you for correcting!
This very long "uses" is made that I just need to copy "*.dpr*.pas *.dfm" without taking care about how user change project options, ie: it works on all setups same way whatever user does do with options.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5759
  • Compiler Developer
Re: System.SysUtils, System.Classes....
« Reply #10 on: May 22, 2024, 09:45:24 pm »
The name spaced approach will soon work with FPC as well.

Most units have been converted to name-spaced versions, e.g. https://gitlab.com/freepascal.org/fpc/source/-/blob/main/rtl/namespaced/common/System.SysUtils.pp
I pray that the FPC team makes it better than the Delphi team was doing.

example that break old code:
Code: Pascal  [Select][+][-]
  1. uses WinApi.Windows;
  2. begin
  3.   Windows.CloseHandle(); // <- can't find closehandle since unit is included by namespace

That will break with FPC as well, because the way dotted units work is implemented in a Delphi-compatible way, because after all we only added that feature for Delphi-compatibility.

 

TinyPortal © 2005-2018