PROGRAM   ChSptS97 ;
{$IFDEF VER80}   USES   WinCRT , Classes ;   {$ENDIF}      {--- Delphi1 }
{$IFDEF WIN32}   {$APPTYPE CONSOLE}   USES   Classes ;   {$ENDIF}      {--- Delphi2,... }

{
!------------------------------------------------------------------------------
! This program toolbox
!------------------------------------------------------------------------------
}
{
!---------------
! TStrings routines
!---------------
! TStrings_ChSplitString
!---------------
}
{===== TStrings_ChSplitString }

PROCEDURE   TStrings_ChSplitString   ( Self : TStrings
                                     ; {$IFDEF VER80}Const{$ENDIF} I_String : String
                                     ; I_ChSeparator : Char );
VAR
   L_AEnd     : Longint ;
   L_FldBegin : Longint ;
   L_FldAEnd  : Longint ;
BEGIN
   Self.BeginUpdate ;
   TRY
      Self.Clear ;

      IF I_String = '' THEN EXIT ;

      L_AEnd     := Length(I_String) + 1 ;
      L_FldBegin := 1 ;
      L_FldAEnd  := 1 ;

      {----- LOOP 1 , Search each field }
      REPEAT

         {----- LOOP 2 , Search separator }
         WHILE (L_FldAEnd < L_AEnd) and (I_String[L_FldAEnd] <> I_ChSeparator)
         DO Inc ( L_FldAEnd );

         {----- Add field }
         Self.Add ( Copy(I_String,L_FldBegin,L_FldAEnd-L_FldBegin) );

         {----- If inside the string (separator found),... }
         IF L_FldAEnd < L_AEnd
         THEN BEGIN
            {----- Prepare next search }
            Inc ( L_FldAEnd );
            L_FldBegin := L_FldAEnd ;
         END;

      UNTIL L_FldAEnd >= L_AEnd ;

      {----- One more at the end... }
      IF I_String[Length(I_String)] = I_ChSeparator
      THEN Self.Add ( '' );
   FINALLY
      Self.EndUpdate ;
   END;
END;


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


FUNCTION   TStrings_Join   ( Self : TStrings
                           ; I_Separator : String ) : String ;
VAR
   L_i : Integer ;
BEGIN
   Result := '' ;

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


VAR
   G_MyStrings : TStrings ;

   G_i : Integer ;

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


      TStrings_ChSplitString ( G_MyStrings , ',' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


      TStrings_ChSplitString ( G_MyStrings , ',,' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


      TStrings_ChSplitString ( G_MyStrings , 'Red,Green,Blue' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );
      WriteLn ;


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


      TStrings_ChSplitString ( G_MyStrings , 'a' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


      TStrings_ChSplitString ( G_MyStrings , 'a,b' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


      TStrings_ChSplitString ( G_MyStrings , 'a,b,c' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


      TStrings_ChSplitString ( G_MyStrings , ',b,c' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


      TStrings_ChSplitString ( G_MyStrings , 'a,,c' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );


      TStrings_ChSplitString ( G_MyStrings , 'a,b,' , ',' );
      WriteLn (   TStrings_Join(G_MyStrings,';')  ,  '<== ( '  ,  G_MyStrings.Count  ,  '  fields )'   );
   FINALLY
      G_MyStrings.Free ;
   END;
END.
