Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2002-08

Problem with TReader and integer idents

5 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mattias Gaertner

Hi all,

I have an object stream for a component with a published property Color: TColor. The stream contains the statement: Color = clRed
Since 'clRed' is an identifier, TReader lookups for an IdentToInt function via FindIdentToInt declared in classes.pp. FindIdentToInt needs a pointer to a TTypeInfo.

The problem is that the TypeInfo pointer differs from unit to unit. A TypeInfo(longint) in classes.pp is not the same as a TypeInfo(longint) in the program. This is incompatible to Delphi.
So, the program can't register a valid TypeInfo pointer.

I guess, it's not easy to fix this, so I suggest a workaround:

The function FindIdentToInt can be extended to not only check for TypeInfo pointers, but also for the values in the typeinfo:

function FindIdentToInt(AIntegerType: Pointer): TIdentToInt;
var
  i: Integer;
begin
  with IntConstList.LockList do
  try
    for i := 0 to Count - 1 do
      with TIntConst(Items[I]) do begin
        if (IntegerType = AIntegerType)
        // start of workaround --------------------
        or ((PTypeInfo(AIntegerType)^.Name = PTypeInfo(IntegerType)^.Name)
          and (PTypeInfo(AIntegerType)^.Kind = PTypeInfo(IntegerType)^.Kind))
        // end of workaround --------------------
        then
          exit(IdentToIntFn);
      end;
    Result := nil;
  finally
    IntConstList.UnlockList;
  end;
end;

The same can be applied to the FindIntToIdent function.

Mattias Gaertner

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 37 lines
Hi all, I have an object stream for a component with a published property Color: TColor. The stream contains the statement: Color = clRed Since 'clRed' is an identifier, TReader lookups for an IdentToInt function via FindIdentToInt declared in classes.pp. FindIdentToInt needs a pointer to a TTypeInfo. The problem is that the TypeInfo pointer differs from unit to unit. A TypeInfo(longint) in classes.pp is not the same as a TypeInfo(longint) in the program. This is incompatible to Delphi. So, the program can't register a valid TypeInfo pointer. I guess, it's not easy to fix this, so I suggest a workaround: The function FindIdentToInt can be extended to not only check for TypeInfo pointers, but also for the values in the typeinfo: function FindIdentToInt(AIntegerType: Pointer): TIdentToInt; var i: Integer; begin with IntConstList.LockList do try for i := 0 to Count - 1 do with TIntConst(Items[I]) do begin if (IntegerType = AIntegerType) // start of workaround -------------------- or ((PTypeInfo(AIntegerType)^.Name = PTypeInfo(IntegerType)^.Name) and (PTypeInfo(AIntegerType)^.Kind = PTypeInfo(IntegerType)^.Kind)) // end of workaround -------------------- then exit(IdentToIntFn); end; Result := nil; finally IntConstList.UnlockList; end; end;

Will this not lead to problems with enumerated values ?

You can perfectly have the same enumerated name in 2 units for 2 different enumeration types.

Unita.EnumA = (enOne,onTwo,EnThree);
Unitb.EnumB = (enZero,enOne,enTWo);

This will lead to incorrect results as 'enOne' will have ordinal values 0 and 1 depending on which unit you take...

So I think a compiler solution is in order, here. Florian, any ideas how this should be solved ? Maybe typeinfo should always be included in the unit where something is defined ?

OTOH, longint is a special case, it is an internal compiler type...

Michael.

Mattias Gaertner
to Michael Van Canneyt
Show quoted text 49 lines
On Tue, 6 Aug 2002, Mattias Gaertner wrote: > Hi all, > > I have an object stream for a component with a published property Color: TColor. The stream contains the statement: > Color = clRed > Since 'clRed' is an identifier, TReader lookups for an IdentToInt function via FindIdentToInt declared in classes.pp. FindIdentToInt needs a pointer to a TTypeInfo. > > The problem is that the TypeInfo pointer differs from unit to unit. > A TypeInfo(longint) in classes.pp is not the same as a TypeInfo(longint) in the program. > This is incompatible to Delphi. > So, the program can't register a valid TypeInfo pointer. > > > I guess, it's not easy to fix this, so I suggest a workaround: > > The function FindIdentToInt can be extended to not only check for TypeInfo pointers, but also for the values in the typeinfo: > > function FindIdentToInt(AIntegerType: Pointer): TIdentToInt; > var > i: Integer; > begin > with IntConstList.LockList do > try > for i := 0 to Count - 1 do > with TIntConst(Items[I]) do begin > if (IntegerType = AIntegerType) > // start of workaround -------------------- > or ((PTypeInfo(AIntegerType)^.Name = PTypeInfo(IntegerType)^.Name) > and (PTypeInfo(AIntegerType)^.Kind = PTypeInfo(IntegerType)^.Kind)) > // end of workaround -------------------- > then > exit(IdentToIntFn); > end; > Result := nil; > finally > IntConstList.UnlockList; > end; > end; Will this not lead to problems with enumerated values ? You can perfectly have the same enumerated name in 2 units for 2 different enumeration types. Unita.EnumA = (enOne,onTwo,EnThree); Unitb.EnumB = (enZero,enOne,enTWo);

Here the property types can be EnumA and EnumB, so I think this should work. But of course you're right, the name and kind is not sufficient to distinguish types. OTOH FindIdentToInt is currently rather useless. So, I guess no one uses it. With the workaround it works pretty well in the intended way.

So I think a compiler solution is in order, here. Florian, any ideas how this should be solved ? Maybe typeinfo should always be included in the unit where something is defined ?

Sounds good.

OTOH, longint is a special case, it is an internal compiler type...

Ok, maybe typeinfo(longint) was a bad example. I don't want to register longint.

Mattias

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 68 lines
On Tue, 6 Aug 2002 13:45:00 +0200 (W. Europe Daylight Time) Michael Van Canneyt wrote: > > > On Tue, 6 Aug 2002, Mattias Gaertner wrote: > > > Hi all, > > > > I have an object stream for a component with a published property Color: TColor. The stream contains the statement: > > Color = clRed > > Since 'clRed' is an identifier, TReader lookups for an IdentToInt function via FindIdentToInt declared in classes.pp. FindIdentToInt needs a pointer to a TTypeInfo. > > > > The problem is that the TypeInfo pointer differs from unit to unit. > > A TypeInfo(longint) in classes.pp is not the same as a TypeInfo(longint) in the program. > > This is incompatible to Delphi. > > So, the program can't register a valid TypeInfo pointer. > > > > > > I guess, it's not easy to fix this, so I suggest a workaround: > > > > The function FindIdentToInt can be extended to not only check for TypeInfo pointers, but also for the values in the typeinfo: > > > > function FindIdentToInt(AIntegerType: Pointer): TIdentToInt; > > var > > i: Integer; > > begin > > with IntConstList.LockList do > > try > > for i := 0 to Count - 1 do > > with TIntConst(Items[I]) do begin > > if (IntegerType = AIntegerType) > > // start of workaround -------------------- > > or ((PTypeInfo(AIntegerType)^.Name = PTypeInfo(IntegerType)^.Name) > > and (PTypeInfo(AIntegerType)^.Kind = PTypeInfo(IntegerType)^.Kind)) > > // end of workaround -------------------- > > then > > exit(IdentToIntFn); > > end; > > Result := nil; > > finally > > IntConstList.UnlockList; > > end; > > end; > > Will this not lead to problems with enumerated values ? > > You can perfectly have the same enumerated name in 2 units for 2 > different enumeration types. > > Unita.EnumA = (enOne,onTwo,EnThree); > Unitb.EnumB = (enZero,enOne,enTWo); Here the property types can be EnumA and EnumB, so I think this should work. But of course you're right, the name and kind is not sufficient to distinguish types. OTOH FindIdentToInt is currently rather useless. So, I guess no one uses it. With the workaround it works pretty well in the intended way. > So I think a compiler solution is in order, here. Florian, any ideas how > this should be solved ? Maybe typeinfo should always be included in the > unit where something is defined ? Sounds good. > OTOH, longint is a special case, it is an internal compiler type... Ok, maybe typeinfo(longint) was a bad example. I don't want to register longint.

Why else do you need it if not for integer types ? It's not needed for enumeration types, since there you can use getenumname. In all other cases, the implementation should work as it is, no ?

Michael.

Mattias Gaertner
to Michael Van Canneyt
Show quoted text 5 lines
> > OTOH, longint is a special case, it is an internal compiler type... > > Ok, maybe typeinfo(longint) was a bad example. I don't want to register longint. Why else do you need it if not for integer types ?

I ment, I don't want to register names for 'longint'. I want to register names for integer types like
type TColor = -$7FFFFFFF-1..$7FFFFFFF;

This is not an internal compiler type and has a typeinfo of its own. But with the current implementation I can't register anything for it.

In all other cases, the implementation should work as it is, no ?

I hope the typeinfo function will improve eventually. For now the workaround can do the job.

Mattias