Using SORT in FORTRAN77

The intrinsic subroutines FSORT and FMERGE perform a sort or merge. A sort accepts records from the input, arranges them in order, and returns them to the output. A merge accepts sorted records from multiple inputs and merges them in order to a single output. These subroutines take four kinds of arguments, as described in the following table:

Argument Type

Description

INFO

A string that describes how the sort or merge will operate. It can be one of the following types:

  • A CHARACTER array or subscripted array reference

  • A CHARACTER variable

  • A CHARACTER substring

  • A CHARACTER constant

INPUT

A logical unit number or a subroutine defined in an EXTERNAL statement. If it is a logical unit number, the records to be arranged are read from the unit. If it is a subroutine, the subroutine is called to retrieve each record. It is called once for each record. One INPUT argument exists for a sort and between 2 and 8 arguments for a merge.

OUTPUT

A logical unit number or a subroutine defined in an EXTERNAL statement. If it is a logical unit number, the arranged records are written to the unit. If it is a subroutine, the subroutine is called once for each record.

COMPARE

An optional argument that can be a subroutine defined in an EXTERNAL statement. If it appears, the subroutine is called whenever two records are compared. The subroutine determines the order of the records. If it does not appear, the order of the records is determined by the keys described in the INFO argument.

The INFO argument is a character string that describes the operation of the sort or merge. It contains a number of clauses, each of which describes an attribute of the process. If an attribute has multiple parts, those parts are contained in parentheses. The clauses are separated by blanks or commas. Examination of the string is terminated at the end of the string or when a period occurs. The clauses in the following table describe the operation of the sort:

Clause

Description

KEY=key-desc

Describes a single key.

KEY=(d,...,d)

Describes several keys. Each key takes the following form: position/length/sequence/type.

COMP

Appears if, and only if, a comparison routine is used. A single instance of either COMP or KEY must appear.

DUPL

Indicates that duplicate keys should be ordered based on appearance (SORT only, not MERGE).

CORE=size

Core size in words (default 12000). If the size specified is below the minimum (8000), an appropriate size is calculated for you.

WORKFILE=type

Describes the type of a single work file. This clause can be abbreviated as WORK.

WORKFILE=(t,t)

Describes disk and tape workfiles.

CCSVERSION=name

Specifies a coded character set version.

CCSVERSION

Uses the default CCSVERSION if no name is specified.

RESTART=r-val

Describes restart functions.

The input procedure, if used, is a subroutine defined in an EXTERNAL statement that has the following three parameters:

  • The record, defined to be a CHARACTER variable

  • The length of the record in characters

  • A logical variable that Indicates when the input is finished. If the value is TRUE, the record is ignored, and the input procedure is not called again.

The output procedure, if used, is a subroutine defined in an EXTERNAL statement that has the following two parameters:

  • The record, defined to be a CHARACTER variable

  • The length of the record in characters

The comparison procedure, if used, is a subroutine defined in an EXTERNAL statement that has the following three parameters:

  • The first and second parameters are records, defined to be CHARACTER variables.

  • The third parameter is an integer that specifies the relation between the two records. It is set to 1 if the record in the first parameter precedes the record in the second parameter, 2 if the order is immaterial, and 3 if the first record follows the second record.

The following example creates a set of test records, sorts them in ascending order, and merges them with an existing file, which eliminates any records with duplicate keys. The comparison routine ensures that test records with duplicate keys appear after existing records.

FILE  1(FILE='SORT/EXAMPLE/INPUT;,' ,STATUS='OLD',MAXRECSIZE=6)
FILE  2(FILE='SORT/EXAMPLE/TEST. ' ,STATUS='NEW',MAXRECSIZE=6)
FILE  3(FILE='SORT/EXAMPLE/OUTPUT. ' ,STATUS='NEW',MAXRECSIZE=6)
    INTEGER COUNT, RANDOMARG
    COMMON COUNT, RANDOMARG
    EXTERNAL INPROC, COMPPROC, OUTPROC
    COUNT = 0
    RANDOMARG = TIME(11)
    CALL FSORT('RSZ=36 KEY=1/6/A/N', INPROC, 2)
    OPEN(3)
    CALL FMERGE('RSZ=36 KEY=1/6. COMP',
 *     1, 2, OUTPROC)
    CLOSE(3)
    STOP
    END
    SUBROUTINE INPROC(RECORD, LTH, EOF)
    CHARACTER*36 RECORD
    LOGICAL EOF
    INTEGER COUNT, RANDOMARG
    COMMON COUNT, RANDOMARG
    LTH = 36
    EOF = COUNT.GE. 100
    IF(EOF) RETURN
    COUNT = COUNT + 1
    KEY = RANDOM(RANDOMARG) * 1000
91  FORMAT(I6.6, 6X, A6, 18X)
    RETURN
    END
    SUBROUTINE COMPPROC(RECA, RECB, RESULT)
CHARACTER*36 RECA, RECB
INTEGER RESULT
IF ( RECA(1:6) .LT. RECB(1:6) ) THEN
    RESULT = 1
ELSE IF(RECA(1:6).GT. RECB(1:6)) THEN
    RESULT = 3
ELSE
 IF RECA(13:18) .EQ. '*TEST*') THEN
     RESULT = 3
ELSE IF (RECB(13:18).EQ. '*TEST*" THEN
    RESULT = 1
ELSE
    RESULT = 2
END IF
RETURN
END
SUBROUTINE OUTPROC(RECORD, LTH)
CHARACTER RECORD*(*)
INTEGER COUNT, RANDOMARG
COMMON COUNT, RANDOMARG, LASTKEY
READ ( RECORD, FMT = '(I6)' ) KEY
IF( KEY .NE. LASTKEY ) THEN
    WRITE( 3, FMT = '(A36)' ) RECORD
ELSE
    WRITE( 6, FMT = '(1X, A12, A36)' ) 'DUPLICATE: ',RECORD
END IF
LASTKEY = KEY
RETURN
END

For more detailed information on values of the various clauses, refer to the FORTRAN77 Programming Reference Manual.