* 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:
peter 2008-02-14 20:15:21 +00:00
parent a4eab5ca58
commit 7ffbfdc9c8
3 changed files with 54 additions and 6 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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
View 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.