View Issue Details

IDProjectCategoryView StatusLast Update
0037898FPCRTLpublic2020-10-09 15:55
Reporterwp Assigned ToMichael Van Canneyt  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Fixed in Version3.3.1 
Summary0037898: Provide option TStringSplitOptions.ExcludeLastEmpty
DescriptionIn FPC, the TStringSplitOptions consists of the elements (None, ExcludeEmpty). In recent Delphi, however, there is a third option ExcludeLastEmpty.

The provided patch implements this new option also in FPC.
Additional InformationI added a test project which checks various cases of empty parts inside the test string passed to the Split() function. After application of the patch all tests are passed (like in Delphi).
TagsNo tags attached.
Fixed in Revision47069
FPCOldBugId
FPCTarget3.2.2
Attached Files

Activities

wp

2020-10-09 13:12

reporter  

sysutils_split_excludelastempty.patch (1,121 bytes)   
Index: rtl/objpas/sysutils/syshelp.inc
===================================================================
--- rtl/objpas/sysutils/syshelp.inc	(revision 47045)
+++ rtl/objpas/sysutils/syshelp.inc	(working copy)
@@ -1232,6 +1232,11 @@
       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 @@
       Inc(Len);
       end;
     end;
+
+  If (TStringSplitOptions.ExcludeLastEmpty=Options) then
+    if (Len > 0) and (Result[Len-1] = '') then
+      dec(Len);
+
   SetLength(Result,Len);
 end;
 
Index: rtl/objpas/sysutils/syshelph.inc
===================================================================
--- rtl/objpas/sysutils/syshelph.inc	(revision 47045)
+++ rtl/objpas/sysutils/syshelph.inc	(working copy)
@@ -52,7 +52,7 @@
   TCompareOptions = system.TCompareOptions;
 
 {$SCOPEDENUMS ON}
-  TStringSplitOptions = (None, ExcludeEmpty);
+  TStringSplitOptions = (None, ExcludeEmpty, ExcludeLastEmpty);
 {$SCOPEDENUMS OFF}
 
   { TStringHelper }
Test_StringSplitOptions.pas (3,449 bytes)   
program Test_StringSplitOptions;

{$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');
    exit;
  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], '"');
      exit;
    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);

  WriteLn;
  WriteLn('Press ENTER to quit...');
  ReadLn;
end.

Test_StringSplitOptions.pas (3,449 bytes)   

Michael Van Canneyt

2020-10-09 13:34

administrator   ~0126176

Checked & applied, thank you very much !
(added test as testspo.pp in testsuite)

wp

2020-10-09 15:55

reporter   ~0126184

Thanks. This was fast!

Issue History

Date Modified Username Field Change
2020-10-09 13:12 wp New Issue
2020-10-09 13:12 wp File Added: sysutils_split_excludelastempty.patch
2020-10-09 13:12 wp File Added: Test_StringSplitOptions.pas
2020-10-09 13:34 Michael Van Canneyt Assigned To => Michael Van Canneyt
2020-10-09 13:34 Michael Van Canneyt Status new => resolved
2020-10-09 13:34 Michael Van Canneyt Resolution open => fixed
2020-10-09 13:34 Michael Van Canneyt Fixed in Version => 3.3.1
2020-10-09 13:34 Michael Van Canneyt Fixed in Revision => 47069
2020-10-09 13:34 Michael Van Canneyt FPCTarget => 3.2.2
2020-10-09 13:34 Michael Van Canneyt Note Added: 0126176
2020-10-09 15:55 wp Status resolved => closed
2020-10-09 15:55 wp Note Added: 0126184