Ver código fonte

* synchronized with trunk

git-svn-id: branches/wasm@47071 -
nickysn 4 anos atrás
pai
commit
b637a9652d

+ 1 - 0
.gitattributes

@@ -16170,6 +16170,7 @@ tests/test/units/sysutils/tbytesof.pp svneol=native#text/pascal
 tests/test/units/sysutils/tdirex.pp svneol=native#text/plain
 tests/test/units/sysutils/tencodingerrors.pp svneol=native#text/pascal
 tests/test/units/sysutils/tencodingtest.pp svneol=native#text/pascal
+tests/test/units/sysutils/testspo.pp svneol=native#text/plain
 tests/test/units/sysutils/texec1.pp svneol=native#text/plain
 tests/test/units/sysutils/texec2.pp svneol=native#text/plain
 tests/test/units/sysutils/texpfncase.pp svneol=native#text/plain

+ 6 - 6
compiler/x86_64/nx64flw.pas

@@ -324,8 +324,8 @@ procedure tx64tryfinallynode.pass_generate_code;
     { i32913 - if the try..finally block is also inside a try..finally or
       try..except block, make a note of any Exit calls so all necessary labels
       are generated. [Kit] }
-    if (fc_exit in flowcontrol) and (fc_inflowcontrol in oldflowcontrol) then
-      Include(oldflowcontrol, fc_exit);
+    if ((flowcontrol*[fc_exit,fc_break,fc_continue])<>[]) and (fc_inflowcontrol in oldflowcontrol) then
+      oldflowcontrol:=oldflowcontrol+(flowcontrol*[fc_exit,fc_break,fc_continue]);
 
     flowcontrol:=[fc_inflowcontrol];
     { generate finally code as a separate procedure }
@@ -440,8 +440,8 @@ procedure tx64tryexceptnode.pass_generate_code;
     { i32913 - if the try..finally block is also inside a try..finally or
       try..except block, make a note of any Exit calls so all necessary labels
       are generated. [Kit] }
-    if (fc_exit in flowcontrol) and (fc_inflowcontrol in oldflowcontrol) then
-      Include(oldflowcontrol, fc_exit);
+    if ((flowcontrol*[fc_exit,fc_break,fc_continue])<>[]) and (fc_inflowcontrol in oldflowcontrol) then
+      oldflowcontrol:=oldflowcontrol+(flowcontrol*[fc_exit,fc_break,fc_continue]);
 
     flowcontrol:=[fc_inflowcontrol];
     { on statements }
@@ -536,8 +536,8 @@ errorexit:
     { i32913 - if the try..finally block is also inside a try..finally or
       try..except block, make a note of any Exit calls so all necessary labels
       are generated. [Kit] }
-    if (fc_exit in flowcontrol) and (fc_inflowcontrol in oldflowcontrol) then
-      Include(oldflowcontrol, fc_exit);
+    if ((flowcontrol*[fc_exit,fc_break,fc_continue])<>[]) and (fc_inflowcontrol in oldflowcontrol) then
+      oldflowcontrol:=oldflowcontrol+(flowcontrol*[fc_exit,fc_break,fc_continue]);
 
     { restore the control flow labels }
     current_procinfo.CurrExitLabel:=oldCurrExitLabel;

+ 10 - 0
rtl/objpas/sysutils/syshelp.inc

@@ -1232,6 +1232,11 @@ begin
       Inc(Len);
       end;
     end;
+
+  if (TStringSplitOptions.ExcludeLastEmpty=Options) then
+    if (Len > 0) and (Result[Len-1] = '') then
+      dec(Len);
+
   SetLength(Result,Len);
 end;
 
@@ -1318,6 +1323,11 @@ begin
       Inc(Len);
       end;
     end;
+
+  If (TStringSplitOptions.ExcludeLastEmpty=Options) then
+    if (Len > 0) and (Result[Len-1] = '') then
+      dec(Len);
+
   SetLength(Result,Len);
 end;
 

+ 1 - 1
rtl/objpas/sysutils/syshelph.inc

@@ -52,7 +52,7 @@ Type
   TCompareOptions = system.TCompareOptions;
 
 {$SCOPEDENUMS ON}
-  TStringSplitOptions = (None, ExcludeEmpty);
+  TStringSplitOptions = (None, ExcludeEmpty, ExcludeLastEmpty);
 {$SCOPEDENUMS OFF}
 
   { TStringHelper }

+ 93 - 0
tests/test/units/sysutils/testspo.pp

@@ -0,0 +1,93 @@
+program testspo;
+
+{$APPTYPE CONSOLE}
+
+uses
+  SysUtils;
+
+{$IFNDEF FPC}
+type
+  TStringArray = TArray<string>;
+{$ENDIF}
+
+procedure Test(TestString: String; const Expected: TStringArray; Options: TStringSplitOptions;
+  UseChar: Boolean);
+var
+  sa: TStringArray;
+  i: Integer;
+begin
+  Write('Testing "', TestString, '"...');
+
+  {$IFDEF FPC}
+  if UseChar then
+    sa := TestString.Split(',', Options)
+  else
+  {$ENDIF}
+    sa := TestString.Split([','], Options);
+
+  if Length(sa) <> Length(Expected) then
+  begin
+    WriteLn('  -->  Length difference');
+    Halt(1);
+  end;
+  for i := Low(sa) to High(sa) do
+    if sa[i] <> Expected[i] then
+    begin
+      WriteLn('  --> Difference found at pos ', i, ': "', sa[i], '" vs "', Expected[i], '"');
+      Halt(1);
+    end;
+  WriteLn('  --> ok');
+end;
+
+begin
+  {$IFDEF FPC}
+  WriteLn('Testing ExcludeLastEmpty with individual separator');
+  WriteLn('--------------------------------------------------');
+  Test('a,b,c', ['a', 'b', 'c'], TStringSplitOptions.ExcludeLastEmpty, true);
+  Test('a,b,', ['a', 'b'], TStringSplitOptions.ExcludeLastEmpty, true);
+  Test('a,,c', ['a', '', 'c'], TStringSplitOptions.ExcludeLastEmpty, true);
+  Test(',b,c', ['', 'b', 'c'], TStringSplitOptions.ExcludeLastEmpty, true);
+  Test('a,,', ['a', ''], TStringSplitOptions.ExcludeLastEmpty, true);
+  Test(',b,', ['','b'], TStringSplitOptions.ExcludeLastEmpty, true);
+  Test(',,', ['', ''], TStringSplitOptions.ExcludeLastEmpty, true);
+
+  WriteLn;
+  WriteLn('Testing ExcludeEmpty with individual separator');
+  WriteLn('----------------------------------------------');
+  Test('a,b,c', ['a', 'b', 'c'], TStringSplitOptions.ExcludeEmpty, true);
+  Test('a,b,,', ['a', 'b'], TStringSplitOptions.ExcludeEmpty, true);
+  Test('a,,c', ['a', 'c'], TStringSplitOptions.ExcludeEmpty, true);
+  Test(',b,c', ['b', 'c'], TStringSplitOptions.ExcludeEmpty, true);
+  Test('a,,', ['a'], TStringSplitOptions.ExcludeEmpty, true);
+  Test(',b,', ['b'], TStringSplitOptions.ExcludeEmpty, true);
+  Test(',,', [], TStringSplitOptions.ExcludeEmpty, true);
+  {$ENDIF}
+
+  WriteLn('Testing ExcludeLastEmpty with set separators');
+  WriteLn('--------------------------------------------');
+  Test('a,b,c', ['a', 'b', 'c'], TStringSplitOptions.ExcludeLastEmpty, false);
+  Test('a,b,', ['a', 'b'], TStringSplitOptions.ExcludeLastEmpty, false);
+  Test('a,,c', ['a', '', 'c'], TStringSplitOptions.ExcludeLastEmpty, false);
+  Test(',b,c', ['', 'b', 'c'], TStringSplitOptions.ExcludeLastEmpty, false);
+  Test('a,,', ['a', ''], TStringSplitOptions.ExcludeLastEmpty, false);
+  Test(',b,', ['','b'], TStringSplitOptions.ExcludeLastEmpty, false);
+  Test(',,', ['', ''], TStringSplitOptions.ExcludeLastEmpty, false);
+
+  WriteLn;
+  WriteLn('Testing ExcludeEmpty with set separators');
+  WriteLn('----------------------------------------');
+  Test('a,b,c', ['a', 'b', 'c'], TStringSplitOptions.ExcludeEmpty, false);
+  Test('a,b,,', ['a', 'b'], TStringSplitOptions.ExcludeEmpty, false);
+  Test('a,,c', ['a', 'c'], TStringSplitOptions.ExcludeEmpty, false);
+  Test(',b,c', ['b', 'c'], TStringSplitOptions.ExcludeEmpty, false);
+  Test('a,,', ['a'], TStringSplitOptions.ExcludeEmpty, false);
+  Test(',b,', ['b'], TStringSplitOptions.ExcludeEmpty, false);
+  Test(',,', [], TStringSplitOptions.ExcludeEmpty, false);
+  
+{$IFNDEF FPC}
+  WriteLn;
+  WriteLn('Press ENTER to quit...');
+  ReadLn;
+{$ENDIF}  
+end.
+

+ 38 - 2
tests/webtbs/tw35841.pp

@@ -1,9 +1,9 @@
 { %norun }
 {$mode objfpc}
-procedure p;
+procedure p1;
   begin
     try
-      writeln
+      writeln;
     except
       try
         writeln;
@@ -14,5 +14,41 @@ procedure p;
     end;
   end;
 
+
+procedure p2;
+  var
+    i : longint;
+  begin
+    for i:=1 to 10 do
+      try
+        writeln;
+      except
+        try
+          writeln;
+          break;
+        finally
+          writeln;
+        end;
+      end;
+  end;
+
+procedure p3;
+  var
+    i : longint;
+  begin
+    for i:=1 to 10 do
+      try
+        writeln;
+      except
+        try
+          writeln;
+          continue;
+        finally
+          writeln;
+        end;
+      end;
+  end;
+
+
 begin
 end.