mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-20 06:49:18 +02:00
* Patch from Ondrej Pokorny to allow correct nodefault/stored for strings
git-svn-id: trunk@37954 -
This commit is contained in:
parent
29badfe5af
commit
f6a08a2c74
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -13441,6 +13441,7 @@ tests/test/tprocvar3.pp svneol=native#text/plain
|
||||
tests/test/tprop.pp svneol=native#text/plain
|
||||
tests/test/tprop1.pp svneol=native#text/plain
|
||||
tests/test/tprop2.pp svneol=native#text/plain
|
||||
tests/test/tpropdef.pp svneol=native#text/plain
|
||||
tests/test/trange1.pp svneol=native#text/plain
|
||||
tests/test/trange2.pp svneol=native#text/plain
|
||||
tests/test/trange3.pp svneol=native#text/plain
|
||||
|
@ -205,6 +205,9 @@ interface
|
||||
{# Returns true if p is a short string type }
|
||||
function is_shortstring(p : tdef) : boolean;
|
||||
|
||||
{# Returns true if p is any pointer def }
|
||||
function is_pointer(p : tdef) : boolean;
|
||||
|
||||
{# Returns true if p is a pchar def }
|
||||
function is_pchar(p : tdef) : boolean;
|
||||
|
||||
@ -856,6 +859,12 @@ implementation
|
||||
is_widechar(tarraydef(p).elementdef);
|
||||
end;
|
||||
|
||||
{ true if p is any pointer def }
|
||||
function is_pointer(p : tdef) : boolean;
|
||||
begin
|
||||
is_pointer:=(p.typ=pointerdef);
|
||||
end;
|
||||
|
||||
{ true if p is a pchar def }
|
||||
function is_pchar(p : tdef) : boolean;
|
||||
begin
|
||||
|
@ -222,6 +222,15 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
function has_implicit_default(p : tpropertysym) : boolean;
|
||||
|
||||
begin
|
||||
has_implicit_default:=
|
||||
(is_string(p.propdef) or
|
||||
is_real(p.propdef) or
|
||||
is_pointer(p.propdef));
|
||||
end;
|
||||
|
||||
function allow_default_property(p : tpropertysym) : boolean;
|
||||
|
||||
begin
|
||||
@ -656,6 +665,10 @@ implementation
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if has_implicit_default(p) then
|
||||
begin
|
||||
p.default:=0;
|
||||
end;
|
||||
if not is_record(astruct) and try_to_consume(_DEFAULT) then
|
||||
begin
|
||||
if not allow_default_property(p) then
|
||||
|
@ -944,7 +944,7 @@ begin
|
||||
DefValue :=PPropInfo(PropInfo)^.Default;
|
||||
DefFloatValue:=PSingle(@PPropInfo(PropInfo)^.Default)^;
|
||||
end;
|
||||
if (FloatValue<>DefFloatValue) or (DefValue=longint($80000000)) then
|
||||
if (FloatValue<>DefFloatValue) or (not HasAncestor and (DefValue=longint($80000000))) then
|
||||
begin
|
||||
Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name);
|
||||
WriteFloat(FloatValue);
|
||||
@ -985,9 +985,12 @@ begin
|
||||
if HasAncestor then
|
||||
DefStrValue := GetStrProp(Ancestor, PropInfo)
|
||||
else
|
||||
begin
|
||||
DefValue :=PPropInfo(PropInfo)^.Default;
|
||||
SetLength(DefStrValue, 0);
|
||||
end;
|
||||
|
||||
if StrValue <> DefStrValue then
|
||||
if (StrValue<>DefStrValue) or (not HasAncestor and (DefValue=longint($80000000))) then
|
||||
begin
|
||||
Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name);
|
||||
if Assigned(FOnWriteStringProperty) then
|
||||
@ -1002,9 +1005,12 @@ begin
|
||||
if HasAncestor then
|
||||
WDefStrValue := GetWideStrProp(Ancestor, PropInfo)
|
||||
else
|
||||
begin
|
||||
DefValue :=PPropInfo(PropInfo)^.Default;
|
||||
SetLength(WDefStrValue, 0);
|
||||
end;
|
||||
|
||||
if WStrValue <> WDefStrValue then
|
||||
if (WStrValue<>WDefStrValue) or (not HasAncestor and (DefValue=longint($80000000))) then
|
||||
begin
|
||||
Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name);
|
||||
WriteWideString(WStrValue);
|
||||
@ -1017,9 +1023,12 @@ begin
|
||||
if HasAncestor then
|
||||
UDefStrValue := GetUnicodeStrProp(Ancestor, PropInfo)
|
||||
else
|
||||
begin
|
||||
DefValue :=PPropInfo(PropInfo)^.Default;
|
||||
SetLength(UDefStrValue, 0);
|
||||
end;
|
||||
|
||||
if UStrValue <> UDefStrValue then
|
||||
if (UStrValue<>UDefStrValue) or (not HasAncestor and (DefValue=longint($80000000))) then
|
||||
begin
|
||||
Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name);
|
||||
WriteUnicodeString(UStrValue);
|
||||
|
116
tests/test/tpropdef.pp
Normal file
116
tests/test/tpropdef.pp
Normal file
@ -0,0 +1,116 @@
|
||||
program EmptyStringWriter;
|
||||
|
||||
{$mode objfpc}{$h+}
|
||||
|
||||
uses
|
||||
SysUtils, Classes;
|
||||
|
||||
type
|
||||
TMyComp = class(TComponent)
|
||||
public const
|
||||
cDefS = 'default';
|
||||
private
|
||||
fS: string;
|
||||
fT: string;
|
||||
fU: string;
|
||||
fSn: string;
|
||||
fTn: string;
|
||||
fUn: string;
|
||||
fSdef: string;
|
||||
function SStored: Boolean;
|
||||
function SnStored: Boolean;
|
||||
function SdefStored: Boolean;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
published
|
||||
property S: string read fS write fS stored SStored nodefault;
|
||||
property T: string read fT write fT nodefault;
|
||||
property U: string read fU write fU;
|
||||
property Sn: string read fSn write fSn stored SnStored nodefault;
|
||||
property Tn: string read fTn write fTn nodefault;
|
||||
property Un: string read fUn write fUn;
|
||||
property Sdef: string read fSdef write fSdef stored SdefStored nodefault;
|
||||
end;
|
||||
|
||||
{ TMyComp }
|
||||
|
||||
constructor TMyComp.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
|
||||
fS := cDefS;
|
||||
fSn := cDefS;
|
||||
fSdef := cDefS;
|
||||
end;
|
||||
|
||||
function TMyComp.SdefStored: Boolean;
|
||||
begin
|
||||
Result := fSdef <> cDefS;
|
||||
end;
|
||||
|
||||
function TMyComp.SnStored: Boolean;
|
||||
begin
|
||||
Result := fSn <> cDefS;
|
||||
end;
|
||||
|
||||
function TMyComp.SStored: Boolean;
|
||||
begin
|
||||
Result := fS <> cDefS;
|
||||
end;
|
||||
|
||||
const
|
||||
ExpectedOutput: RawByteString = #7#84#77#121#67#111#109#112#0#1#83#6#0#1#84#6#0#2#83#110#6#1#110#2#84#110#6#1#110#2#85#110#6#1#110#0#0;
|
||||
var
|
||||
xStream: TStream;
|
||||
xWriter: TWriter;
|
||||
C: TMyComp;
|
||||
xReader: TReader;
|
||||
B: Byte;
|
||||
I: Integer;
|
||||
begin
|
||||
xStream := TMemoryStream.Create;
|
||||
C := TMyComp.Create(nil);
|
||||
C.S := '';
|
||||
C.T := '';
|
||||
C.U := '';
|
||||
C.Sn := 'n';
|
||||
C.Tn := 'n';
|
||||
C.Un := 'n';
|
||||
//keep SDef to default value -> won't be streamed
|
||||
xWriter := TWriter.Create(xStream, 1024);
|
||||
xWriter.WriteComponent(C);
|
||||
C.Free;
|
||||
xWriter.Free;
|
||||
xStream.Position := 0;
|
||||
I := 1;
|
||||
while xStream.Read(B, 1) = 1 do
|
||||
begin
|
||||
if (I>Length(ExpectedOutput)) or (B<>Ord(ExpectedOutput[I])) then
|
||||
raise Exception.CreateFmt('Wrong output at character index: %d', [I]);
|
||||
Inc(I);
|
||||
end;
|
||||
xStream.Position := 0;
|
||||
C := TMyComp.Create(nil);
|
||||
xReader := TReader.Create(xStream, 1024);
|
||||
xReader.BeginReferences;
|
||||
xReader.ReadComponent(C);
|
||||
xReader.EndReferences;
|
||||
if C.S<>'' then
|
||||
raise Exception.Create('S invalid.');
|
||||
if C.T<>'' then
|
||||
raise Exception.Create('T invalid.');
|
||||
if C.U<>'' then
|
||||
raise Exception.Create('U invalid.');
|
||||
if C.Sn<>'n' then
|
||||
raise Exception.Create('Sn invalid.');
|
||||
if C.Tn<>'n' then
|
||||
raise Exception.Create('Tn invalid.');
|
||||
if C.Un<>'n' then
|
||||
raise Exception.Create('Un invalid.');
|
||||
if C.Sdef<>TMyComp.cDefS then
|
||||
raise Exception.Create('Un invalid.');
|
||||
C.Free;
|
||||
xReader.Free;
|
||||
xStream.Free;
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user