From 7ffbfdc9c82d646e678d9ff98ada0fd26989c49b Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 14 Feb 2008 20:15:21 +0000 Subject: [PATCH] * 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 - --- .gitattributes | 1 + rtl/inc/wustrings.inc | 40 ++++++++++++++++++++++++++++++++++------ tests/webtbs/tw10825.pp | 19 +++++++++++++++++++ 3 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 tests/webtbs/tw10825.pp diff --git a/.gitattributes b/.gitattributes index 67b78f630a..354d47ed7d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/rtl/inc/wustrings.inc b/rtl/inc/wustrings.inc index d31f36f72e..37fa32a797 100644 --- a/rtl/inc/wustrings.inc +++ b/rtl/inc/wustrings.inc @@ -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; diff --git a/tests/webtbs/tw10825.pp b/tests/webtbs/tw10825.pp new file mode 100644 index 0000000000..80b1ea5630 --- /dev/null +++ b/tests/webtbs/tw10825.pp @@ -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.