PROGRAM   ChSptS23 ;
{$IFDEF VER70}{$IFDEF WINDOWS}   USES   WinCRT ;   {$ENDIF}{$ENDIF}
{$IFDEF VER80}   USES   WinCRT ;   {$ENDIF}      {--- Delphi1 }
{$IFDEF WIN32}   {$APPTYPE CONSOLE}   {$ENDIF}      {--- Delphi2,... }

{
!------------------------------------------------------------------------------
! Small toolbox
!------------------------------------------------------------------------------
}
{
!---------------
! G_MyStrings routines
!---------------
! G_MyStrings_Add
!---------------
}
VAR
   G_MyStrings : RECORD
      Count : Integer ;
      Items : ARRAY[0..99] of String[100];
   END;

{===== G_MyStrings_Add }

PROCEDURE   G_MyStrings_Add   ( {$IFDEF VER70}Const{$ENDIF} I_String : String );
BEGIN
   Inc ( G_MyStrings.Count );
   G_MyStrings.Items[G_MyStrings.Count-1] := I_String ;
END;

{
!------------------------------------------------------------------------------
! This program toolbox
!------------------------------------------------------------------------------
}
{
!---------------
! G_MyStrings routines
!---------------
! G_MyStrings_ChSplitString
!---------------
}
{===== G_MyStrings_ChSplitString }

PROCEDURE   G_MyStrings_ChSplitString   ( {$IFDEF VER70}Const{$ENDIF} I_String : String
                                        ; I_ChSeparator : Char );
LABEL
   L_LOOP_END ;
VAR
   L_FldBegin : Longint ;
   L_FldAEnd  : Longint ;
   L_FldLen   : Longint ;
BEGIN
   G_MyStrings.Count := 0 ;

   L_FldBegin := 1 ;
   L_FldAEnd  := 1 ;
   L_FldLen   := 0 ;

   {----- LOOP 1 , Search each field }
   WHILE TRUE DO BEGIN
      {----- LOOP 2 , Search separator }
      WHILE (L_FldAEnd <= Length(I_String)) and (I_String[L_FldAEnd] <> I_ChSeparator)
      DO BEGIN  Inc ( L_FldAEnd );  Inc(L_FldLen);  END;

      {----- If inside the string (separator found),... }
      IF L_FldAEnd <= Length(I_String)
      THEN BEGIN
         {----- Add field }
         G_MyStrings_Add ( Copy(I_String,L_FldBegin,L_FldLen) );

         {----- Prepare next search }
         Inc ( L_FldAEnd );
         L_FldBegin := L_FldAEnd ;
         L_FldLen   := 0 ;
      END
      ELSE GOTO L_LOOP_END ;      {--BREAK ;--}
   END;{while}
  L_LOOP_END:

   {----- One more at the end... }
   IF I_String <> ''
   THEN G_MyStrings_Add ( Copy(I_String,L_FldBegin,L_FldLen) );
END;


{===============}


FUNCTION   G_MyStrings_Join   ( I_Separator : String ) : String ;
VAR
   L_Result : String ;
   L_i : Integer ;
BEGIN
   L_Result := '' ;

   {----- LOOP , Concat items }
   FOR L_i := 0 TO G_MyStrings.Count -1 DO BEGIN
      IF L_i > 0 THEN L_Result := L_Result  +  I_Separator ;
      L_Result := L_Result  +  G_MyStrings.Items[L_i];
   END;{for}

   G_MyStrings_Join := L_Result ;
END;

{===== Test Speed variables }
LABEL
   G_TEST_SPEED ;
VAR
   G_SPEED_LoopMax  : Longint ;
   G_SPEED_i        : Longint ;
   G_SPEED_DummyStr : String ;

   GI_SPEED_TmpStr : String ;
   G_SPEED_ErrPos  : Integer ;

VAR
   G_i : Integer ;

BEGIN
   G_MyStrings.Count := 0 ;



   IF ParamStr(1) = 'TestSpeed' THEN GOTO G_TEST_SPEED ;      {--- Test speed ?  }



   G_MyStrings_ChSplitString ( '' , ',' );
   FOR G_i := 0 TO G_MyStrings.Count -1 DO BEGIN
      IF G_i > 0 THEN Write (   ';'   );
      Write (   G_MyStrings.Items[G_i]   );
   END;{i}
   WriteLn (   '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


   G_MyStrings_ChSplitString ( ',' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


   G_MyStrings_ChSplitString ( ',,' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


   G_MyStrings_ChSplitString ( 'Red,Green,Blue' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );
   WriteLn ;


   {---------------}


   G_MyStrings_ChSplitString ( 'a' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


   G_MyStrings_ChSplitString ( 'a,b' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


   G_MyStrings_ChSplitString ( 'a,b,c' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


   G_MyStrings_ChSplitString ( ',b,c' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


   G_MyStrings_ChSplitString ( 'a,,c' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


   G_MyStrings_ChSplitString ( 'a,b,' , ',' );
   WriteLn (   G_MyStrings_Join(';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );



   {***************  TEST SPEED  ***************}
  G_TEST_SPEED:

   {----- Get Parameter 2  ( optional ) : Loop max }
   G_SPEED_LoopMax := 10 ;      {--- Default value }
   GI_SPEED_TmpStr := ParamStr(2);
   IF GI_SPEED_TmpStr <> '' THEN BEGIN
      Val ( GI_SPEED_TmpStr , G_SPEED_LoopMax , G_SPEED_ErrPos );
      IF G_SPEED_ErrPos <> 0 THEN BEGIN
         WriteLn (   'ERROR: '  ,  'Number expected  ( Parameter 2 ).'   );
         HALT ( 1 );
      END;
   END;

   {----- LOOP , Call a split }
   FOR G_SPEED_i := 1 TO G_SPEED_LoopMax DO BEGIN
      G_MyStrings_ChSplitString (
'Red,Green,Blue,Red,,..........,Green..........,Blue..........,,Red,Green,Blue,,,' , ',' );
{12345678901234567890123456789012345678901234567890123456789012345678901234567890}
   END;{i}
END.
