*DECK S$PRSPC 
          PROC S$PRSPC(SPEC$,STATUS$);
  
#**       S$PRSPC -  PROCESS SPEC$                                     #
#                                                                      #
#     CALLING SEQUENCE-                                                #
#         S$PRSPC(SPEC$):                                              #
#                                                                      #
#     GIVEN-                                                           #
#         SPEC$ = USER SPECFICIATION.                                  #
#                                                                      #
#     DOES-                                                            #
#         ENSURES THAT SPEC$OUTFIT, SPEC$EXCFIT AND ALL SPEC$INFIT-S   #
#         POINT TO FIT-S.                                              #
#         SETS SPEC$FIXED, SPEC$FIXLEN, SPEC$MNR AND UPDATES SPEC$MRL. #
  
  
          BEGIN 
  
*CALL A 
  
*CALL E$
  
*CALL SPEC$ 
  
*CALL STATUS$ 
  
          XREF
              BEGIN 
              PROC  S$CMALF;           # ALLOCATE FIXED BLOCK          #
              PROC  S$ERROR;           # HANDLE USER ERROR             #
              PROC S$ABT; 
              PROC  S$FETCH;           # FETCH VALUE FROM FIT          #
              PROC  S$FINFO;           # ISSUE FILINFO MACRO           #
              PROC  S$GTLOF;           # SEARCH LIST OF FILES AND      #
                                       # COPY FIT FIELDS TO SORT FIT   #
              PROC  S$STBFS;           # SET BFS IN FIT                #
              PROC  S$STFIT;           # SET FIT                       #
  
              ARRAY S$ARRY  [1:15]; 
                  ITEM S$ARRYELEM    I(0, 0, 60); 
              END 
  
          XREF
*CALL S$CALLR 
  
*CALL MACHINE 
  
          BASED ARRAY FIT[FITSIZE]; 
              ITEM  FIT$WORD     U(0, 0,60);
  
          ARRAY KEY$ [1:200]; # TO STORE KEY AND SUM FIELD INFO.      # 
              BEGIN 
              ITEM  KEY$SEQAON   B(0, 0, 1);     # SEQA IS ON          #
              ITEM  KEY$SUMFLD   B(0, 1, 1);     # TRUE IF SUM FIELD   #
              ITEM  KEY$LENGTH   I(0, 2,28);     # BIT LENGTH OF A KEY #
              ITEM  KEY$OFFSET   I(0,30,30);     # BIT OFFSET OF A KEY #
              END 
          ARRAY  OVER[1:200];      # TO STORE KEY INFO FOR OVERLAPPING #
              BEGIN 
              ITEM  OVER$LENGTH  I(0, 0,20);     # BIT LENGTH OF A KEY #
              ITEM  OVER$OFFSET  I(0,20,20);     # BIT OFFSET OF A KEY #
              ITEM  OVER$LASTBT  I(0,40,20);     # LAST BIT POSITION   #
              END 
  
  
          ITEM  FASTIN       B;        # IF FAST INPUT STILL POSS.     #
          ITEM  FITADDR      I;        # FIT ADDR OR 0 BY S$GTLOF      #
          ITEM  FIXLEN       I;        # LENGTH OF ALL FIXED RECORDS   #
          ITEM  FL           I;        # LENGTH OF A FIXED RECORD      #
          ITEM  I            I;        # SCRATCH                       #
          ITEM  J            I;        # SCRATCH                       #
          ITEM  L            I;        # MRL FIELD FROM FIT            #
          ITEM  LASTBIT      I;        # LAST BIT NO. OF KEY FIELD     #
          ITEM  LK           I;        # LENGTH OF KEY IN BITS         #
          ITEM  MNR          I;        # MINIMUM REC LEN OF VAR RECS   #
          ITEM  MRL          I;        # MAXIMUM REC. LEN OF ALL RECS  #
          ITEM  NFITAREA     I=8;      # NO FIT AREAS ALLOC. BY S$MAIN #
          ITEM  RECLEN I; 
          ITEM  RT           I;        # RECORD TYPE OF A FILE         #
          ITEM  SI           I;        # SPEC$ INDEX                   #
          ITEM  OVERLAP$PNTR I;      # FOR KEY/SUM OVERLAP           #
          ITEM  K            I; 
          ITEM  OVERLAP      B = FALSE;# FLAG KEY FIELDS OVERLAP       #
          ITEM  LASTKEY      I;        # POINT TO THE LAST KEY FIELD   #
          ITEM  BITOP        B = FALSE;# BIT OPERATION INDICATES THE   #
                                       # FIRST KEY IS IN BIT POSITION  #
          ITEM  SORTED       B; 
          ITEM  NKEYS        I; 
          ITEM  TAPEFLAG     B; 
  
          CONTROL DISJOINT; 
  
          CONTROL INERT;
  
CONTROL EJECT;
  
          PROC UPDATE(ADDRFIT); 
              ITEM  ADDRFIT      I;    # ADDRESS OF FIT                #
              BEGIN 
              IF ADDRFIT EQ 0 THEN
#***#             RETURN; 
              S$FETCH(ADDRFIT, "RT", RT); 
              IF (( RT EQ 1)    #F# 
                   OR ( RT EQ 3))    #Z#
                  AND  SPEC$FIXEDOW  THEN 
                  BEGIN 
                  IF FIXLEN EQ 0 THEN 
                      S$FETCH(ADDRFIT, "FL", FIXLEN); 
                  ELSE
                      BEGIN 
                      S$FETCH(ADDRFIT, "FL", FL); 
                      IF FL NQ FIXLEN THEN
                          BEGIN 
                          S$ERROR(E$73); # UNEQUAL FL FOR F,Z RECS #
                          SPEC$FIXED = FALSE; 
                          IF MNR EQ 0 THEN
                              MNR = FIXLEN; 
                          IF FL LS MNR THEN 
                             MNR = FL;
                          IF MRL LS FL THEN 
                             MRL = FL;
                          END 
                      END 
                  IF MRL LS FIXLEN THEN 
                      MRL = FIXLEN; 
                  END 
              ELSE                     # VARIABLE LENGTH RECORD        #
                  BEGIN 
                  SPEC$FIXED = FALSE; 
                  S$FETCH(ADDRFIT,"MRL",L); 
                  IF MRL LS L THEN
                      MRL = L;
                  S$FETCH(ADDRFIT,"MNR",L); 
                  IF MNR LS L THEN
                      MNR = L;
                  END 
              END # UPDATE #
CONTROL EJECT;
  
#     CREATE AND SET ANY NECESSARY FIT-S                               #
  
          MNR = 0;
          I = SPEC$1STINF;
          FOR I=I WHILE I NQ 0 DO 
              BEGIN 
              IF SPEC$INFIT[I] EQ 0  THEN 
                  BEGIN 
                  # CONVERT TRAILING SPACES OF FIT TO ZEROS            #
                  FOR J=0 STEP 1 UNTIL 6 DO 
                      BEGIN 
                      IF C<J,1>SPEC$INNAME[I] EQ " " THEN 
                          C<J,1>SPEC$INNAME[I] = 0; 
                      END 
  
                  S$GTLOF(FITADDR, SPEC$INNAME[I]);     # SEARCH LOF   #
                                       # SET FITADDR TO FIT FOUND OR 0 #
  
                  IF FITADDR EQ 0 THEN    # IF FIT NOT FOUND FOR LFN   #
                      BEGIN 
                      IF NFITAREA GR 1 THEN 
                          BEGIN 
                          SPEC$INFIT[I] = SPEC$LOFIT; # USE ALLOC.AREA #
                          SPEC$LOFIT = SPEC$LOFIT + FITSIZE; #NEXT AREA#
                          NFITAREA = NFITAREA - 1; # 1 FIT AREA LESS   #
                          END 
                      ELSE
                          BEGIN 
                          S$CMALF(P<FIT>,FITSIZE,0,0); # ALLOCATE FIT  #
                          SPEC$INFIT[I] = P<FIT>; 
                          END 
                      S$STFIT(SPEC$INFIT[I], SPEC$INNAME[I]); 
                      END 
                  ELSE
                      SPEC$INFIT[I] = FITADDR;
                  END 
              I = SPEC$NEXTIN[I]; 
              END 
  
          IF SPEC$OUTNAME NQ " "
           AND SPEC$OUTFIT EQ 0 THEN
              BEGIN 
                  # CONVERT TRAILING SPACES OF FIT TO ZEROS            #
                  FOR J=0 STEP 1 UNTIL 6 DO 
                      BEGIN 
                      IF C<J,1>SPEC$OUTNAME EQ " " THEN 
                          C<J,1>SPEC$OUTNAME = 0; 
                      END 
  
                  S$GTLOF(FITADDR, SPEC$OUTNAME);    # SEARCH LOF   # 
                                       # SET FITADDR TO FIT FOUND OR 0 #
  
                  IF FITADDR EQ 0 THEN    # IF FIT NOT FOUND FOR LFN   #
                      BEGIN 
                      SPEC$OUTFIT = SPEC$LOFIT; #USE AREA ALLOC.BY MAIN#
  
                      S$STFIT(SPEC$OUTFIT, SPEC$OUTNAME); 
                      END 
                  ELSE
                      SPEC$OUTFIT = FITADDR;
              END 
  
#     IF OUTPUT FILE AND ALL INPUT FILES ARE RT=F OR RT=Z,             #
#         SET SPEC$FIXED = TRUE                                        #
#         SET SPEC$FIXLEN = LENGTH OF ALL RECORDS                      #
#         SET SPEC$MNR = 0                                             #
#         SET SPEC$MRL = LARGER OF SPEC$MRL AND SPEC$FIXLEN            #
#     ELSE (AT LEAST ONE IS VARIABLE-LENGTH)                           #
#         SET SPEC$FIXED = FALSE                                       #
#         SET SPEC$FIXLEN = 0                                          #
#         SET SPEC$MNR = MINIMUM RECORD NEEDED FOR ALL KEYS            #
#         SET SPEC$MRL = LARGEST OF SPEC$MRL AND MRL/FL OF ALL FILES   #
#                                                                      #
#     SIMULTANEOUSLY,                                                  #
#     IF SPEC$FASTIO AND ALL INPUT FILES ARE RT=F WITH SAME FL,        #
#         SET SPEC$FASTIN = FL                                         #
#     IF SPEC$FASTIO AND ALL INPUT FILS ARE RT=W,                      #
#         SET SPEC$FASTIN = -(MAXIMUM MRL)                             #
#     ELSE# 
#         SET SPEC$FASTIN = 0.                                         #
#     IF SPEC$FASTIO AND OUTPUT FILE IS RT=F,                          #
#         SET SPEC$FASTOUT = FL                                        #
#     ELSE# 
#     IF SPEC$FASTIO AND OUTPUT FILE IS RT=W,                          #
#         SET SPEC$FASTOUT = -MRL                                      #
#     ELSE# 
#         SET SPEC$FASTOUT = 0.                                        #
  
          SPEC$FIXED = TRUE; # GUESS ALL FIXED LENGTH RECORDS          #
          FIXLEN = 0;        # NOTE FIRST TIME                         #
          MRL = 0;
          SPEC$FASTIN = 0;
          FASTIN = TRUE;               # START ASSUMING FAST INPUT     #
  
          I = SPEC$1STINF;
          FOR I=I WHILE I NQ 0 DO 
              BEGIN 
              UPDATE(SPEC$INFIT[I]);
              IF SPEC$FASTIO THEN  #IF FAST I/O WANTED                 #
                  BEGIN 
                  IF FASTIN THEN
                      BEGIN  #STIL CANDIDATE FOR FAST INPUT            #
                      TAPEFLAG = TRUE;
                      S$FINFO(SPEC$INFIT[I], TAPEFLAG); 
                      IF TAPEFLAG THEN
                          BEGIN 
                          FASTIN=FALSE; 
                          S$ERROR(E$117);  # FASTIO NOT FOR TAPES # 
                          END 
                      IF RT EQ 1 #F# THEN 
                          BEGIN 
                          S$FETCH(SPEC$INFIT[I], "FL", FL); 
                          IF SPEC$FASTIN EQ 0 THEN  #IF FIRST FILE     #
                              SPEC$FASTIN = FL; 
                          ELSE                      #IF NOT FIRST FILE #
                          IF SPEC$FASTIN NQ FL THEN 
                              FASTIN = FALSE; # NOT ALL IN FL-S SAME   #
                          END 
                      ELSE
                      IF RT EQ 0 #W# THEN 
                          BEGIN 
                          S$FETCH(SPEC$INFIT[I], "MRL", MRL); 
                          IF SPEC$FASTIN EQ 0 THEN  # IF FIRST FILE    #
                              SPEC$FASTIN = -MRL; 
                          ELSE
                          IF SPEC$FASTIN GR 0 THEN  # IF PREV. WAS RT=F#
                              FASTIN = FALSE; 
                          ELSE
                          IF MRL GR -SPEC$FASTIN THEN 
                              SPEC$FASTIN = -MRL;   # USER LAGRGER MRL #
                          END 
                      ELSE
                          FASTIN = FALSE; 
                      END 
                  END 
              I = SPEC$NEXTIN[I]; 
              END 
  
          IF SPEC$FASTIO AND (NOT FASTIN) THEN
              BEGIN 
              SPEC$FASTIN = 0;   # THIS IS A USER ERROR # 
              S$ERROR(E$118);   # FASTIO DIDN-T HAPPEN #
              END 
  
  
          # SINCE FASTIO FOR I-W RECORDS DOES NOT WORK, WE             #
          # NEED TO TURN IT OFF TO PREVENT AN INACCURATE SORT          #
  
          IF SPEC$FASTIN LS 0 THEN
              SPEC$FASTIN = 0;
          IF SPEC$OUTFIT NQ 0 THEN
              BEGIN 
              UPDATE(SPEC$OUTFIT);
              IF SPEC$FASTIO THEN  # IF FAST I/O WANTED                #
                  BEGIN 
                  IF RT EQ 1 #F# THEN 
                      BEGIN 
                      S$FETCH(SPEC$OUTFIT, "FL", FL); 
                      SPEC$FASTOUT = FL;
                      END 
                  ELSE
                  IF RT EQ 0 #W# THEN 
                      BEGIN 
                      S$FETCH(SPEC$OUTFIT, "MRL", MRL); 
                      SPEC$FASTOUT = -MRL;
                      END 
                  ELSE
                      SPEC$FASTOUT = 0; 
                  S$FINFO(SPEC$OUTFIT, TAPEFLAG); 
                  IF TAPEFLAG THEN
                      BEGIN 
                      SPEC$FASTOUT = 0; 
                      S$ERROR(E$117);   # FASTIO NOT FOR TAPES #
                      END 
                  END 
              ELSE
                  SPEC$FASTOUT = 0; 
              END 
  
          ELSE
              SPEC$FASTOUT = 0; 
#     TAKE INTO ACCOUNT OWNCODE FIXED-LENGTH RECORDS                   #
          IF SPEC$FASTOUT LS 0 THEN 
              SPEC$FASTOUT = 0; 
  
          IF SPEC$FIXED THEN           # IF NO FILES OR ALL WITH FIXED #
              BEGIN 
              IF FIXLEN EQ 0               # IF NO FILES               #
                AND SPEC$FIXLEN EQ 0 THEN  # AND NOT FIXED OWNCODE     #
                  SPEC$FIXED = FALSE; 
  
              IF FIXLEN NQ 0               # IF FIXED FILES            #
                AND SPEC$FIXLEN NQ 0 THEN  # AND FIXED OWNCODE         #
                  BEGIN 
                  IF FIXLEN NQ SPEC$FIXLEN THEN       # IF DIFF. FIXED #
                      SPEC$FIXED = FALSE; 
                  END 
  
              END 
          # SPEC$FIXED AND SPEC$FIXLEN NOW ACCOUNT FOR OWNCODE         #
  
  
# IF NO KEY MENTIONED, SET KEY LENGTH IN BYTES TO RECORD LENGTH        #
# KEYTYPE AND OTHER  PARAMETERS WERE SET IN S$SETWH                    #
          # IGNORE MRL FROM FITS IF THIS IS A SORT-4 COMPATIBLE        #
          # CALL                                                       #
          #  AND THE FIT LENGTH IS UNREASONABLE                        #
          IF SPEC$MRL LS MRL THEN 
              BEGIN 
              IF S$CALLR NQ 3 THEN
                  SPEC$MRL = MRL; 
              ELSE    # SORT-4 COMPATIBLE CALL  # 
                  IF (MRL GR 0) AND (MRL LS 5001) THEN  #  REASONABLE  #
                      SPEC$MRL = MRL; 
              END 
  
          RECLEN = SPEC$FIXLEN; 
          IF RECLEN LS SPEC$MRL THEN
              RECLEN = SPEC$MRL;
  
          IF SPEC$NOKEY THEN        # IF NO KEY SPECIFIED              #
              BEGIN 
              SPEC$1STKEY = SPEC$1STINDX; 
              SPEC$KEYNBYT[SPEC$1STKEY] = RECLEN; 
              END 
  
  
          IF SPEC$FIXED THEN
              BEGIN 
              SPEC$MNR = 0; 
              IF SPEC$MRL LS FIXLEN THEN
                  SPEC$MRL = FIXLEN;
              IF SPEC$MRL LS SPEC$FIXLEN THEN 
                  SPEC$MRL = SPEC$FIXLEN; 
              END 
  
          # NOW FIND OUT WHAT THE IMPLICIT MINIMUM RECORD              #
          # LENGTH IS. THE IMPLICIT LENGTH IS THE LENGTH               #
          # WHICH IS NEEDED TO HOLD ALL THE KEY AND SUM FIELDS.        #
  
          RECLEN = 0; 
          FOR I = SPEC$1STKEY WHILE I NQ 0 DO 
              BEGIN 
              LASTBIT = BYTE*SPEC$KEYBYTE[I] + SPEC$KEYBIT[I] 
               + BYTE*SPEC$KEYNBYT[I] + SPEC$KEYNBIT[I];
              IF RECLEN LS LASTBIT THEN 
                  RECLEN = LASTBIT; 
              I = SPEC$NEXTKEY[I];
              END 
          FOR I = SPEC$1STSUM WHILE I NQ 0 DO 
              BEGIN 
              LASTBIT = SPEC$SUMBIT[I]
                        + SPEC$SUMREP[I]*SPEC$SMLENE[I];
              IF RECLEN LS LASTBIT THEN 
                  RECLEN = LASTBIT; 
              I = SPEC$NEXTSUM[I];
              END 
  
          # VARIABLE RECLEN NOW HAS THE IMPLICIT MNR                   #
          # SET RECLEN := RECLEN DIV BYTE                              #
  
          RECLEN = (RECLEN + BYTE - 1)/BYTE;
          SPEC$MNR = MNR; 
          IF SPEC$MNR LS RECLEN THEN
              SPEC$MNR = RECLEN;
  
          # NOW MAKE SURE THAT SPEC$MRL                                #
          # IS  REASONABLE WHEN COMPARED TO SPEC$MNR                   #
  
          IF SPEC$MRL LS SPEC$MNR THEN
              BEGIN 
              S$ERROR(E$116); 
              SPEC$MRL = SPEC$MNR;
              END 
  
          IF SPEC$MNR EQ SPEC$MRL THEN
              BEGIN 
              SPEC$FIXED = TRUE;
              SPEC$FIXLEN = SPEC$MRL; 
              END 
  
          # MAKE SURE THAT THE RECORD LENGTH (FL OR MRL) IS            #
          # NOT RIDICULOUSLY LARGE -- AVOID ABORT LABELLED S$ALCS-1    #
  
          IF SPEC$MRL GR 5000 OR SPEC$FIXLEN GR 5000 THEN 
              BEGIN 
              # SORT 4 CALLED FROM FTN WITH *SMABT* DOES NOT           #
              # COMPLAIN ABOUT *MRL* NEGATIVE OR TOO LARGE, SO         #
              # SORT 5 ALSO CANNOT.                                    #
              IF S$CALLR EQ 5 THEN
                  BEGIN 
                  SPEC$MRL = 5000;
                  SPEC$FIXLEN = 5000; 
                  END 
              ELSE
                  BEGIN 
                  S$ERROR(E$113); 
                  SPEC$MRL = MRL; 
                  SPEC$FIXLEN = FIXLEN; 
                  END 
              END 
  
  
          # IF KEY OR SUM FIELDS OVERLAP, THEN DIAGNOSE AND STOP       #
          # ALSO DIAGNOSE TOO MANY KEY/SUM CHARACTERS                  #
  
          FOR I = 1 STEP 1 UNTIL 200 DO 
          BEGIN 
              KEY$SUMFLD[I] = FALSE;
              KEY$SEQAON[I] = FALSE;
          END 
          LK = 0;  # TOTAL OF KEY/SUM BITS SPECIFIED                   #
          NKEYS = 0;
          FOR I = SPEC$1STKEY WHILE I NQ 0 DO 
              BEGIN 
              NKEYS = NKEYS + 1;
              KEY$LENGTH[NKEYS] = BYTE * SPEC$KEYNBYT[I] +
                  SPEC$KEYNBIT[I];
              KEY$OFFSET[NKEYS] = BYTE * SPEC$KEYBYTE[I] +
                  SPEC$KEYBIT[I]; 
              KEY$SEQAON[NKEYS] = SPEC$SEQAON[I]; 
              I = SPEC$NEXTKEY[I];
              END 
#     ADD SUM FIELDS TO KEY FIELD ARRAY                               # 
  
          IF SPEC$1STSUM NQ 0 THEN
              BEGIN 
              FOR I = SPEC$1STSUM WHILE I NQ 0 DO 
                  BEGIN 
                  NKEYS = NKEYS+1;
                  KEY$OFFSET[NKEYS] = SPEC$SUMBIT[I]; 
                  KEY$LENGTH[NKEYS] = SPEC$SMLENE[I] *
                      SPEC$SUMREP[I]; 
                  KEY$SUMFLD[NKEYS] = TRUE;      # THIS IS A SUM FIELD #
                  LK = LK + KEY$LENGTH[NKEYS];
                  I = SPEC$NEXTSUM[I];
                  END 
              END 
  
          IF NKEYS GQ 2 THEN
              BEGIN 
              SORTED = FALSE; 
              FOR I=I WHILE NOT SORTED DO 
                  BEGIN 
                  SORTED = TRUE;
                  FOR I = 1 STEP 1 UNTIL NKEYS-1 DO 
                      BEGIN 
                      IF KEY$OFFSET[I] GR KEY$OFFSET[I+1] THEN
                          BEGIN 
                          KEY$OFFSET[I] == KEY$OFFSET[I+1]; 
                          KEY$LENGTH[I] == KEY$LENGTH[I+1]; 
                          KEY$SUMFLD[I] == KEY$SUMFLD[I+1]; 
                          KEY$SEQAON[I] == KEY$SEQAON[I+1]; 
                          SORTED = FALSE; 
                          END 
                      END 
                  END 
              END 
  
  
          IF NKEYS GQ 2 THEN
              BEGIN 
              FOR I = 1 STEP 1 UNTIL NKEYS-1 DO 
                  BEGIN 
                  OVERLAP$PNTR = KEY$OFFSET[I] + KEY$LENGTH[I]; 
                  IF KEY$OFFSET[I+1] LS OVERLAP$PNTR THEN 
                   BEGIN
                     IF (KEY$SUMFLD[I] OR KEY$SUMFLD[I+1]) THEN 
                     BEGIN
                          IF (KEY$SUMFLD[I] AND KEY$SUMFLD[I+1]) THEN 
                          BEGIN 
                              S$ERROR(E$161);# SUM FIELDS OVERLAP      #
                              STATUS$NORML = FALSE; 
                          END 
                     ELSE 
                      BEGIN 
                      S$ERROR(E$81);
                      STATUS$NORML=FALSE; 
                      END 
                     END
                     ELSE 
                      BEGIN 
                          IF (KEY$SEQAON[I] OR KEY$SEQAON[I+1]) THEN
                          BEGIN 
                              S$ERROR(E$160);# ALTER ON OVERLAPPING KEY#
                              STATUS$NORML = FALSE; 
                          END 
                          ELSE
                          BEGIN 
                              S$ERROR(E$159);# KEY FIELDS OVERLAP      #
                              OVERLAP = TRUE; 
                          END 
                      END 
                   END
                  END 
              END 
  
          IF OVERLAP THEN                # IF KEY FIELDS OVERLAP       #
          BEGIN                          # GET ALL NEEDED KEY INFO     #
            FOR I = SPEC$1STKEY WHILE I NQ 0 DO 
            BEGIN 
                  OVER$LENGTH[I] = BYTE * SPEC$KEYNBYT[I] 
                                   + SPEC$KEYNBIT[I]; 
                  OVER$OFFSET[I] = BYTE * SPEC$KEYBYTE[I] 
                                   + SPEC$KEYBIT[I];
                  OVER$LASTBT[I] = OVER$LENGTH[I] + OVER$OFFSET[I] - 1; 
                  IF I NQ SPEC$1STKEY THEN
                     SPEC$PREKEY[I] = I - 2;
                  LASTKEY = I;
                  I = SPEC$NEXTKEY[I];
            END 
# **                                                                ** #
#   FROM FIRST KEY FIELD TO THE END, CHECK EACH FOLLOWING KEY FIELD    #
#   TO DETERMINE WHICH KIND OF THE OVERLAPPING SITUATIONS :            #
#   (1) IF SECOND OVERLAPS THE LEFT PART OF THE FIRST ONE, CHOP  OFF   #
#       THE OVERLAPPING PART OF THE SECOND ONE AND GET NEW LENGTH.     #
#   (2) IF SECOND OVERLAPS THE RIGHT SIDE OF THE FIRST ONE, CHOP  OFF  #
#       AND GET A NEW OFFSET AND LENGTH.                               #
#   (3) IF SECOND CONTAINED IN THE FIRST ONE, ADJUST  POINTERS FOR     #
#       PREVIOUS ONE AND NEXT ONE. THIS KEY CAN BE SKIPPED.            #
#   (4) IF SECOND CONTAINS THE FIRST ONE, SPLIT  THE SECOND ONE INTO   #
#       THREE PARTS :(I) ADJUST KEY LENGTH OF OLD KEY FIELD .          #
#                    (II) IGNOR THIS PART.                             #
#                    (III) CREATE NEW KEY FIELD WITH NEW OFFSET,LENGTH.#
#                          ADJUST PREVIOUS AND NEXT KEY POINTERS.      #
# **                                                                ** #
            FOR I = SPEC$1STKEY WHILE I NQ 0  DO
            BEGIN 
              IF (SPEC$KEYNBIT[I] NQ 0) THEN
                  BITOP = TRUE; 
              FOR K = SPEC$NEXTKEY[I] WHILE K NQ 0 DO 
              BEGIN 
#   (1)   # 
                  IF (OVER$LASTBT[K] GQ OVER$OFFSET[I]) 
                                  AND 
                     (OVER$LASTBT[K] LQ OVER$LASTBT[I]) 
                                  AND 
                     (OVER$OFFSET[K] LS OVER$OFFSET[I]) THEN
                    BEGIN 
                       IF (SPEC$KEYNBYT[K] EQ 0) AND
                          (SPEC$KEYBYTE[K] EQ 0) THEN 
                              SPEC$KEYNBIT[K] = OVER$OFFSET[I] -
                                                OVER$OFFSET[K]; 
                       ELSE 
                         BEGIN
                             SPEC$KEYNBYT[K] = (OVER$OFFSET[I] -
                                   SPEC$KEYBYTE[K] * BYTE) / BYTE;
                             IF BITOP THEN
                               SPEC$KEYNBYT[K] = SPEC$KEYNBYT[K] + 1; 
                         END
                    END 
#   (2)   #       ELSE
                  IF (OVER$OFFSET[K] GQ OVER$OFFSET[I]) 
                                AND 
                     (OVER$LASTBT[K] GR OVER$LASTBT[I]) 
                                AND 
                     (OVER$OFFSET[K] LQ OVER$LASTBT[I]) THEN
                    BEGIN 
                      IF (SPEC$KEYBYTE[K] EQ 0) AND 
                         (SPEC$KEYNBYT[K] EQ 0) THEN
                         BEGIN
                          SPEC$KEYBIT[K] = OVER$LASTBT[I];
                          SPEC$KEYNBIT[K]= OVER$LASTBT[K] 
                                                  - OVER$LASTBT[I]; 
                         END
                      ELSE
                         BEGIN
                          SPEC$KEYBYTE[K] =(OVER$LASTBT[I]+1) / BYTE; 
                          SPEC$KEYNBYT[K] =(OVER$LASTBT[K]
                                  - SPEC$KEYBYTE[K]* BYTE+1 ) / BYTE; 
                         END
                    END 
#   (3)   #       ELSE
                  IF (OVER$OFFSET[I] LQ OVER$OFFSET[K]) 
                                   AND
                     (OVER$LASTBT[I] GQ OVER$LASTBT[K]) THEN
                    BEGIN 
                        SPEC$PREKEY[SPEC$NEXTKEY[K]] = SPEC$PREKEY[K];
                        SPEC$NEXTKEY[SPEC$PREKEY[K]] = SPEC$NEXTKEY[K]; 
                        NKEYS = NKEYS - 1;
                    END 
#   (4)   #       ELSE
                  IF (OVER$OFFSET[I] GR OVER$OFFSET[K]) 
                                   AND
                     (OVER$LASTBT[I] LS OVER$LASTBT[K]) THEN
                    BEGIN 
                       IF (SPEC$KEYNBYT[K] EQ 0) AND
                          (SPEC$KEYBYTE[K] EQ 0) THEN 
                         BEGIN
                            SPEC$KEYNBIT[K] = OVER$OFFSET[I] -
                                              OVER$OFFSET[K]; 
                            SPEC$KEYBIT[LASTKEY + 2] = OVER$LASTBT[I];
                            SPEC$KEYNBIT[LASTKEY + 2] = OVER$LASTBT[K]
                                                     - OVER$LASTBT[I];
                            SPEC$KEYBYTE[LASTKEY + 2] = 0;
                            SPEC$KEYNBYT[LASTKEY + 2] = 0;
                         END
                       ELSE 
                         BEGIN
                           SPEC$KEYNBYT[K] =(OVER$OFFSET[I] - 
                                SPEC$KEYBYTE[K] * BYTE ) / BYTE;
                           SPEC$KEYBYTE[LASTKEY + 2] =
                                  (OVER$LASTBT[I] +1)  / BYTE;
                           SPEC$KEYNBYT[LASTKEY + 2] = (OVER$LASTBT[K]
                            - SPEC$KEYBYTE[LASTKEY + 2]* BYTE+1 )/ BYTE;
                           IF BITOP  THEN 
                             SPEC$KEYNBYT[K] = SPEC$KEYNBYT[K] + 1; 
                           SPEC$KEYBIT[LASTKEY + 2] = 0;
                           SPEC$KEYNBIT[LASTKEY + 2] = 0; 
                         END
                     SPEC$KEYTYPE[LASTKEY + 2] = SPEC$KEYTYPE[K]; 
                     SPEC$KEYASC[LASTKEY + 2] = SPEC$KEYASC[K]; 
                     SPEC$KEYCS[LASTKEY + 2] = SPEC$KEYCS[K]; 
                     SPEC$KEYALT[LASTKEY + 2] = SPEC$KEYALT[K]; 
                     SPEC$NEXTKEY[LASTKEY + 2] = SPEC$NEXTKEY[K]; 
                     SPEC$PREKEY[LASTKEY + 2] = K;
                     SPEC$PREKEY[SPEC$NEXTKEY[K]] = LASTKEY + 2;
                     SPEC$NEXTKEY[K] = LASTKEY + 2; 
                     OVER$LENGTH[LASTKEY + 2] = 
                       BYTE * SPEC$KEYNBYT[LASTKEY +2] +
                              SPEC$KEYNBIT[LASTKEY +2]; 
                     OVER$OFFSET[LASTKEY + 2] = 
                       BYTE * SPEC$KEYBYTE[LASTKEY +2] +
                              SPEC$KEYBIT[LASTKEY +2];
                     OVER$LASTBT[LASTKEY +2] =
                       OVER$OFFSET[LASTKEY +2] +
                              OVER$LENGTH[LASTKEY + 2] - 1; 
                     LASTKEY = LASTKEY + 2; 
                     NKEYS = NKEYS + 1; 
                    END 
                  IF (SPEC$KEYBIT[K] EQ 0) AND
                     (SPEC$KEYNBIT[K] EQ 0) AND 
                     (SPEC$KEYNBYT[K] EQ 0) THEN
                     SPEC$KEYNBYT[K] = SPEC$KEYNBYT[K] + 1; 
                  OVER$LENGTH[K] = BYTE * SPEC$KEYNBYT[K] + 
                                              SPEC$KEYNBIT[K];
                  OVER$OFFSET[K] = BYTE * SPEC$KEYBYTE[K] + 
                                              SPEC$KEYBIT[K]; 
                  OVER$LASTBT[K] = OVER$OFFSET[K] + OVER$LENGTH[K]-1; 
                  K  = SPEC$NEXTKEY[K]; 
              END  # FOR K #
              BITOP = FALSE;
              I = SPEC$NEXTKEY[I];
            END    # FOR I #
          END        # OUTTER IF OVERLAP #
          FOR I = SPEC$1STKEY WHILE I NQ 0 DO  # KEY/SUM LENGTH (LK) #
            BEGIN 
               LK = LK + BYTE * SPEC$KEYNBYT[I] + SPEC$KEYNBIT[I];
               I = SPEC$NEXTKEY[I]; 
            END 
          SPEC$NKEYS = NKEYS; 
          IF LK GR 255*BYTE THEN
              BEGIN 
              S$ERROR(E$99);   # F = MORE THAN 255 KEY/SUM CHARS       #
              STATUS$NORML = FALSE;  # TELL S$GTCSP                    #
              END 
  
          # ENSURE THAT FILE NAMES FOR A MERGE ARE UNIQUE              #
  
          IF NOT SPEC$SORT THEN   # A MERGE HAS BEEN SPECIFIED         #
              IF S$CALLR NQ 3 THEN  # SMEND SETS ALL FITS TO (FTN)     #
                  BEGIN 
                  FOR I = SPEC$1STINF WHILE I NQ 0 DO 
                      BEGIN 
                      IF SPEC$INNAME[I] EQ SPEC$OUTNAME THEN
                          BEGIN 
                          S$ERROR(E$158); 
                          STATUS$NORML = FALSE; 
                          END 
                      FOR J = SPEC$NEXTIN[I] WHILE J NQ 0 DO
                          BEGIN 
                          IF SPEC$INNAME[J] EQ SPEC$INNAME[I] THEN
                                  BEGIN 
                                  S$ERROR(E$158); 
                                  STATUS$NORML = FALSE; 
                                  END 
                          J = SPEC$NEXTIN[J]; 
                          END 
                      I = SPEC$NEXTIN[I]; 
                      END 
                  END 
  
#     IF FAST I/O WANTED, SET BFS APPROPRIATELY                        #
  
          IF SPEC$FASTIN GR 0 THEN
              BEGIN                    # ALL INPUT FILES ARE RT=F      #
              FOR I = SPEC$1STINF WHILE I NQ 0 DO 
                  BEGIN 
                  S$STBFS(SPEC$INFIT[I]); 
                  I = SPEC$NEXTIN[I]; 
                  END 
              END 
          IF SPEC$FASTOUT GR 0 THEN 
              S$STBFS(SPEC$OUTFIT); 
  
          IF SPEC$FIXED THEN
              BEGIN 
              IF SPEC$FIXLEN LS SPEC$MRL THEN 
                  SPEC$FIXLEN=SPEC$MRL; 
              ELSE
                  SPEC$MRL=SPEC$FIXLEN; 
              END 
  
#            SET THE MRL AND MNR INTO STATISTICS ARRAY                 #
  
#            N O T E -  THIS SETTING OF THE STATISTICS ARRAY MUST BE   #
#                       DONE AFTER SPEC$FIXLEN,-MRL, AND -MNR ARE SET  #
#                       WITH THEIR FINAL VALUE(S), VALUES THAT WON'T   #
#                       BE CHANGED.                                    #
  
            IF SPEC$FIXED  THEN 
              BEGIN 
              S$ARRYELEM[13] = SPEC$FIXLEN; 
              S$ARRYELEM[15] = SPEC$FIXLEN; 
  
#               SET THE RESERVED ELEMENT OF S$ARRY TO                  #
#               1 IF RECORDS HAVE FIXED LENGTH, AND LEAVE              #
#               0 WHEN RECORDS HAVE VARIABLE LENGTH                    #
              S$ARRYELEM[9]  = 1; 
              END 
            ELSE  # RECORDS DO NOT HAVE FIXED LENGTH #
              BEGIN 
              S$ARRYELEM[13] = SPEC$MNR;
              S$ARRYELEM[15] = SPEC$MRL;
              END 
  
          END  # S$PRSPC #
          TERM
