*DECK CBBLDDC 
USETEXT TSBP2CM 
      PROC CBBLDDC; 
      BEGIN 
# LOCAL FILEORG DEF # 
      DEF FITFO #B<39,3>SBDCARFITWRD[DCOFFSET+11]#; 
      DEF AK #6#; 
  
# EXTERNAL REFERENCES#
      XREF PROC CBCKBUF;      #MEMORY MANAGER PROC# 
      XREF PROC READSC;      #DA ROUTINE TO READ SCHEMA GIVEN ADDRESS#
      XREF PROC CBDBPBD;    #PROC TO A DBP TO DBP TABLE#
      XREF PROC DDLPRNT;     #PROC TO PRINT LINE TO DDL LISTING#
      XREF PROC CBERROR;       #ERROR HANDLER PROC# 
      XREF FUNC CBSSITA;     #FUNC RTNS SBSCH ADDR GIVEN SCH NAME#
      XREF FUNC CBSSRCA;     #FUNC RTNS SBSCH REC ADDR GIVEN SCH NAME#
      XREF ITEM MAXSELENG;   #CONTAINS THE MAXIMUM SUB-ENTRY LENGTH#
  
# LOCAL SCRATCH ITEMS#
      ITEM TEMP1; 
      ITEM TEMP2; 
      ITEM CONCATADR;                  # CONTAINS THE SUB-SCHEMA WORD  #
                                       # ADDRESS OF THE ITEM ENTRY THAT#
                                       # IS DEFINED HAS A CONCATENATED #
                                       # KEY.                          #
      ITEM CONCATCNTR;                 # CONTAINS THE NUMBER OF ITEM   #
                                       # ENTRIES SUBORDINATE TO THE GRP#
                                       # DEFINED HAS A CONCATINATED KEY#
                                       # NEW GROUP ITEMS ARE EXCLUDED  #
                                       # IN THE COUNT.                 #
      ITEM CONCATPTR;                  # POINTS TO THE ITEM ADDRESSES  #
                                       # (DESIGNATED AS CONCATENATED   #
                                       # KEYS) IN THE KEY ENTRY IN THE #
                                       # DATA CONTROL ENTRY.           #
      ITEM LASTKEYADR;                 # WORD ADDRESS OF THE LAST ITEM #
                                       # ENTRY SUBORDINATE TO THE ITEM #
                                       # ENTRY DEFINED AS A CONCAT KEY.#
      ITEM TEMPITMOFSET;       # CONTAINS THE WORD ADDRESS OF THE CONCA#
                               # ATENATED                              #
                               # TENATED ENTRY (SUB-SCHEMA). LATER TO  #
                               # BE USED TO RESTORE THE ORIGINAL VALUE #
                               # BACK INTO SSITEMOFFSET.               #
      CONTROL EJECT;
# SET DC OFFSET, INCREASE SUBSCHEMA SIZE FOR DATACONTROL ENTRY# 
      DCOFFSET = SBCWSBLENG[0]; 
      SBCWSBLENG[0] = SBCWSBLENG[0]+SCAREADCLENG[0];
      CBCKBUF(P<SUBSCHEMA>,SBCWSBLENG[0]);
# SET NEXT DC OFFSET POINTER IN LAST DC PROCESSED#
      IF LASTDATACONT NQ 0 THEN 
        SBDCNXTAREAP[LASTDATACONT] = DCOFFSET-LASTDATACONT; 
      LASTDATACONT = DCOFFSET;
# READ DATA-CONTROL ENTRY FROM SCHEMA INTO SUBSCHEMA# 
      P<DATACONT> = LOC(SUBSCHEMA)+DCOFFSET;
      READSC(DATACONT,SCAREADCLENG[0],SCAREADCNTLA[0]); 
# ZERO NEXT DATA-CONTROL OFFSET POINTER IN DATACONTROL ENTRY# 
      SBDCNXTAREAP[DCOFFSET] = 0; 
# IF SDA PROC ADD TO DBP LIST AND PUT ORDINAL INTO SUBSCHEMA ENTRY# 
      IF SCDCSDAPRCN[DCOFFSET] NQ 0 THEN
        BEGIN 
        CBDBPBD(SCDCSDAPRCN[DCOFFSET]); 
        SBDCSDAORD [DCOFFSET] = DBPINDEX + 1; 
        END 
      ELSE
        SBDCSDAORD[DCOFFSET] = 0; 
# IF COMP/DCMP PROC ADD TO DBP LIST, PUT ORDINAL INTO SUBSCHEMA ENTRY  #
      CDTBLOFFSET = DCOFFSET + SBDCCDTBLPTR[DCOFFSET];
      IF SBDCCDTBLPTR[DCOFFSET] NQ 0 THEN 
        BEGIN 
        FOR TEMP1 = 0 STEP 1 UNTIL SBDCCDTBLENG[DCOFFSET]-1 DO
          BEGIN 
          CBDBPBD(SCDCCDDBPNME[CDTBLOFFSET + TEMP1]); 
          SBDCCDDBPORD[CDTBLOFFSET + TEMP1] = DBPINDEX + 1; 
          END 
        END 
# RECORD CODE ENTRY#
      RCOFFSET = DCOFFSET+SBDCRECCDPTR[DCOFFSET]; 
      IF SBDCRECCDPTR[DCOFFSET] NQ 0 THEN 
        BEGIN 
# CHECK RECORD CODE SUB-ENTRY LENGTH AGAINST THE MAXIMUM# 
        IF SBDCRECCDLEN[DCOFFSET] GR MAXSELENG THEN 
          MAXSELENG = SBDCRECCDLEN[DCOFFSET]; 
# IF TYPE DB PROC THEN CBDBPBD AND PUT ORDINAL INTO ENTRY#
        IF SBDCRCDETYP[RCOFFSET] THEN 
          BEGIN 
          CBDBPBD(SCDCRCDEPROC[RCOFFSET]);
          SBDCRCDEPRCO [RCOFFSET] = DBPINDEX + 1; 
          END 
        ELSE
          IF NOT SBDCRECCDFLG[DCOFFSET] THEN
            BEGIN 
            SCDCRCDEITMP[RCOFFSET] = 0; 
            RCOFFSET = RCOFFSET + 1;
            END 
# LOOP THRU LITERAL WORDS REPLACING RECORD ADDRESS WITH RECORD ORDINAL# 
RCLOOP: 
        RCOFFSET = RCOFFSET+1;
        INDEX = CBSSRCA(SCDCRCDERECA[RCOFFSET]);
      SCDCRCDERECA[RCOFFSET] = 0; 
      IF INDEX EQ 0 THEN
        SBDCRCDERECO[RCOFFSET] = 0; 
      ELSE
        BEGIN 
        SBDCRCDERECO[RCOFFSET]
          = SBRECORDINAL[INDEX];
        END 
        IF SBDCRCDENEXT[RCOFFSET] THEN GOTO RCLOOP; 
        END 
      CONTROL EJECT;
# PROCESS KEY TABLE FROM DATA CONTROL ENTRY#
      IF SBDCALTRKYPT[DCOFFSET] NQ 0 THEN 
        BEGIN 
        KEYOFFSET = DCOFFSET+SBDCALTRKYPT[DCOFFSET];
KEYLOOP:  
# **IF ALTERNATE KEY IN SCHEMA, THEN SET FLAG TO FALSE.                #
        IF NOT SCDCKEYPRI[KEYOFFSET+1] THEN    #THIS IS AN ALT KEY.    #
          SBCWALTKEY[0] = FALSE;     #ALT KEYS EXIST. # 
# **GET ADDRESS OF SUB-SCHEMA RECORD# 
        RECOFFSET = CBSSRCA(SCDCRCENTRYA[KEYOFFSET]); 
        SCDCRCENTRYA[KEYOFFSET] = 0;
        SBDCRCENTRYA[KEYOFFSET] = RECOFFSET;
# **IF IMBEDDED KEY UPDATE DATA NAME ADDRESS AND RECORD ORDINAL#
# **FOR NON-IMBEDDED KEY DONT CHANGE INFO FROM SCHEMA#
      IF SCDCKEYIMBED[KEYOFFSET+1] THEN 
          BEGIN 
# **IF RECORD NOT IN SUBSCHEMA AND PRIMARY KEY THEN ERROR#
          IF RECOFFSET EQ 0 THEN
            BEGIN 
            IF SCDCKEYPRI[KEYOFFSET+1] THEN 
          CBERROR(304,FALSE,SBARNAME30[AREAOFFSET+SBARNAMEPTR 
                 [AREAOFFSET]],SBARLENGCHAR[AREAOFFSET]); 
              GOTO KEYLOOPNEXT; 
            END 
# ****IF PRIMARY KEY ITEM NOT IN SUBSCHEMA THEN ERROR#
          IF SBDCCONCTFG[KEYOFFSET+1] THEN # CHECK FOR CONCATENATED KEY#
            CONCTKY;                       # ENTRY.                    #
           ELSE 
            SSITEMOFFSET = CBSSITA(SCDCKEYDNADR[KEYOFFSET+2],0);
      CHKMAJK;
          SBDCKEYDNADR[KEYOFFSET+2] = SSITEMOFFSET; 
          SBDCRECORD[KEYOFFSET+2] = SBRECORDINAL[RECOFFSET];
        IF SSITEMOFFSET EQ 0 AND SCDCKEYPRI[KEYOFFSET+1] THEN 
          CBERROR(304,FALSE,SBARNAME30[AREAOFFSET+SBARNAMEPTR 
                  [AREAOFFSET]],SBARLENGCHAR[AREAOFFSET]);
# ****SET KEY FLAG IN SUBSCHEMA ITEM ENTRY# 
        IF SSITEMOFFSET NQ 0 THEN 
        BEGIN 
        IF SCDCKEYPRI[KEYOFFSET+1] THEN 
          SBITMKEYFLG[SSITEMOFFSET] = TRUE; 
        ELSE
          SBITMALTKEYF[SSITEMOFFSET] = TRUE;
# ****IF RT=AK AND IMBEDDED PRIMARY KEY NOT IDENTICAL THEN ERROR# 
          IF FITFO EQ AK
          AND SBDCKEYPRI[KEYOFFSET+1] 
        AND (SBITMDBCLASS[SSITEMOFFSET] NQ 10 OR
                             SBITMPTINFO[SSITEMOFFSET] NQ 0) THEN 
          CBERROR(305,TRUE,SBARNAME30[AREAOFFSET+SBARNAMEPTR
                  [AREAOFFSET]],SBARLENGCHAR[AREAOFFSET]);
        END 
# ****IF ALTERNATE KEY AND ITEM NOT IN SUBSCH SET FLAG IN KEY ENTRY#
          IF SSITEMOFFSET EQ 0 AND NOT SCDCKEYPRI[KEYOFFSET] THEN 
            BEGIN 
            SBDCKEYOMIT[KEYOFFSET+1] = TRUE;
            GOTO KEYLOOPNEXT; 
            END 
# ****NO QUALIFIER NECESSARY IN SUBSCHEMA#
          SBDCKEYNXT[KEYOFFSET+2] = FALSE;
      KEYMESSAGE = " "; 
# ****PRINT IMBEDDED KEY TO OUTPUT LISTING# 
          IF SBDCKEYPRI[KEYOFFSET+1] THEN 
            C<1,14>KEYMESSAGE = "PRIMARY KEY";
          ELSE
        IF SBDCKEYSORT[KEYOFFSET+1] THEN
          C<1,14>KEYMESSAGE = "SEQ SORT KEY"; 
        ELSE
            C<1,14>KEYMESSAGE = "ALTERNATE KEY";
          TEMP1 = SBITMSRCLNEN[SSITEMOFFSET]; 
          FOR INDEX=19 STEP -1 UNTIL 15 DO
            BEGIN 
            TEMP2 = TEMP1/10; 
            C<INDEX>KEYMESSAGE = TEMP1-10*TEMP2+"0";
            TEMP1 = TEMP2;
            END 
          C<27,SBITMNMELENC[SSITEMOFFSET]>KEYMESSAGE
          = SBITMNAME30[SSITEMOFFSET+SBITMNAMEPTR[SSITEMOFFSET]]; 
          INDEX = 27+SBITMNMELENC[SSITEMOFFSET];
          C<INDEX,10>KEYMESSAGE = " FOR AREA "; 
          INDEX = INDEX+10; 
          C<INDEX,SBARLENGCHAR[AREAOFFSET]>KEYMESSAGE 
          = SBARNAME30[AREAOFFSET+SBARNAMEPTR[AREAOFFSET]]; 
          INDEX = INDEX+SBARLENGCHAR[AREAOFFSET]; 
          DDLPRNT(KEYMESSAGE,INDEX+1);
          END 
        ELSE
# ****PRINT NON-IMBEDDED KEYS TO OUTPUT LISTING#
          BEGIN 
          C<1,26>KEYMESSAGE = "NON-IMBEDDED KEY"; 
          C<27,SBDCKEYDNLEN[KEYOFFSET+2]>KEYMESSAGE 
            = SBDCKEYDNM30[KEYOFFSET+SBDCKEYDNPTR[KEYOFFSET+2]];
          INDEX = 27+SBDCKEYDNLEN[KEYOFFSET+2]; 
          C<INDEX,10>KEYMESSAGE = " FOR AREA "; 
          INDEX = INDEX+10; 
          C<INDEX,SBARLENGCHAR[AREAOFFSET]>KEYMESSAGE 
          = SBARNAME30[AREAOFFSET+SBARNAMEPTR[AREAOFFSET]]; 
          INDEX = INDEX+SBARLENGCHAR[AREAOFFSET]; 
          DDLPRNT(KEYMESSAGE,INDEX+1);
          END 
KEYLOOPNEXT:  
        IF SBDCKEYNITM[KEYOFFSET+1] NQ 0 THEN 
          BEGIN 
        IF SBDCKEYNITM[KEYOFFSET+1] GR MAXSELENG THEN 
          MAXSELENG = SBDCKEYNITM[KEYOFFSET+1]; 
          KEYOFFSET = KEYOFFSET+SBDCKEYNITM[KEYOFFSET+1]; 
          GOTO KEYLOOP; 
          END 
# CALCULATE LENGTH OF LAST KEY ITEM IF IT IS A CONCATENATED KEY AND    #
# COMPARE AGAINST MAXIMUM SUB-ENTRY LENGTH. OTHER TYPES OF KEYS ARE    #
# NOT CONSIDERED BECAUSE THEIR LENGTHS WILL BE LESS THAN THE MINIMUM   #
# SUB-ENTRY LENGTH FOR FORSEEABLE FUTURE IMPLEMENTATIONS.              #
      IF SBDCCONCTFG[KEYOFFSET+1] THEN
        BEGIN 
        TEMP1 = 2+SBDCCNNMELW[KEYOFFSET+2]+SBDCCNNBRITM[KEYOFFSET+2]; 
        IF TEMP1 GR MAXSELENG THEN
          MAXSELENG = TEMP1;
        END 
        END 
      RETURN; 
  PROC CONCTKY; 
    BEGIN 
      SSITEMOFFSET = SBRECNXITEMP[RECOFFSET] + RECOFFSET; # GET THE    #
          # WORD ADDRESS OF THE FIRST ITEM ENTRY IN THE SUBJECT RECORD.#
  
      FOR TEMP1 = 1 WHILE TEMP1 NQ SBRECNBRITMS[RECOFFSET] DO 
        BEGIN # STEP THROUGH THE ITEM ENTRIES LOOKING FOR A MATCH      #
              # WITH THE KEY-NAME.                                     #
        IF (SBITMLEVEL[SSITEMOFFSET] EQ LEVEL88) # IF LEVEL88 ITEM     #
         AND (SBITMNEXTP[SSITEMOFFSET] NQ 0)     # AND NOT LAST ITEM   #
        THEN
          BEGIN 
          SSITEMOFFSET = SSITEMOFFSET + SBITMNEXTP[SSITEMOFFSET]; 
          TEST TEMP1;                            # SKIP IT             #
          END 
  
          IF C<0,SBITMNMELENC[SSITEMOFFSET]>SBITMNAME30 
            [SSITEMOFFSET+SBITMNAMEPTR[SSITEMOFFSET]] NQ
            C<0,SBDCCNNMELC[KEYOFFSET+2]>SBDCCNNME30[KEYOFFSET+3] THEN
              BEGIN 
                SSITEMOFFSET = SSITEMOFFSET + SBITMNEXTP[SSITEMOFFSET]; 
                 # GET THE WORD ADDRESS OF THE NEXT ITEM ENTRY.        #
                TEMP1 = TEMP1 + 1;
                TEST TEMP1; 
              END 
          CONCATADR = SSITEMOFFSET; 
          TEMPITMOFSET = SSITEMOFFSET;
          SBDCCNKEYORD[KEYOFFSET+2] = SBITMORDINAL[CONCATADR];
          CONCATPTR = KEYOFFSET + SBDCCNNMELW[KEYOFFSET+2] + 3; # ADJ P#
                 # TO THE DBI ADDREES IN THE KEY ENTRY.                #
              CONCATCNTR = 0;  # INITIALIZE CONCATINATED KEY COUNTER.  #
          FOR TEMP2 = CONCATADR+SBITMNEXTP[CONCATADR] 
            STEP SBITMNEXTP[TEMP2] WHILE SBITMLEVEL[TEMP2] GR 
              SBITMLEVEL[CONCATADR] DO
                BEGIN # STEP THRU THE ITEM ENTRIES SUBORDINATE TO THE  #
                      # KEY ENTRY. TALLY THE NUMBER OF ITEMS EXCLUDING #
                      # THE NEW GROUP ENTRIES.                         #
                  IF NOT SBITMNEWGRP[TEMP2] THEN
                    IF SBITMLEVEL[TEMP2] NQ O"64" THEN
                      IF NOT SBITMREDEFFG[TEMP2] THEN 
                  # CHECK IF NEW GROUP OR LEVEL 88 OR REDEFINE ITEM.   #
                    CONCATCNTR = CONCATCNTR + 1; # NOT A NEW GROUP ENT #
                                                 # INCREMENT COUNTER.  #
                  IF SBITMNEXTP[TEMP2] EQ 0 THEN # CHECK FOR LAST ITEM #
                                                 # OF THE RECORD.      #
                    GOTO CKCNTR;
                END 
    CKCNTR:   #   # 
          LASTKEYADR = TEMP2; 
          IF SBITMTYPE[CONCATADR] NQ 0 OR  # CHECK IF THE CONCATENATED #
                              # KEY ITEM IS A NON-REPEATING GROUP ITEM #
            CONCATCNTR NQ SBDCCNNBRITM[KEYOFFSET+2] THEN # CK IF THE   #
                   # NUMBER OF ITEMS FOUND SUBORDINATE TO THE KEY MATCH#
                   # THE THE NUMBER OF ITEMS SPECIFIED IN THE DATA     #
                   # CONTROL ENTRY.                                    #
            GOTO ISSUEDIAG; 
          FOR TEMP2=0 STEP 1 UNTIL SBDCCNNBRITM[KEYOFFSET+2] - 1 DO 
            BEGIN # STEP THRU THE DBI ENTRIES IN THE KEY ENTRIES       #
                 # VERIFING THAT THE DBIS IN THE SUB-SCHEMA ARE SPECIF-#
                 # IED IN THE CONTIGIOUS MANNER AS IN THE SCHEMA.      #
              SSITEMOFFSET = CBSSITA(SBDCCNDBIS[CONCATPTR + TEMP2]
                                     ,TEMPITMOFSET);
                 # GET THE SUB-SCHEMA ADDRESS OF THE DBI WHOSE ADDRESS #
                 # WAS SPECIFIED IN THE KEY ENTRY.                     #
              CONCATADR = SBITMNEXTP[CONCATADR] + CONCATADR; # CALC    #
                 # THE WORD ADDRESS OF THE NEXT ITEM ENTRY.            #
              IF SSITEMOFFSET LQ TEMPITMOFSET OR
                SSITEMOFFSET GR LASTKEYADR OR 
                (TEMP2 NQ 0 AND SSITEMOFFSET LQ SBDCCNDBIS[CONCATPTR +
                  TEMP2 - 1]) THEN      # CHECK IF THE                 #
                       # SUB-SCHEMA ADDRESS FALLS IN THE CONCATINATED  #
                       # KEY RANGE. ALSO CHECK IF THE CONCATENATED KEYS#
                       # ARE IN THE SAME ORDER AS IN THE SCHEMA.       #
                BEGIN 
    ISSUEDIAG:   #   #
                  SSITEMOFFSET = TEMPITMOFSET;
              CBERROR(313,TRUE,SBITMNAME30[SSITEMOFFSET+
               SBITMNAMEPTR[SSITEMOFFSET]],SBITMNMELENC[SSITEMOFFSET]); 
                  RETURN; 
                END 
              SBDCCNDBIS[CONCATPTR+TEMP2] = SSITEMOFFSET; 
            END 
          SSITEMOFFSET = TEMPITMOFSET; # RESTORE THE WORD ADDRESS OF   #
                                       # KEY ENTRY IN THE SUB-SCHEMA.  #
          RETURN; 
        END 
      SSITEMOFFSET = 0; 
      RETURN; 
    END 
   PROC CHKMAJK;
#**********************************************************************#
#                            C H K M A J K                             #
#   PURPOSE:                                                           #
#         TO FLAG MAJOR KEYS, BOTH PRIMARY AND ALTERNATE, IN THE       #
#         COBOL SUB-SCHEMA.                                            #
#                                                                      #
#   ENTRY CONDITIONS:                                                  #
#         THIS ROUTINE IS CALLED FROM CBBLDDC WHEN A KEY ITEM IS       #
#         DETECTED DURING THE PROCESSING OF THE DATA CONTROL ENTRY     #
#         IN THE COBOL SUB-SCHEMA.                                     #
#         THE SUB-SCHEMA IS IN CORE AND THE WORD ADDRESS OF THE KEY    #
#         ITEM IS KNOWN(SSITEMOFFSET).                                 #
#                                                                      #
#   EXIT CONDITIONS:                                                   #
#         THE MAJOR KEY FLAG IS SET FOR ITEM'S THAT QUALIFY AS MAJOR   #
#         KEYS.                                                        #
#                                                                      #
#   DESCRIPTION:                                                       #
#         THE FUNCTION OF THIS CODE IS TO, WORKING FROM A GIVEN LEVEL, #
#         LOOK FOR ITEMS THAT QUALIFY AS MAJOR KEYS.  AN ARRAY IS KEPT #
#         TO HOLD THE CURRENT LEVEL BEING SEARCHED.  AN ITEM LEVEL IS  #
#         INSERTED INTO THIS ARRAY IF IT IS GREATER THAN THE CURRENT   #
#         LEVEL.  THE FIRST LEVEL INSERTED INTO THIS ARRAY IS THE KEY  #
#         LEVEL.  THIS IS THE LOWEST LEVEL THAT WILL BE SEARCHED FOR   #
#         MAJOR KEYS.                                                  #
#                                                                      #
#           WHILE THE ITEM LEVEL IS GREATER THAN OR EQUAL TO THE       #
#           CURRENT LEVEL ENTER THE LOOP TO CHECK THE ITEM FOR         #
#           MAJOR KEY QUALIFICATION.                                   #
#           IF THE ITEM LEVEL EQUALS 66 THEN END THE SEARCH.           #
#           IF THE ITEM LEVEL EQUALS 88 THEN SKIP IT AND PROCEED TO    #
#           THE NEXT ITEM.                                             #
#           IF THE ITEM LEVEL IS EQUAL TO THE CURRENT LEVEL,           #
#           THEN IF THE ITEM IS NOT A REDEFINER THEN THE SEARCH IS     #
#           ENDED AT THIS LEVEL.  GET THE PREVIOUS LEVEL FROM THE      #
#           ARRAY OF CURRENT LEVELS AND CONTINUE THE SEARCH AT THAT    #
#           LEVEL.  IF NO MORE LEVELS ARE PRESENT IN THE ARRAY THEN END#
#           THE SEARCH.                                                #
#           ELSE THE ITEM LEVEL IS GREATER THAN THE CURRENT LEVEL,     #
#           THEREFORE ADD THIS ITEM LEVEL TO THE ARRAY OF CURRENT      #
#           LEVELS.  THIS LEVEL BECOMES THE CURRENT SEARCH LEVEL.      #
#           AFTER ALL THE ABOVE CHECKS, ONLY THE ITEM THAT IS THE      #
#           FIRST SUBORDINATE TO THE CURRENT LEVEL OR REDEFINES THE    #
#           CURRENT LEVEL GO THROUGH THE MAJOR KEY CHECK:              #
#           IF THE USAGE SIZE OF THE ITEM IS LESS THAN THAT OF THE KEY #
#           THEN IT QUALIFIES AS A MAJOR KEY.                          #
#           IF THIS WAS THE LAST ITEM IN THE SUBSCHEMA THEN END THE    #
#           SEARCH ELSE CONTINUE THE SEARCH.                           #
#**********************************************************************#
    BEGIN 
      ITEM I1,I2,I3;               # SCRATCH VARIABLES. # 
      ITEM INDEX I;                # ARRAY INDEX.                      #
      ITEM ENDSEARCH B;            # LOOP CONTROL.                     #
  
      ARRAY CURRENT [0:49];        # CURRENT ITEM LEVELS ENCOUNTERED.  #
                                   # A LEVEL IS INSERTED HERE WHEN IT  #
                                   # IS GREATER THAN THAT OF THE LAST  #
                                   # ONE INSERTED.                     #
        BEGIN 
        ITEM CURWORD  I(00,00,60) = [50(0)];
        ITEM CURLEVEL U(00,00,06);
        END 
  
#     STORE THE KEY LEVEL INTO THE ARRAY OF CURRENT LEVELS.            #
#     INDEX = 0 IS USED AS A TERMINATION CONDITION.                    #
  
      INDEX = 1;
      CURLEVEL[INDEX] = SBITMLEVEL[SSITEMOFFSET]; 
      I2 = SSITEMOFFSET + SBITMNEXTP[SSITEMOFFSET]; 
      ENDSEARCH = FALSE;
  
#     PROCESS MAJOR KEYS.                                              #
  
      FOR I1 = I1 
        WHILE NOT ENDSEARCH 
      DO
        BEGIN 
  
#     SEARCH SUBORDINATE ITEMS OF GROUP KEYS AND OF REDEFINED ITEMS FOR#
#     MAJOR KEYS.                                                      #
  
        FOR I2 = I2 STEP SBITMNEXTP[I2] 
          WHILE SBITMLEVEL[I2] GQ CURLEVEL[INDEX] 
        DO
          BEGIN 
  
          IF SBITMLEVEL[I2] EQ LEVEL66
          THEN
            BEGIN 
            ENDSEARCH = TRUE; 
            TEST I1;
            END 
  
          IF SBITMLEVEL[I2] EQ LEVEL88
          THEN
            BEGIN 
            TEST I2;
            END 
  
          IF SBITMLEVEL[I2] EQ CURLEVEL[INDEX]
          THEN
            BEGIN 
            IF SBITMRNRDPTR[I2] EQ 0
            THEN
              BEGIN 
  
#     THE ITEM LEVELS ARE EQUAL AND THE ITEM IS NOT A REDEFINER.       #
#     SKIP TO AN ITEM WHICH HAS THE SAME LEVEL OR ONE LESS THAN THE    #
#     LEVEL IN THE PREVIOUS INDEX LOCATION OF ARRAY CURRENT AND RESUME #
#     THE SEARCH, IF NECESSARY.                                        #
  
              CURLEVEL[INDEX] = 0;
              INDEX = INDEX - 1;
  
              IF INDEX EQ 0        # IF LAST LEVEL IN ARRAY THEN       #
                                   # END THE SEARCH.                   #
              THEN
                BEGIN 
                ENDSEARCH = TRUE; 
                TEST I1;
                END 
  
              I3 = I2;
  
              FOR I3 =I3 STEP SBITMNEXTP[I3]
                WHILE SBITMLEVEL[I3] GR CURLEVEL[INDEX] 
              DO
                BEGIN 
                IF SBITMLEVEL[I3] EQ LEVEL66
                   OR 
                   SBITMNEXTP[I3] EQ 0
                THEN
                  BEGIN 
                  ENDSEARCH = TRUE; 
                  TEST I1;
                  END 
                I2 = I3;
                END 
  
              TEST I2;
              END 
            END 
          ELSE                     # ELSE ITEM LEVEL IS GREATER THAN,  #
                                   # STORE IT IN THE ARRAY CURRENT.    #
            BEGIN 
            INDEX = INDEX + 1;
            CURLEVEL[INDEX] = SBITMLEVEL[I2]; 
            END 
  
#     IF THE USAGE SIZE OF THE ITEM IS LESS THAN THAT OF THE KEY AND   #
#     THE USAGE SIZE IS NOT ZERO, THEN THE ITEM QUALIFIES AS A MAJOR   #
#     KEY.                                                             #
  
          IF SBITMUSESIZE[I2] LS SBITMUSESIZE[SSITEMOFFSET] 
             AND
             SBITMUSESIZE[I2] NQ 0
          THEN
            BEGIN 
            SBITMMAJKEYF[I2] = TRUE;
            END 
  
          IF SBITMNEXTP[I2] EQ 0
          THEN
            BEGIN 
            ENDSEARCH = TRUE; 
            TEST I1;
            END 
  
          END                      #  END SUBORDINATE SEARCH.          #
  
#     THE ITEM LEVEL IS LESS THAN THE LEVEL AT THE INDEX LOCATION IN   #
#     THE ARRAY OF CURRENT LEVELS.  SEARCH THIS ARRAY FOR A LEVEL THAT #
#     IS LESS THAN OR EQUAL TO THE ITEM LEVEL.                         #
  
        FOR INDEX = INDEX STEP -1 
          WHILE SBITMLEVEL[I2] LQ CURLEVEL[INDEX] 
                AND 
                INDEX NQ 0
        DO
          BEGIN 
          IF SBITMLEVEL[I2] EQ CURLEVEL[INDEX]
          THEN
            BEGIN 
            TEST I1;
            END 
  
          CURLEVEL[INDEX] = 0;
          END 
  
#     NO QUALIFYING ITEM WAS FOUND, END THE SEARCH FOR MAJOR KEYS.     #
  
        IF INDEX EQ 0 
        THEN
          BEGIN 
          ENDSEARCH = TRUE; 
          TEST I1;
          END 
  
#     THIS ITEM LEVEL IS NOT CONTAINED IN THE ARRAY OF CURRENT         #
#     ITEM LEVELS.  SKIP THIS ITEM AND GO TO THE NEXT ITEM THAT EQUALS #
#     THE LEVEL AT THE INDEX LOCATION OF ARRAY CURRENT.                #
  
        FOR I2 = I2 STEP SBITMNEXTP[I2] 
          WHILE SBITMLEVEL[I2] GR CURLEVEL[INDEX] 
        DO
          BEGIN 
          IF SBITMLEVEL[I2] EQ LEVEL66
             OR 
             SBITMNEXTP[I2] EQ 0
          THEN
            BEGIN 
            ENDSEARCH = TRUE; 
            TEST I1;
            END 
          END 
        END                        # END PROCESSING FOR MAJOR KEYS.    #
      RETURN; 
    END          # END OF PROC #
      END 
      TERM; 
