*------------- Telecommunications & Signal Processing Lab --------------
*                          McGill University
*
*
* Module:
*     SUBROUTINE FNDPAR (LINE, KEYTAB, NOKEY, TOKEN, NCT, N)
*
*
* Purpose:
*     Separate keyword/token strings
*
*
* Description:
*     The input string has syntax of the following form:
*       Keyword1 = Token1 [,] Keyword2 [,] = Token2 [,] ...
*     String Processing:
*     1) This routine looks for a separator consisting of a comma
*        and/or whitespace not in parentheses or quotes.  This
*        separator separates the input string into a left part and a
*        right part.  If no separator is found, the left part is the
*        whole string and the right part is null.  The left part will
*        be further processed.  The input string is replaced by the
*        right part.
*     2) The left part of the input string is parsed into a keyword
*        string and a token string separated by an equal sign.  If no
*        equal sign is found, the token string is considered to be
*        null.
*     Keyword Processing:
*     1) White space (blanks, tabs or nulls) surrounding the keyword is
*        removed.  The keyword is translated to uppercase and compared
*        with a table of keywords.  The index of the keyword in the
*        table is returned.
*     2) The keyword table is a character array containing candidate
*        keyword strings.
*        a) An optional asterisk ('*') is used to indicate the minimum
*           number of characters needed for a match.
*        b) A second asterisk can be used to indicate that characters
*           after this point need not match.
*        c) The special keyword table entry '***' can be used to match
*           any keyword in the input string.  For this case both the
*           keyword and the token parts of the input string are
*           are returned in the token string.  Normally such an entry
*           would be the last entry in the keyword table.  This feature
*           can be used to trap unmatched keywords for special action.
*     3) After searching the given table of keywords without success,
*        an additional comparison is made with the keywords HELP and ?.
*        If the input matches either of these keywords, the list of the
*        given keywords is printed on the standard output unit.  A
*        match with HELP or ? results in the keyword index being set to
*        -1 and the TOKEN string being returned as null.
*     Token String Processing:
*     1) White space surrounding the token string is removed.  Outer
*        parentheses surrounding the remaining token string are also
*        removed.  Note that white space is not removed inside the
*        parentheses.
*     2) If the match occured with the special keyword table entry
*        '***', the token string is set to the keyword string together
*        with the token string if supplied.  The output string is an
*        edited (leading and trailing white space removed, and white
*        space surrounding an equal sign collapsed) version of the
*        input string before the comma/white space delimiter.  This
*        feature can be used to trap unmatched keywords for special
*        treatment.
*
*
* Parameters:
* C <-> LINE   - Input string.  On return, LINE is equal to the input
*                string with the decoded first part removed.  The
*                substrings of LINE between comma or white space
*                separators can be up to 1024 characters long.
* C ->  KEYTAB - Table of keywords.  These should be in uppercase.
* I ->  NOKEY  - Number of keywords
* C <-  TOKEN  - Token string.  Leading and trailing white space
*                (blanks, tabs or nulls) are removed.  In addition,
*                redundant parentheses are removed.  TOKEN is returned
*                as blanks if no match to a keyword is found or if the
*                HELP or ? keywords are specified.  The maximum number
*                of characters returned is 1024.
* I <-  NCT    - Number of characters in the token string.  NCT is zero
*                if no match to a keyword is found or if the HELP or ?
*                keywords are specified.
* I <-  N      - Keyword index,
*                1 to NOKEY - Normal returned value
*                         0 - No match
*                        -1 - HELP or ?
*
*
* Author / revision:
*     P. Kabal
*     $Revision: 1.4 $  $Date: 1995/03/08 15:36:48 $
*
*
*-----------------------------------------------------------------------

      SUBROUTINE FNDPAR (LINE, KEYTAB, NOKEY, TOKEN, NCT, N)


      INTEGER NOKEY,NCT,N
      INTEGER LK,LT,LS,NN
      INTEGER KEYUPC

      CHARACTER*(*) LINE,TOKEN,KEYTAB(NOKEY)
      CHARACTER*1024 KEYWRD,STOKEN,STRING
      CHARACTER*4 HLPTAB(2)

      DATA HLPTAB/'HELP', '?'/


* Find a KEYWORD=TOKEN string
* Note that LINE is written back into LINE
      CALL PPARST(LINE,KEYWRD,LK,STOKEN,LT,STRING,LS,LINE)

* Find the keyword match
      N=KEYUPC(KEYWRD(1:LK),KEYTAB,NOKEY)

* Keyword not found (try HELP and ?)
      IF (N.EQ.0) THEN
        NN=KEYUPC(KEYWRD(1:LK),HLPTAB,2)
        IF (NN.NE.0) THEN
          WRITE (UNIT=*,FMT=*) 'Keywords:'
          CALL PRMENU(KEYTAB,NOKEY,21)
          IF (LT.GT.0 .AND. LT.LE.38) THEN
            CALL MESS('FNDPAR - Unexpected characters: "'//
     -                STOKEN(1:LT)//'"')
          ELSE IF (LT.GT.0) THEN
            CALL MESS('FNDPAR - Unexpected characters: "'//
     -                STOKEN(1:35)//'..."')
          END IF
          N=-1

* Error messages
        ELSE IF (LS.GT.0 .AND. LS.LE.35) THEN
          CALL MESS('FNDPAR - Invalid keyword in string: "'//
     -              STRING(1:LS)//'"')

        ELSE IF (LS.GT.0) THEN
          CALL MESS('FNDPAR - Invalid keyword in string: "'//
     -              STRING(1:32)//'..."')

        ELSE
* Note: The null keyword message will be printed for all except
*       trailing comma separators, e.g.
*         ",AAA,BBB"  Null keyword message
*         "AAA,,BBB"  Null keyword message
*         "AAA,BBB,"  No message
          CALL MESS('FNDPAR - Null keyword in string')

        END IF

        TOKEN=' '
        NCT=0

* Catch-all keyword check
      ELSE IF (KEYTAB(N).EQ.'***') THEN

        CALL STCOPY(STRING(1:LS),TOKEN,NCT)

      ELSE

* Process the token string
* Remove outer parentheses from the token string
        CALL STRPAR(STOKEN(1:LT),TOKEN,NCT)

      END IF


      RETURN

      END
