*DECK DB$M30M 
USETEXT UTMPTTX 
USETEXT MDBCMTX 
 PROC DB$M30M;
    BEGIN 
 #
  *   DB$M30M - CNTRL ROUTINE FOR THE CST BLD    PAGE  1
  *   M. D. SAXE                                 DATE  05/04/76 
  *   A. W. LO                                   DATE  05/08/77 
  
  DC  PURPOSE 
  
      CONTROLLING ROUTINE FOR THE CST BUILD. EITHER THE CSTS ARE TRANSF-
      ERED FROM THE OLD MD TO THE NEW MD OR DB$CBLD IS CALL TO CREATE 
      A NEW CST.
  
  DC  ENTRY CONDITIONS
  
      1. THE SUB-SCHEMA DIRECTORY MUST BE COMPLETE AND RESIDE IN CORD.
      2. PUTWA MUST CONTAIN THE FIRST AVAILABLE WORD IN THE NEW MD. 
  
  DC  EXIT CONDITIONS 
  
      THE SUB-SCHEMA DIRECTORY AND ITS CORRESPONDING CSTS HAVE BEEN 
      WRITTEN TO THE NEW MD.
  
  DC  CALLING ROUTINES
  
      DBMSTRD - MAIN CONTROLLING ROUTINE
  
  DC CALLED ROUTINES
 #
      XREF
        BEGIN 
##
        PROC DB$CBLD;        # CST BUILDER MAIN MODULE #
        PROC DB$FTMD;        # FIT FOR THE NEW MD                      #
        PROC DB$FTOD;        # FIT FOR THE OLD MD                      #
        PROC DB$WGET;        # READS THE OLD MD                        #
        PROC DB$WPUT;        # WRITES TO THE NEW MD                    #
        PROC DB$ERMD;        # CRM ERROR ROUTINE FOR THE NEW MD        #
        PROC DB$EROD;        # CRE ERROR ROUTINE FOR THE OLD MD        #
        PROC DB$EPRT;        # WRITES ERROR MSG TO THE OUTPUT FILE     #
        PROC DB$MABT;        # JOB ABORT ROUTINE - ISSUES DAYFILE MSG  #
        PROC DB$UALC;        # ALLOCATES CMM BLOCK.                    #
        PROC DB$UAWS;        # INCREASES THE SIZE OF THE CMM BLOCK.    #
        PROC DB$UFRE;        # FREE A MANAGED MEMORY BLOCK IN CORE #
        PROC DB$UPRT;        # UTILITY PROC TO PRINT A LINE ON OUTPUT#
        PROC DB$USHR;        # SHRINKS THE SPECIFIED CMM BLOCK BACK TO #
                             # ITS HEADER WORD.                        #
##
        END 
      CONTROL NOLIST; 
 #
  DC  NON-LOCAL VARIABLES 
 #
*CALL MDABTDCLS 
*CALL UTMPCDCLS 
  
      BASED ARRAY CSTSSTBL S; 
        BEGIN 
*CALL MDSBDDCLS 
        END 
  
      BASED ARRAY MDSCENTRY [0] S;
        BEGIN 
*CALL MDSCDDCLS 
        END 
  
      CONTROL LIST; 
*CALL MD30CDCLS 
#     LOCAL ITEMS                                                      #
      ITEM I;                # SCRATCH ITEM                            #
      ITEM J;                # SCRATCH ITEM                            #
      ITEM NXTGETLNG;        # LENGTH IN WORDS OF THE CST ENTRY YET TO #
                             # BE READ OR WRITTEN.                     #
  
      DEF DFMAXCSTSZ #1024#; # MAXIMUM BUFFER SIZE WHEN MOVING A CST #
      DEF FATALSS #1#;       # FATAL ERROR IN SUB-SCHEMA               #
      DEF FATALSC #2#;       # FATAL ERROR IN SCHEMA                   #
  
      ITEM SSDIRWA;          # WORD ADDRESS OF WHERE THE SUB-SCHEMA    #
                             # DIRECTORY IS TO BE PLACED IN THE NEW MD #
      ITEM SSDIRLNG;         # LENGTH IN WORDS OF THE SUB-SCHEMA DIR   #
                             # EXCLUDING THE HEADER WORD.              #
  
      ARRAY CSTERR1 P(8); 
        ITEM CSTER1 C(0,0,80) = 
          [" ***** FATAL SCHEMA ERROR, UNABLE TO CONTINUE PROCESSING FOR
 THIS SCHEMA "];
 #
  DC  DESCRIPTION 
 #
  
 #
      IF SCFATAL IS NON-ZERO (INDICATING ERRORS DURING THE SYNTAX 
      CRACKING OF THE SCHEMA), RETURN TO CALLER WITHOUT DOING 
      ANY CST PROCESSING.  THE (1,0) OVERLAY ROUTINE DB$SR10 WILL 
      FREE ALL THE CMM BLOCKS THAT WOULD HAVE BEEN OTHERWISE
      RELEASED BY THIS MODULE (MDCHKSM, DBPROC, AND CSTDIR).
 #
  
      IF SCFATAL GR 0 
      THEN
        BEGIN 
        RETURN; 
  
        END 
  
  
 #
      POINT THE SUB-SCHEMA BASED ARRAY TO THE FIRST SUB-SCHEMA ENTRY
 #
              P<CSTSSTBL> = CSTDIRBP + 1 + DFCSTSSHD; 
 #
      SET UP THE SCHEMA INFORMATION IN THE PARAMETER LIST FOR THE CST 
      BUILDER. THIS IS DONE AT THIS TIME SO THAT THE SCHEMA INFO, AREA
      DIR, AND AREA INFO TABLES CAN BE REDUCED TO GIVE THE CST BUILDER
      MORE FL.
 #
      P<MDSCENTRY> = SCDRBP + 1;
      PCSCNAME[0] = MDSCNAME[SCHDIRP];
      PCSCIDNT[0] = MDSCIDNT[SCHDIRP];
      PCWAAREA[0] = MDSCWAAD[SCHDIRP];
      PCSCLFN[0] = C<0,7>MDSISCLF[0]; 
 #
      SET FLAG TO INDICATE THAT THE SCHEMA ENTRY HAS BEEN WRITTEN TO
      THE NEW MD. 
 #
      MDSCWRTFLG[SCHDIRP] = TRUE; 
  
 #
      CALC THE LENGTH IN WORDS OF THE SUB-SCHEMA DIRECTORY (LESS CNTWRD)
 #
      SSDIRLNG = CSTDCNT * DFCSTSSEN; 
  
 #
      SAVE THE WORD ADDRESS OF WHERE THE SUB-SCHEMA DIRECTORY IS TO BE
      WRITTEN.
 #
      SSDIRWA = PUTWA;
  
 #
      CALCULATE THE WORD ADDRESS WHERE THE CST IS TO BE PLACED IN THE 
      NEW MD. 
 #
      PUTWA = PUTWA + 1 + SSDIRLNG; 
  
      DB$UALC(LOC(WRKBUFBP),0,0); 
 #
      LOOP THRU THE SUB-SCHEMA DIRECTORY CHECKING EACH ENTRY TO SEE IF
      A SUB-SCHEMA CST HAS BEEN WRITTEN TO THE NEW MD.
 #
      FOR I=0 STEP DFCSTSSEN WHILE I NQ SSDIRLNG DO 
        BEGIN 
  
 #POINT TO CST/SUBSCHEMA DIRECTORY SKIPPING THE HEADER WORD            #
  
          P<CSTSSTBL> = CSTDIRBP + 1 + DFCSTSSHD + I ;
          IF MDSBINFO[0] THEN 
            BEGIN 
 #
          SET UP THE SUB-SCHEMA INFORMATION IN THE PARAMETER LIST FOR 
          THE CST BUILDER.
 #
              PCSBNAME[0] = MDSBNAME[0];
              PCSBLFN[0] = C<0,7>MDSBENCW[0]; 
              PCWACST[0] = PUTWA; 
              PCSCTMDT[0] = MDSITMDT[0];
              OVLLEVEL = 3; 
              DB$CBLD;
              OVLLEVEL = 0; 
              P<CSTSSTBL> = CSTDIRBP + 1 + DFCSTSSHD + I ;
 #
      CHECK IF CST BUILDER ISSUED AN ERROR
 #
      IF PCSTATWD[0] GR 0 THEN
        BEGIN 
 #
        CHECK IF SUB-SCHEMA ERROR 
 #
          IF PCSTATWD[0] EQ FATALSS THEN # PROCEED WITH THE NEXT SS    #
            TEST I; 
          IF PCSTATWD[0] EQ FATALSC THEN # FATAL SCHEMA ERROR          #
            BEGIN 
              DB$EPRT(CSTERR1,80);
              DB$UPRT("  ",2);         # OUTPUT COMPLETELY BLANK LINE#
              GOTO CSTEXIT; 
            END 
          DB$MABT(DFCSTFATAL); # FATAL ERROR IN THE MD, ABORT RUN      #
        END 
 #
          ZERO OUT THE SUB-SCHEMA LFN.
 #
              MDSBENCW[0] = 0 ; 
 #
      CLEAR THE SUBSCHEMA WRITTEN TO THE NEW MD FLAG. 
 #
      MDSBINFO[0] = FALSE;
 #
          STORE THE SIZE IN WORDS AND THE WORD ADDRESS OF THE NEW CST.
 #
              MDSBSZCS[0] = PCSIZCST[0];
              MDSBCPLN[0] = PCCAPLNG[0] ; 
              MDSBSSTMDT[0] = PCSBTMDT[0] ; 
              MDSBCKSM[0] = PCSBCKSM[0];
              MDSBWACS[0] = PUTWA;
              PUTWA = PUTWA + PCSIZCST[0] + PCCAPLNG[0];
            END 
         ELSE 
            BEGIN 
  
 #
          GET THE WA AND SIZE OF THE SUB-SCHEMA CST TABLE IN THE OLD MD.
 #
              GETWA = MDSBWACS[0] ; 
               GETLNG = MDSBSZCS[0] + MDSBCPLN[0] ; 
  
              MDSBWACS[0] = PUTWA;
  
 #IF SUBSCHEMA CST TABLE IS GREATER THAN THE ALLOCATED WORK BLOCK THEN #
 #READ ONE BLOCK AT A TIME FROM THE OLD MD AND WRITE IT OUT TO THE NEW #
 #MD                                                                   #
  
              IF GETLNG GR DFMAXCSTSZ THEN
                BEGIN 
                NXTGETLNG = GETLNG - DFMAXCSTSZ;
                GETLNG = DFMAXCSTSZ;
  
 #ALLOCATE A WORK BLOCK                                                #
  
                DB$UAWS(LOC(WRKBUFBP),DFMAXCSTSZ);
  
 #LOOP THRU TO READ AND WRITE THE ENTIRE SUBSCHEMA CST TABLE           #
  
                FOR J=0 WHILE NXTGETLNG GQ 0 DO 
                  BEGIN 
                  P<GETENTRY> = WRKBUFBP + 1; 
  
 # READ A BLOCK FROM THE OLD MD                                        #
  
                  DBGET;
                  PUTLNG =GETLNG; 
                  P<PUTENTRY> = WRKBUFBP + 1; 
  
 #  WRITE A BLOCK TO THE NEW MD                                        #
  
                  DBPUT;
  
 # IF THERE IS STILL SOME MORE INFORMATION LEFT IN THE OLD MD          #
  
                  IF NXTGETLNG GR DFMAXCSTSZ THEN 
                  NXTGETLNG = NXTGETLNG - DFMAXCSTSZ ;
                  ELSE
  
 # IF THIS IS THE FINAL READ AND WRITE NEEDED                          #
  
                  IF NXTGETLNG NQ 0 THEN
                    BEGIN 
                    GETLNG = NXTGETLNG; 
                    NXTGETLNG = 0;
                    END 
                    ELSE
  
 # EVERYTHING HAS BEEN READ IN AND WRITTEN OUT SO SET FLAG TO -1 TO    #
 # FALL OUT OF LOOP                                                    #
  
                    NXTGETLNG = -1; 
                  END 
                END 
               ELSE 
                BEGIN 
                  DB$UAWS(LOC(WRKBUFBP),GETLNG);
                  P<GETENTRY> = WRKBUFBP + 1; 
                  DBGET;
                  PUTLNG = GETLNG;
                  P<PUTENTRY> = WRKBUFBP + 1; 
                  DBPUT;
                END 
              DB$USHR(LOC(WRKBUFBP)); 
            END 
        END 
 #
      STORE THE RUNNING WA INTO A TEMPOARRY ITEM. 
 #
      I = PUTWA;
      P<CSTSSTBL> = CSTDIRBP + 1; 
      MDSBNBSB[0] = CSTDCNT;
  
 #
      STORE THE WA OF WHERE THE SUB-SCHEMA DIRECTORY IS TO BE WRITTEN TO
 #
      P<MDSCENTRY> = SCDRBP + 1;
      P<PUTENTRY> = CSTDIRBP + 1; 
      PUTWA = SSDIRWA;
      PUTLNG = SSDIRLNG + 1;
      MDSCWASB[SCHDIRP] = PUTWA;
      MDSCSSSZ[SCHDIRP] = PUTLNG; 
      DBPUT;
 #
      RESTORE THE RUNNING WA. 
 #
      PUTWA = I;
 #
      FREE UP THE DATA BASE PROCEDURE TABLE AND CUBSCHEMA/CST DIRECTORY 
      MANAGED MEMORY BLOCKS 
 #
CSTEXIT:  
      DB$UFRE(LOC(DBPROCBP)); 
      DB$UFRE(LOC(CSTDIRBP)); 
      DB$UFRE (LOC(MDCHKSMBP)); 
      DB$UFRE(LOC(WRKBUFBP)); 
      RETURN; 
    END 
  TERM; 
