	SUBROUTINE ALPHA(A,N,LENGTH,NCHAR,NFULL,NREST,NPOS)
C
C       This subroutine handles alphanumeric information.
C
C		Version 2, Donald H. Gudehus, August, 1988
C		Added possibility 4
C		Version 3, Donald H. Gudehus, June, 1995
C		Added possibility 5
C		Version 4, Donald H. Gudehus, September 17, 2004
C		Added Control K ('0B'X) to the list of characters to be
C		filtered.
C		Version 5, Donald H. Gudehus, February 15, 2005
C		Added Control B ('02'X) and Control L ('0C'X) to the list
C		of characters to be filtered.
C
C		A	(C)	is the input array
C		N 	(C)	is the dimension of A
C		LENGTH	(C)	is the length of the words (in bytes)
C		NCHAR	(R)	is the number of actual characters
C		NFULL	(R)	is the number of full words
C		NREST	(R)	is the number of remaining characters
C		NPOS    (C)	is the possibilty selector.
C				If NPOS=1 the number of characters in all
C				words are counted, excluding those blanks 
C				at the end of the string.  NCHAR is always 
C				>= 1
C				If NPOS=2 the remaining 0's are set to
C				blanks.
C				If NPOS=3, the number of characters in all 
C				words exclusive of control characters and 
C				blanks at the end of the string are counted.
C				If NPOS=4 the remaining 0's and ,'s are set
C				to blanks and each word is placed in its
C				correct position.  If there are only blanks,
C				NFULL and NCHAR are set to zero.
C				A Tab is read as a Tab on Linux but as
C				eight blanks (ASCII 32) on the Mac OS.
C				If NPOS=5 the words are checked for the 
C				presence of decimal points.  If a decimal
C				point is not found, one is inserted in each
C				required word.  This is useful if USRINP
C				is accepting character input which is to
C				be decoded into F format numbers.  Any 
C				zeros are changed to blanks.

C
	BYTE A(1)
	LOGICAL DECIMAL_POINT,WORD
C
	NL=N*LENGTH
	IF (NPOS.EQ.1) THEN
	  NCHAR=1 !  The shortest possible string is 1 byte long
	  DO I=NL,1,-1
	    X=A(I)
	    IF (X.NE.0.0.AND.X.NE.32.0) THEN
	      NCHAR=I
	      GO TO 100
	    END IF
	  END DO
 100	  CONTINUE
	  NFULL=NCHAR/LENGTH !  Only valid if text contains no spaces
	  NREST=NFULL*LENGTH-NCHAR
C
	ELSE IF (NPOS.EQ.2) THEN
C
	  DO I=1,NL
	    IF (A(I).EQ.0) A(I)=32
	  END DO
C
	ELSE IF (NPOS.EQ.3) THEN
C
	  NCHAR=1 !  The shortest possible string is 1 byte long
	  DO I=NL,1,-1
	    X=A(I)
	    IF (X.NE.0.0.AND.X.NE.32.0) THEN
	      NCHAR=I
	      GO TO 200
	    END IF
	  END DO
 200	  CONTINUE
C  Do not count control characters '02'X, '08'X, '09'X, '0A'X, '0B'X, or
C  '0C'X which are used for alphabet selection, backspacing, and sub- and
C  and sub- and superscripting in the plotting package.
	  NDUMMY=NCHAR
	  DO I=1,NDUMMY
	    IF (A(I).EQ.'02'X.OR.A(I).EQ.'08'X.OR.A(I).EQ.'09'X.OR.
	1   A(I).EQ.'0A'X.OR.A(I).EQ.'0B'X.OR.A(I).EQ.'0C'X) NCHAR=NCHAR-1
	  END DO
	  NFULL=NCHAR/LENGTH !  Only valid if text contains no spaces
	  NREST=NFULL*LENGTH-NCHAR
C
	ELSE IF (NPOS.EQ.4) THEN
C
	  DO I=1,NL
C	    IF (A(I).EQ.0.OR.A(I).EQ.44) A(I)=32
	    IF (A(I).EQ.0.OR.A(I).EQ.9) A(I)=32 !  Zero or Tab
	  END DO
C  If there are only blanks, set NFULL=0 and return;  the code below will
C  go into an infinite loop if there are only blanks.
	  NCHAR=0
	  DO I=NL,1,-1
	    X=A(I)
	    IF (X.NE.32.0) THEN
	      NCHAR=I
	      GO TO 300
	    END IF
	  END DO
 300	  IF (NCHAR.EQ.0) THEN !  All blanks
	    NFULL=0
	    RETURN
	  END IF
C  Ensure that there are no blanks at the beginning of the string
	  II=0 !  Number of blanks at the beginning of the string
	  DO WHILE (A(1).EQ.32)
	    II=II+1
	    DO I=1,NL-1
	      A(I)=A(I+1)
	    END DO
	    A(NL-II+1)=32 !  Writes a blank to the correct location at the
			  !  current end of the array.
	  END DO
	  NCHAR=NCHAR-II
C  Find the next nonblank character following a blank one and shift the
C  string so as to put things in the position of the next word.
	  IC=2 !  The character pointer
	  IW=2 !  The word pointer
	  DO WHILE (IC.LT.NL)
	    ISHIFT=0 !  A positive shift is to the right
	    IF (A(IC).NE.32.AND.A(IC-1).EQ.32) THEN	      
	      ISHIFT=(IW-1)*LENGTH+1-IC
	      IF (ISHIFT.GT.0) THEN !  Must shift to the right
	        DO I=NL,(IW-1)*LENGTH+1,-1
	          A(I)=A(I-ISHIFT)
	        END DO
C  Clean up
	        DO I=(IW-1)*LENGTH,IC,-1
	          A(I)=32
	        END DO
	      ELSE IF (ISHIFT.LT.0) THEN !  Must shift to the left
	        DO I=(IW-1)*LENGTH+1,NL+ISHIFT
	          A(I)=A(I-ISHIFT)	      
	        END DO
	      END IF
	      IW=IW+1
	    END IF
	    IC=IC+1+ISHIFT
	  END DO
	  NFULL=IW-1
C
	ELSE IF (NPOS.EQ.5) THEN
C
C  Find the beginning of the first word
	  I=1
	  DO WHILE((A(I).EQ.0.OR.A(I).EQ.32).AND.I.LE.NL)
	    I=I+1
	  END DO
C  Read through the word untill the next blank or zero, checking to see
C  if a decimal point is present
	  DO WHILE(I.LE.NL)
	    DECIMAL_POINT=.FALSE.
	    WORD=.FALSE.
	    DO WHILE(A(I).NE.0.AND.A(I).NE.32.AND.I.LE.NL)
	      WORD=.TRUE.
	      IF (A(I).EQ.46) DECIMAL_POINT=.TRUE.
	      I=I+1
	    END DO
C  If no decimal point was found in a word, add one by inserting and shifting
	    IF (.NOT.DECIMAL_POINT.AND.WORD) THEN
	      A(I)=46
	      DO II=NL,I+2,-1
	        A(II)=A(II-1)
	      END DO
	      IF (I+1.LE.NL) A(I+1)=32
	    END IF
	    I=I+1
	  END DO
C  Change the zeros to blanks
	  DO I=1,NL
	    IF (A(I).EQ.0) A(I)=32
	  END DO
	END IF
	RETURN
	END
