Recent

Author Topic: [SOLVED] macOS: TMemo.Lines vs TMemo.Text and PosEx()  (Read 5843 times)

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2032
  • Former Delphi 1-7, 10.2 user
[SOLVED] macOS: TMemo.Lines vs TMemo.Text and PosEx()
« on: July 10, 2019, 02:36:44 pm »
In the never-ending saga that is my application, I have discovered that my text search fails (ie using PosEx fails to correctly locate the search characters in the TMemo) if I assign lines read from a file to a TMemo using TMemo.Lines := strList rather than TMemo.Text := strList.Text.

It appears to me to be related to the number of lines and therefore likely the LineEndings are causing the issue.

macOS 10.14.5, Lazarus v2.10 (trunk), FPC 3.0.4 or FPC 3.3.1 (trunk).

Curiously it works fine under:

o  Ubuntu 18.04 64 bit with Lazarus v1.8.2; FPC v3.0.4;
o  FreeBSD 12.0 64 bit with Lazarus v2.00;  FPC v3.0.4; and
o  Windows 10 64 bit cross-compiled under macOS for 32 bit

using either method.

Easy enough to work around now that I figured out what is going on, but... I doubt it should be happening.
« Last Edit: July 12, 2019, 02:48:25 am by trev »

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #1 on: July 10, 2019, 03:15:27 pm »
In the never-ending saga that is my application, I have discovered that my text search fails (ie using PosEx fails to correctly locate the search characters in the TMemo) if I assign lines read from a file to a TMemo using TMemo.Lines := strList rather than TMemo.Text := strList.Text.

It appears to me to be related to the number of lines and therefore likely the LineEndings are causing the issue.
where do you search at Memo.Text or Memo.Lines.Text? (something else?)

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11944
  • FPC developer.
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #2 on: July 10, 2019, 04:24:54 pm »
Did you use posex(substr,wholestr,value) and not  (wholestr,substr). Show more code.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #3 on: July 10, 2019, 05:40:40 pm »
Note also that for memos it's best to use UTF8Pos() and UTF8RPos(). Pos(), PosEx(), RPos(), etc. tend to fail for anything other than single-byte character strings.

Another thing to take into account: The string functions return a 1-based position but SelStart, etc. are 0-based.

And that's not counting the problems with UTF8-BOM, ZWJs, etc. :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2032
  • Former Delphi 1-7, 10.2 user
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #4 on: July 11, 2019, 08:33:24 am »
In the never-ending saga that is my application, I have discovered that my text search fails (ie using PosEx fails to correctly locate the search characters in the TMemo) if I assign lines read from a file to a TMemo using TMemo.Lines := strList rather than TMemo.Text := strList.Text.

It appears to me to be related to the number of lines and therefore likely the LineEndings are causing the issue.
where do you search at Memo.Text or Memo.Lines.Text? (something else?)

Code: Pascal  [Select][+][-]
  1.   // we have a match...
  2.   else
  3.     begin
  4.       // select characters to highlight
  5.       Memo.SelStart := PosEx(UpperCase(Edit.Text), UpperCase(Memo.Text), searchOFS) - 1;
  6.       Memo.SelLength := Length(Edit.Text);
  7.       searchOFS := Memo.SelStart + 1;
  8.     end;    
  9.  

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2032
  • Former Delphi 1-7, 10.2 user
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #5 on: July 11, 2019, 08:34:03 am »
Did you use posex(substr,wholestr,value) and not  (wholestr,substr). Show more code.

Yes, see above.

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2032
  • Former Delphi 1-7, 10.2 user
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #6 on: July 11, 2019, 08:38:52 am »
Note also that for memos it's best to use UTF8Pos() and UTF8RPos(). Pos(), PosEx(), RPos(), etc. tend to fail for anything other than single-byte character strings.

The files contain PIC microcontroller config word settings, registers, interrupts etc and are definitely always going to be single byte characters... yeah, I know, famous last words ;)

Quote
Another thing to take into account: The string functions return a 1-based position but SelStart, etc. are 0-based.

Aware and accounted for.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #7 on: July 11, 2019, 02:25:18 pm »
Try using:
Code: Pascal  [Select][+][-]
  1. Memo.Lines.AddStrings(StringList, True);
or even
Code: Pascal  [Select][+][-]
  1. Memo.Lines.Assign(StringList);

Any of those should work right everywhere.

Also, I'm assuming (because your "we have a match") that you test that PosEx > 0 somewhere? If not your search should be more lke:
Code: Pascal  [Select][+][-]
  1.   // we have a match...
  2.   else
  3.     begin
  4.       searchOFS := PosEx(UpperCase(Edit.Text), UpperCase(Memo.Text), searchOFS);
  5.       if searchOFS > 0 then begin
  6.         Memo.SelStart := searchOFS - 1;
  7.         Memo.SelLength := Length(Edit.Text);
  8.       end else
  9.         ShowMessage('Not found');
  10.     end;
« Last Edit: July 11, 2019, 02:33:58 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #8 on: July 11, 2019, 03:26:16 pm »
Code: Pascal  [Select][+][-]
  1.       Memo.SelStart := PosEx(UpperCase(Edit.Text), UpperCase(Memo.Text), searchOFS) - 1;
try r61567 please

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2032
  • Former Delphi 1-7, 10.2 user
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #9 on: July 12, 2019, 03:11:12 am »
Try using:
Code: Pascal  [Select][+][-]
  1. Memo.Lines.AddStrings(StringList, True);

The assignment with the above takes approx 10s vs 1ms for:
Code: Pascal  [Select][+][-]
  1. Memo.Text := strList.Text;

Quote
or even
Code: Pascal  [Select][+][-]
  1. Memo.Lines.Assign(StringList);

Any of those should work right everywhere.

Only at the cost of a huge performance hit (28s): see https://forum.lazarus.freepascal.org/index.php/topic,45733.0.html

Quote
Also, I'm assuming (because your "we have a match") that you test that PosEx > 0 somewhere? If not your search should be more like:

You assumed right.

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2032
  • Former Delphi 1-7, 10.2 user
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #10 on: July 12, 2019, 03:12:36 am »
try r61567 please

Thanks Dmitry - yes, that fixed the text location issue.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
« Reply #11 on: July 12, 2019, 04:37:18 am »
Thanks Dmitry - yes, that fixed the text location issue.
Keep that in mind: https://wiki.lazarus.freepascal.org/Cocoa_Internals/Text_Controls#Forcing_Lines_Breaks
(in case you need to load/save files across systems)

 

TinyPortal © 2005-2018