Re: [fpc-devel] OSX: Setting up parameters to objc_msgSend()

2018-10-12 Thread David Jenkins



On 10/12/18 8:17 AM, Dmitry Boyarintsev wrote:


So, I'm wondering if it's actually a compiler issue or headers issue.
and can ByteBool be used as a substitute for signed char.

thanks,
Dmitry


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Changing the header for NSMenuItem.setEnable(BOOL) to 
NSMenuItem(ByteBool) results in the following code in 
TCocoaWSmenuITem.setEnable:


    0x1001ba67e <+70>:  movq   %rax, %rbx
    0x1001ba681 <+73>:  movq   0x329ef8(%rip), %rsi  ; "setEnabled:"
    0x1001ba688 <+80>:  movb   -0x10(%rbp), %al
    0x1001ba68b <+83>:  orb    %al, %al
    0x1001ba68d <+85>:  setne  %dl
    0x1001ba690 <+88>:  negb   %dl
    0x1001ba692 <+90>:  movsbl %dl, %edx
    0x1001ba695 <+93>:  movq   %rbx, %rdi
    0x1001ba698 <+96>:  callq  0x1002d23da   ; symbol stub 
for: objc


The movsbl %dl, %edx is good.  Unfortunately the value of %edx is 
0x not 0x0001.  This is the same result I saw when I changed 
it to LongBool.


David


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] OSX: Setting up parameters to objc_msgSend()

2018-10-11 Thread David Jenkins

Thanks.  I'll get a bug report in tomorrow morning.

On 10/11/18 3:16 PM, Jonas Maebe wrote:

On 11/10/18 21:41, David Jenkins wrote:

Here is the assembly code generated by fpc (3.1.1) for just the 
section where .setEnabled(Enabled) is called


->  0x1001ba68d <+61>:  movq   -0x8(%rbp), %rdi
 0x1001ba691 <+65>:  callq  0x1002016d0 ; GETHANDLE at 
menuitem.inc:515

 0x1001ba696 <+70>:  movq   %rax, %rbx
 0x1001ba699 <+73>:  movq   0x329ee0(%rip), %rsi ; "setEnabled:"
 0x1001ba6a0 <+80>:  movb   -0x10(%rbp), %dl
 0x1001ba6a3 <+83>:  movq   %rbx, %rdi
 0x1001ba6a6 <+86>:  callq  0x1002d23da ; symbol stub for: 
objc_msgSend


Notice the the value of Enabled (a BOOL) is treated as 8bit (which 
BOOL is) and placed into the lowest 8 bits of edx with the line 'movb 
-0x10(%rbp), %dl'.  Which means that the upper 24 bits of edx are not 
changed (not cleared, not signed extended, nothing, just left alone).


That's because the x86-64 ABI says 
(https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf 
):


***
When a value of type _Bool is returned or passed in a register or on 
the stack, bit 0 contains the truth value and bits 1 to 7 shall be 
zero. (14)


...

(14) Other bits are left unspecified, hence the consumer side of those 
values can rely on it being 0 or 1 when truncated to 8 bit

***

However, the Objective-C BOOL type does not map to _Bool on x86-64, 
but to signed char. And values of that type indeed do need to (sign) 
extended. So this needs to be fixed in the compiler. Please file a bug 
report, and thanks for the analysis.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] OSX: Setting up parameters to objc_msgSend()

2018-10-11 Thread David Jenkins
This is specifically about objectivce C bridge.  Hopefully this is the 
right forum.


I am seeing a problem with how BOOL values are passed to objc_msgSend.  
The example is a call to NSMenuItem.setEnable(BOOL) from the 
lcl/interfaces/cocoa/cocoawsmenus.pas file.  Here is the code:


class function TCocoaWSMenuItem.SetEnable(const AMenuItem: TMenuItem;
  const Enabled: boolean): boolean;
begin
  Result:=Assigned(AMenuItem) and (AMenuItem.Handle<>0);
  if not Result then Exit;
  NSMenuItem(AMenuItem.Handle).setEnabled( Enabled );
end;

Here is the assembly code generated by fpc (3.1.1) for just the section 
where .setEnabled(Enabled) is called


->  0x1001ba68d <+61>:  movq   -0x8(%rbp), %rdi
    0x1001ba691 <+65>:  callq  0x1002016d0   ; GETHANDLE at 
menuitem.inc:515

    0x1001ba696 <+70>:  movq   %rax, %rbx
    0x1001ba699 <+73>:  movq   0x329ee0(%rip), %rsi  ; "setEnabled:"
    0x1001ba6a0 <+80>:  movb   -0x10(%rbp), %dl
    0x1001ba6a3 <+83>:  movq   %rbx, %rdi
    0x1001ba6a6 <+86>:  callq  0x1002d23da   ; symbol stub 
for: objc_msgSend


Notice the the value of Enabled (a BOOL) is treated as 8bit (which BOOL 
is) and placed into the lowest 8 bits of edx with the line 'movb   
-0x10(%rbp), %dl'.  Which means that the upper 24 bits of edx are not 
changed (not cleared, not signed extended, nothing, just left alone).


Here is the assembly code generated by XCode for a similar call to 
NSMenuItem.setEnable() from objective c code:

0x11258 <+440>: movq   -0x40(%rbp), %rax
    0x1125c <+444>: movb   -0x19(%rbp), %cl
    0x1125f <+447>: movq   0x185a(%rip), %rsi    ; "setEnabled:"
    0x11266 <+454>: movq   %rax, %rdi
    0x11269 <+457>: movsbl %cl, %edx
    0x1126c <+460>: callq  *0xd9e(%rip)  ; (void 
*)0x7fff55e30e80: objc_msgSend


Register 'edx' is the register of concern again.  In this case the 8 bit 
BOOL value stored in %cl is placed into %edx with the line 'movsbl %cl, 
%edx'.  In other words the 8 bit BOOL value is sign extended through all 
the bits of %edx.


This is different than what fpc does and I think causing a problem. The 
top level symptom of the problem that lead me to look at this is that 
currently I cannot manually enable/disable NSMenuItem's because calling 
.setEnable doesn't work.


Looking at the disassembly for .setEnable I see that the 'disable' flag 
for the object is stored in a 32bit record bitfield (bit 8) in 
NSMenuItem._miFlags;  The code loads %ecx with the _miFlags, shifts left 
8 to get the 'disable' bit in to 0 position, and then ands with 
0x0001 to mask off all other bits.  It then does a cmpl of %edx and 
%ecx to determine if the NSMenuITem is already in the desired state or 
not.  If it is in the desired state then the code exists without 
changing the state.


here is the assembly for the first part of NSMenuItem.setEnabled:

AppKit`-[NSMenuItem setEnabled:]:
->  0x7fff2bff1a5f <+0>:   pushq  %rbp
    0x7fff2bff1a60 <+1>:   movq   %rsp, %rbp
    0x7fff2bff1a63 <+4>:   pushq  %r15
    0x7fff2bff1a65 <+6>:   pushq  %r14
    0x7fff2bff1a67 <+8>:   pushq  %rbx
    0x7fff2bff1a68 <+9>:   pushq  %rax
    0x7fff2bff1a69 <+10>:  movq   %rdi, %rbx
 0x7fff2bff1a6c <+13>:  movq   0x5c365045(%rip), %rax    ; 
NSMenuItem._miFlags

    0x7fff2bff1a73 <+20>:  movl   (%rbx,%rax), %esi
    0x7fff2bff1a76 <+23>:  movl   %esi, %ecx
    0x7fff2bff1a78 <+25>:  shrl   $0x8, %ecx
    0x7fff2bff1a7b <+28>:  andl   $0x1, %ecx
    0x7fff2bff1a7e <+31>:  cmpl   %edx, %ecx
    0x7fff2bff1a80 <+33>:  jne    0x7fff2bff1ae8    ; <+137>


The FPC code works when %edx upper bits are, by luck, empty but not when 
they have non-zero bits.  On my machine coming into the above LCL code 
%edx always has upper bits set and I cannot get .setEnable to work.


It appears to me that objc_msgSend is expecting that parameters passed 
in are signed extended and that any code called by objc_msgSend will 
treat the registers as such.  I spent some time trying to find 
documentation for objc runtime / objc_msgSend that shows this but didn't 
find anything that went into that level of detail.


If objc_msgSend does expect this then I think the FPC objective c 
bridging is not correct.  Can any of you all verify this?


David Jenkins
Scooter Software





___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] FPC fails on overload

2018-06-18 Thread David Jenkins

Done.  Mantis 33875.


On 6/18/18 3:01 PM, Florian Klämpfl wrote:

Am 18.06.2018 um 22:00 schrieb David Jenkins:
This is something that has just recently stopped working for us(with 
update

to current trunk).  We previously were using trunk rev 36812 with no
problems.


Please submit a bug report to mantis.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] FPC fails on overload

2018-06-18 Thread David Jenkins

This is something that has just recently stopped working for us(with update
to current trunk).  We previously were using trunk rev 36812 with no
problems.


Placing a second call

foo('a')

calls the expected WideChar version.

David


On 6/18/18 1:11 PM, Marcos Douglas B. Santos wrote:

On Mon, Jun 18, 2018 at 3:04 PM, David Jenkins
 wrote:

The following code:


{$MODE DELPHI}

program CharOverload;

uses
   SysUtils;

procedure Foo(const aArg: UnicodeString); overload;
begin
   WriteLn('WideString: ', aArg);
end;

procedure Foo(c: WideChar); overload;
begin
   WriteLn('Char: ', c);
end;

begin
   Foo('abc');
end.


Fails with current trunk fpc with the following messages


[odysseus:fpc-trunk$] compiler/ppc386 ~/Desktop/test/CharOverload.pp
Free Pascal Compiler version 3.1.1 [2018/06/18] for i386
Copyright (c) 1993-2018 by Florian Klaempfl and others
Target OS: Darwin for i386
Compiling /Users/djenkins/Desktop/test/CharOverload.pp
CharOverload.pp(19,3) Error: Can't determine which overloaded function to
call
CharOverload.pp(19,12) Error: Illegal type conversion: "Constant String" to
"WideChar"
CharOverload.pp(20,4) Fatal: There were 2 errors compiling module, stopping
Fatal: Compilation aborted


It fails with same messages with {$MODE OBJFPC}.  Is this known. I can enter
a Mantis if desired.

Hey David,
The compiler says "Can't determine which overloaded function to call"
because both are strings.

Marcos Douglas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] FPC fails on overload

2018-06-18 Thread David Jenkins

The following code:


{$MODE DELPHI}

program CharOverload;

uses
  SysUtils;

procedure Foo(const aArg: UnicodeString); overload;
begin
  WriteLn('WideString: ', aArg);
end;

procedure Foo(c: WideChar); overload;
begin
  WriteLn('Char: ', c);
end;

begin
  Foo('abc');
end.


Fails with current trunk fpc with the following messages


[odysseus:fpc-trunk$] compiler/ppc386 ~/Desktop/test/CharOverload.pp
Free Pascal Compiler version 3.1.1 [2018/06/18] for i386
Copyright (c) 1993-2018 by Florian Klaempfl and others
Target OS: Darwin for i386
Compiling /Users/djenkins/Desktop/test/CharOverload.pp
CharOverload.pp(19,3) Error: Can't determine which overloaded function 
to call
CharOverload.pp(19,12) Error: Illegal type conversion: "Constant String" 
to "WideChar"

CharOverload.pp(20,4) Fatal: There were 2 errors compiling module, stopping
Fatal: Compilation aborted


It fails with same messages with {$MODE OBJFPC}.  Is this known. I can 
enter a Mantis if desired.



Thanks

David Jenkins



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Overload failure

2018-06-18 Thread David Jenkins
Sorry.  Forgot to add that I tried on MacOS and Linux, 32bit & 64bit.  
Same message on all.


David



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] mode Delphi, property overload, and svn 19564

2016-05-02 Thread David Jenkins



On 4/26/16 1:02 AM, Sven Barth wrote:
Overloaded properties are a more specialized variant of duplicate 
symbols, so of course they aren't mentioned especially in a fix.


If the code you posted doesn't work in Delphi then we definitely won't 
add code in our Delphi mode to make it working there again, because in 
that case it had been a bug in FPC that had been fixed.
If this code works in Delphi however then it's a bug in FPC and you 
should report it on Mantis.


Regards,
Sven



I entered a Mantis (#30088) for this including example code that does 
compile on Delphi - as Maciej pointed out Delphi only accepts this for 
default properties.


David Jenkins


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] mode Delphi, property overload, and svn 19564

2016-04-25 Thread David Jenkins

I was trying to compile code with overloaded properties:

MyClass = class
  function GetX(idx: integer): integer;
  function GetX(idxStr: string): integer;
public
  property X[ id : integer] : integer read GetX;
  property X[ id : string] : integer read GetX;
end;

I got the 'duplicate X' error.  I googled and found that previously this 
should compile with {$mode delphi} (a google hit from before 2011).  
However setting mode delphi resulted in the same error.


Digging around in the compiler code and the repository I found SVN rev 
19564 which was responding to Mantis 20580.  I verified that the lines 
removed from symtable.pas:tObjectSymtable.checkduplicate lines 1298 - 
1301 seem to have been the same code that allowed overloaded properties 
in Delphi mode (I stuck them back in and I was able to compile my 
overloaded properties code).


So the question is:

Mantis 20580 & SVN 19564 are about duplicate symbols but not overloaded 
properties in particular.  However overloaded properties in mode Delphi 
appear to have gone away with that change.  Was this intentional?  (I 
tried to find discussion on this and couldn't).


I guess the other question would be if I am right that overloaded 
properties in mode delphi don't work since that change.


This is not critical to my work just something I ran across and wanted 
to get some clarification.  I saw several discussions that indicated 
that overloaded properties are not available for objfpc (and not 
intended to be available).  But I couldn't find anything recent about 
whether it was still intended to be available for mode delphi.


Thanks
David Jenkins



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-29 Thread David Jenkins



On 3/26/16 4:19 AM, Michael Van Canneyt wrote:


I have implemented a new property

 TStringsSortStyle = (sslNone,sslUser,sslAuto);

 Property SortStyle : TStringsSortStyle Read FSortStyle Write 
SetSortStyle;


I assume the meaning is clear.

- Sorted is true if SortStyle is in [sslUser,sslAuto], so it reflects 
actual state.


- Setting sorted to True is equivalent to setting SortStyle = sslAuto

- Setting sorted to false is equivalent to setting SortStyle = sslNone

- Find will work on one of those values, but it will raise an 
exception if sortstyle = sslnone


- Add will put a new string on the 'correct' place if SortStyle=sslAuto

- Insert will raise an error (as it was) if SortStyle=sslAuto.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Michael,

I have checked out this code and imported it into our code base.  It 
works great.  Thank you very much.  In addition the work of searching 
through our code and making sure we are setting SortStyle correctly has 
uncovered a bug in our usage.  So additional thanks :D


David Jenkins


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-22 Thread David Jenkins



On 3/22/16 10:48 AM, Michael Van Canneyt wrote:



On Tue, 22 Mar 2016, David Jenkins wrote:

No one here holds Delphi up on a pedestal - least of all me.  My 
viewpoint is completely practical/funcitonal - I have to make our 
code base work with FPC/LCL and VCL.  Given the way we use find 
functionality (with a mixture of naturally sorted and automatically 
sorted lists) it has ceased to work with both (it did previously). I 
want to fix that as elegantly and as effectively as possible. Making 
suggestions for FPC improvement is a side effect - and as we both 
agree TStringList.Find can use some improvement.


"by intention not by accident." Clearly this is not the case, given 
the warning in Delphi's help.
I do not see it as a warning.  It is a statement of requirement on the 
input.  By passing in a naturally sorted list I am complying with that 
requirement (the requirement is only that it be sorted not how it is 
sorted).  So the code works not by accident but because I have complied 
with the requirement and the code functions properly.   Adding a check 
to make sure I comply with the requirement makes the code more robust 
and is a great thing to do.  Checking for 'Sorted' actually doesn't 
always do this.


The problem is that the Sorted flag is both a request and a loose 
statement of state.  My list can be sorted without me requesting 
(through the flag) that the code sort and maintain the list.  But 
throughout the code (Delphi and FPC) 'Sorted' is treated as an accurate 
mirror of list state whether the list is automatically sorted, naturally 
sorted, or not sorted at all (it can't tell the difference between the 
latter two).  In the case of naturally sorted this state can be 
inaccurate (Sorted not set) and so some code won't run or accurate 
(Sorted set) but requesting unneeded actions.


To me, after spending this amount of time thinking about it, this calls 
out for improvement as much as the concern about an accidental call to 
Find with an unsorted list.  Though I understand that getting an 
erroneous result, unknowingly, is far more critical than inefficient 
code.   However, for us we are parsing a whole lot of text strings - 
running through unneeded calls to sort (no matter how fast it might be 
on an already sorted list) adds up.  And not running at all is a failure 
of function.

In each case, there is no argument that the code can be improved.

We'll sort something out in the end.

Is your preference for an extra argument to Find() or an additional 
property ?


Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


I do not have a preference.

I like the auto param because 1) it is simple 2) doesn't change the 
interface for code that doesn't care and 3) solves the base problem.  
However, it doesn't decouple "Sorted" request from sorted state.


An additional property could solve the base problem and clarify what the 
list state actually is.  Though additional code would need to change to 
take advantage of the clarity.


Maybe something (not extensibly thought on) like

Sorted: boolean read GetSorted write SetSorted
NaturalSorted: boolean read FNaturalSorted write FNaturalSorted

SetSorted(AValue: Boolean)
begin
FAutoSorted := AValue;  // This is the request to auto sort or not
end

GetSorted: Boolean
begin
Result := FAutoSorted or FNaturalSorted  // This gets the state right 
for both Auto and Natural (as long is Natural truly is :D)

end

or have a ListType property that is ltAutoSort, ltNaturalSort, ltNone

and GetSorted = ListType in [ltAutoSort, ltNaturalSort]


The additional properties (not necessarily implemented as above) is 
attractive as it seems like a more complete solution.  There is still 
the chance of an unsorted list getting by.


Adding Denis' solution in .Find along with the new properties would 
narrow the window of unsorted lists coming through while still allowing 
bypass of sorting code for explicitly set Naturally sorted lists (lists 
with NaturallySorted=True but not actually sorted could still sneak 
through).


All the above are fine with me.

David



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-22 Thread David Jenkins



On 3/22/16 9:53 AM, Denis Kozlov wrote:




Please consider the following implementation logic, I think it covers 
all angles:


procedure Find(const S: string; out Index: Integer):Boolean;
begin
  if Sorted then
Result := FindSorted(S, Index);
  else
  begin
Index := IndexOf(S);
Result := (Index >= 0);
  end;
end;

procedure FindSorted(const S: string; out Index: Integer; CheckSorted: 
Boolean = True):Boolean;

begin
  if CheckSorted and not Sorted then
raise Exception.Create('List must be sorted');
  // search logic here...
end;


Denis


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Denis,

I like how this solves the issue of calling find on truly unsorted 
lists.  My only quibble with this is that 'Sorted' still does not 
reflect the actual state of the list.  For a naturally sorted list there 
is still unnecessary calls to sort both in your suggested code above and 
in the existing code (if sorted is set).  Can that be handled as well?  
'Sorted' right now is a request and an expression of state.  As an 
expression of state it is only valid if the request has been first made.


David

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-22 Thread David Jenkins



On 3/22/16 9:43 AM, Michael Van Canneyt wrote:




Here we disagree.
It IS buggy behavior. Delphi is not sacrosanct, it does contain bugs like
any software. This is one of them.




No one here holds Delphi up on a pedestal - least of all me.  My 
viewpoint is completely practical/funcitonal - I have to make our code 
base work with FPC/LCL and VCL.  Given the way we use find functionality 
(with a mixture of naturally sorted and automatically sorted lists) it 
has ceased to work with both (it did previously). I want to fix that as 
elegantly and as effectively as possible. Making suggestions for FPC 
improvement is a side effect - and as we both agree TStringList.Find can 
use some improvement.


And I am fine disagreeing.  My definition of 'bug' is again completely 
functional.  If I knowingly stick in a naturally sorted list into 
Find(), the code operates as expected without error, and I get the 
desired result.  Both user and producer operated as expected - by 
intention not by accident.  I do not see a bug there.


If I stick in a non-sorted list (knowingly or unknowingly) then results 
are undefined.  Is that user error or buggy code?  It certainly isn't 
robust code and can be improved.  Label it as you like I am only 
interested it seeing it improved.


As we have all pointed out there is some inherent issues with a function 
traditionally named 'find' that essentially hides input requirements 
(again label that as you like).  Michalis has pointed out that 
TFSMap.Find has a similar issue.


The other weakness I see in the current traditional implementation 
(Delphi and FPC) is that the 'Sorted' flag is somewhat loosely coupled 
to the actual state of the list i.e. it can be in a sorted state and the 
flag does not reflect that at all.  To me it seems that the flag really 
means 'auto sort this please'.  Once it is enabled the code will sort 
and maintain sort.   But the code is also intended to support naturally 
sorted lists and not induce the overhead of auto sort.  In that 
situation the sorted property has nothing to do with the actual state of 
the list.  IMO better designed code would account for this.


Perhaps it should have been called TStringSortedList and enforced auto 
sort all the way through instead of purposely handling both sorted and 
unsorted lists.


As to our decision to use TStringList directly.  Whether we use it 
directly or create our own doesn't fix the code that we all agree is 
insufficiently robust, 'buggy', 'prone to allow bad use', or whatever 
label you want to use.  So I find your concern touching but not 
applicable to the point at hand.


Furthermore TStringList has provided exactly what we needed (and we have 
been careful to only pass sorted - natural or automatic - to it).  Why 
would we purposely rebuild the wheel.  Libraries exist for just this.


And that's all I have to say about that (as Forrest Gump said). Thanks 
for the discussion.


David




___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-22 Thread David Jenkins



On 3/22/16 4:15 AM, Michalis Kamburelis wrote:

2016-03-22 8:18 GMT+01:00 Ondrej Pokorny :
This would be my preference too --- just raise the exception. Or just
fallback on linear search using IndexOf, if the list is not known to
be sorted.

In my experience, it's a common bug right now to call Find on an
unsorted list. I stumbled on this bug, and I saw other people
stumbling on it too. Even though it's clearly documented that "Find
only works on sorted lists", it's still a problem --- you just don't
check documentation for something as obvious as "Find". Just like you
don't check documentation of "IndexOf", "Add" and other
seemingly-obvious methods. A nice API would call the method
"FindInSorted" if the method was assuming the list to be sorted,
right?

The case when the list is already known to be naturally sorted should
be marked by the caller, e.g. by an optional parameter to Find (like
AssumeAlwaysSorted=true), or by using special method to assume a
sorted list. Also, setting "Sorted := true" on an already-sorted list
should be rather fast (quicksort on an already-sorted list should go
fast, in linear time; sure, it's not zero time, but still it's often
fast enough).

But the default should really be safer (IMHO), which is either
1. "raise exception" (predictable, and easy to catch the bug ---
developer will either make it sorted, or use IndexOf instead), or
2. fallback to linear search (so it always works correctly, but with a
speed penalty if you forgot to sort).

Delphi behavior in this case (blindly trust the list is already
sorted) is just a bug IMHO, and this case warrants breaking Delphi
compatibility.

Also: for consistency, it would be great to apply any fixes developed
here also to FGL unit containers, as the TFPSMap.Find shares the same
problem: it's name is simply "Find", and it assumes the contents to be
Sorted.

Regards,
Michalis
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
I'd also be fine with this suggestion of the optional 
AssumeAlwaysSorted=true parameter as a way of maintaining the particular 
functionality we are interested in (instead of the ManualSorted property).


David


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-22 Thread David Jenkins



On 3/22/16 2:01 AM, Michael Van Canneyt wrote:

But you agree that if Find is called on an unsorted list, bogus data will
be returned ? Or, worse, an never-ending loop may occur ?
In short, as you say, an "error condition" can ensue without you 
knowing it.


That is a bug. So, in my opinion (and of some others), Find is 
implemented buggy in Delphi.


Consider the buggyness a given in what follows.

If we consider something a bug in Delphi, we do not copy the bug.

You happen to rely on this buggy behaviour. This is of course 
unfortunate.


I attempted to fix this bug using a not too invasive method.
Originally I simply wanted to raise an exception, but that was deemed too
invasive.

There are now several options:
1. I change the code to raise an exception instead (as was my original 
plan)

2. I change the code to resort to a linear search if sorted is false.
3. I introduce a boolean property that determines whether Find does 
any check.

   By default the check will be done, to warn people they're doing
   something stupid. If they override the check, we can assume they 
know what

   they are doing.
4. Combine 1 and 3.

Or,

5. You override sort so it does nothing. It is virtual.
   You can then set sorted to True, no sort will occur, and find will 
do it's job.


6. You use another TStringList where you change find to suit your needs.
   All it takes for you is to copy the implementation, you can keep 
the same
   name, and insert the unit after the classes unit in places where 
you need it.


It's your call which of the 5 methods is used.

But one thing is sure: we're not reverting the behaviour back to the 
buggy behaviour.


Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
#1 is what Zoe Peterson (my coworker) has suggested as well. Without 
that exception (as the code now is) there is no warning issued just an 
ambiguous return of False.  Which means that the code is still buggy as 
the user could assume that the Index value points to next insert spot 
and instead it is out of range and causes a crash.   Setting Index value 
to -1 would be a better indicator of bad usage than just returning False 
(with raising an exception still being the best warning).


Keep in mind though that being able to call find on a manually sorted 
list (Sorted <> true) is not buggy behavior (this is the Delphi 
compatibility that we are interested in maintaining).  In which case 
adding in #3 would be necessary.  So I guess I am for #4.


I would suggest that the added boolean flag be named to indicate that 
the list is manually sorted (ManualSorted ?) rather than the flag being 
just a 'bypass check' indicator.  The check in Find would be "if not 
Sorted or not ManualSorted then raise exception'.  But that's just a 
personal preference and not something that I feel extra committed to.


My second choice would be #1 by itself.

David


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-21 Thread David Jenkins



On 3/21/16 3:44 PM, Michael Van Canneyt wrote:


The reason for this behaviour is that find needs to be sure that the 
list is sorted.
If it thinks the list is not sorted, the result cannot be guaranteed 
to be

correct, and this is an error condition.

What I don't understand about these discussions is:

TStringList is just one possible implementation of TStrings. It is 
only there for your ease of use.


If you don't like it, you can use another one. You can find several. 
There is one in inifiles, the LCL probably also contains a couple.


If all APIs work with TStrings, then they don't care what TStrings
descendent you use. So you are free to use one that does whatever you 
want.


Anyone declaring an API that explicitly expects TStringList, is simply 
doing something wrong, in my view.


This is Object Pascal for a reason, after all.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


I understand the need for the list to be sorted and agree that calling 
find on an unsorted list is an error condition.


I am not convinced that current change deals with that well.

For one, the Sorted flag and actual state of the list are not directly 
linked.  I can manually sort the list so that Find binary search will 
work just fine.  But Find will exit before the binary search can occur - 
without any indication why.


Ff the list is not sorted,  I don't think the current change creates a 
true error response to the error condition.  Returning False indicates 
string not found - not an error.  Furthermore I think the change makes 
the error condition worse by leaving values in Index that can cause 
crashes beyond just the error condition of not finding the right string.


Raising an exception if not Sorted would be an error response.  Or 
providing some feedback to the user to indicate the difference between 
not found and error condition.


We can use our own descendant of TStrings or we could apply a local 
patch to TStringList as already mentioned.  So we can actually create a 
work around.  Our interest was in pointing out a change in fpc code that 
we thought was a regression rather than an improvement.



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-21 Thread David Jenkins



On 3/21/16 2:55 PM, Michael Van Canneyt wrote:

We can introduce a property which disables the check, if you want.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


However..  now that I've thought about it some more.  That 
change would be nice and all for us but doesn't it just muddle the 
picture even more for anyone else using the code?


I'm feeling tempted to argue against my side a little.  If the change is 
correct i.e. makes for better code or behavior then it should stay and 
we'll go ahead and take it out in our local files if we don't like it 
(we'll grumble at having to maintain a local patch be we already have a 
few of those).


My thought is that it doesn't make for better code or behavior while at 
the same time breaking Delphi compatibility.  Delphi compatibility isn't 
the golden standard but it seems any breakage should be for a good reason.


David



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-21 Thread David Jenkins

On 3/21/16 2:55 PM, Michael Van Canneyt wrote:

We can introduce a property which disables the check, if you want.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


That would work for us.  Our other option is to pull the check out in 
our local version of stringl.inc.  But we prefer to maintain as few 
local patches as possible.





___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Questions on TStringList.Find change (Mantis 28744)

2016-03-21 Thread David Jenkins
I just ran across the change that checks Sorted at beginning of find and 
exits if Sorted = False.  This has caused some problems for us


a)  We have lists that are sorted manually and we'd like to continue 
keeping them sorted manually (and be able to call .insert()).  This 
means not setting the sorted flag.  But without setting 'sorted' we can 
no longer use find.  We are sharing code between VCL and FPC - delphi 
compatibility has been broken.


b) The change, in my opinion, hasn't solved the unpredictable response 
problem.  There is still nothing to indicate to a caller that they have 
called the function inappropriately i.e. they do not know why find has 
returned false.


Furthermore the documentation also indicates that if false is returned 
then 'Index' will contain the position where the string should be 
inserted.  Index used to at least be within the range of FCount or 0.  
Now the value 'Index' is even more indeterminte as the code exits before 
Index has been set to anything.  It has gone from possibly placing a 
string at a wrong location to possibly causing a crash with index out of 
range.


It could be argued whether this is worse but it certainly doesn't seem 
to have made the situation any better for people blindly misusing Find 
an unsorted list - while at the same time breaking Delphi compatibility 
and the option to manually keep lists sorted.


Thoughts?

David Jenkins
da...@scootersoftware.com

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] safecall_exceptions in OSX

2014-11-12 Thread David Jenkins


Thanks Jonas,

I enabled tf_safecall_exceptions for system_i386_darwin_info and it is 
working for my particular need.


I am using jcl (JclCompression) and the unix port of 7zip (p7zip) to 
provide 7z support for our app.  Official current JclCompression is 
MSWINDOWS only and uses safecall for the interface connections to the 
7z.dll.  By enabling the safecall result passing for darwin I am able to 
use JclCompression with 7z.so with only slight modifications.  So far I 
have seen no issues.  I would not claim that this is a full test of 
XPCOM/safecall_exceptions on OSX.


Regards
David Jenkins


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] safecall_exceptions in OSX

2014-11-07 Thread David Jenkins
I have been using the safecall functionality in linux and it has been 
working.  I now am porting the same code to OSX and find that 
safecall_exceptions is not turned on.  In particular I need the 
functionality that catches the HRESULT and passes it back to the calling 
function.  I see that tf_safecall_exceptions is only enabled in 
tsysteminfo for i_linux and i_win.


Is it possible to enable tf_safecall_exceptions for i_macos.

Thanks
David Jenkins
da...@scootersoftware.com

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] nestedprocvar questions

2012-07-31 Thread David Jenkins

Some questions about 'nestedprocvars' mode switch

We have a simplified version of the nested procedure calling 
demonstrated in tests/test/tmaclocalprocparam3d.pp.  It looks more or 
less like:


{$mode DELPHI}
{$modeswitch nestedprocvars}

type
  tnestedprocvar = function(AArg: string): boolean;


  procedure p1(AArg: string; pp: tnestedprocvar);
  begin
if pp(AArg) then
  writeln('true');
  end;

  procedure q;

function r(AArg: string): boolean;
begin
  writeln(AArg)
  Result := true;
end;

  begin
 p1('test string', @r);
  end;

Notice that it is $MODE DELPHI, that the proc var is a function, and that we do 
not access any external variables in the nested function.

Question #1:
There seems to be an interaction between $MODE DELPHI and the 'is nested' 
construct.  I.e. I cannot put the 'is nested' after the tnestedprocvar type and 
do the function passing with '@r'.  If I do the compiler complains about 
getting a pointer (@r) when it was expecting a function (..): boolean is 
nested.  So either I remove the'@' and just pass 'r' or I do not include the 
'is nested'.

Is this correct?

Question #2:
This code is being compiled both with Delphi compiler and with FPC.  Delphi 
handles the nesting with no problem and with no 'is nested' directive.

Should nestedprocvar be included automatically with $MODE DELPHI for 
compatibility?

Question #3:
If we set up our code as above can we expect the compiler to be consistent in 
parameter set up for the next while?

Question #4:
If we set up our code as above (with no 'is nested') would it be safe to 
include access of an external variable (internal to procedure q) to the nested 
function?


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] FreePascal Git Repo and 2_6 branch

2012-05-01 Thread David Jenkins



On 4/28/2012 12:23 PM, Graeme Geldenhuys wrote:
What I can do in an automated fashion, is to simply mirror the 2.6 
fixes branch as a separate git repository (with limited history - 
going back to when 2.6 fixes branch was started). If this would be 
sufficient, I can set it up on Wednesday when I am back in the office. 
That's no trouble. 


For my situation this would be sufficient.

I have some local patches that git-rebase does a nice job of plopping on 
the head of the branch whenever there are changes.  Right now those 
patches are sitting on trunk but I would like to move them to fixes-2_6 
and maintain them there.


I had started to do a 'git svn clone' of the fpc repository myself and 
after it ran for 16 hours wondered if there were a better way.  Creating 
the limited history 2.6 fixes branch repository myself is probably also 
an option if you have better things to do.


Thanks

David


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


[fpc-devel] FreePascal Git Repo and 2_6 branch

2012-04-27 Thread David Jenkins
I am wondering if Graeme can update his FreePascal git mirror to include 
the 2_6 branches.


Thanks

David Jenkins


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


[fpc-devel] TMultiReadExclusiveWriteSynchronizer

2012-02-17 Thread David Jenkins
Under Delphi if the TMultiReadExclusiveWriteSynchronizer writelock is 
held a read is not blocked if the ThreadID for the read is the same as 
the ThreadID for the write.  Under FreePascal if writelock is held the 
read is always blocked regardless of ThreadID or anything else 
(implemented in the BeginRead method).


I have some third party code that assumes that 
TMultiReadExclusiveWriteSynchronizer will work as it does in Delphi.  I 
am wondering if the freepascal implementation is purposeful (read block 
even when in same thread is intentional) and I should talk to my third 
party vendor.  Or if this is something that could/should be addressed in 
FreePascal.


Thanks

David Jenkins
Scooter Software


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel