Browse Source

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

peter 17 years ago
parent
commit
7ffbfdc9c8
3 changed files with 54 additions and 6 deletions
  1. 1 0
      .gitattributes
  2. 34 6
      rtl/inc/wustrings.inc
  3. 19 0
      tests/webtbs/tw10825.pp

+ 1 - 0
.gitattributes

@@ -7981,6 +7981,7 @@ tests/webtbs/tw10800.pp svneol=native#text/plain
 tests/webtbs/tw10807.pp svneol=native#text/plain
 tests/webtbs/tw10807.pp svneol=native#text/plain
 tests/webtbs/tw1081.pp svneol=native#text/plain
 tests/webtbs/tw1081.pp svneol=native#text/plain
 tests/webtbs/tw10815.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/tw1090.pp svneol=native#text/plain
 tests/webtbs/tw1092.pp svneol=native#text/plain
 tests/webtbs/tw1092.pp svneol=native#text/plain
 tests/webtbs/tw1096.pp svneol=native#text/plain
 tests/webtbs/tw1096.pp svneol=native#text/plain

+ 34 - 6
rtl/inc/wustrings.inc

@@ -574,17 +574,23 @@ end;
 
 
 procedure fpc_WideStr_Concat_multi (var DestS:Widestring;const sarr:array of Widestring); compilerproc;
 procedure fpc_WideStr_Concat_multi (var DestS:Widestring;const sarr:array of Widestring); compilerproc;
 Var
 Var
-  lowstart,i  : Longint;
+  i           : Longint;
   p,pc        : pointer;
   p,pc        : pointer;
-  Size,NewLen,
-  OldDestLen  : SizeInt;
+  Size,NewLen : SizeInt;
+{$ifndef FPC_WINLIKEWIDESTRING}
+  lowstart    : longint;
   destcopy    : pointer;
   destcopy    : pointer;
+  OldDestLen  : SizeInt;
+{$else FPC_WINLIKEWIDESTRING}
+  DestTmp     : Widestring;
+{$endif FPC_WINLIKEWIDESTRING}
 begin
 begin
   if high(sarr)=0 then
   if high(sarr)=0 then
     begin
     begin
       DestS:='';
       DestS:='';
       exit;
       exit;
     end;
     end;
+{$ifndef FPC_WINLIKEWIDESTRING}
   destcopy:=nil;
   destcopy:=nil;
   lowstart:=low(sarr);
   lowstart:=low(sarr);
   if Pointer(DestS)=Pointer(sarr[lowstart]) then
   if Pointer(DestS)=Pointer(sarr[lowstart]) then
@@ -597,7 +603,9 @@ begin
         begin
         begin
           { if DestS is used somewhere in the middle of the expression,
           { if DestS is used somewhere in the middle of the expression,
             we need to make sure the original string still exists after
             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);
           destcopy:=pointer(dests);
           fpc_WideStr_Incr_Ref(destcopy);
           fpc_WideStr_Incr_Ref(destcopy);
           lowstart:=low(sarr);
           lowstart:=low(sarr);
@@ -629,6 +637,26 @@ begin
         end;
         end;
     end;
     end;
   fpc_WideStr_Decr_Ref(destcopy);
   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;
 end;
 
 
 {$endif STR_CONCAT_PROCS}
 {$endif STR_CONCAT_PROCS}
@@ -722,7 +750,7 @@ begin
   begin
   begin
     fpc_pchar_to_widestr := '';
     fpc_pchar_to_widestr := '';
     exit;
     exit;
-  end;  
+  end;
   l:=IndexChar(p^,-1,#0);
   l:=IndexChar(p^,-1,#0);
   widestringmanager.Ansi2WideMoveProc(P,fpc_PChar_To_WideStr,l);
   widestringmanager.Ansi2WideMoveProc(P,fpc_PChar_To_WideStr,l);
 end;
 end;
@@ -738,7 +766,7 @@ begin
       begin
       begin
         fpc_chararray_to_widestr := '';
         fpc_chararray_to_widestr := '';
         exit;
         exit;
-      end;  
+      end;
       i:=IndexChar(arr,high(arr)+1,#0);
       i:=IndexChar(arr,high(arr)+1,#0);
       if i = -1 then
       if i = -1 then
         i := high(arr)+1;
         i := high(arr)+1;

+ 19 - 0
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.