mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 10:59:18 +02:00
* rework/extend SetToString/StringToSet so that sets with a size > 4 can be converted as well (this is Delphi compatible)
+ added test git-svn-id: trunk@42240 -
This commit is contained in:
parent
749c4d4e47
commit
89e454aca8
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -14032,6 +14032,7 @@ tests/test/trtti18a.pp svneol=native#text/pascal
|
|||||||
tests/test/trtti18b.pp svneol=native#text/pascal
|
tests/test/trtti18b.pp svneol=native#text/pascal
|
||||||
tests/test/trtti19.pp svneol=native#text/pascal
|
tests/test/trtti19.pp svneol=native#text/pascal
|
||||||
tests/test/trtti2.pp svneol=native#text/plain
|
tests/test/trtti2.pp svneol=native#text/plain
|
||||||
|
tests/test/trtti20.pp svneol=native#text/pascal
|
||||||
tests/test/trtti3.pp svneol=native#text/plain
|
tests/test/trtti3.pp svneol=native#text/plain
|
||||||
tests/test/trtti4.pp svneol=native#text/plain
|
tests/test/trtti4.pp svneol=native#text/plain
|
||||||
tests/test/trtti5.pp svneol=native#text/plain
|
tests/test/trtti5.pp svneol=native#text/plain
|
||||||
|
@ -884,8 +884,12 @@ function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Int
|
|||||||
function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
|
function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
|
||||||
function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
|
function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
|
||||||
function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
|
function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
|
||||||
|
function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean = False) : String;
|
||||||
|
function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean = False) : String;
|
||||||
function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
|
function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
|
||||||
function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
|
function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
|
||||||
|
procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
|
||||||
|
procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
|
||||||
|
|
||||||
const
|
const
|
||||||
BooleanIdents: array[Boolean] of String = ('False', 'True');
|
BooleanIdents: array[Boolean] of String = ('False', 'True');
|
||||||
@ -1044,50 +1048,83 @@ end;
|
|||||||
Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
|
Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=SetToString(PropInfo^.PropType,Value,Brackets);
|
Result:=SetToString(PropInfo^.PropType, @Value, Brackets);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
|
Function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
|
||||||
|
begin
|
||||||
|
Result := SetToString(TypeInfo, @Value, Brackets);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean): String;
|
||||||
type
|
type
|
||||||
tsetarr = bitpacked array[0..SizeOf(Integer)*8-1] of 0..1;
|
tsetarr = bitpacked array[0..SizeOf(Integer)*8-1] of 0..1;
|
||||||
Var
|
Var
|
||||||
I : Integer;
|
I,El,Els,Rem,V,Max : Integer;
|
||||||
PTI : PTypeInfo;
|
PTI : PTypeInfo;
|
||||||
|
PTD : PTypeData;
|
||||||
|
ValueArr : PLongWord;
|
||||||
begin
|
begin
|
||||||
{$if defined(FPC_BIG_ENDIAN)}
|
PTD := GetTypeData(TypeInfo);
|
||||||
{ On big endian systems, set element 0 is in the most significant bit,
|
PTI:=PTD^.CompType;
|
||||||
and the same goes for the elements of bitpacked arrays there. }
|
ValueArr := PLongWord(Value);
|
||||||
case GetTypeData(TypeInfo)^.OrdType of
|
Result:='';
|
||||||
otSByte,otUByte: Value:=Value shl (SizeOf(Integer)*8-8);
|
{$ifdef ver3_0}
|
||||||
otSWord,otUWord: Value:=Value shl (SizeOf(Integer)*8-16);
|
case PTD^.OrdType of
|
||||||
|
otSByte, otUByte: begin
|
||||||
|
Els := 0;
|
||||||
|
Rem := 1;
|
||||||
end;
|
end;
|
||||||
|
otSWord, otUWord: begin
|
||||||
|
Els := 0;
|
||||||
|
Rem := 2;
|
||||||
|
end;
|
||||||
|
otSLong, otULong: begin
|
||||||
|
Els := 1;
|
||||||
|
Rem := 0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{$else}
|
||||||
|
Els := PTD^.SetSize div SizeOf(Integer);
|
||||||
|
Rem := PTD^.SetSize mod SizeOf(Integer);
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
PTI:=GetTypeData(TypeInfo)^.CompType;
|
{$ifdef ver3_0}
|
||||||
Result:='';
|
El := 0;
|
||||||
For I:=0 to SizeOf(Integer)*8-1 do
|
{$else}
|
||||||
|
for El := 0 to (PTD^.SetSize - 1) div SizeOf(Integer) do
|
||||||
|
{$endif}
|
||||||
begin
|
begin
|
||||||
if (tsetarr(Value)[i]<>0) then
|
if El = Els then
|
||||||
begin
|
Max := Rem
|
||||||
If Result='' then
|
|
||||||
Result:=GetEnumName(PTI,i)
|
|
||||||
else
|
else
|
||||||
Result:=Result+','+GetEnumName(PTI,I);
|
Max := SizeOf(Integer);
|
||||||
|
For I:=0 to Max*8-1 do
|
||||||
|
begin
|
||||||
|
if (tsetarr(ValueArr[El])[i]<>0) then
|
||||||
|
begin
|
||||||
|
V := I + SizeOf(Integer) * 8 * El;
|
||||||
|
If Result='' then
|
||||||
|
Result:=GetEnumName(PTI,V)
|
||||||
|
else
|
||||||
|
Result:=Result+','+GetEnumName(PTI,V);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if Brackets then
|
if Brackets then
|
||||||
Result:='['+Result+']';
|
Result:='['+Result+']';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
|
Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=SetToString(PropInfo,Value,False);
|
Result:=SetToString(PropInfo,Value,False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean): String;
|
||||||
|
begin
|
||||||
|
Result := SetToString(PropInfo^.PropType, Value, Brackets);
|
||||||
|
end;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
SetDelim = ['[',']',',',' '];
|
SetDelim = ['[',']',',',' '];
|
||||||
@ -1110,18 +1147,31 @@ end;
|
|||||||
Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
|
Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=StringToSet(PropInfo^.PropType,Value);
|
StringToSet(PropInfo^.PropType,Value,@Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
|
Function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
|
||||||
|
begin
|
||||||
|
StringToSet(TypeInfo, Value, @Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
|
||||||
Var
|
Var
|
||||||
S,T : String;
|
S,T : String;
|
||||||
I : Integer;
|
I, ElOfs, BitOfs : Integer;
|
||||||
|
PTD: PTypeData;
|
||||||
PTI : PTypeInfo;
|
PTI : PTypeInfo;
|
||||||
|
ResArr: PLongWord;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=0;
|
PTD:=GetTypeData(TypeInfo);
|
||||||
PTI:=GetTypeData(TypeInfo)^.Comptype;
|
{$ifndef ver3_0}
|
||||||
|
FillChar(Result^, PTD^.SetSize, 0);
|
||||||
|
{$else}
|
||||||
|
PInteger(Result)^ := 0;
|
||||||
|
{$endif}
|
||||||
|
PTI:=PTD^.Comptype;
|
||||||
|
ResArr := PLongWord(Result);
|
||||||
S:=Value;
|
S:=Value;
|
||||||
I:=1;
|
I:=1;
|
||||||
If Length(S)>0 then
|
If Length(S)>0 then
|
||||||
@ -1138,11 +1188,22 @@ begin
|
|||||||
I:=GetEnumValue(PTI,T);
|
I:=GetEnumValue(PTI,T);
|
||||||
if (I<0) then
|
if (I<0) then
|
||||||
raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
|
raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
|
||||||
Result:=Result or (1 shl i);
|
ElOfs := I shr 5;
|
||||||
|
BitOfs := I and $1F;
|
||||||
|
{$ifdef FPC_BIG_ENDIAN}
|
||||||
|
{ on Big Endian systems enum values start from the MSB, thus we need
|
||||||
|
to reverse the shift }
|
||||||
|
BitOfs := 31 - BitOfs;
|
||||||
|
{$endif}
|
||||||
|
ResArr[ElOfs] := ResArr[ElOfs] or (1 shl BitOfs);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
|
||||||
|
begin
|
||||||
|
StringToSet(PropInfo^.PropType, Value, Result);
|
||||||
|
end;
|
||||||
|
|
||||||
Function AlignTypeData(p : Pointer) : Pointer;
|
Function AlignTypeData(p : Pointer) : Pointer;
|
||||||
{$packrecords c}
|
{$packrecords c}
|
||||||
|
184
tests/test/trtti20.pp
Normal file
184
tests/test/trtti20.pp
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
program trtti20;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
|
||||||
|
uses
|
||||||
|
TypInfo;
|
||||||
|
|
||||||
|
type
|
||||||
|
TByteEnum = (
|
||||||
|
be1,
|
||||||
|
be2,
|
||||||
|
be3,
|
||||||
|
be4,
|
||||||
|
be5,
|
||||||
|
be6
|
||||||
|
);
|
||||||
|
|
||||||
|
TWordEnum = (
|
||||||
|
we1,
|
||||||
|
we2,
|
||||||
|
we3,
|
||||||
|
we4,
|
||||||
|
we5,
|
||||||
|
we6,
|
||||||
|
we7,
|
||||||
|
we8,
|
||||||
|
we9,
|
||||||
|
we10
|
||||||
|
);
|
||||||
|
|
||||||
|
TDWordEnum = (
|
||||||
|
de1,
|
||||||
|
de2,
|
||||||
|
de3,
|
||||||
|
de4,
|
||||||
|
de5,
|
||||||
|
de6,
|
||||||
|
de7,
|
||||||
|
de8,
|
||||||
|
de9,
|
||||||
|
de10,
|
||||||
|
de11,
|
||||||
|
de12,
|
||||||
|
de13,
|
||||||
|
de14,
|
||||||
|
de15,
|
||||||
|
de16,
|
||||||
|
de17,
|
||||||
|
de18,
|
||||||
|
de19,
|
||||||
|
de20
|
||||||
|
);
|
||||||
|
|
||||||
|
TLargeEnum = (
|
||||||
|
le1,
|
||||||
|
le2,
|
||||||
|
le3,
|
||||||
|
le4,
|
||||||
|
le5,
|
||||||
|
le6,
|
||||||
|
le7,
|
||||||
|
le8,
|
||||||
|
le9,
|
||||||
|
le10,
|
||||||
|
le11,
|
||||||
|
le12,
|
||||||
|
le13,
|
||||||
|
le14,
|
||||||
|
le15,
|
||||||
|
le16,
|
||||||
|
le17,
|
||||||
|
le18,
|
||||||
|
le19,
|
||||||
|
le20,
|
||||||
|
le21,
|
||||||
|
le22,
|
||||||
|
le23,
|
||||||
|
le24,
|
||||||
|
le25,
|
||||||
|
le26,
|
||||||
|
le27,
|
||||||
|
le28,
|
||||||
|
le29,
|
||||||
|
le30,
|
||||||
|
le31,
|
||||||
|
le32,
|
||||||
|
le33,
|
||||||
|
le34,
|
||||||
|
le35,
|
||||||
|
le36,
|
||||||
|
le37,
|
||||||
|
le38,
|
||||||
|
le39,
|
||||||
|
le40
|
||||||
|
);
|
||||||
|
|
||||||
|
TByteSet = set of TByteEnum;
|
||||||
|
TWordSet = set of TWordEnum;
|
||||||
|
TDWordSet = set of TDWordEnum;
|
||||||
|
TLargeSet = set of TLargeEnum;
|
||||||
|
|
||||||
|
{$push}
|
||||||
|
{$packset 1}
|
||||||
|
TByteSetP = set of TByteEnum;
|
||||||
|
TWordSetP = set of TWordEnum;
|
||||||
|
TDWordSetP = set of TDWordEnum;
|
||||||
|
TLargeSetP = set of TLargeEnum;
|
||||||
|
{$pop}
|
||||||
|
|
||||||
|
const
|
||||||
|
StrBS = '[be1,be6]';
|
||||||
|
StrWS = '[we1,we8,we10]';
|
||||||
|
StrDS = '[de1,de7,de20]';
|
||||||
|
StrLS = '[le1,le20,le31,le40]';
|
||||||
|
|
||||||
|
var
|
||||||
|
bs1, bs2: TByteSet;
|
||||||
|
ws1, ws2: TWordSet;
|
||||||
|
ds1, ds2: TDWordSet;
|
||||||
|
ls1, ls2: TLargeSet;
|
||||||
|
bsp1, bsp2: TByteSetP;
|
||||||
|
wsp1, wsp2: TWordSetP;
|
||||||
|
dsp1, dsp2: TDWordSetP;
|
||||||
|
lsp1, lsp2: TLargeSetP;
|
||||||
|
begin
|
||||||
|
bs1 := [be1, be6];
|
||||||
|
ws1 := [we1, we8, we10];
|
||||||
|
ds1 := [de1, de7, de20];
|
||||||
|
ls1 := [le1, le20, le31, le40];
|
||||||
|
bsp1 := [be1, be6];
|
||||||
|
wsp1 := [we1, we8, we10];
|
||||||
|
dsp1 := [de1, de7, de20];
|
||||||
|
lsp1 := [le1, le20, le31, le40];
|
||||||
|
|
||||||
|
if SetToString(PTypeInfo(TypeInfo(TByteSet)), @bs1, True) <> StrBS then
|
||||||
|
Halt(1);
|
||||||
|
if SetToString(PTypeInfo(TypeInfo(TWordSet)), @ws1, True) <> StrWS then
|
||||||
|
Halt(2);
|
||||||
|
if SetToString(PTypeInfo(TypeInfo(TDWordSet)), @ds1, True) <> StrDS then
|
||||||
|
Halt(3);
|
||||||
|
if SetToString(PTypeInfo(TypeInfo(TLargeSet)), @ls1, True) <> StrLS then
|
||||||
|
Halt(4);
|
||||||
|
|
||||||
|
if SetToString(PTypeInfo(TypeInfo(TByteSetP)), @bsp1, True) <> StrBS then
|
||||||
|
Halt(5);
|
||||||
|
if SetToString(PTypeInfo(TypeInfo(TWordSetP)), @wsp1, True) <> StrWS then
|
||||||
|
Halt(6);
|
||||||
|
if SetToString(PTypeInfo(TypeInfo(TDWordSetP)), @dsp1, True) <> StrDS then
|
||||||
|
Halt(7);
|
||||||
|
if SetToString(PTypeInfo(TypeInfo(TLargeSetP)), @lsp1, True) <> StrLS then
|
||||||
|
Halt(8);
|
||||||
|
|
||||||
|
StringToSet(PTypeInfo(TypeInfo(TByteSet)), StrBS, @bs2);
|
||||||
|
if bs2<>bs1 then
|
||||||
|
Halt(9);
|
||||||
|
|
||||||
|
StringToSet(PTypeInfo(TypeInfo(TWordSet)), StrWS, @ws2);
|
||||||
|
if ws2<>ws1 then
|
||||||
|
Halt(10);
|
||||||
|
|
||||||
|
StringToSet(PTypeInfo(TypeInfo(TDWordSet)), StrDS, @ds2);
|
||||||
|
if ds2<>ds1 then
|
||||||
|
Halt(11);
|
||||||
|
|
||||||
|
StringToSet(PTypeInfo(TypeInfo(TLargeSet)), StrLS, @ls2);
|
||||||
|
if ls2<>ls1 then
|
||||||
|
Halt(12);
|
||||||
|
|
||||||
|
StringToSet(PTypeInfo(TypeInfo(TByteSetP)), StrBS, @bsp2);
|
||||||
|
if bsp2<>bsp1 then
|
||||||
|
Halt(9);
|
||||||
|
|
||||||
|
StringToSet(PTypeInfo(TypeInfo(TWordSetP)), StrWS, @wsp2);
|
||||||
|
if wsp2<>wsp1 then
|
||||||
|
Halt(10);
|
||||||
|
|
||||||
|
StringToSet(PTypeInfo(TypeInfo(TDWordSetP)), StrDS, @dsp2);
|
||||||
|
if dsp2<>dsp1 then
|
||||||
|
Halt(11);
|
||||||
|
|
||||||
|
StringToSet(PTypeInfo(TypeInfo(TLargeSetP)), StrLS, @lsp2);
|
||||||
|
if lsp2<>lsp1 then
|
||||||
|
Halt(12);
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user