Lazarus

Free Pascal => Other OS => Topic started by: trev on July 10, 2019, 02:36:44 pm

Title: [SOLVED] macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: trev 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.
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: skalogryz 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?)
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: marcov on July 10, 2019, 04:24:54 pm
Did you use posex(substr,wholestr,value) and not  (wholestr,substr). Show more code.
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: lucamar 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. :)
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: trev 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.  
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: trev 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.
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: trev 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.
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: lucamar 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;
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: skalogryz 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
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: trev 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.
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: trev on July 12, 2019, 03:12:36 am
try r61567 please

Thanks Dmitry - yes, that fixed the text location issue.
Title: Re: macOS: TMemo.Lines vs TMemo.Text and PosEx()
Post by: skalogryz 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