      SUBROUTINE MAIN
      INTEGER GETARG, OPEN
      INTEGER I, FD
      LOGICAL*1 ARG(40)
      I=1
23000 IF(.NOT.(GETARG(I, ARG, 40) .NE. -1))GOTO 23002
      IF(.NOT.(ARG(1) .EQ. 63 .AND. ARG(2) .EQ. 0))GOTO 23003
      CALL USAGE
      GOTO 23004
23003 CONTINUE
      IF(.NOT.(ARG(1) .EQ. 45 .AND. ARG(2) .EQ. 0))GOTO 23005
      FD = 1
      GOTO 23006
23005 CONTINUE
      FD = OPEN(ARG, 1)
      IF(.NOT.(FD .EQ. -3))GOTO 23007
      CALL CANT(ARG)
23007 CONTINUE
23006 CONTINUE
23004 CONTINUE
      CALL TPSORT (FD)
      IF(.NOT.(FD .NE. 1))GOTO 23009
      CALL CLOSE(FD)
23009 CONTINUE
23001 I=I+1
      GOTO 23000
23002 CONTINUE
      IF(.NOT.(I .EQ. 1))GOTO 23011
      CALL TPSORT (1)
23011 CONTINUE
      RETURN
      END
      SUBROUTINE TPSORT (FD)
      LOGICAL*1 LINBUF(400), SYMBUF(120)
      INTEGER I, J, F, R, N, FD
      INTEGER GETWRD, GETLIN, LOOKS
      COMMON /CTSORT/ HASH(128), NXTSYM, NXTFRE, BUF(5000)
      INTEGER HASH
      INTEGER NXTSYM
      INTEGER NXTFRE
      INTEGER BUF
      NXTSYM = 1
      NXTFRE = 5000
      I = 1
23013 IF(.NOT.(I .LE. 128))GOTO 23015
      HASH(I) = 0
23014 I = I + 1
      GOTO 23013
23015 CONTINUE
23016 IF(.NOT.(GETLIN(LINBUF, FD) .NE. -1))GOTO 23017
      I = 1
      IF(.NOT.(GETWRD(LINBUF, I, SYMBUF) .LE. 0))GOTO 23018
      GOTO 23016
23018 CONTINUE
      J = LOOKS(SYMBUF)
23020 IF(.NOT.(GETWRD(LINBUF, I, SYMBUF) .GT. 0))GOTO 23021
      CALL ENTPRC(J, LOOKS(SYMBUF))
      GOTO 23020
23021 CONTINUE
      GOTO 23016
23017 CONTINUE
      F = 0
      I = 1
23022 IF(.NOT.(I .LT. NXTSYM .AND. F .EQ. 0))GOTO 23024
      IF(.NOT.(BUF(I+1) .EQ. 0))GOTO 23025
      F = I
23025 CONTINUE
23023 I = I + 3
      GOTO 23022
23024 CONTINUE
      R = F
23027 IF(.NOT.(I .LT. NXTSYM))GOTO 23029
      IF(.NOT.(BUF(I+1) .EQ. 0))GOTO 23030
      BUF(R+1) = I
      R = I
23030 CONTINUE
23028 I = I + 3
      GOTO 23027
23029 CONTINUE
      N = NXTSYM
23032 IF(.NOT.(F .GT. 0))GOTO 23034
      CALL ICOPYS (BUF, BUF(F+0), LINBUF, 1)
      CALL PUTLIN(LINBUF, 2)
      CALL PUTCH(10, 2)
      I = BUF(F+2)
23035 IF(.NOT.(I .GT. 0))GOTO 23037
      J = BUF(I+1)
      BUF(J+1) = BUF(J+1) - 1
      IF(.NOT.(BUF(J+1) .EQ. 0))GOTO 23038
      BUF(R+1) = J
      R = J
23038 CONTINUE
23036 I = BUF(I+0)
      GOTO 23035
23037 CONTINUE
      N = N - 3
23033 F = BUF(F+1)
      GOTO 23032
23034 CONTINUE
      IF(.NOT.(N .GT. 1))GOTO 23040
      CALL ERROR(9Hcircular.)
23040 CONTINUE
      RETURN
      END
      SUBROUTINE ENTPRC(A, B)
      INTEGER A, B
      INTEGER P
      INTEGER NALLOC
      COMMON /CTSORT/ HASH(128), NXTSYM, NXTFRE, BUF(5000)
      INTEGER HASH
      INTEGER NXTSYM
      INTEGER NXTFRE
      INTEGER BUF
      BUF(B+1) = BUF(B+1) + 1
      P = NALLOC(2)
      BUF(P+0) = BUF(A+2)
      BUF(P+1) = B
      BUF(A+2) = P
      RETURN
      END
      INTEGER FUNCTION LOOKS(S)
      LOGICAL*1 S(120), LIN(120)
      INTEGER I
      INTEGER LENGTH, NALLOC, EQUAL, SYMALC
      COMMON /CTSORT/ HASH(128), NXTSYM, NXTFRE, BUF(5000)
      INTEGER HASH
      INTEGER NXTSYM
      INTEGER NXTFRE
      INTEGER BUF
      I = HASH(S(1)+1)
23042 IF(.NOT.(I .GT. 0))GOTO 23044
      CALL ICOPYS (BUF, I+2, LIN, 1)
      IF(.NOT.(EQUAL(S, LIN) .EQ. 1))GOTO 23045
      LOOKS=(BUF(I+1))
      RETURN
23045 CONTINUE
23043 I = BUF(I+0)
      GOTO 23042
23044 CONTINUE
      I = NALLOC(2 + 1 + LENGTH(S) + 1)
      BUF(I+0) = HASH(S(1)+1)
      HASH(S(1)+1) = I
      BUF(I+1) = SYMALC(I+2)
      CALL SCOPYI(S, 1, BUF, I + 2)
      LOOKS=(BUF(I+1))
      RETURN
      END
      INTEGER FUNCTION NALLOC(N)
      INTEGER N
      COMMON /CTSORT/ HASH(128), NXTSYM, NXTFRE, BUF(5000)
      INTEGER HASH
      INTEGER NXTSYM
      INTEGER NXTFRE
      INTEGER BUF
      NXTFRE = NXTFRE - N
      IF(.NOT.(NXTFRE .LT. NXTSYM))GOTO 23047
      CALL ERROR(15Hout of storage.)
23047 CONTINUE
      NALLOC=(NXTFRE + 1)
      RETURN
      END
      INTEGER FUNCTION SYMALC(S)
      INTEGER S
      INTEGER P
      COMMON /CTSORT/ HASH(128), NXTSYM, NXTFRE, BUF(5000)
      INTEGER HASH
      INTEGER NXTSYM
      INTEGER NXTFRE
      INTEGER BUF
      P = NXTSYM
      NXTSYM = NXTSYM + 3
      IF(.NOT.(NXTSYM .GT. NXTFRE))GOTO 23049
      CALL ERROR(15Hout of storage.)
23049 CONTINUE
      BUF(P+0) = S
      BUF(P+1) = 0
      BUF(P+2) = 0
      SYMALC=(P)
      RETURN
      END
      SUBROUTINE USAGE
      CALL ERROR (22Husage:  tsort [files].)
      RETURN
      END
      SUBROUTINE ICOPYS(FROM, I, TO, J)
      INTEGER FROM(100)
      LOGICAL*1 TO(100)
      INTEGER I, J, K1, K2
      K2 = J
      K1 = I
23051 IF(.NOT.(FROM(K1) .NE. 0))GOTO 23053
      TO(K2) = FROM(K1)
      K2 = K2 + 1
23052 K1 = K1 + 1
      GOTO 23051
23053 CONTINUE
      TO(K2) = 0
      RETURN
      END
      SUBROUTINE SCOPYI(FROM, I, TO, J)
      LOGICAL*1 FROM(100)
      INTEGER TO(100)
      INTEGER I, J, K1, K2
      K2 = J
      K1 = I
23054 IF(.NOT.(FROM(K1) .NE. 0))GOTO 23056
      TO(K2) = FROM(K1)
      K2 = K2 + 1
23055 K1 = K1 + 1
      GOTO 23054
23056 CONTINUE
      TO(K2) = 0
      RETURN
      END
