mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-02 01:30:46 +02:00
* fix widestring concat multi for winlikewidestring. The
append optimization can't be used in this can because the trick with refcnt is not supported git-svn-id: trunk@10327 -
This commit is contained in:
parent
a4eab5ca58
commit
7ffbfdc9c8
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -7981,6 +7981,7 @@ tests/webtbs/tw10800.pp svneol=native#text/plain
|
||||
tests/webtbs/tw10807.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1081.pp svneol=native#text/plain
|
||||
tests/webtbs/tw10815.pp svneol=native#text/plain
|
||||
tests/webtbs/tw10825.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1090.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1092.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1096.pp svneol=native#text/plain
|
||||
|
@ -574,17 +574,23 @@ end;
|
||||
|
||||
procedure fpc_WideStr_Concat_multi (var DestS:Widestring;const sarr:array of Widestring); compilerproc;
|
||||
Var
|
||||
lowstart,i : Longint;
|
||||
i : Longint;
|
||||
p,pc : pointer;
|
||||
Size,NewLen,
|
||||
OldDestLen : SizeInt;
|
||||
Size,NewLen : SizeInt;
|
||||
{$ifndef FPC_WINLIKEWIDESTRING}
|
||||
lowstart : longint;
|
||||
destcopy : pointer;
|
||||
OldDestLen : SizeInt;
|
||||
{$else FPC_WINLIKEWIDESTRING}
|
||||
DestTmp : Widestring;
|
||||
{$endif FPC_WINLIKEWIDESTRING}
|
||||
begin
|
||||
if high(sarr)=0 then
|
||||
begin
|
||||
DestS:='';
|
||||
exit;
|
||||
end;
|
||||
{$ifndef FPC_WINLIKEWIDESTRING}
|
||||
destcopy:=nil;
|
||||
lowstart:=low(sarr);
|
||||
if Pointer(DestS)=Pointer(sarr[lowstart]) then
|
||||
@ -597,7 +603,9 @@ begin
|
||||
begin
|
||||
{ if DestS is used somewhere in the middle of the expression,
|
||||
we need to make sure the original string still exists after
|
||||
we empty/modify DestS }
|
||||
we empty/modify DestS.
|
||||
This trick only works with reference counted strings. Therefor
|
||||
this optimization is disabled for WINLIKEWIDESTRING }
|
||||
destcopy:=pointer(dests);
|
||||
fpc_WideStr_Incr_Ref(destcopy);
|
||||
lowstart:=low(sarr);
|
||||
@ -629,6 +637,26 @@ begin
|
||||
end;
|
||||
end;
|
||||
fpc_WideStr_Decr_Ref(destcopy);
|
||||
{$else FPC_WINLIKEWIDESTRING}
|
||||
{ First calculate size of the result so we can do
|
||||
a single call to SetLength() }
|
||||
NewLen:=0;
|
||||
for i:=low(sarr) to high(sarr) do
|
||||
inc(NewLen,length(sarr[i]));
|
||||
SetLength(DestTmp,NewLen);
|
||||
pc:=pwidechar(DestTmp);
|
||||
for i:=low(sarr) to high(sarr) do
|
||||
begin
|
||||
p:=pointer(sarr[i]);
|
||||
if assigned(p) then
|
||||
begin
|
||||
Size:=length(widestring(p));
|
||||
Move(p^,pc^,(Size+1)*sizeof(WideChar));
|
||||
inc(pc,size*sizeof(WideChar));
|
||||
end;
|
||||
end;
|
||||
DestS:=DestTmp;
|
||||
{$endif FPC_WINLIKEWIDESTRING}
|
||||
end;
|
||||
|
||||
{$endif STR_CONCAT_PROCS}
|
||||
@ -722,7 +750,7 @@ begin
|
||||
begin
|
||||
fpc_pchar_to_widestr := '';
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
l:=IndexChar(p^,-1,#0);
|
||||
widestringmanager.Ansi2WideMoveProc(P,fpc_PChar_To_WideStr,l);
|
||||
end;
|
||||
@ -738,7 +766,7 @@ begin
|
||||
begin
|
||||
fpc_chararray_to_widestr := '';
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
i:=IndexChar(arr,high(arr)+1,#0);
|
||||
if i = -1 then
|
||||
i := high(arr)+1;
|
||||
|
19
tests/webtbs/tw10825.pp
Normal file
19
tests/webtbs/tw10825.pp
Normal file
@ -0,0 +1,19 @@
|
||||
program stringconcat;
|
||||
//compile with -gh
|
||||
|
||||
{$ifdef FPC}{$mode objfpc}{$h+}{$INTERFACES CORBA}{$endif}
|
||||
{$ifdef mswindows}{$apptype console}{$endif}
|
||||
uses
|
||||
{$ifdef FPC}{$ifdef linux}cthreads,{$endif}{$endif}
|
||||
sysutils;
|
||||
|
||||
var
|
||||
wstr1: widestring;
|
||||
begin
|
||||
winwidestringalloc:= false;
|
||||
//crash exist with winwidestringalloc also but with bigger application only
|
||||
wstr1:= '123';
|
||||
wstr1:= 'ABC'+wstr1+'abc';
|
||||
writeln(wstr1);
|
||||
flush(output);
|
||||
end.
|
Loading…
Reference in New Issue
Block a user