*DECK DB$CCPP 
USETEXT UTMPTTX 
USETEXT UTCITTX 
USETEXT UTCDFTX 
USETEXT CUGBATX 
      PROC DB$CCPP; 
  
      BEGIN 
  
 #
* *   DB$CCPP - CONSTRAINT PREPROCESSOR          PAGE  1
* *   G. F. KENDALL                              DATE  10/09/78 
* 
* DC  PURPOSE 
* 
*     PREPROCESS AREAS IN THE SUBSCHEMA TO DETERMINE WHAT CONSTRAINTS 
*     ARE INVOLVED, AND WHAT OTHER AREAS FROM THE SCHEMA ARE NEEDED 
*     FOR CONSTRAINT PROCESSING.
* 
* DC  ENTRY CONDITIONS
* 
*     THE FOLLOWING COMMON ITEMS SHOULD CONTAIN THE INDICATED 
*     INFORMATION.
*     CALADDR  - ADDRESS OF FIRST USABLE WORD OF MEMORY BLOCK TO BE USED
*                FOR STORING A LIST OF AREAS FOR WHICH AREA 
*                WORK BLOCKS (USED IN CDCS CONSTRAINT PROCESSING) 
*                ARE REQUIRED.
*     CITADDR  - ADDRESS OF FIRST USABLE WORD OF MEMORY BLOCK TO BE 
*                USED FOR STORING CONSTRAINT INTEGRITY TABLES READ FROM 
*                SCHEMA.
*     CONNBEXA - NUMBER OF EXTENDED AREAS (ZERO TO START) 
*     CONSTNUM - NUMBER OF CONSTRAINTS (ZERO TO START)
*     SBFWADDR - SUBSCHEMA FIRST WORD ADDRESS IN SUBSCHEMA LIBRARY. 
*     SBNUMARE - SUBSCHEMA TOTAL NUMBER OF AREAS. 
*     SCHEADDR - SCHEMA MEMORY BLOCK ADDRESS OF WORD AFTER HEADER.
*     SCNUMCON - ZERO IF THERE ARE NO CONSTRAINTS IN SCHEMA.
*     THE SCHEMA AND SUBSCHEMA FILES MUST BE OPEN.
* 
* DC  EXIT CONDITIONS 
* 
*     ON NORMAL RETURN, 
*       CALADDR  = ADDRESS OF A LIST OF AREAS FOR WHICH AREA WORK 
*                  BLOCKS ARE REQUIRED FOR CDCS CONSTRAINT PROCESSING.
*                  (AREALIST ARRAY) 
*       CITADDR  = ADDRESS OF THE NEW CONSTRAINT INTEGRITY TABLES USED
*                  FOR AREAS IN THIS SUBSCHEMA, IF THERE ARE CONSTRAINTS
*                  FOR THIS SUBSCHEMA. (SCCSLIST ARRAY) 
*       CONNBEXA = NUMBER OF EXTENDED AREAS REQUIRED FOR CONSTRAINT 
*                  PROCESSING FOR THIS SUBSCHEMA. 
*       CONSTNUM = NUMBER OF CONSTRAINTS FOR THIS SUBSCHEMA.
*     ABNORMAL RETURN IS AN ABORT OF THE CST BUILDER THROUGH DB$CERR. 
*     DIAGNOSTICS RETURNED ARE -
*       7751CCPP  SUBSCHEMA AREA ENTRY HAD WRONG TYPE 
*       7752CCPP  SCHEMA AREA ENTRY HAD WRONG TYPE
*       7753CCPP  SCHEMA CONSTRAINT ENTRY HAD WRONG TYPE
*       7754CCPP  SCHEMA AREA ENTRY POINTS TO CONSTRAINT
*                 WHICH DOES NOT INVOLVE THIS AREA
* 
* DC  CALLING ROUTINES
* 
*     DB$CBLD - CONDENSED SCHEMA/SUBSCHEMA TABLE BUILDER MAIN MODULE. 
* 
* DC  CALLED ROUTINES 
* 
# 
      XREF PROC DB$CERR;     # FATAL ERROR MESSAGE AND RETURN HANDLER  #
      XREF FUNC DB$CFIL C(30); # BLANK OR BINARY ZERO FILL CHAR STRING #
      XREF PROC DB$CGSB;     # DB$CGSD ENT PT FOR CRM GET ON SUBSCHEMA #
      XREF PROC DB$CGSC;     # DB$CGSD ENT PT FOR CRM GET ON SCHEMA    #
      XREF PROC DB$CNSC;     # GET SCHEMA HEADER FOR ENTRY             #
      XREF PROC DB$UAWS;     # ADJUST WORK SPACE IN MAMAGED MEM BLOCKS #
      XREF PROC DB$USHR;     # SHRINK MANAGED MEMORY BLOCK TO HDR WORD #
# 
* 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     CONNBEXA - NUMBER OF EXTENDED AREAS FOR THIS SUBSCHEMA
*     CONSTNUM - NUMBER OF CONSTRAINTS FOR THIS SUBSCHEMA 
*     CURNAME  - CURRENT SUBSCHEMA AREA NAME
*     CURORDNL - CURRENT SUBSCHEMA AREA ORDINAL 
*     CURSCRAT - CURRENT SCRATCH NAME (USED AS A TEMPORARY) 
*     SBCURRAD - SUBSCHEMA CURRENT AREA HEADER ADDRESS
*     SBNEXTAD - SUBSCHEMA NEXT AREA HEADER ADDRESS 
* 
* DC  DESCRIPTION 
* 
*     THE FOLLOWING ABBREVIATIONS ARE USED IN THE DOCUMENTATION IN THIS 
*     MODULE: 
*     AR    - AREA
*     BA    - BASIC 
*     CON   - CONSTRAINT
*     CONST - CONSTRAINT
*     CIT   - CONSTRAINT INTEGRITY TABLE (DDL DATA STRUCTURE) 
*     EX    - EXTENDED
*     MEM   - MEMBER
*     NCIT  - NEW CONSTRAINT INTEGRITY TABLE (CIT MODIFIED BY DB$CCPP)
*     OWN   - OWNER 
*     SB    - SUBSCHEMA 
*     SC    - SCHEMA
*     WA    - WORD ADDRESS
* 
*     THIS ROUTINE SERVES TWO MAIN FUNCTIONS - FIRST, TO BUILD AN IN- 
*     CORE LIST OF ALL CONSTRAINT INTEGRITY TABLES (CIT-S) REQUIRED 
*     FOR THIS SUBSCHEMA, AND SECOND, TO BUILD AN IN-CORE LIST OF ALL 
*     AREAS FOR WHICH AREA WORK BLOCKS ARE REQUIRED.  THE LIST OF AREAS 
*     IS DIVIDED INTO 2 GROUPS, THE FIRST SBNUMARE ENTRIES BEING FOR
*     BASIC AREAS, AND THE LAST CONNBEXA ENTRIES BEING FOR EXTENDED 
*     AREAS.
*     THE LIST OF CIT-S (THE NCIT) IS USED BY THE CONSTRAINT WORK BLOCK 
*     BUILDER, DB$CCON, TO INDICATE WHICH CONSTRAINTS REQUIRE WORK
*     BLOCKS FOR THIS SUBSCHEMA, AND TO PROVIDE SOME OF THE INFORMATION 
*     REQUIRED FOR BUILDING THE WORK BLOCKS.
*     THE NCIT ENTRIES ARE LINKED BY POINTERS TO THE NEXT ENTRY 
*     INVOLVING THIS AREA FOR THE BASIC AND EXTENDED ENTRIES, 
*     FOR BOTH THE MEMBER AND OWNER AREAS (4 CHAINS). 
*     THE LIST OF AREAS IS USED BY THE AREA WORK BLOCK BUILDER, DB$CARE,
*     EACH AREA-S ENTRY POINTING TO THE FIRST 
*     NCIT ENTRY THAT THIS AREA IS INVOLVED WITH, AND FLAGGING THIS 
*     AREA-S INVOLVMENT AS A MEMBER OR OWNER. A BASIC AREA WORK BLOCK 
*     IS BUILT FOR AN AREA IF IT IS EXPLICITLY MENTIONED IN THE 
*     SUBSCHEMA. AN EXTENDED AREA WORK BLOCK IS REQUIRED FOR AN AREA
*     INVOLVED IN AT LEAST ONE CONSTRAINT WITH AN AREA EXPLICITLY 
*     MENTIONED IN THE SUBSCHEMA.  IF AN AREA IS INVOLVED IN A
*     CONSTRAINT WHERE IT IS BOTH THE OWNER AND THE MEMBER, BOTH A BASIC
*     AND AN EXTENDED AREA WORK BLOCK WILL BE REQUIRED FOR THE AREA.
*     NO MORE THAN ONE EXTENDED AREA WORK BLOCK IS EVER REQUIRED
*     FOR ANY AREA, EVEN IF IT IS INVOLVED IN MORE THAN ONE CONSTRAINT, 
*     BECAUSE CDCS CONSTRAINT PROCESSING IS NOT INTERRUPTABLE.
* 
*     SCCSLIST IS THE ARRAY WHICH WILL BE USED TO REFERENCE THE 
*     CITADDR MEMORY BLOCK.  AREALIST IS THE ARRAY WHICH WILL BE
*     USED TO REFERENCE THE CALADDR MEMORY BLOCK. 
* 
*     EXECUTION BEGINS WITH A CALL TO DB$UAWS TO ADD ENOUGH WORDS TO
*     THE AREALIST ARRAY FOR BASIC AREA ENTRIES.
* 
*     CITFLAG IS SET TO TRUE TO INDICATE THAT SPACE FOR A NCIT ENTRY
*     SHOULD BE  ALLOCATED. 
*     FOR EVERY SUBSCHEMA AREA, LOOPING THROUGH BY ORDINAL OF AREA -
*       - CALL DB$CGSB TO READ SUBSCHEMA AREA HEADER FROM SUBSCHEMA 
*         LIBRARY FILE. 
*       - PROCESS POSSIBLE ALIAS NAMES TO GET SCHEMA AREA NAME. 
*       - CALL DB$CNSC TO READ SCHEMA AREA HEADER FOR THIS AREA NAME. 
*       - START AREALIST ENTRY FOR THIS BASIC AREA BY SETTING 
*         AREA-S SCHEMA ENTRY WORD ADDRESS FIELD IN AREALIST. 
*       - IF THERE ARE NO CONSTRAINTS FOR THIS AREA, GO TO NEXT SUB-
*         SCHEMA AREA.
*       - IF THERE ARE CONSTRAINTS, FOR EACH CONSTRAINT FOR THIS AREA - 
*           = IF CITFLAG IS TRUE, CALL DB$UAWS TO ADD ENOUGH WORDS FOR
*             A NEW ENTRY TO THE SCCSLIST ARRAY.
*           = CALL DB$CGSC TO READ CONSTRAINT INTEGRITY TABLE FROM
*             THE SCHEMA INTO CURRENT SCCSLIST ENTRY. 
*           = ADJUST THE NCIT ENTRY SO THAT THE CONSTRAINT NAME 
*             TAKES 3 WORDS.
*           = SEARCH ALL NCIT-S IN SCCSLIST TO SEE IF THIS CIT IS 
*             ALREADY IN THE LIST. IF IT IS, THIS CIT WILL NOT BE MADE
*             INTO A NEW ENTRY, SO SET CITFLAG TO FALSE.
*             IF IT IS NOT, A NCIT ENTRY WILL BE MADE OF THIS CIT, SO 
*             INCREMENT CONSTNUM BY ONE, ZERO THE AREA ORDINAL FIELDS 
*             IN THE OWNER AND MEMBER WORDS OF THE NCIT, AND SET THE
*             ORDINAL OF THE NCIT ENTRY TO CONSTNUM.
*           = FOR THE SUBSCHEMA AREA BEING PROCESSED, IF THIS IS THE
*             FIRST CONSTRAINT FOR THIS AREA, SET THE POINTER IN
*             AREALIST TO THE FIRST NCIT ENTRY INVOLVING THIS AREA. IF
*             NOT, RESET POINTERS IN NCIT TO POINT TO NEXT NCIT 
*             INVOLVING THIS AREA. RESET THE LAST CONSTRAINT POINTER
*             IN AREALIST.
*           = FOR THE AREA IN THE CONSTRAINT WHICH IS NOT THE SUBSCHEMA 
*             AREA BEING PROCESSED (OR, IF BOTH MEMBER AND OWNER AREAS
*             ARE THE SAME, FOR THE SUBSCHEMA AREA BEING PROCESSED),
*             SEARCH THE EXTENDED AREA ENTRIES IN AREALIST TO DETERMINE 
*             IF THERE IS ALREADY AN ENTRY FOR THIS AREA. 
*               IF SO, THIS AREA ALREADY WILL HAVE AN EXTENDED AREA WORK
*             BLOCK BEING BUILD FOR IT. RESET LAST CONSTRAINT POINTER 
*             IN AREALIST ENTRY JUST LOCATED, AND POINTERS TO NEXT NCIT 
*             INVOLVING THIS AREA IN NCIT.
*               IF NOT, THIS AREA MUST HAVE AN EXTENDED AREA WORK BLOCK 
*             BUILD FOR IT. CALL DB$UAWS TO ADD A NEW ENTRY TO THE
*             AREALIST ARRAY AND BUILD A NEW EXTENDED AREA ENTRY. 
*             INCREMENT CONNBEXA BY ONE.
*           = STORE THE ORDINAL OF THE EXTENDED AREA IN THE NCIT, IN
*             THE EXTENDED AREA ORDINAL FIELD IN THE OWNER OR MEMBER
*             WORD WHICH REFERS TO THIS AREA.  THE ORDINAL IS THE 
*             POSITION OF THE AREA-S ENTRY IN AREALIST. 
*           = STORE THE ORDINAL FOR THE BASIC AREA IN THE CONSTRAINT
*             (THE SUBSCHEMA AREA BEING PROCESSED) INTO THE NCIT, IN
*             THE BASIC AREA ORDINAL FIELD IN THE OWNER OR MEMBER WORD
*             WHICH REFERS TO THIS AREA.
*           = IF THIS AREA IS THE OWNER (WORD ADDRESS OF THIS AREA-S
*             SCHEMA ENTRY MATCHES WORD ADDRESS OF OWNER IN CIT), SET 
*             THE WORD ADDRESS FOR THE NEXT READ OF A CIT FROM THIS 
*             CIT-S NEXT OWNER CONSTRAINT ENTRY ADDRESS.
*           = IF THIS AREA IS THE MEMBER, SET THE WORD ADDRESS FOR THE
*             NEXT READ OF A CIT FROM THIS CIT-S NEXT MEMBER CONSTRAINT 
*             ENTRY ADDRESS. (IF THIS AREA IS BOTH OWNER AND MEMBER, THE
*             NEXT MEMBER AND NEXT OWNER CONSTRAINT ENTRY ADDRESSES 
*             WILL BE IDENTICAL.) 
*           = IF THE WORD ADDRESS FOR THE NEXT READ OF A CIT IS ZERO, 
*             ALL CONSTRAINTS FOR THIS AREA HAVE BEEN PROCESSED.
*           = IF THE WORD ADDRESS FOR THE NEXT READ OF A CIT IS NON-
*             ZERO, USE THIS ADDRESS TO GO TO THE NEXT CONSTRAINT FOR 
*             THIS AREA.  GO TO TOP OF LOOP TO PROCESS THIS CONSTRAINT. 
*     WHEN ALL SUBSCHEMA AREAS HAVE BEEN PROCESSED, RETURN. 
 #
      CONTROL EJECT;
  
#     THE FOLLOWING COMDECKS ARE UNLISTED:  UTCDFDCLS, UTCITDCLS       #
#     CUGBADCLS, UTMPTDCLS, AND UTCCSDCLS                              #
  
      CONTROL NOLIST; 
  
      CONTROL EJECT;
      CONTROL EJECT;
      CONTROL EJECT;
*CALL UTCCSDCLS 
      CONTROL EJECT;
      CONTROL LIST; 
      CONTROL EJECT;
  
#     THE FOLLOWING COMMON IS FOR DDL SUBSCHEMA AND SCHEMA AREA HDERS  #
  
      COMMON DB$CCAH; 
        BEGIN                # COMMON                                  #
  
#     THE FOLLOWING ARRAY IS FOR SUBSCHEMA AREA HEADER ENTRY           #
  
        ARRAY SBHEADER[0:0] P(DFSBHEAD);
          BEGIN              #  SBHEADER                               #
*CALL SBAHDDCLS 
          END                #  SBHEADER                               #
  
#     THE FOLLOWING ARRAY IS FOR THE SCHEMA AREA HEADER ENTRY          #
  
        ARRAY SCHEADER[0:0] P(DFSCHEAD);
          BEGIN              #  SCHEADER                               #
*CALL SCAHDDCLS 
          END                #  SCHEADER                               #
        END                  # COMMON                                  #
      CONTROL EJECT;
  
#     THE FOLLOWING ITEMS ARE LOCAL TO DB$CCPP                         #
  
      ITEM  ALINDEX     U;   # AN INDEX INTO AREALIST                  #
      ITEM  CALFLAG     B;   # TRUE IMPLIES BUILD A AREALIST ENTRY     #
      ITEM  CITFLAG     B;   # TRUE IMPLIES BUILD A NCIT ENTRY         #
      ITEM  CITNXWA     I;   # WORD ADDRESS OF NEXT CIT ENTRY          #
      ITEM  CONINDEX    U;   # INDEX FOR THE CONSTRAINT LOOP           #
      ITEM  EXARWA      U;   # WORD ADDRESS OF EXTENDED AREA           #
      ITEM  MEMARWA     U;   # WORD ADDRESS OF MEMBER AREA             #
      ITEM  NXCITPTR    U;   # OFFSET  OF NEXT FREE ENTRY SPACE IN NCIT#
      ITEM  OWNARWA     U;   # WORD ADDRESS OF OWNER AREA              #
      ITEM  TARGTORD    U;   # CIT ORDINAL USED AS SEARCH TARGET       #
      ITEM  TEMPPTR     I;   # TEMPORARY OFFSET POINTER                #
      CONTROL EJECT;
  
#     PROCESS AREAS FOR THIS SUBSCHEMA                                 #
  
      XCALL DB$UAWS(LOC(CALPOINT),SBNUMARE);  # ALLOC MEM FOR BASIC AR #
      CITFLAG = TRUE;        # BUILD A NCIT ENTRY                      #
      FOR CURORDNL = 1 STEP 1 UNTIL SBNUMARE DO 
        BEGIN 
  
#       CALL DB$CGSB TO GET NEXT SUBSCHEMA AREA HEADER                 #
  
        XCALL DB$CGSB(LOC(SBHEADER),DFSBHEAD,SBNEXTAD); #GET SB AR HDER#
        SBCURRAD = SBNEXTAD;   # ADDRESS OF CURRENT SB ENTRY           #
        SBNEXTAD = SBFWADDR + SBARNEXT[0];  #ADDRESS OF NEXT SB AR HDER#
        IF SBARTYPE[0] NQ 1  # IF ENTRY TYPE IS NOT AREA               #
          THEN               # ABORT                                   #
            XCALL DB$CERR("7751CCPP",SBARTYPE[0]);
        XCALL DB$CGSB(SUBSADDR,DFNAMEWD,SBCURRAD + SBARNAMEPTR[0]); 
        P<GETENTRY> = SUBSADDR;  # POINT AT SUBSCHEMA AREA NAME        #
        CURNAME = DB$CFIL(GETENTRY[0],SBARLENGCHAR[0]," "); 
  
#       CALL DB$CNSC TO GET SUBSCHEMA AREA-S SCHEMA HEADER             #
  
        IF SBARALIASPTR[0] GR 0    # IF THERE IS AN AREA ALIAS         #
          THEN                     # GET SCHEMA AREA HEADER USING ALIAS#
            BEGIN 
            XCALL DB$CGSB(SUBSADDR,DFNAMEWD,SBCURRAD + SBARALIASPTR[0]);
            XCALL DB$CNSC(3,SBARALIASLW[0]);
            END 
          ELSE                     # GET SCHEMA AREA HEADER            #
            XCALL DB$CNSC(3,SBARLENGWRDS[0]); 
  
        IF SCAREADATATY[0] NQ 0    # IF ENTRY TYPE NOT AREA            #
          THEN                     # ABORT                             #
            XCALL DB$CERR("7752CCPP",SCAREADATATY[0]);
  
#       START BASIC AREA ENTRY ON AREALIST                             #
  
        P<AREALIST> = CALADDR + CURORDNL - 1;  #PT AT BASIC AREA ENTRY #
        ALSCWA[0] = SCCURRAD;                  #SET BASIC AREA SC WA   #
  
#       IF THERE ARE NO CONSTRAINTS ON THIS AREA, PROCESS NEXT AREA    #
  
        IF SCAREACSTR[0] EQ 0 
          THEN
            TEST CURORDNL;
  
      CONTROL EJECT;
  
#       PROCESS CONSTRAINTS FOR THIS AREA                              #
  
        CITNXWA = SCAREACSTR[0];   # WORD ADDRESS OF NEXT DDL CIT      #
  
        FOR CONINDEX = 1 STEP 1 
          WHILE CITNXWA GR 0 DO    # WHILE THERE ARE MORE CONSTRAINTS  #
          BEGIN 
  
          IF CITFLAG         # IF A NCIT ENTRY WILL BE BUILT           #
            THEN             # ALLOCATE MEMORY FOR IT                  #
              XCALL DB$UAWS(LOC(CITPOINT),DFNCITLEN); 
  
#         SET POINTER TO NEXT ENTRY SPACE AVAILABLE FOR CIT            #
  
          NXCITPTR = CONSTNUM * DFNCITLEN;
  
#         GET CIT FROM SCHEMA LIBRARY                                  #
  
          XCALL DB$CGSC(CITADDR + NXCITPTR,DFNCITLEN,CITNXWA);
          P<SCCSLIST> = CITADDR + NXCITPTR;  # POINT AT CIT            #
          IF SCCSDATATYP[0] NQ 11  # IF ENTRY TYPE NOT CONSTRAINT      #
            THEN                   # ABORT                             #
              XCALL DB$CERR("7753CCPP",SCCSDATATYP[0]); 
  
#         ADJUST CIT ENTRY SO THAT CONSTRAINT NAME TAKES 3 WORDS       #
  
          IF SCCSNAMLENW[0] LS 3   # IF CONSTRAINT NAME LENGTH LT 3    #
            THEN                   # EXPAND IT TO 3 WORDS              #
              BEGIN 
  
#             MOVE -NEXT CONSTRAINT ENTRY ADDRESSES- WORD              #
  
              SCCSWORD[DFNCITNXT] = SCCSWORD[SCCSNAMPTR[0] +
                SCCSNAMLENW[0] + DFNCITNAMADR]; 
  
#             MOVE -OWNER- WORD                                        #
  
              SCCSWORD[DFNCITOWN] = SCCSWORD[SCCSNAMPTR[0] +
                SCCSNAMLENW[0] + DFNCITNAMOWN]; 
  
#             MOVE -MEMBER- WORD                                       #
  
              SCCSWORD[DFNCITMEM] = SCCSWORD[SCCSNAMPTR[0] +
                SCCSNAMLENW[0] + DFNCITNAMMEM]; 
              END 
      CONTROL EJECT;
  
#         BLANK FILL CONSTRAINT NAME                                   #
  
          SCCSTRNAM30[SCCSNAMPTR[0]] =
            DB$CFIL(SCCSTRNAM30[SCCSNAMPTR[0]],SCCSNAMLENC[0]," "); 
  
          CURSCRAT = SCCSTRNAM30[SCCSNAMPTR[0]];  # SAVE CURRENT CONST #
                                                  # NAME FOR ERR PROCES#
  
          TARGTORD = SCCSCITORD[0];  # TARGET OF FOLLOWING SEARCH      #
  
#         SET MEMBER AND OWNER AREA WORD ADDRESSES                     #
  
          P<SCCSLIST> = CITADDR + NXCITPTR + DFNCITMEM; # PNT AT MEM WD#
          MEMARWA = SCCSAREAWA[0];       # SET MEMBER AREA WORD ADDRESS#
          P<SCCSLIST> = CITADDR + NXCITPTR + DFNCITOWN; # PNT AT OWN WD#
          OWNARWA = SCCSAREAWA[0];       # SET OWNER AREA WORD ADDRESS #
  
#         SEARCH ALL NCIT-S TO AVOID BUILDING DUPLICATE ENTRIES        #
  
          TEMPPTR = 0;         # POINT TO FIRST ENTRY                  #
          CITFLAG = TRUE; 
          LOOP
            WHILE TEMPPTR LS NXCITPTR  # WHILE NOT TO CURRENT CONST    #
            AND CITFLAG DO             # AND DUP CIT NOT YET FOUND     #
            BEGIN 
            P<SCCSLIST> = CITADDR + TEMPPTR;
            IF TARGTORD EQ SCCSCITORD[0]
              THEN
                CITFLAG = FALSE;
              ELSE
                TEMPPTR = TEMPPTR + DFNCITLEN;  # TEMPPTR IS LEFT      #
                                                # POINTING AT FIRST    #
                                                # NCIT ENTRY FOR THIS  #
                                                # CONSTRAINT           #
            END 
  
          IF CITFLAG         # IF CONSTRAINT SHOULD HAVE NCIT BUILT    #
            THEN
              BEGIN 
              CONSTNUM = CONSTNUM + 1;    # INCREMENT NUMBER OF CONST  #
              P<SCCSLIST> = CITADDR + NXCITPTR + DFNCITMEM; 
              SCCSBAORD[0] = 0;  # ZERO MEMBER ORDINALS                #
              SCCSEXORD[0] = 0; 
              P<SCCSLIST> = CITADDR + NXCITPTR + DFNCITOWN; 
              SCCSBAORD[0] = 0;  # ZERO OWNER ORDINALS                 #
              SCCSEXORD[0] = 0; 
              P<SCCSLIST> = CITADDR + NXCITPTR + DFNCITORD; 
              SCCSNCITORD[0] = CONSTNUM; # ORDINAL OF THIS NCIT ENTRY  #
              END 
      CONTROL EJECT;
  
#         PUT DATA FOR THIS BASIC AREA ON AREALIST, AND RESET          #
#         NCIT NEXT CONSTRAINT POINTERS, AS NEEDED                     #
  
          P<AREALIST> = CALADDR + CURORDNL - 1;  #PT AT BASIC AREA ENT #
          IF MEMARWA EQ SCCURRAD  # IF THIS SCHEMA AREA IS THE MEMBER  #
            THEN                  # THEN OWNER AREA IS EXTENDED AREA   #
              BEGIN 
              EXARWA = OWNARWA; 
              ALMEMFLG[0] = TRUE;  # MEMBER FLAG OF BASIC AREA ENTRY   #
              IF MEMARWA EQ OWNARWA   # IF THIS IS INTRA-REC CONST     #
                THEN                  # SET OWNER FLAG, TOO            #
                  ALOWNFLG[0] = TRUE; 
              END 
            ELSE
              BEGIN 
              IF OWNARWA EQ SCCURRAD  #IF THIS SCHEMA AREA IS THE OWNER#
                THEN              # THEN MEMBER AREA IS EXTENDED AREA  #
                  BEGIN 
                  EXARWA = MEMARWA; 
                  ALOWNFLG[0] = TRUE;  # OWNER FLAG OF BASIC AREA ENTRY#
                  END 
                ELSE         # ABORT (CON DOES NOT POINT TO THIS SC AR)#
                  BEGIN 
                  P<SCCSLIST> = CITADDR + NXCITPTR; 
                  XCALL DB$CERR("7754CCPP",SCCSNAMLENC[0]); 
                  END 
              END 
  
          P<SCCSLIST> = CITADDR + ALLSTCON[0];  # PT AT LAST NCIT ENTRY#
                                                # INVOLVING THIS AREA  #
          IF CONINDEX EQ 1   # IF THIS IS FIRST CONST FOR THIS AREA    #
            THEN
              ALFIRCON[0] = TEMPPTR;           # FIRST CONSTRAINT PTR  #
            ELSE             # RESET THE SCCSLIST NEXT ENT PTRS        #
              BEGIN 
                IF SCCSBAORD[DFNCITMEM] EQ CURORDNL  # IF BA AR IS MEM #
                  THEN      # SET BA MEM NEXT PTR                      #
                    SCCSBANXT[DFNCITMEMNXT] = TEMPPTR;
                IF SCCSBAORD[DFNCITOWN] EQ CURORDNL  # IF BA AR IS OWN #
                  THEN      # SET BA OWN NEXT PTR                      #
                    SCCSBANXT[DFNCITOWNNXT] = TEMPPTR;
              END 
          ALLSTCON[0] = TEMPPTR;               # LAST CONSTRAINT PTR   #
      CONTROL EJECT;
  
#         PUT DATA FOR THIS EXTENDED AREA ON AREALIST, AND RESET       #
#         NCIT NEXT CONSTRAINT POINTERS, AS NEEDED                     #
  
          CALFLAG = TRUE; 
          FOR ALINDEX = SBNUMARE       # SEARCH THE EXTENDED AREA LIST #
            WHILE ALINDEX LS CONNBEXA + SBNUMARE  # WHILE IT LASTS     #
              AND CALFLAG DO                      # AND NO MATCH FOUND #
            BEGIN 
            P<AREALIST> = CALADDR + ALINDEX;
            IF EXARWA EQ ALSCWA[0]
              THEN
                CALFLAG = FALSE;
              ELSE
                ALINDEX = ALINDEX + 1;   # ALINDEX IS LEFT POINTING AT #
                                     # AREALIST ENTRY FOR THIS EX AREA #
            END 
  
          IF CALFLAG         # IF A NEW AREALIST EX AR ENTRY IS NEEDED #
            THEN             # BUILD ONE                               #
              BEGIN 
              XCALL DB$UAWS(LOC(CALPOINT),1);  # ALLOCATE MEMORY       #
              P<AREALIST> = CALADDR + SBNUMARE + CONNBEXA;
              ALSCWA[0] = EXARWA;  # SCHEMA WORD ADDRESS               #
              ALFIRCON[0] = TEMPPTR;          # FIRST CONSTRAINT PTR   #
              ALLSTCON[0] = TEMPPTR;          # LAST  CONSTRAINT PTR   #
              CONNBEXA = CONNBEXA + 1;  # NUMBER OF EXTENDED AREAS     #
              END 
            ELSE             # RESET NEXT PTR IN NCIT, AND             #
              BEGIN          # RESET LAST CONST PTR IN AREALIST        #
              P<AREALIST> = CALADDR + ALINDEX;
              P<SCCSLIST> = CITADDR + ALLSTCON[0];
              ALLSTCON[0] = TEMPPTR;
              IF SCCSEXORD[DFNCITMEM] EQ ALINDEX + 1 # IF EX AR IS MEM #
                                                     # AR IN LAST NCIT #
                                                     # FOR THIS AREA   #
                THEN
                  SCCSEXNXT[DFNCITMEMNXT] = TEMPPTR;
              IF SCCSEXORD[DFNCITOWN] EQ ALINDEX + 1 # IF EX AR IS OWN #
                                                     # AR IN LAST NCIT #
                                                     # FOR THIS AREA   #
                THEN
                  SCCSEXNXT[DFNCITOWNNXT] = TEMPPTR;
              END 
          IF EXARWA EQ MEMARWA      # IF EXTENDED AREA IS MEM AREA     #
            THEN
              ALMEMFLG[0] = TRUE; 
          IF EXARWA EQ OWNARWA      # IF EXTENDED AREA IS OWN AREA     #
            THEN
              ALOWNFLG[0] = TRUE; 
      CONTROL EJECT;
  
#         STORE ORDINALS OF BASIC AND EXTENDED AREAS IN NCIT           #
  
          P<SCCSLIST> = CITADDR + TEMPPTR;
          IF MEMARWA EQ EXARWA    # IF MEMBER AREA IS EXTENDED AREA    #
            THEN
              BEGIN 
              SCCSEXORD[DFNCITMEM] = ALINDEX + 1; # SET MEM EX AREA ORD#
              SCCSBAORD[DFNCITOWN] = CURORDNL; # SET OWN BASIC AREA ORD#
              END 
          IF OWNARWA EQ EXARWA    # IF OWNER AREA IS EXTENDED AREA     #
            THEN
              BEGIN 
              SCCSBAORD[DFNCITMEM] = CURORDNL; # SET MEM BASIC AREA ORD#
              SCCSEXORD[DFNCITOWN] = ALINDEX + 1; # SET OWN EX AREA ORD#
              END 
  
#         SET WORD ADDRESS FOR NEXT CONSTRAINT TO BE PROCESSED         #
  
          P<SCCSLIST> = CITADDR + NXCITPTR; 
          IF MEMARWA EQ SCCURRAD           # IF THIS IS THE MEMBER AREA#
            THEN                           # FOLLOW THE MEMBER POINTER #
              CITNXWA = SCCSMEMNXT[DFNCITNXT];
            ELSE                           # FOLLOW THE OWNER POINTER  #
              CITNXWA = SCCSOWNNXT[DFNCITNXT];
          SCCSBANXT[DFNCITMEMNXT] = -1;  # SET POINTERS TO INCICATE    #
          SCCSEXNXT[DFNCITMEMNXT] = -1;  # END OF CHAIN                #
          SCCSBANXT[DFNCITOWNNXT] = -1; 
          SCCSEXNXT[DFNCITOWNNXT] = -1; 
  
          END                # CONSTRAINT LOOP                         #
  
        END                  # AREA LOOP                               #
  
#     RETURN UNUSED MANAGED MEMORY                                     #
  
      IF CONSTNUM EQ 0   # IF NO CONSTRAINTS                           #
        THEN             # SHRINK MANAGED MEM BLOCKS TO HEADER WORD    #
          BEGIN 
          XCALL DB$USHR(LOC(CALPOINT)); 
          XCALL DB$USHR(LOC(CITPOINT)); 
          END 
        ELSE             # TRIM MANAGED MEM BLOCKS TO USED WORDS       #
          BEGIN 
          XCALL DB$UAWS(LOC(CALPOINT),0); 
          XCALL DB$UAWS(LOC(CITPOINT),0); 
          END 
  
#     RESET ITEMS IN COMMON                                            #
  
      CURNAME = " ";
  
      RETURN; 
  
      END                    #  DB$CCPP                                #
  
      TERM
