*DECK BGTABLE                                                           003330
USETEXT TAREATB 
USETEXT TCRMDEF 
USETEXT TEXPRES 
USETEXT TFIT
     PROC BGTABLE;                                                      003340
          BEGIN                                                         003350
      XREF FUNC  CMM$ALF; 
      XREF PROC NXTATTR;           # READ NEXT DBI ENTRY AND RETURN IT #
                                   # IN CRM FORMAT IN ARRAY            #
                                   # DIRECTENTRY.  DIFFERENT PROCS ARE #
                                   # LOADED FOR CRM OR CDCS SUBSCHEMAS #
      XREF PROC CMM$FRF;           # CMM ROUTINE TO FREE CM BLOCK      #
      XREF PROC DIAG; 
     BASED ARRAY BGHEAD; #ARRAY WITH 1 ENTRY FOR EVERY RECORD DESCRIPTIO
                         THAT CONTAINS 1 OR MORE NON-DISPLAY ITEMS.#
                         #BGHEAD HAS UP TO 15 ENTRIES OVERLAYING THE
                         SUBSCHEMA FDB IN THE USE TABLE. IF NEEDED, 
                         OVERFLOW TABLES ARE ACQUIRED AND LINKED.#
     BEGIN
          ITEM BGDIRWA   U(0, 0,30);  #DIRECTORY WORD ADDRESS OF
                                       RECORD DESCRIPTION#
          ITEM BGTABADD  U(0,30,30);  #ADDRESS OF TABLE DESCRIBING
                                       NON-DISPLAY ITEMS IN RECORD# 
          ITEM BGHWORD   U(0, 0,60);  #LAST ENTRY WHEN ALL 0, 
                                       PTR TO OVERFLOW WHEN BGDIRWA=0#
     END
      BASED ARRAY BGROUND S(2);    # BACKGROUND TABLE WITH ONE ENTRY   #
                                   # FOR EVERY NON-DISPLAY ITEM OR     #
                                   # GROUP OF CONTIGUOUS NON-OCCURRING #
                                   # ITEMS OF THE SAME TYPE            #
      BEGIN 
        ITEM BGTYPE   U(00,00,06); # TYPE OF 0 OR NULL-VALUE           #
        ITEM BGSIZE   U(00,06,12); # ITEM SIZE IN CHARACTERS           #
        ITEM BGOCCUR  U(00,18,12); # NUM OF OCCURRENCES IF OCCURRING   #
        ITEM BGSTEP   U(00,30,18); # DISTANCE IN CHAR BETWEEN ITEM     #
                                   # ORIGIN AND ITS DOMINANT ITEM IF   #
                                   # WITHIN OCCURRING GROUP            #
        ITEM BGGRSIZE U(01,00,18); # TOTAL GROUP SIZE IN CHARACTERS    #
        ITEM BGSTARTW U(01,18,18); # STARTING WORD POSITION OF ITEM    #
                                   # WITHIN RECORD                     #
        ITEM BGSTARTC U(01,36,04); # STARTING CHAR POSITION IN WORD    #
        ITEM BGRCTYPE U(00,48,06); # ENTRY TYPE                        #
        ITEM BGLEVEL  U(00,54,06); # ENTRY LEVEL                       #
        ITEM BGTWORD  U(00,00,60); # LAST WHEN = 0,  OR                #
                                   # POINTER TO OVERFLOW IF BGSIZE = 0 #
     END
     ITEM DISPLAYONLY B;  #TRUE IF RECORD DESCRIPTION BEING EXAMINED
                         CONTAINS ONLY DISPLAY ITEMS# 
     ITEM H;   #INDEX INTO BGHEAD#
     ITEM T;   #INDEX INTO BGROUND# 
           ITEM GROUPSIZE;
      XREF  BASED ARRAY  SCHEMAFIT;;
      XREF ITEM  TAREA4X;          # POINTER TO AREA SET BY USE        #
           ITEM SAVEOCCUR,GROUPLEVEL,M; 
           ITEM ADDSIZE B;
     ITEM J, K, DUMMY;                                                  003580
     DEF ELEMENTARY #1#;                                                003600
     DEF ENDOFAREA #O"77"#; 
     DEF GROUP #0#; 
     BASED ARRAY A; ITEM IA;
                                                                        003630
                                                                        003640
                                                                        003870
                                                                        003880
          PROC INCRT;  #PROCEDURE TO LOCATE THE NEXT ENTRY IN THE 
                        BACKGROUNG TABLE, ACQUIRE OVERFLOW SPACE IF 
                        NECESSARY AND LINK IT TO THE PREVIOUS TABLE,
                        AND SET THE LOCATED ENTRY TO 0# 
          BEGIN 
          T=T+1;
               IF T EQ 14 THEN
                    BEGIN 
                                   # GET OVERFLOW SPACE AND LINK IT    #
                    BGTWORD[14] = CMM$ALF(29,0,AT$GROUPID); 
                    P<BGROUND>=BGTWORD[14];   #LINK TO PREVIOUS TABLE#
                    T=0;      #START AT TOP OF NEW TABLE# 
                    END 
          BGTWORD[T]=0; 
          END 
  
  
                                                                        003890
                                                                        003900
      DUMMY = 0;
           GROUPLEVEL = 0;
           SAVEOCCUR = 0; 
      P<AREA$TABLE> = TAREA4X;     # POSITION TO CURRENT AREA          #
      AT$BGSTRNG = CMM$ALF (15, 0, AT$GROUPID); 
      P<BGHEAD> = AT$BGSTRNG; 
      AT$KEYEXCL = FALSE;          # INITIAL ASSUMPTION THAT KEYS ARE  #
                                   # IN RECORDS                        #
      H = 0;                       # INITIALIZE                        #
      T = -1; 
      GROUPLEVEL = 0; 
      SAVEOCCUR = 0;
     DIRWORDADDR=0;  #TO TELL NXTATTR TO START AT 1ST RECORD DESCRIPTIO#
  
     NXTATTR;  #GET ATTRIBUTES OF 1ST RECORD DESCRIPTION# 
     IF DIRWORDADDR EQ 0 THEN 
               BEGIN     DIAG(859); #AT LEAST 1 DESCRIPTION MUST EXIST# 
                         RETURN;    END 
      P<BGROUND> = CMM$ALF (29, 0, AT$GROUPID); 
     BGTWORD[0]=0;  BGHWORD[0]=0;  #INITIALIZE 1ST ENTRY OF EACH TABLE# 
  
TESTKEYEXCLU: 
           ADDSIZE = FALSE; 
     BGDIRWA[H]=DIRWORDADDR;  #SAVE ADDRESS OF RECORD DESCRIPTION#
      IF T GQ 0 
      THEN
        BEGIN 
        BGTABADD[H] = P<BGROUND>+2*T+2;# SAVE ADDRESS OF TABLE         #
        END 
      ELSE
        BEGIN 
        BGTABADD[H] = P<BGROUND>;     # FIRST ENTRY                    #
        END 
           BGHWORD[H+1] = 0;
     DISPLAYONLY=TRUE;  #TENTATIVE ASSUMPTION THAT ALL ITEMS ARE DISPLA#
  
GETNEXTITEM:  
     NXTATTR;  #GET ATTRIBUTES OF NEXT ITEM#
           IF GROUPLEVEL GQ ITEMLEVEL[0] THEN 
             BEGIN
           SAVEOCCUR = 0; 
           GROUPLEVEL = 0;
             END
      IF RCTYPE[0] EQ ET$ITEM      # IF ELEMENTARY ITEM                #
        OR RCTYPE[0] EQ ET$VECTOR  # OR VECTOR                         #
        OR RCTYPE[0] EQ ET$RPTVECTOR  # OR VECTOR IN GROUP             #
      THEN
        BEGIN 
        IF CLASS[0] EQ DT$CHAR     # SKIP CHARACTERS                   #
          AND SAVEOCCUR EQ 0       # IF NOT PART OF OCCURING GROUP     #
        THEN
          BEGIN 
          ADDSIZE = FALSE;
          GOTO GETNEXTITEM; 
          END 
        DISPLAYONLY = FALSE;       # SIGNAL NON-DISPLAY ITEM FOUND     #
        IF RCTYPE[0] EQ ET$VECTOR 
          OR RCTYPE[0] EQ ET$RPTVECTOR
          OR T EQ - 1              # NO ADD ON FIRST TIME THRU         #
        THEN
          BEGIN 
          ADDSIZE = FALSE;         # DO NOT ADD TO VECTORS             #
          END 
        IF ADDSIZE
        THEN
          BEGIN 
          IF CLASS[0] EQ BGTYPE[T]  # SEE IF ALL SAME ATTRIBUTES       #
            AND BGOCCUR[T] EQ SAVEOCCUR 
            AND ITEMLEVEL[0] EQ BGLEVEL[T]
            AND BGSIZE[T] + DATALENG LQ O"177"
          THEN
            BEGIN 
            BGSIZE[T] = BGSIZE[T] + DATALENG;  # ACCUMLATE USAGE       #
                                   # SIZES OF CONTIGUOUS ITEMS         #
                                   # OF SAME TYPE THAT DO NOT OCCUR.   #
                                   # DO NOT GET NEW ENTRY, NEXT ONE    #
                                   # MAY MORE OF THE SAME.             #
            GOTO GETNEXTITEM; 
            END 
          END 
        INCRT;                     # NEED NEW ENTRY                    #
  
               BGSIZE[T]=DATALENG;
               BGSTARTC[T]=DATACHARPOS; 
               BGSTARTW[T]=DATAWORDADDR;
               BGTYPE[T]=DATATYPE;
               BGOCCUR[T] = 0;     # OCCURS SAVED AT GROUP ENTRY       #
               BGLEVEL[T] = ITEMLEVEL[0];  # SAVE ITEM LEVEL           #
               BGRCTYPE[T] = RCTYPE[0];    # SAVE ENTRY TYPE           #
           IF RCTYPE[0] EQ ET$VECTOR   # IF VECTOR                     #
              OR RCTYPE[0] EQ ET$RPTVECTOR  # OR VECTOR IN GROUP       #
           THEN 
             BEGIN
             BGOCCUR[T] = OCCURCOUNT[0];  # NUMBER OF OCCURRENCES      #
             END
  
           IF GROUPLEVEL NQ 0 THEN BGGRSIZE[T]=GROUPSIZE;ELSE 
           BGGRSIZE[T]=0; 
           IF RCTYPE[0] EQ ET$VECTOR  # IF VECTOR                      #
             OR RCTYPE[0] EQ ET$RPTVECTOR  # OR VECTOR IN GROUP        #
           THEN 
             BEGIN
                                   # LENGTH OF ALL OCCURRENCES         #
             BGGRSIZE[0] = DATALENG * OCCURCOUNT[0];
             END
  
           ADDSIZE = TRUE;
               GOTO GETNEXTITEM;
          END 
      IF RCTYPE[0] EQ ET$GROUP
        OR RCTYPE[0] EQ ET$RPTGROUP 
        OR RCTYPE[0] EQ ET$RPTRPTGRP
        OR RCTYPE[0] EQ ET$VARGRP 
      THEN
        BEGIN 
        INCRT;                     # NEED NEW ENTRY FOR GROUPS         #
          IF OCCURS[0] THEN 
               BEGIN
           GROUPLEVEL = ITEMLEVEL[0]; 
           SAVEOCCUR = OCCURCOUNT[0];  # NUMBER OF OCCURRENCES         #
           GROUPSIZE=USESIZE[0];
           ADDSIZE=FALSE; 
               END
          BGLEVEL[T] = ITEMLEVEL[0]; # GROUP ENTRY CONTAINS ONLY LEVEL #
          BGOCCUR[T] = OCCURCOUNT[0];   # AND OCCUR                    #
          BGGRSIZE[T] = USESIZE[0];  # SET GROUP SIZE                  #
          IF SAVEOCCUR EQ 0 THEN
            BEGIN 
            BGSTEP[T] = USESIZE[0]; 
            END 
          ELSE
            BEGIN 
            BGSTEP[T] = USESIZE[0] / SAVEOCCUR; 
                                     # DISTANCE BETWEEN OCCUR          #
            END 
          GOTO GETNEXTITEM; 
          END 
  
         #IF NOT ELEMENTARY OR GROUP ITEM, IT IS A NEW RECORD OR THE END
      OF THE AREA DESCRIPTION. IF THE RECORD DESCRIPTION JUST EXAMINED
      CONTAINS ONLY DISPLAY ITEMS, THE ENTRY IN BGHEAD IS DELETED.# 
     IF NOT DISPLAYONLY THEN
          BEGIN 
          H=H+1;  #LOCATE NEXT ENTRY IN BGHEAD# 
          IF H EQ 14 THEN 
               BEGIN
                                   # GET OVERFLOW SPACE AND LINK IT    #
               BGHWORD[14] = CMM$ALF (15, 0, AT$GROUPID); 
               P<BGHEAD>=BGHWORD[14]; 
               H=0; 
               END
          END 
      BGHWORD[H] = 0;              # CLEAR NEXT HEADER WORD            #
      IF RCTYPE[0] NQ ENDOFAREA    # IF NOT END                        #
      THEN
        BEGIN 
        INCRT;                     # WRITE WORD OF ZEROS               #
        GOTO TESTKEYEXCLU;         # CONTINUE PROCESSING               #
        END 
  
      IF DISPLAYONLY
      THEN
        BEGIN 
        BGHWORD[H] = 0;            # SIGNAL NO TABLE                   #
        END 
           IF DISPLAYONLY THEN BGHWORD[H] = 0;
  
      P<BGHEAD> = AT$BGSTRNG; 
      IF BGHWORD[0] EQ 0 THEN 
        BEGIN 
        CMM$FRF(LOC(BGROUND));     # RETURN UNUSED TABLE               #
        END 
     RETURN;
     END
     TERM                                                               004410
