Recent

Author Topic: Convert Delphi Unit to Lazarus Unit fails with nested functions  (Read 5720 times)

rhapdog

  • New Member
  • *
  • Posts: 11
  • Woof y'all!
Today, I attempted to convert a Delphi unit that I have written and have kept up with for a number of years, as it is a list of basic functions I use regularly with almost every project.

There are a number of function calls that have function calls as parameters.  These are completely borked by the compiler.

For example:
Code: [Select]
if FileExists(ExpandFileName(Copy(S, 1, i))) then begin
becomes:
Code: [Select]
if FileExistsUTF8(ExpandFileName(Copy(S) { *Converted from FileExists*  } then begin

As you can see, it only keeps one closing parenthesis, and only the first parameter within each nested function.  Also, parameters that are function calls do not have their function converted, as ExpandFileName should have been converted to ExpandFileNameUTF8, as it was in other places.

The correct conversion should have been:
Code: [Select]
if FileExistsUTF8(ExpandFileNameUTF8(Copy(S, 1, i)) { *Converted from ExpandFileName*  } ) { *Converted from FileExists*  } then begin

There just needs to be a recursive call to convert further functions when looking at parameters of a function.

I'm not even going to attempt to convert my larger projects to Lazarus until there is a fix for this one, as it seems pretty basic.  I can't believe others haven't been complaining about it, but then, maybe I don't know where to look.  I just did a search for "Delphi Convert" on wiki and forums, but I suppose not a lot of people are attempting this, or they give up and stick with Delphi without voicing their concerns.

I've got a couple of projects I'd like to make available to Linux and Mac users, just can't do it until this particular issue is resolved, as the projects are over a million lines of code each, and that's too much manual editing to fix.  I realize no conversion of that size will be perfect, but nested function calls are too common of a programming practice not to include that in the converter.
Code: [Select]
uses 'Signature.pas';
function ASCII(Requestor: TUser): TReceive;
begin
  Writeln(Requestor, 'ASCII and ye shall receive.');
end;

Timewarp

  • Full Member
  • ***
  • Posts: 144
Re: Convert Delphi Unit to Lazarus Unit fails with nested functions
« Reply #1 on: August 07, 2013, 10:30:12 pm »
Make sure you use Lazarus svn.

Fileexists bug is fixed long time ago. http://bugs.freepascal.org/view.php?id=22537

rhapdog

  • New Member
  • *
  • Posts: 11
  • Woof y'all!
Re: Convert Delphi Unit to Lazarus Unit fails with nested functions
« Reply #2 on: August 07, 2013, 10:54:40 pm »
Thanks.  Looks like the notes address the issue correctly.  Even though this occurs with most all nested functions, looks like from what was said in the notes the fix there should fix it everywhere, so I look forward to testing that.

Can't use Lazarus SVN at the moment.  Will have to wait until I get broadband access to download a snapshot.

Currently using 1.0.8, but am working on downloading 1.0.10.  Hoping this will fix the issue.  Will check back after.
Code: [Select]
uses 'Signature.pas';
function ASCII(Requestor: TUser): TReceive;
begin
  Writeln(Requestor, 'ASCII and ye shall receive.');
end;

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4692
  • I like bugs.
Re: Convert Delphi Unit to Lazarus Unit fails with nested functions
« Reply #3 on: August 07, 2013, 11:54:21 pm »
Thanks.  Looks like the notes address the issue correctly.  Even though this occurs with most all nested functions, looks like from what was said in the notes the fix there should fix it everywhere, so I look forward to testing that.

Actually the recursive conversion for nested function calls is not implemented. The fix only counts the brackets correctly and copies the right strings into parameters.
True, the functions should be converted recursive. You can either reopen the mentioned bug report or create a new one with the example code.
If you provide a patch it will be solved quickly. I am working now with compiler options GUI + other things and cannot concentrate on this one soon. See r38273, converter/convcodetool, TConvDelphiCodeTool.ReplaceFuncCalls, starting now at line 552. The recursion may be easy to add.

Quote
Can't use Lazarus SVN at the moment.  Will have to wait until I get broadband access to download a snapshot.

Uhhh!
Don't use snapshots especially if you have limited bandwidth. Use SVN directly. Then updating the latest changes creates very little traffic because only the diffs are downloaded.
Or better yet, use the Git mirror. Then you can look at the whole commit history off-line.

You must definitely use trunk if you are doing such on-the-edge conversion. The converter in trunk has many improvements. Conversion does not stop for an exception any more (?). Codetools threw exceptions sometimes but now there are defines simulating Delphi and other fall-backs to take care of it.
If somebody still sees an interrupted conversion, please report it. I want to get them weeded out before Lazarus 1.2.
The conversions are still primitive but they are done better.

The next step will be more advanced conversions like replacing classes and their methods.
I have realized Codetools is just fine for a parser, despite my comments in the report. It allows modifying code in place, not loosing comments or indentation, and it provides scanner primitives for the code. A parse tree is only stored for definitions but it is ok.
« Last Edit: August 08, 2013, 10:47:07 pm by JuhaManninen »
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

rhapdog

  • New Member
  • *
  • Posts: 11
  • Woof y'all!
Re: Convert Delphi Unit to Lazarus Unit fails with nested functions
« Reply #4 on: August 08, 2013, 10:49:10 pm »
Actually the recursive conversion for nested function calls does not work. The fix only counts the brackets correctly and copies the right strings into parameters.
True, the functions should be converted recursive. You can either reopen the mentioned bug report or create a new one with the example code.
If you provide a patch it will be solved quickly. I am working now with compiler options GUI + other things and cannot concentrate on this one soon. See r38273, converter/convcodetool, TConvDelphiCodeTool.ReplaceFuncCalls, starting now at line 552. The recursion may be easy to add.
Thanks for that.  I'll try to get around to that soon, but will be too busy for the next 4 or 5 days at least.


Uhhh!
Don't use snapshots especially if you have limited bandwidth. Use SVN directly. Then updating the latest changes creates very little traffic because only the diffs are downloaded.
Well, to download the SVN directly the first time, I'll need broadband access.  Since I don't have a laptop, only a high-end desktop tower that holds 10 HDs, 4 PCIe Graphics cards, and 8 large fans and cooling system, and a large widescreen monitor, it's going to be fun toting it somewhere to get what I need started.  That's what I have to do.  Take my rig on a drive for an hour and a half, after taking a half hour to pack it up, do what I need on broad band, then return and set back up.  Not a fun thing to do, but I usually do it once every 6 weeks when we visit family.  Should be in the next couple of weeks. 

I just spent 18 hours or so downloading and updating to 1.0.10, so things are a little better already.



I do have an idea for the converter, however.  For functions where the only change is the function name (like in my example), there should be first a global search and replace for function names before actual parsing is done.  This will lighten the load on the parsing/converting somewhat as not as much will need to be fixed.  It also will catch the functions as parameters inside other function calls that way (those that don't require parameter changes). 

Just an idea.
Code: [Select]
uses 'Signature.pas';
function ASCII(Requestor: TUser): TReceive;
begin
  Writeln(Requestor, 'ASCII and ye shall receive.');
end;

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4692
  • I like bugs.
Re: Convert Delphi Unit to Lazarus Unit fails with nested functions
« Reply #5 on: August 09, 2013, 12:01:44 am »
Well, to download the SVN directly the first time, I'll need broadband access.

Yes but that is only once. Afterwards it is the most efficient way to update. You don't need release versions at all. You can get trunk and then release fixes branch if you need it.

Quote
I do have an idea for the converter, however.  For functions where the only change is the function name (like in my example), there should be first a global search and replace for function names before actual parsing is done.  This will lighten the load on the parsing/converting somewhat as not as much will need to be fixed.  It also will catch the functions as parameters inside other function calls that way (those that don't require parameter changes). 

Sounds like a useless hack. Parsing and converting are not loaded too much. :)
The context checking in the parser is already primitive. Your search and replace system would loose it completely for some functions but not for others.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

rhapdog

  • New Member
  • *
  • Posts: 11
  • Woof y'all!
Re: Convert Delphi Unit to Lazarus Unit fails with nested functions
« Reply #6 on: August 09, 2013, 02:19:54 am »
Quote
Your search and replace system would loose it completely for some functions but not for others.
No, it would only do it for those functions that only have a name change, so nothing would be broken.

I am already using a script in UEStudio (why I use UEStudio instead of Lazarus IDE is a topic for a separate discussion.)  The script I am using does just what I said, and I find that after running the script in most of my projects, little else is needed of conversion.

Quote
Use SVN directly.
Okay, I've been searching the site, and I've also been searching the FPC site as well for that code.  I can find snapshots available, and I can find full source code download to the latest stable version, but I have yet to locate (even with a forum search) the SVN, where it is located, etc.  I'm not going to spend 3 days looking for it, as it looks like I will be packing up the PC early tomorrow and heading out of town with it for that access.  I'll need to know how to find it when I get there, or wait another 6 weeks.

Nevermind... found it.
« Last Edit: August 09, 2013, 02:21:54 am by rhapdog »
Code: [Select]
uses 'Signature.pas';
function ASCII(Requestor: TUser): TReceive;
begin
  Writeln(Requestor, 'ASCII and ye shall receive.');
end;

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4692
  • I like bugs.
Re: Convert Delphi Unit to Lazarus Unit fails with nested functions
« Reply #7 on: August 09, 2013, 01:46:46 pm »
I should have given links for the SVN checkout :
  http://wiki.lazarus.freepascal.org/Getting_Lazarus#Getting_Lazarus_SVN_development_version

Basically just :
 $  svn co http://svn.freepascal.org/svn/lazarus/trunk lazarus

or the similar thing with TortoiseSVN.
Note: You do not need FPC trunk to use Lazarus trunk. FPC 2.6.2 is just fine.

P.S.
If I understood your explanation right, your "portable computer" and the "internet hotspot" would need some fine-tuning. :)
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

 

TinyPortal © 2005-2018