*DECK DCBGTBL 
USETEXT TAREATB 
USETEXT TCMMDEF 
USETEXT TCRMDEF 
USETEXT TDESATT 
USETEXT TEXPRES 
USETEXT TFIT
      PROC DCBGTBL; 
      BEGIN 
      DEF RENAMELEVEL #O"62"#;     # LEVEL NUMBER FOR RENAMED ITEM     #
*CALL COMHDRLEN 
      XREF PROC GET;               # CRM READ FROM FILE                #
      XREF ITEM RA0 I;             # ITS ADDRESS IS ALWAYS ZERO.  IT IS#
                                   # USED TO TERMINATE PARAMETER LISTS #
      XREF ITEM RECDORD I;         # INDEX INTO KEY$TBL                #
      XREF ITEM SBSCADD I;         # FWA OF SUBSCHEMA WITHIN SUBSCHEMA #
                                   # LIBRARY                           #
      XREF ITEM TAREA4X;           # POINTER TO AREA TABLE SET BY USE  #
  
      XREF BASED ARRAY SCHEMAFIT;;
  
      ITEM BITPOSITION I;          # RELATIVE BIT POSITION WITHIN RECD #
                                   # ARRAY TO CONVERT FROM CDCS DBMS   #
                                   # CLASS TO CRM CLASS                #
      ITEM CLASSCVT = O"0001 1000 0020 3456 7770";
      ITEM I I;                    # SCRATCH VARIABLE                  #
      ITEM LOOPCON B;              # LOOP CONTROL                      #
      ITEM MAXKEYLEN I;            # LENGTH OF LARGEST KEY IN CHARS    #
      ITEM MAXRECLENC I;           # LENGTH OF LARGEST RECORD IN CHARS #
      ITEM NUMRECS I;              # NUMBER OF RECORDS IN AREA         #
                                   # ARRAY TO CONVERT FROM CDCS TYPE   #
                                   # TO CRM TYPE                       #
      ITEM TYPECVT = O"0123 4524 0000 0000 0000"; 
      ITEM WRECADDR I;             # WA ADDR OF SUBSCHEMA RECORD LIST  #
                                   # ENTRY WITHIN REALM/RELATION TABLE #
  
      ARRAY DBIENTRY [0:0] S(DFSBITMLG);;  # ARRAY TO READ DBI ENTRY   #
      ARRAY OCCURARRAY [0:0] S(DFSBOCCLG);;  # ARRAY TO READ OCCURRING #
                                             # PART OF DBI ENTRY       #
      ARRAY RECDLIST [0:0]  S(DFSBRECLST);   # ARRAY TO READ RECORD    #
                                             # LIST POINTED TO BY      #
                                             # REALM/RELATION LIST     #
          BEGIN 
*CALL SBRECLST
          END 
      ARRAY RLMLSTENT [0:0] S(DFSBRLMLST);  # ARRAY TO READ REALM ENTRY#
                                            # IN REALM/RELATION LIST   #
          BEGIN 
*CALL SBRLMLST
          END 
  
      BASED ARRAY SBITEMENTRY;     # DESCRIPTION OF ITEM ENTRY         #
          BEGIN 
*CALL SBIHDDCLS 
          END 
      BASED ARRAY SBITEMOCCURA;    # DESCRIPTION OF OCCURRING PART OF  #
                                   # ITEM ENTRY                        #
          BEGIN 
*CALL SBIOCDCLS 
          END 
      BASED ARRAY SBRECENTRY;      # DESCRIPTION OF RECORD ENTRY       #
          BEGIN 
*CALL SBRHDDCLS 
          END 
CONTROL EJECT;
*CALL TRNSDBI 
CONTROL EJECT;
#----------------------------------------------------------------------#
#                                                                      #
#     NXTATTR                                                          #
#                                                                      #
#     READ NEXT DBI ENTRY FROM CDCS SUBSCEHMA AND CONVERT INTO CRM     #
#     FORMAT IN ARRAY *DIRECTENTRY*                                    #
#                                                                      #
#     ON ENTRY                                                         #
#                                                                      #
#     TAREA4X CONTAINS POINTER TO AREA TABLE.                          #
#     DIRWORDADDR CONTAINS ADDRESS OF LAST DBI ENTRY OR ZERO IF THERE  #
#     WAS NO PREVIOUS DBI ENTRY.                                       #
#                                                                      #
#     ON EXIT                                                          #
#                                                                      #
#     IF DBI IS PRIMARY KEY, KEY TABLE DESCRIBES THE KEY               #
#     ARRAY DIRECTENTRY CONTAINS DBI ENTRY AS CONVERTED TO CRM FORMAT  #
#     COMMON BLOCK CEXPRES DESCRIBES THE ITEM                          #
#     DIRWORDADDR CONTAINS ADDRESS OF ITEM ENTRY READ OR ZERO IF NO    #
#     MORE ITEMS.                                                      #
#                                                                      #
#----------------------------------------------------------------------#
  
      XDEF PROC NXTATTR;
      PROC NXTATTR; 
      BEGIN 
      LOOPCON = TRUE; 
      FOR I = I                    # LOOP UNTIL RECORD OR NON          #
                                   # (REDEFINED OR RENAMED) ITEM IS    #
                                   # READ                              #
        WHILE LOOPCON 
      DO
      BEGIN 
      IF DIRWORDADDR EQ 0          # IF FIRST CALL TO NXTATTR          #
      THEN
        BEGIN 
        MAXKEYLEN = 0;             # INITIALIZE LENGTH OF LARGEST KEY  #
        MAXRECLENC = 0;            # INITIALIZE LENGTH OF LARGEST RECRD#
        P<AREA$TABLE> = TAREA4X;   # POSITION TO CURRENT AREA          #
        RECDORD = 1;
        GET (SCHEMAFIT, RLMLSTENT,
            AT$RLMLSTADR + AT$RLMLSTENT + SBSCADD,
            0, 0, DFSBRLMLST * 10, RA0);  # READ REALM LIST ENTRY      #
        NUMRECS = REALMRECLEN[0];  # NUMBER OF RECORDS IN AREA         #
        WRECADDR = REALMRECLIST[0] + AT$RLMLSTADR;
                                   # WA ADDR OF RECORD LIST ENTRY      #
                                   # WITHIN REALM/RELATION TABLE       #
        GET (SCHEMAFIT, RECDLIST, WRECADDR + SBSCADD, 0, 0, 
             DFSBRECLST * 10, RA0);  # READ RECORD LIST ENTRY WITHIN   #
                                     # REALM/RELATION TABLE            #
        GET (SCHEMAFIT, DBIENTRY, RECLISTLADR[0] + SBSCADD, 
             0, 0, DFSBRCLG * 10, RA0);  # READ RECORD ENTRY           #
        DIRWORDADDR = RECLISTLADR[0];  # ADDRESS OF RECORD ENTRY       #
        P<KEY$TBL> = CMM$ALF (NUMRECS * 3, 0, AT$GROUPID);
                                   # REQUEST CM FOR KEY TABLE          #
        AT$PKEYDPTR = P<KEY$TBL>;  # SAVE ADDRESS OF KEY TABLE         #
        KT$RECNAM[RECDORD] = DIRWORDADDR;  # ADDRESS OF RECORD ENTRY   #
        AT$RECWA = DIRWORDADDR;    # ADDRESS OF 1ST RECORD ENTRY IN    #
                                   # AREA                              #
        END 
  
      ELSE                         # PREVIOUS ENTRY HAS BEEN READ      #
        BEGIN 
        P<SBITEMENTRY> = LOC(DBIENTRY);  # POSITION TO DBI ENTRY       #
        IF SBITMENTRY EQ SE$RECORD # IF PREVIOUS ENTRY WAS RECORD      #
        THEN
          BEGIN 
          P<SBRECENTRY> = LOC(DBIENTRY);
          DIRWORDADDR = DIRWORDADDR + SBRECNXITEMP;  # ADDR OF 1ST ITEM#
                                                     # WITHIN RECORD   #
          END 
  
        ELSE                       # IF PREVIOUS ENTRY WAS ITEM        #
          BEGIN 
          P<SBITEMENTRY> = LOC(DBIENTRY); 
          IF SBITMNEXTP EQ 0       # IF PREVIOUS WAS LAST ITEM IN RECRD#
          THEN
            BEGIN 
            IF RECDORD EQ NUMRECS  # IF LAST RECORD                    #
            THEN
              BEGIN 
              RCTYPE[0] = ET$ENDOFAREA;  # ALL RECORDS PROCESSED       #
              AT$CURRKEY = AT$NEXTFREE;  # OFFSET TO KEY AREA RELATIVE #
                                         # TO P<AREA$TABLE>            #
              IF FITKL GR MAXKEYLEN  # IF SCHEMA PRIMARY KEY LENGTH    #
                                     # LARGER THAN PREVIOUS.  SINCE    #
                                     # BLP RETURNS PRIMARY KEYS IN     #
                                     # SCHEMA FORMAT, KA MUST BE LARGE #
                                     # ENOUGH TO HOLD A SCHEMA KEY     #
              THEN
                BEGIN 
                MAXKEYLEN = FITKL;   # SAVE LENGTH OF LARGEST KEY      #
                END 
  
                                   # COMPUTE OFFSET OF LWA+1 OF KEY ARE#
              AT$NEXTFREE = AT$NEXTFREE + ((MAXKEYLEN + 9) / 10 ) ; 
              AT$MRL = MAXRECLENC;  # MAXIMUM RECORD LENGTH IN CHARS   #
              RETURN; 
              END 
  
            RECDORD = RECDORD + 1; # PROCESS NEXT RECORD               #
            WRECADDR = WRECADDR + 1;  # ADDR OF NEXT RECORD LIST ENTRY #
                                      # IN REALM/RELATION LIST         #
            GET (SCHEMAFIT, RECDLIST, WRECADDR + SBSCADD, 0, 0, 
                 DFSBRECLST * 10, RA0);  # READ RECORD LIST ENTRY      #
            DIRWORDADDR = RECLISTLADR[0];  # ADDRESS OF RECORD ENTRY   #
            KT$RECNAM[RECDORD] = DIRWORDADDR;  # ADDR OF RECORD ENTRY  #
            END 
  
          ELSE
            BEGIN 
                                   # ADDRESS OF NEXT ITEM              #
            DIRWORDADDR = DIRWORDADDR + SBITMNEXTP; 
            END 
          END 
        END 
  
      GET (SCHEMAFIT, DBIENTRY, DIRWORDADDR + SBSCADD,
           0, 0, DFSBITMLG * 10, RA0);  # READ DBI ENTRY               #
  
      P<SBITEMENTRY> = LOC(DBIENTRY);  # POSITION TO ITEM ENTRY        #
      IF SBITMENTRY EQ SE$RECORD   # IF RECORD ENTRY                   #
        OR (SBITMLEVEL NQ RENAMELEVEL  # IF NOT RENAMED                #
          AND NOT SBITMREDEFFG)    # IF NOT REDEFINED                  #
      THEN
        BEGIN 
        LOOPCON = FALSE;           # EXIT LOOP                         #
        END 
      END                          # END I LOOP                        #
                                   # TRANSFORM CDCS DBI ENTRY INTO CRM #
                                   # DBI ENTRY                         #
      TRNSDBI (DBIENTRY, DIRECTENTRY, DIRWORDADDR + SBSCADD); 
  
      IF SBITMENTRY EQ SE$RECORD   # IF RECORD ENTRY                   #
      THEN
        BEGIN 
        P<SBRECENTRY> = LOC(DBIENTRY);
        KT$SBRCDORD[RECDORD] = SBRECORDINAL;  # SUBSCHEMA RECORD ORDINL#
        KT$RECLENC[RECDORD] = SBRECLENGTH;  # RECORD LENGTH IN CHARS   #
        IF SBRECLENGTH GR MAXRECLENC  # IF LARGER THAN PREVIOUS LARGEST#
        THEN
          BEGIN 
          MAXRECLENC = SBRECLENGTH;  # SAVE LENGTH OF LARGEST RECORD   #
          END 
  
        END 
  
      IF (SBITMENTRY EQ SE$ITEM    # IF ITEM ENTRY                     #
        AND SBITMDOMORD NQ 0)      # IF SUBORDINATE TO REPEATING GROUP #
      THEN
        BEGIN 
        BITPOSITION = DEWPOS * 60 + DBITPOS;  # CALCULATE BIT POSITION #
        LOOPCON = TRUE; 
        FOR I = I 
          WHILE LOOPCON 
        DO
          BEGIN 
          GET (SCHEMAFIT, DBIENTRY,  # READ DOMINANT ITEM ENTRY        #
               SBITMDOMADR + SBSCADD, 
               0, 0, DFSBITMLG * 10, RA0);
          BITPOSITION = BITPOSITION + SBITMBWP * 60 + SBITMBBP; 
                                   # ADD BEGINNING BIT POSITION OF GRP #
          IF SBITMDOMORD EQ 0      # IF NO MORE REPEATING GROUPS       #
          THEN
            BEGIN 
            LOOPCON = FALSE;
            END 
          END 
  
        BWP[0] = BITPOSITION / 60;  # CALCULATE BEGINNING WORD POSITION#
        BBP[0] = BITPOSITION - (BWP[0] * 60);  # BEGINNING BIT POSITION#
        GET (SCHEMAFIT, DBIENTRY, DIRWORDADDR + SBSCADD,
             0, 0, DFSBITMLG * 10, RA0);  # REREAD ORIGINAL DBI ENTRY  #
        END 
  
      DATATYPE = CLASS[0];         # DATA CLASS, IE INTEGER OR FLOATING#
      DATAWORDADDR = BWP[0];       # BEGINNING WORD POSITION           #
      DATACHARPOS = BBP[0] / 6;    # BEGINNING CHARACTER POSITION      #
      RESULTSIZE = INCPICSIZE[0];  # PICTURE SIZE INCLUDING INSERTS    #
      IF RCTYPE[0] EQ ET$GROUP     # IF GROUP                          #
        OR RCTYPE[0] EQ ET$RPTGROUP  # IF REPEATING GROUP              #
        OR RCTYPE[0] EQ ET$RPTRPTGRP  # REPEAT GROUP WITHIN REPEAT GRP #
        OR RCTYPE[0] EQ ET$RECORD  # IF RECORD                         #
      THEN
        BEGIN 
        RESULTSIZE = USESIZE[0];   # INTERNAL SIZE IN CHARACTERS       #
        END 
  
      IF OCCURS[0]                 # IF ITEM ENTRY HAS OCCURRING WORD  #
      THEN
        BEGIN 
        OCCURWORD[0] = OCCURWORD[1];
        IF RCTYPE[0] EQ ET$RPTGROUP     # IF REPEATING GROUP           #
          OR RCTYPE[0] EQ ET$RPTRPTGRP  # REPEAT GRP WITHIN REPEAT GRP #
        THEN
          BEGIN 
          USESIZE[0] = USESIZE[0] * OCCURCOUNT[0];
                                   # SIZE OF ALL OCCURRENCES           #
          END 
                                   # OVERWRITE SAMENAME WORD WITH      #
                                   # OCCURRING INFO BECAUSE SAMENAME   #
                                   # INFO NOT USED AND OCCURRING INFO  #
                                   # IS NOW IN A FIXED POSITION        #
        END 
  
      DATALENG = USESIZE[0];       # INTERNAL SIZE IN CHARACTERS       #
      IF KEYFLAG[0]                # IF PRIMARY KEY                    #
      THEN
        BEGIN 
        KT$WPOS[RECDORD] = DATAWORDADDR;  # WORD POSITION              #
        KT$LENGTH[RECDORD] = DATALENG;    # INTERNAL LENGTH IN CHARS   #
        KT$CPOS[RECDORD] = DATACHARPOS;   # CHARACTER POSITION         #
        KT$TYPE[RECDORD] = DATATYPE;      # TYPE                       #
        KT$PICLEN[RECDORD] = RESULTSIZE;  # PIC SIZE INCLUDING INSERTS #
        KT$DPTLOC[RECDORD] = CDPTLOC[0];  # POSITION OF DECIMAL POINT  #
        KT$OVERPUN[RECDORD] = SIGN[0];    # SIGN OVERPUNCH FLAG        #
        KT$ITEMORD[RECDORD] = SBITMORDINAL;  # ITEM ORDINAL            #
        P<FIT> = LOC(AT$AFITPOS);  # POSITION TO FIT                   #
        IF FITFO EQ FOAK           # IF ACTUAL KEY FILE                #
        THEN
          BEGIN                    # SAVE KEY POSITION AND LENGTH THE  #
                                   # WAY CRM SEES IT, THAT IS, 8 OR    #
                                   # LESS CHARACTERS, RIGHT JUSTIFIED  #
          I = EXPICSIZE[0];        # PIC SIZE EXCLUDING INSERTS        #
          IF I GR 8                # GREATER THAN MAX SIZE FOR CRM     #
          THEN
            BEGIN 
            I = 8;                 # SET IT TO MAXIMUM SIZE            #
            END 
  
          KT$ACTKEYLNG[RECDORD] = I;  # KEY LENGTH AS CRM SEES IT      #
          KT$ACTKEYPOS[RECDORD] = 10 - I;  #KEY POSITION AS CRM SEES IT#
          END 
        END 
      IF KEYFLAG[0]                # IF PRIMARY KEY                    #
        OR ALTERKEYFLG[0]          # IF ALTERNATE KEY                  #
      THEN
        BEGIN 
        IF USESIZE[0] GR MAXKEYLEN  # IF LARGER THAN PREVIOUS LARGEST  #
        THEN
          BEGIN 
          MAXKEYLEN = USESIZE[0];  # SAVE LENGTH OF LARGEST KEY        #
          END 
        END 
      RETURN; 
      END 
      END 
      TERM
