	INTEGER*4 FUNCTION Q_STRING
	1	( STRING, QUALIFIER, ABBREV_S, QUAL_STRING, QUAL_STR_S )
C   ---------------------------------------------------------------------------
C   Q_STRING - The function of this subroutine is to search the specified
C	string for the specified slash qualifier.  If a match is found the
C	qualifier is removed from the string and replaced with blanks.  If 
C	there was a string attached to the qualifier (via '=' or ':'), then
C	the qualifier string is returned.
C
C	If mulitple occurences of the qualifier appear in the passed string
C	then the last occurence will be returned and the previous entries
C	blanked out.
C
C	It is assumed that the qualifier has a negative value associated with
C	it, which is be express as /NOqualifier.  This form of the qualifier
C	is also considered a match and proper status to indicate if positive
C	or negative response was returned.
C
C	If an ambiguous qualifier is found (abbreviation match but wrong 
C	spelling after abbrev limit) an ambiguous error status is returned,
C	the entire qualifier string and substring are returned in the qualifier
C	string return parameter, and the ambiguous qualifier is blanked from
C	the input string.
C
C	  Input string:
C	    rrrrrrrrrrrrrrrr/QUALIFIER=QUAL_STRING rrrrrrrrrrrrrrrr
C	  Qutput string:
C	    RRRRRRRRRRRRRRRR                       RRRRRRRRRRRRRRRR
C
C	Special Note:  The input string will be translated to all upper case
C		       and all tabs will be replaced with a single blank.
C
C   Calling Procedure:
C
C	status = Q_STRING
C	1	( string, qualifier, abbrev_size, qual_string [,qual_str_s] )
C
C   Entry Conditions:
C
C	string - must be the address of a string descriptor which contains
C		the input string to be scanned for the qualifier.  String will
C		be translated to upper case and all tabs will be replaced with
C		a single blank.  Any qualifiers found will be blanked out of
C		the string.
C
C	qualifier - must be the address of a string descriptor which contains
C		the qualifier (including the '/').  The qualifier must be
C		passed as an upper case string.
C
C	abbrev_size - must be the address of a numeric value (integer*4) which
C		specifies how many characters of the qualifier are required
C		to make a match.
C
C   Exit conditions:
C
C	qual_string - Must be the address of a string descriptor pointing to
C		a string storage area large enough to hold the qualifier
C		associated string value.  The string associated with the
C		qualifier will be stored there if it is found.
C
C		If an ambiguous qualifier is found both the qualifier and 
C		the qualifier string will be returned in this parameter.
C
C	qual_str_s - Optional address of an Integer*4 variable where the
C		length of the qual_string stored will be returned.
C
C	status - will contain the completion status of the function.
C		= 0 -- qualifier not found.
C		= 1 -- good completion; qualifier string returned.
C		= 2 -- ambiguous qualifier found.  The entire qualifier and 
C		       qualifier string are returned in the qualifier string
C		       return parameter.
C		= 3 -- qualifier found; no qualifier string available to 
C		       return.
C		= 11 - good completion; negative form of qualifier w/qualifier
C		       string returned.
C		= 13 - negative form of qualifier found; no qualifier string
C		       available to return.
C
C   ---------------------------------------------------------------------------
C
	IMPLICIT INTEGER*4 (A-Z)
C
	PARAMETER	NEG_QUAL_Z=67		! Maximum number of characters
C						!  allowed in the negative form
C						!  of the qualifier including
C						!  the '/'.
C
	CHARACTER	STRING*(*)		! Input string to search.
	CHARACTER	QUALIFIER*(*)		! Positive form of qualifier 
C						!  passed as input to search
C						!  the input string for.  This
C						!  must include the '/' at the
C						!  beginning.
	CHARACTER	QUAL_STRING*(*)		! Return parameter where the
C						!  qualifier string is returned
C
	CHARACTER	NEG_QUAL*(NEG_QUAL_Z)	! Temp string used to form the
C						!  the negative form of the
C						!  qualifier ('/NOqualifier').
C
	INTEGER*4	ABBREV_S		! Number of characters in the
C						!  qualifier which must be 
C						!  present to indicate a match
C						!  This includes the '/'.
C
	INTEGER*4	STATUS			! General return status area.
	INTEGER*4	Q_STRING_NEG		! 1/2 of return status.  used
C						!  to indicate that a negative
C						!  form of the qualifier was
C						!  found.  later added to
C						!  Q_STRING_TMP
	INTEGER*4	Q_STRING_TMP		! 1/2 of return status.  used
C						!  to indicate if qualifier
C						!  was found and if qualifier
C						!  string was returned.
	INTEGER*4	P1, P2			! Substring pointers used to
C						!  isolate the qualifier
C						!  return string.
	INTEGER*4	Q1, Q2, Q3		! Substring pointers used to
C						!  indicate the beginning of
C						!  found qualifier, the end
C						!  of the found qualifier, and
C						!  the end of the qualifer 
C						!  return string.
	INTEGER*4	N1			! Substring pointer to indicate
C						!  the location of a found 
C						!  negative form of the 
C						!  qualifer.
C
C   ---------------------------------------------------------------------------
C
C   Translate all characters to upper case.
C
	STATUS = Q_UPCASE( STRING, STRING )
C
C   Initialize return status.
C
	Q_STRING = 0
C
C   Determine how many return qualifiers have been passed and init return args
C
	IF ( LIB_NARGS() .GE. 5 ) THEN
	    QUAL_STR_S = 0
	ENDIF
	QUAL_STRING = ' '
C
C   ---------------------------------------------------------------------------
C
C   Determine what the negative form of the qualifier looks like.
C
	Q_S = LEN( QUALIFIER )
C
C   If qualifier is only 1 char long; form negative as '/NO'
C
	IF ( Q_S .EQ. 1 ) THEN
	    NEG_QUAL = QUALIFIER(1:1) // 'NO'
C
C   If qualifier is too large to fit negative form tmp space; build to fit.
C
	ELSEIF ( Q_S .GT. (NEG_QUAL_Z - 2) ) THEN
		NEG_QUAL = QUALIFIER(1:1) // 'NO' // QUALIFIER(2:NEG_QUAL_Z-2)
C
C   Build negative form of qualifier using entier passed qualifier.
C
	ELSE
		NEG_QUAL = QUALIFIER(1:1) // 'NO' // QUALIFIER(2:Q_S)
	ENDIF
C
C   ---------------------------------------------------------------------------
C
C   Establish the loop to find all occurences of the qualifier.
C
	DO WHILE (.TRUE.)
	    Q_STRING_TMP = 0				! Init 1/2 rtn status
	    Q_STRING_NEG = 0				! Init 1/2 rtn status
C
C	  Determine if there are any occurences of the qualifier in the string.
C
	    Q1 = INDEX( STRING, QUALIFIER(1:ABBREV_S) )		! check pos
	    N1 = INDEX( STRING, NEG_QUAL(1:ABBREV_S+2) )	! check neg
C
C	  If neither positive form or negative form; exit loop and return.
C
	    IF ( (Q1 + N1) .EQ. 0 ) GOTO 1999
C
C	  Determine if the string is positive or negative form of qualifier.
C
	    IF ( Q1 .EQ. 0 ) Q1 = 99999999
	    IF ( N1 .EQ. 0 ) N1 = 99999999
	    IF ( Q1 .GT. N1 ) THEN
		Q_STRING_NEG = 10			! set return status
		Q1 = N1					! store start loc
	    ENDIF
C
C	  Isolate the qualifier ( space, tab, '/', end-of-string).
C
	    Q3 = Q1 - 1
	    STATUS = GET_STRING( STRING, Q1, Q3 )   ! look for space, tab, eol
	    Q2 = INDEX( STRING(Q1+1:Q3), QUALIFIER(1:1) ) ! look for '/'
C
C	  Determine if '/' or space,tab,eol is first found.
C
	    IF ( Q2 .NE. 0 ) THEN
		    Q2 = Q2 + Q1
		    IF ( Q2 .LT. Q3 ) THEN
			    Q3 = Q2 - 1
		    ENDIF
	    ENDIF
C
C	  See if the qualifier has a value attached.
C
	    P1 = INDEX( STRING(Q1:Q3), '=' )	! look for '='
	    P2 = INDEX( STRING(Q1:Q3), ':' )	! look for ':'
	    IF ( P1 .EQ. 0 ) P1 = P2		! adjust for '=' not found
	    IF ( P2 .EQ. 0 ) P2 = P1		! adjust for ':' not found
	    P1 = MIN( P1, P2 )			! determine which is closest.
	    IF ( P1 .NE. 0 ) THEN		! see if either found
		P1 = P1 + (Q1-1)		! calc delimiter loc in string
		P2 = Q3				! get end string position
		Q2 = P1 - 1			! calc end of qualifier
		P1 = P1 + 1			! calc begin qual str loc.
		IF ( P1 .GT. P2 ) THEN		! if no string, then
		    Q_STRING_TMP = 3		!   set return status w/no str
		ELSE				! else
		    Q_STRING_TMP = 1		!   set return status w/string
		ENDIF				! endif
	    ELSE	
C
C	      No string attached to qualifier; no string to return.
C
		Q2 = Q3				! set end of qualifier loc
		Q_STRING_TMP = 3		! set return status w/ no str
	    ENDIF
C
C	  Verify that the qualifier matches the spelling.
C
	    IF ( Q_STRING_NEG .EQ. 0 ) THEN
		IF ( STRING(Q1:Q2) .NE. QUALIFIER(1:Q2-Q1+1) ) THEN
		    Q_STRING_TMP = 2
		ENDIF
	    ELSE
		IF ( STRING(Q1:Q2) .NE. NEG_QUAL(1:Q2-Q1+1) ) THEN
		    Q_STRING_TMP = 2
		    Q_STRING_NEG = 0
		ENDIF
	    ENDIF
C
C	  Store the associated qualifier string for return if present.
C
	    IF ( Q_STRING_TMP .EQ. 1 ) THEN	! If qual string found, then
		QUAL_STRING = STRING(P1:P2)	!   Store qualifier string.
		Q_S_S = P2 - (P1-1)		!   Store length of string.
	    ELSEIF ( Q_STRING_TMP .EQ. 2 ) THEN ! If ambiguous qualifier, 
		QUAL_STRING = STRING(Q1:Q3)	!   Store qual and qual str.
		Q_S_S = Q3 - (Q1-1)		!   Store length of string.
	    ELSE				! Else
		QUAL_STRING = ' '		!   Store blank.
		Q_S_S = 0			!   Store length zero.
	    ENDIF
C
C	  Store the length of the qualifier string.
C
	    IF ( LIB_NARGS() .GE. 5 ) THEN
		QUAL_STR_S = Q_S_S
		IF ( LEN( QUAL_STRING ) .LT. Q_S_S ) THEN
		    QUAL_STR_S = LEN( QUAL_STRING )
		ENDIF
	    ENDIF
C
C	  Remove the qualifier and qualifier string from the input string.
C
	    STRING(Q1:Q3) = ' '
C
C	  Update the return status.
C
	    Q_STRING = Q_STRING_TMP + Q_STRING_NEG
C
C	  If ambiguous string found exit from loop.
C
	    IF ( Q_STRING_TMP .EQ. 2 ) GOTO 1999
	ENDDO
1999	CONTINUE
C
C   ---------------------------------------------------------------------------
C
C   Return.
C
	RETURN
	END
