' PARSE%(1.0)  Parse Char String into SubStr Array     01/19/1996-06/01/2001
' --------------------------------------------------------------------------
' Copyright (C) 1996-2001 by Vladimir Veytsel                  www.davar.net

' Type ---------------------------------------------------------------------

'    Function [actionable]

' Description --------------------------------------------------------------

'    PARSE$ function parses its first character string parameter into array
'    of substrings specified by its second parameter, using its third
'    parameter as a delimiter of substrings, and returns the actual number
'    of resultant substrings parsed into the array.

' Declaration --------------------------------------------------------------

'    DECLARE FUNCTION PARSE%(Strng$,SubStr$(),Delim$)

' Parameters ---------------------------------------------------------------

'    Strng$   - Character string to be parsed
'    SubStr$  - Array of substrings for parsed values
'    Delim$   - Delimiter to be used for parsing

' Action -------------------------------------------------------------------

'    Input string is parsed into specified array of substrings.

' Value --------------------------------------------------------------------

'  - Actual number of parsed substrings in substring array.

'  - If input string is EMPTY;
'       then returned number of parsed substrings is 0.

'  - If delimiter is not found in input string,
'       then first array element contains entire input string.

'  - If max number of substring array elements is LESS than number of substrings,
'       then returned number of parsed substrings is NEGATIVE
'       (last array element contains in this case entire tail of input string).

'  - If max number of substring array elements is GREATER than number of substrings,
'       then remaining array elements contain empty strings.

' Notes --------------------------------------------------------------------

'  - If delimiter string is EMPTY,
'       then input string is checked for presence of ",":
'            If "," is found in input string
'               then "," is taken as substring delimiter;
'               else " " is taken as substring delimiter.

'  - If delimiter string is longer than 1,
'       then FIRST symbol is taken as delimiter.

'  - If delimiter is "*" (self-defined),
'       then FIRST symbol of string to be parsed is taken as delimiter.

'  - If " " is specified or is taken as substring delimiter,
'       then all successive SPACEs in the string to be parsed
'            are compressed to the single space.
'            This enables parameter alignment in batch files.

' Examples (for DIM SubStr(3) Array) ---------------------------------------

'    PARSE%(""             ,SubStr$(),"." )= 0   SubStr$()="","",""
'    PARSE%("A,BC,DEF"     ,SubStr$(),""  )= 3   SubStr$()="A","BC","DEF"
'    PARSE%("A BC DEF"     ,SubStr$(),""  )= 3   SubStr$()="A","BC","DEF"
'    PARSE%("A  BC   DEF"  ,SubStr$(),""  )= 3   SubStr$()="A","BC","DEF"
'    PARSE%("A"            ,SubStr$(),"." )= 1   SubStr$()="A","",""
'    PARSE%("A."           ,SubStr$(),"." )= 2   SubStr$()="A","",""
'    PARSE%("A.BC"         ,SubStr$(),"." )= 2   SubStr$()="A","BC",""
'    PARSE%("A.BC.DEF"     ,SubStr$(),"." )= 3   SubStr$()="A","BC","DEF"
'    PARSE%("A.BC.DEF."    ,SubStr$(),".:")=-3   SubStr$()="A","BC","DEF."
'    PARSE%(".A.BC.DEF"    ,SubStr$(),"*" )= 3   SubStr$()="A","BC","DEF"
'    PARSE%("A.BC.DEF.GHIJ",SubStr$(),"." )=-3   SubStr$()="A","BC","DEF.GHIJ"
'    PARSE%("A.BC.DEF.GHIJ",SubStr$(),":" )= 1   SubStr$()="A.BC.DEF.GHIJ","",""

' External Function --------------------------------------------------------

     DECLARE FUNCTION COMPRES$(Strng$,Chars$)

' Start Function -----------------------------------------------------------

     DEFINT A-Z     ' All defaulted variables are integer
     OPTION BASE 1  ' Default array indexation starts from "1"

     FUNCTION PARSE%(Strng$,SubStr$(1),Delim$) PUBLIC

' Copy Modifiable Parameters Into Working Variables ------------------------

     Work.Delim$=Delim$
     Work.Strng$=Strng$

' Form Actual Delimiter for Input String Parsing ---------------------------

     IF (LEN(Work.Delim$)>0) THEN
        Work.Delim$=LEFT$(Work.Delim$,1)
        IF (Work.Delim$="*") THEN
           Work.Delim$=LEFT$(Work.Strng$,1)
           Work.Strng$=MID$(Work.Strng$,2)
        END IF
     ELSE
        IF (INSTR(Work.Strng$,",")>0) THEN
           Work.Delim$=","  ' If string         contains ","
        ELSE
           Work.Delim$=" "  ' If string doesn't contain  ","
        END IF
     END IF

     IF (Work.Delim$=" ") THEN Work.Strng$=COMPRES$(Work.Strng$," ")

' Parse String into SubString Array Using Actual Delimiter -----------------

     SubStrings=UBOUND(SubStr$)
     IF (LEN(Work.Strng$)=0) THEN
        Act.SubStrs=0
     ELSE
        Delimiters=TALLY(Work.Strng$,Work.Delim$)+1
        IF (Delimiters=0) THEN
           SubStr$(1)=Work.Strng$ :I=2
        ELSE
           Act.SubStrs=MIN(SubStrings,Delimiters)
           Work.Strng$=Work.Strng$+Work.Delim$    ' Add post-last delimiter
           FOR I=1 TO Act.SubStrs
               J=INSTR(Work.Strng$,Work.Delim$)   ' Find next delimiter
               SubStr$(I)=LEFT$(Work.Strng$,J-1)  ' Get next substring
               Work.Strng$=MID$(Work.Strng$,J+1)  ' Trim current substring
           NEXT I
        END IF
     END IF

' Empty Remaining SubString Array Elements (if Any) ------------------------

     FOR I=MAX(1,I) TO SubStrings
         SubStr$(I)=""
     NEXT I

' Adjustment when Array Dimensions is Less Than Number of SubStrings -------

     IF (SubStrings<Delimiters) THEN
        SubStr$(SubStrings)=SubStr$(SubStrings)+Work.Delim$+LEFT$(Work.Strng$,LEN(Work.Strng$)-1)
        Act.SubStrs=-Act.SubStrs
     END IF

' Return Function Value to the Point of Invocation and Finish It -----------

     PARSE%=Act.SubStrs

     END FUNCTION
