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:
|
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.