[fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

2007-11-20 Thread Graeme Geldenhuys
Hi,

I've included a program that shows the problem. I'm using FPC 2.2.0
under Linux on a Intel P4.
I've got a function PropertyMatch() which returns true or false if a
given property matches a specified value. All very simple.
But for some strange reason TypInfo.GetPropValue returns a boolean
which seems to test ok using VarIsType(), but if I cast it as a
boolean variant using VarIsType() just to be sure, the application
throws the error show below.

Any ideas how to resolve this issue?  Is it a FPC bug?  This same code
works perfectly with Delphi 7-2007.


[EMAIL PROTECTED]:rtti_bug$ ./project1
Test 1 passed. Integer property matched.
Test 2 passed. String property matched.
An unhandled exception occurred at $0807F54D :
EVariantTypeCastError : Could not convert variant of type (Int64) into
type (Boolean)
  $0807F54D
  $0807C5EB
  $0807D139
  $08048467  main,  line 85 of project1.lpr



[  Backtrace  ]--
(gdb) break fpc_raiseexception
Breakpoint 1 at 0x8054886
(gdb) run
Starting program: /home/graemeg/programming/tests/rtti_bug/project1
Test 1 passed. Integer property matched.
Test 2 passed. String property matched.

Breakpoint 1, 0x08054886 in fpc_raiseexception ()
(gdb) bt
#0  0x08054886 in fpc_raiseexception ()
#1  0x0807f539 in VARIANTS_VARCASTERROR$WORD$WORD ()
#2  0x0807c5cb in VARIANTS_SYSVARCAST$VARIANT$VARIANT$LONGINT ()
#3  0x0807d119 in VARIANTS_VARASTYPE$VARIANT$WORD$$VARIANT ()
#4  0xbfa82934 in ?? ()
#5  0xbfa828d4 in ?? ()
#6  0x08048189 in PROPERTYMATCH (AOBJECT=0xb7f4a100,
PROPNAME=0x80a1ab4, PROPVALUE=void)
at project1.lpr:41
#7  0x08048467 in main () at project1.lpr:82
-  end  



-[  the program code  ]--
program project1;

{$mode objfpc}{$H+}

uses
  Classes, typinfo, variants;


type
  {$M+}
  TMyObject = class(TObject)
  private
FBoolProp: Boolean;
FIntProp: Integer;
FStrProp: string;
  published
property IntProp: Integer read FIntProp write FIntProp;
property BoolProp: Boolean read FBoolProp write FBoolProp;
property StrProp: string read FStrProp write FStrProp;
  end;
  {$M-}


  // This does a test to see if the property PropName's value
  // matches PropValue.
  function PropertyMatch(AObject: TObject; PropName: string;
PropValue: variant): boolean;
  var
lSearch, lItem: variant;
lVarType: TVarType;
lPropInfo: PPropInfo;
  begin
lSearch := PropValue;

lItem := TypInfo.GetPropValue(AObject, PropName);
lVarType := VarType(lItem);

// Just to be sure that I'm comparing the SAME kind of values
if VarIsType(PropValue, varBoolean) then
begin
  lItem := VarAsType(lItem, varBoolean);  // === EVariantTypeCastError
//  lItem := VarAsType(True, varBoolean);  // this passes if we
force boolean
end
else
begin
  lSearch := VarAsType(lSearch, lVarType);
  lItem := VarAsType(lItem, lVarType);
end;

result := (lSearch = lItem);
  end;


var
  obj: TMyObject;
  lBool: Boolean;
begin
  obj := TMyObject.Create;
  try
obj.IntProp   := 123;
obj.BoolProp  := True;
obj.StrProp   := 'abcd';


// Testing a Integer property
if PropertyMatch(obj, 'IntProp', 123) then
  writeln('Test 1 passed. Integer property matched.')
else
  writeln('Test 1 failed');


// Testing a String property
if PropertyMatch(obj, 'StrProp', 'abcd') then
  writeln('Test 2 passed. String property matched.')
else
  writeln('Test 2 failed');


// Testing a Boolean property
// We can also try it with a typed variable
//lBool := True;
//if PropertyMatch(obj, 'BoolProp', lBool) then
if PropertyMatch(obj, 'BoolProp', True) then
  writeln('Test 3 passed. Boolean property matched.')
else
  writeln('Test 3 failed');

  finally
obj.Free;
  end;
end.

-  end  


Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

2007-11-20 Thread Michael Van Canneyt


On Tue, 20 Nov 2007, Graeme Geldenhuys wrote:

 Hi,
 
 I've included a program that shows the problem. I'm using FPC 2.2.0
 under Linux on a Intel P4.
 I've got a function PropertyMatch() which returns true or false if a
 given property matches a specified value. All very simple.
 But for some strange reason TypInfo.GetPropValue returns a boolean
 which seems to test ok using VarIsType(), but if I cast it as a
 boolean variant using VarIsType() just to be sure, the application
 throws the error show below.
 
 Any ideas how to resolve this issue?  Is it a FPC bug?  This same code
 works perfectly with Delphi 7-2007.

It depends on the choices made when converting variants to native types or
vice versa (even more difficult when it occurs in an expression).
It's hard to say whether this is an actual error or an incompatibility. 
Looking at the code and the error, I'd say that somewhere along the line 
fpc converted a variant to int64 instead of to an integer as delphi seems 
to do.

It's just one of these reasons why it is IMHO better not to use Variants:
things happen behind the scenes that are not very clear (and that are 
not documented )

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


Re: [fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

2007-11-20 Thread Graeme Geldenhuys
On 20/11/2007, Michael Van Canneyt [EMAIL PROTECTED] wrote:
 It's hard to say whether this is an actual error or an incompatibility.

Well this 'error' has been around in tiOPF since I ported it to FPC
(about 3 years) and now it's really bugging me.  :)

 Looking at the code and the error, I'd say that somewhere along the line
 fpc converted a variant to int64 instead of to an integer as delphi seems
 to do.

No idea, I may not look at the Delphi code remember!  ;-)


 It's just one of these reasons why it is IMHO better not to use Variants:
 things happen behind the scenes that are not very clear (and that are
 not documented )

Fair enough. I'm not a fan of Variants either, but how else would I
write the PropertyMatch() function then?  Yes I could do some extra
tests and use GetStrProp, GetIntProp, GetFloatProp etc. but there
isn't a GetBooleanProp().  I would imagine I need to use the
GetOrdProp for Boolean, but looking at the function definition for
GetOrdProp, it outputs a Int64 which is probably what gave me the
error in the first place (casting Bool to Int64 or vice-versa).

Note that the PropertyMatch() function I have in the example is a
scaled down version (just to highlight the issue) of the full one in
tiOPF.  I need to handle all property types.


Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

2007-11-20 Thread Michael Van Canneyt


On Tue, 20 Nov 2007, Graeme Geldenhuys wrote:

 On 20/11/2007, Michael Van Canneyt [EMAIL PROTECTED] wrote:
  It's hard to say whether this is an actual error or an incompatibility.
 
 Well this 'error' has been around in tiOPF since I ported it to FPC
 (about 3 years) and now it's really bugging me.  :)
 
  Looking at the code and the error, I'd say that somewhere along the line
  fpc converted a variant to int64 instead of to an integer as delphi seems
  to do.
 
 No idea, I may not look at the Delphi code remember!  ;-)

Point scored :-)

 
 
  It's just one of these reasons why it is IMHO better not to use Variants:
  things happen behind the scenes that are not very clear (and that are
  not documented )
 
 Fair enough. I'm not a fan of Variants either, but how else would I
 write the PropertyMatch() function then?  Yes I could do some extra
 tests and use GetStrProp, GetIntProp, GetFloatProp etc. 

This is IMHO the only correct way.

 but there
 isn't a GetBooleanProp().  I would imagine I need to use the
 GetOrdProp for Boolean, but looking at the function definition for
 GetOrdProp, it outputs a Int64 which is probably what gave me the
 error in the first place (casting Bool to Int64 or vice-versa).

It probably retuns an int(64), and when it's converted to variant 
- I don't know. I'd have to look at the code.

 
 Note that the PropertyMatch() function I have in the example is a
 scaled down version (just to highlight the issue) of the full one in
 tiOPF.  I need to handle all property types.

This is exactly where the easy access to RTTI would come in handy, and 
which is why I would like to have it. If you want we can always discuss
in private the design of such an easy-acces method.

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


Re: [fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

2007-11-20 Thread Graeme Geldenhuys
On 20/11/2007, Michael Van Canneyt [EMAIL PROTECTED] wrote:
  Fair enough. I'm not a fan of Variants either, but how else would I
  write the PropertyMatch() function then?  Yes I could do some extra
  tests and use GetStrProp, GetIntProp, GetFloatProp etc.

 This is IMHO the only correct way.

I've extended the PropertyMatch() function to test for tkBool types
(no variants) and do a writeln when it finds it. That parts seems to
work fine.


 It probably retuns an int(64), and when it's converted to variant
 - I don't know. I'd have to look at the code.

That would be great.  I'm on my way home now, but will continue
looking at the code tomorrow. More eyeballs on the code is always
better.


 This is exactly where the easy access to RTTI would come in handy, and
 which is why I would like to have it. If you want we can always discuss
 in private the design of such an easy-acces method.

I've created a tiRTTI.pas unit in tiOPF, but it's simply wrappers for
calling many other functions. It makes it a bit easier to use RTTI
though.  But yes I wouldn't mind discussion an 'easy-access' method
for RTTI.


Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

2007-11-20 Thread Graeme Geldenhuys
On 20/11/2007, Graeme Geldenhuys [EMAIL PROTECTED] wrote:

 I've extended the PropertyMatch() function to test for tkBool types
 (no variants) and do a writeln when it finds it. That parts seems to
 work fine.


Here is the debug code I added to PropertyMatch() which successfully
compare the results, but I have to explicitly cast GetOrdProp to a
Boolean.  Is that normal???

PropInfo := GetPropInfo(AObject.ClassType, PropName);
if tiGetTypeInfo(PropInfo)^.Kind = tkBool then
begin
  writeln('Found rtti bool type');
  lbool := Boolean(GetOrdProp(AObject, PropName));
  if lSearch = lbool then
writeln('Comparison was a success');
end;


Regards,
  - Graeme -


___
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

2007-11-20 Thread Michael Van Canneyt


On Tue, 20 Nov 2007, Graeme Geldenhuys wrote:

 On 20/11/2007, Graeme Geldenhuys [EMAIL PROTECTED] wrote:
 
  I've extended the PropertyMatch() function to test for tkBool types
  (no variants) and do a writeln when it finds it. That parts seems to
  work fine.
 
 
 Here is the debug code I added to PropertyMatch() which successfully
 compare the results, but I have to explicitly cast GetOrdProp to a
 Boolean.  Is that normal???

Yes.

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


Re: [fpc-devel] RTTI's GetPropValue returns corrupt Boolean value

2007-11-20 Thread Joao Morais

Graeme Geldenhuys wrote:

On 20/11/2007, Graeme Geldenhuys [EMAIL PROTECTED] wrote:

I've extended the PropertyMatch() function to test for tkBool types
(no variants) and do a writeln when it finds it. That parts seems to
work fine.


Here is the debug code I added to PropertyMatch() which successfully
compare the results, but I have to explicitly cast GetOrdProp to a
Boolean.  Is that normal???

PropInfo := GetPropInfo(AObject.ClassType, PropName);
if tiGetTypeInfo(PropInfo)^.Kind = tkBool then
begin
  writeln('Found rtti bool type');
  lbool := Boolean(GetOrdProp(AObject, PropName));
  if lSearch = lbool then
writeln('Comparison was a success');
end;


Sounds familiar. Here I have:

  if UsePublishedGetter then
Result := Boolean(GetOrdProp(Owner, Metadata.Name))
  else
Result := Value;

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