home *** CD-ROM | disk | FTP | other *** search
/ gdead.berkeley.edu / gdead.berkeley.edu.tar / gdead.berkeley.edu / pub / cad-tools / ciftomann.tar / CD / cd.c < prev    next >
C/C++ Source or Header  |  1988-01-28  |  83KB  |  2,907 lines

  1. /*
  2.  * cd.c
  3.  *
  4.  * Copyright -C- 1981 Kenneth H. Keller, Giles C. Billingsley
  5.  * sccsid "%W%  %G%"
  6.  *
  7.  *     CD is a CIF database package that was developed by the integrated
  8.  * circuits group of the Electronics Research Laboratory and the
  9.  * Department of Electrical Engineering and Computer Sciences at
  10.  * the University of California, Berkeley, California.  The programs in
  11.  * CD are available free of charge to any interested party.
  12.  * The sale, resale, or use of these programs for profit without the
  13.  * express written consent of the Department of Electrical Engineering
  14.  * and Computer Sciences, University of California, Berkeley, California,
  15.  * is forbidden.
  16.  */
  17.  
  18.  
  19. /*======================================================================*
  20.  *                                    *
  21.  *                       CCCCCC       DDDDDDD                 *
  22.  *                      CC    CC      DD    DD                 *
  23.  *                     CC      CC     DD     DD                *
  24.  *                     CC             DD     DD                       *
  25.  *                     CC             DD     DD                         *
  26.  *                     CC      CC     DD     DD                *
  27.  *                      CC    CC      DD    DD                *
  28.  *                       CCCCCC       DDDDDDD                *
  29.  *                                    *
  30.  *                                    *
  31.  * CD package code.                            *
  32.  *                                    *
  33.  *                                    *
  34.  *======================================================================*/
  35.  
  36. #include "cd.h" 
  37. #include "parser.h"
  38.  
  39. /* Library routines */
  40. char *strcpy();
  41. #ifndef vms
  42. char *sprintf();
  43. #endif
  44.  
  45.  
  46. /*
  47.  * The following is the policy for handling errors in CD:
  48.  * When a routine encounters difficulty, it will set CDStatusInt
  49.  * to some identifying value, copy a diagnostic string into
  50.  * CDStatusString, and return a 'False'.  Otherwise, the routine
  51.  * will return 'True' and not alter the value of CDStatusInt.
  52.  * Every routine that uses malloc will test the returned value
  53.  * and return Flase via CDError() if malloc fails.
  54.  */
  55. char *CDStatusString;
  56. int  CDStatusInt;
  57.  
  58. #define    LARGEBUFFERSIZE        400
  59.  
  60.  
  61.  
  62.  
  63.  
  64. /*===========================================================================*
  65.  *                                         *
  66.  * III N   N III TTTTT III   A   L     III ZZZZZ   A   TTTTT III  OOO  N   N *
  67.  *  I  NN  N  I    T    I   A A  L      I     Z   A A    T    I  O   O NN  N *
  68.  *  I  N N N  I    T    I  A   A L      I    Z   A   A   T    I  O   O N N N *
  69.  *  I  N  NN  I    T    I  AAAAA L      I   Z    AAAAA   T    I  O   O N  NN *
  70.  * III N   N III   T   III A   A LLLLL III ZZZZZ A   A   T   III  OOO  N   N *
  71.  *                                         *
  72.  *             RRRR   OOO  U   U TTTTT III N   N EEEEE  SSSS             *
  73.  *             R   R O   O U   U   T    I  NN  N E     S                 *
  74.  *             RRRR  O   O U   U   T    I  N N N EEE    SSS             *
  75.  *             R R   O   O U   U   T    I  N  NN E         S             *
  76.  *             R  R   OOO   UUU    T   III N   N EEEEE SSSS             *
  77.  *                                         *
  78.  *                                         *
  79.  *                                         *
  80.  *    CDInit()                                 *
  81.  *    CDPath(Path)                                 *
  82.  *    CDSetLayer(Layer,Tech,Mask)                         *
  83.  *    CDDebug(Flag)                                 *
  84.  *                                         *
  85.  *===========================================================================*/
  86.  
  87. void
  88. CDInit(){
  89.     /*
  90.      * This must be the first CD routine called.  It initializes
  91.      * the layer table, search path, symbol table, and transform
  92.      * stack.  No returned value.
  93.      */
  94.     static char CDDiagnosticString[LARGEBUFFERSIZE];
  95.     int Layer,Int1;
  96.     for(Int1 = 0;Int1 < CDNUMLAYERS;++Int1)
  97.     CDSymbolTable[Int1] = NULL;
  98.     for(Layer = 1;Layer <= CDNUMLAYERS;++Layer){
  99.     CDLayer[Layer].lTechnology = ' ';
  100.     CDLayer[Layer].lMask[0] = ' ';
  101.     CDLayer[Layer].lMask[1] = ' ';
  102.     CDLayer[Layer].lMask[2] = ' ';
  103.     CDLayer[Layer].lCDFrom = False;
  104.     }
  105.     CDPath(".");
  106.     CDDebug(False);
  107.     CDDesc.dPrptyList = NULL;
  108.     CDDesc.dNumSymbolsAllocated = 0;
  109.     CDStatusString = CDDiagnosticString;
  110.  
  111.     /* Vanilla operation. */
  112.     CDDesc.dControl = DCONTROLVANILLA;
  113.     TInit();
  114.     }
  115.  
  116.  
  117. int
  118. CDPath(Path)
  119.     char *Path;
  120.     /*
  121.      * Sets search rules for symbol name resolution.
  122.      * Path is a list of directory names to search separated by blanks.
  123.      * csh-style names are understood.
  124.      * False is returned if the search path argument is invalid.
  125.      */
  126.     {
  127.     if(Not PSetPath(Path))
  128.     return(CDError(CDBADPATH));
  129.     else
  130.     return(True);
  131.     }
  132.  
  133.  
  134. void
  135. CDSetLayer(Layer,Technology,Mask)
  136.     int  Layer;
  137.     char Technology,Mask[];
  138.     /*
  139.      * This routine sets the layer Layer to the name 'TechnologyMask'.
  140.      * There is no returned value.
  141.      */
  142.     {
  143.     CDLayer[Layer].lTechnology = Technology;
  144.     CDLayer[Layer].lMask[0] = Mask[0];
  145.     CDLayer[Layer].lMask[1] = Mask[1];
  146.     CDLayer[Layer].lMask[2] = Mask[2];
  147.     }
  148.  
  149.  
  150. void
  151. CDDebug(Debug)
  152.     int Debug;
  153.     {
  154.     /*
  155.      * If Debug is true, then CD will run in debug mode.  There is
  156.      * no returned value.
  157.      */
  158.     CDDesc.dDebug = Debug;
  159.     }
  160.  
  161.  
  162.  
  163.  
  164. /*======================================================================*
  165.  *                                    *
  166.  *                SSSS Y   Y M   M BBBB   OOO  L            *
  167.  *               S      Y Y  MM MM B   B O   O L            *
  168.  *                SSS    Y   M M M BBBB  O   O L            *
  169.  *                   S   Y   M   M B   B O   O L            *
  170.  *               SSSS    Y   M   M BBBB   OOO  LLLLL            *
  171.  *                                    *
  172.  *    M   M   A   N   N   A    GGG  EEEEE M   M EEEEE N   N TTTTT    *
  173.  *    MM MM  A A  NN  N  A A  G     E     MM MM E     NN  N   T        *
  174.  *    M M M A   A N N N A   A G GGG EEE   M M M EEE   N N N   T        *
  175.  *    M   M AAAAA N  NN AAAAA G   G E     M   M E     N  NN   T        *
  176.  *    M   M A   A N   N A   A  GGG  EEEEE M   M EEEEE N   N   T        *
  177.  *                                    *
  178.  *                                    *
  179.  *                                    *
  180.  *    CDOpen(SymbolName,SymbolDesc,Access)                *
  181.  *    CDSymbol(SymbolName,SymbolDesc)                    *
  182.  *    CDClose(SymbolDesc)                        *
  183.  *    CDReflect(SymbolDesc)                        *
  184.  *    CDPatchInstances(SymbolDesc,MasterName)                *
  185.  *                                    *
  186.  *======================================================================*/
  187.  
  188. int
  189. CDOpen(SymbolName,SymbolDesc,Access)
  190.     char Access;
  191.     char *SymbolName;
  192.     struct s **SymbolDesc;
  193.     /*
  194.      * Open symbol and return desc for it.
  195.      * 
  196.      * CDOpen returns False if parse failed or out of memory.  When CDOpen
  197.      * returns, CDStatusInt assumes one of the following values:
  198.      *   (FATAL)-CDPARSEFAILED if parser failed or out of memory.
  199.      *           CDOLDSYMBOL if success and symbol already exists in memory. 
  200.      *           CDNEWSYMBOL if success and symbol is a new (empty) one.
  201.      *           CDSUCCEEDED if no problem was encountered.
  202.      * If the return is fatal, CDStatusString contains a diagnostic message.
  203.      * Only CDPARSEFAILED is returned as a fatal error; this simplifies
  204.      * the diagnostic test.
  205.      *
  206.      * If Access == 'w', then create the cell if it doesn't already exist.
  207.      * In other words, open cell for writing.  This solves the following
  208.      * problem: if the user tries to create an instance of a cell that 
  209.      * doesn't exist, it will not be created in the database.  If the cell
  210.      * was added to the database, a second attempt to place the cell that
  211.      * doesn't exist would succeed.  Bad News!
  212.      *
  213.      * If Access == 'n', then create a new cell if it doesn't already exist
  214.      * in the database.  Unlike Access == 'w', the cell will not be parsed
  215.      * if it exists in the current search path.
  216.      */
  217.     {
  218.     int Key,Int1;
  219.     int Layer;
  220.     int StatusInt;
  221.     char *cp;
  222.     char *StatusString;
  223.     FILE *FDesc;
  224.     struct bu *Bucket;
  225.     struct m *MasterListDesc;
  226.     struct s *MasterSymbolDesc;
  227.     struct s *NewDesc;
  228.     struct prpty PrptyCopy;
  229.     static int RecursionLevel = 0; 
  230.     unsigned int size;
  231.  
  232. #ifdef DEBUGREFLECT
  233. printf("Begin CDOpen of symbol %s.\n",SymbolName);
  234. #endif
  235.  
  236.     if(SymbolName == NULL Or *SymbolName == NULL){
  237.     CDStatusInt = CDPARSEFAILED;
  238.     sprintf(CDStatusString,"Null symbol name encountered.");
  239.     return(False);
  240.     }
  241.     CDDesc.dControl = DCONTROLCDOPEN;
  242.     ++RecursionLevel;
  243.  
  244.     /* Is symbol open already? */
  245.     CDSymbol(SymbolName,SymbolDesc);
  246.     if(*SymbolDesc != NULL){
  247.     CDStatusInt = CDOLDSYMBOL;
  248.     *CDStatusString = NULL;
  249.     }
  250.     else {
  251.     /* first, try to allocate memory */
  252.     if((NewDesc = (struct s *)malloc(sizeof(struct s))) == NULL){
  253.         CDStatusInt = CDError(CDMALLOCFAILED);
  254.         CDStatusInt = CDPARSEFAILED;
  255.         return(False);
  256.         }
  257.     size = strlen(SymbolName) + 2; 
  258.     if((cp = malloc(size)) == NULL){
  259.         CDStatusInt = CDError(CDMALLOCFAILED);
  260.         CDStatusInt = CDPARSEFAILED;
  261.         return(False);
  262.         }
  263.     if((Bucket = (struct bu *)malloc(sizeof(struct bu))) == NULL){
  264.         CDStatusInt = CDError(CDMALLOCFAILED);
  265.         CDStatusInt = CDPARSEFAILED;
  266.         return(False);
  267.         }
  268.     if(Access != 'n' And (FDesc = POpen(SymbolName,"r",(char *)NULL,
  269.         (char **)NULL)) != NULL){
  270.         /*
  271.          * Symbol already exists, so user probably intends
  272.          * to edit it or just read it.
  273.          */
  274.  
  275.         /* put symbol into symbol table */
  276.         *SymbolDesc = CDDesc.dSymbolDesc = NewDesc;
  277.         ++CDDesc.dNumSymbolsAllocated;
  278.         for(Layer = 0;Layer <= CDNUMLAYERS;++Layer)
  279.         CDDesc.dSymbolDesc->sBin[Layer] = (struct o ***)NULL;
  280.         CDDesc.dSymbolDesc->sName = cp;
  281.         strcpy(CDDesc.dSymbolName,SymbolName); 
  282.         strcpy(CDDesc.dSymbolDesc->sName,CDDesc.dSymbolName); 
  283.         CDDesc.dNumX = CDDesc.dNumY = 1;
  284.         CDDesc.dDX = CDDesc.dDY = 0;
  285.         CDDesc.dSymbolDesc->sA = 1;
  286.         CDDesc.dSymbolDesc->sB = 1;
  287.         CDDesc.dSymbolDesc->sBBValid = True; 
  288.         CDDesc.dSymbolDesc->sLeft = CDDesc.dSymbolDesc->sBottom =INFINITY;
  289.         CDDesc.dSymbolDesc->sRight = CDDesc.dSymbolDesc->sTop = -INFINITY;
  290.         CDDesc.dSymbolDesc->sInfo = 0;
  291.         CDDesc.dSymbolDesc->sMasterList = NULL;
  292.         CDDesc.dSymbolDesc->sPrptyList = NULL;
  293.         /* add property list information */
  294.         while(CDDesc.dPrptyList != NULL){
  295.             if(Not CDAddProperty(CDDesc.dSymbolDesc,(struct o *)NULL,
  296.             CDDesc.dPrptyList->prpty_Value,
  297.             CDDesc.dPrptyList->prpty_String)){
  298.             CDStatusInt = CDError(CDMALLOCFAILED);
  299.             CDStatusInt = CDPARSEFAILED;
  300.             return(False);
  301.             }
  302.             /* free storage of CDDesc.dPrptyList */
  303.             PrptyCopy = *CDDesc.dPrptyList;
  304.             free(CDDesc.dPrptyList->prpty_String);
  305.             free((struct prpty *)CDDesc.dPrptyList);
  306.             CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  307.             }
  308.         /* Insert symbol desc in symbol table */
  309.         Key = 0;
  310.         for(Int1 = 0;Int1 < strlen(SymbolName);++Int1)
  311.         Key += SymbolName[Int1];
  312.         if(CDSymbolTable[Key % CDNUMLAYERS] != NULL)
  313.         CDSymbolTable[Key % CDNUMLAYERS]->buPred = Bucket;
  314.         Bucket->buPred = NULL;
  315.         Bucket->buSucc = CDSymbolTable[Key % CDNUMLAYERS];
  316.         Bucket->buSymbolDesc = *SymbolDesc;
  317.         CDSymbolTable[Key % CDNUMLAYERS] = Bucket; 
  318.         fclose(FDesc); 
  319.         PCIF(SymbolName,&StatusString,&StatusInt);
  320.         if(StatusInt == PSUCCEEDED)
  321.         CDStatusInt = CDOLDSYMBOL;
  322.         else{
  323.         CDStatusInt = CDPARSEFAILED;
  324.         sprintf(CDStatusString,"%s",StatusString);
  325.         if(Not CDClose(*SymbolDesc))
  326.             return(CDError(CDMALLOCFAILED));
  327.         return(False);
  328.         }
  329.         /*
  330.          * Now, the master list descs and instance descs, if any, have
  331.          * to be filled in.  See the discussion in CDBeginMakeCall for
  332.          * why this wasn't done earlier.
  333.          */
  334.         MasterListDesc = CDDesc.dSymbolDesc->sMasterList;
  335.         while(MasterListDesc != NULL){
  336.         /*
  337.          * This recursive call is safe, because PCIF has done its work.
  338.          * Because StatusInt is checked, we ignore the returned value.
  339.          */
  340.         CDOpen(MasterListDesc->mName,&MasterSymbolDesc,'r');
  341.         if(CDStatusInt == CDNEWSYMBOL Or CDStatusInt == CDPARSEFAILED){
  342.             if(CDStatusInt == CDNEWSYMBOL){
  343.             CDStatusInt = CDPARSEFAILED;
  344.             sprintf(CDStatusString,
  345.                 "Master %s doesn't seem to be around.\n",
  346.                  MasterListDesc->mName);
  347.             }
  348.             return(False);
  349.             }
  350.         if(Not CDReflect(MasterSymbolDesc)){
  351.             CDStatusInt = CDPARSEFAILED;
  352.             return(False);
  353.             }
  354.         MasterListDesc = MasterListDesc->mSucc;
  355.         }
  356.         CDStatusInt = CDSUCCEEDED;
  357.         }
  358.     else {
  359.         if(Access == 'w' Or Access == 'n'){
  360.         /* create cell in database */
  361.         CDDesc.dSymbolDesc = NewDesc;
  362.         ++CDDesc.dNumSymbolsAllocated;
  363.         for(Layer = 0;Layer <= CDNUMLAYERS;++Layer)
  364.             CDDesc.dSymbolDesc->sBin[Layer] = (struct o ***)NULL;
  365.         CDDesc.dSymbolDesc->sName = cp;
  366.         strcpy(CDDesc.dSymbolName,SymbolName); 
  367.         strcpy(CDDesc.dSymbolDesc->sName,CDDesc.dSymbolName); 
  368.         CDDesc.dNumX = CDDesc.dNumY = 1;
  369.         CDDesc.dDX = CDDesc.dDY = 0;
  370.         CDDesc.dSymbolDesc->sA = 1;
  371.         CDDesc.dSymbolDesc->sB = 1;
  372.         CDDesc.dSymbolDesc->sBBValid = True; 
  373.         CDDesc.dSymbolDesc->sLeft
  374.             = CDDesc.dSymbolDesc->sBottom = INFINITY;
  375.         CDDesc.dSymbolDesc->sRight
  376.             = CDDesc.dSymbolDesc->sTop = -INFINITY;
  377.         CDDesc.dSymbolDesc->sInfo = 0;
  378.         CDDesc.dSymbolDesc->sMasterList = NULL;
  379.         CDDesc.dSymbolDesc->sPrptyList = NULL;
  380.             /* add property list information */
  381.             while(CDDesc.dPrptyList != NULL){
  382.                 if(Not CDAddProperty(CDDesc.dSymbolDesc,(struct o *)NULL,
  383.                 CDDesc.dPrptyList->prpty_Value,
  384.                 CDDesc.dPrptyList->prpty_String)){
  385.             CDStatusInt = CDError(CDMALLOCFAILED);
  386.             CDStatusInt = CDPARSEFAILED;
  387.             return(False);
  388.             }
  389.                 /* free storage of CDDesc.dPrptyList */
  390.                 PrptyCopy = *CDDesc.dPrptyList;
  391.                 free(CDDesc.dPrptyList->prpty_String);
  392.                 free((struct prpty *)CDDesc.dPrptyList);
  393.                 CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  394.                 }
  395.         /* Insert symbol desc in symbol table */
  396.         *SymbolDesc = CDDesc.dSymbolDesc;
  397.         Key = 0;
  398.         for(Int1 = 0;Int1 < strlen(SymbolName);++Int1)
  399.             Key += SymbolName[Int1];
  400.         if(CDSymbolTable[Key % CDNUMLAYERS] != NULL)
  401.             CDSymbolTable[Key % CDNUMLAYERS]->buPred = Bucket;
  402.         Bucket->buSucc = CDSymbolTable[Key % CDNUMLAYERS];
  403.         Bucket->buSymbolDesc = *SymbolDesc;
  404.         Bucket->buPred = NULL;
  405.         CDSymbolTable[Key % CDNUMLAYERS] = Bucket; 
  406.         }
  407.         else {
  408.             *SymbolDesc = NULL;
  409.         /* free the previously allocated memory.  It's not needed */
  410.         free((struct s *)NewDesc);
  411.         free((struct bu *)Bucket);
  412.         free(cp);
  413.         }
  414.         CDStatusInt = CDNEWSYMBOL;
  415.         }
  416.     }
  417.     --RecursionLevel;
  418.     if(RecursionLevel == 0 And CDDesc.dControl != DCONTROLPCIF)
  419.     CDDesc.dControl = DCONTROLVANILLA;
  420.  
  421. #ifdef DEBUGREFLECT
  422. printf("End CDOpen of symbol %s.\n",SymbolName);
  423. #endif
  424.  
  425.     return(True);
  426.     }
  427.  
  428.  
  429. void
  430. CDSymbol(SymbolName,SymbolDesc)
  431.     char *SymbolName;
  432.     struct s **SymbolDesc;
  433.     /*
  434.      * Returns symbol desc if any for symbol.
  435.      * If SymbolName is not in symbol table, the pointer SymbolDesc
  436.      * is returned NULL.
  437.      */
  438.     {
  439.     int Key,Int1;
  440.     struct bu *Bucket;
  441.  
  442.     Key = 0;
  443.     *SymbolDesc = NULL;
  444.     if(SymbolName == NULL)
  445.     return;
  446.     for(Int1 = 0;Int1 < strlen(SymbolName);++Int1)
  447.     Key += SymbolName[Int1];
  448.     Bucket = CDSymbolTable[Key % CDNUMLAYERS];
  449.     while(Bucket != NULL){
  450.     if(strcmp(Bucket->buSymbolDesc->sName,SymbolName) == 0){
  451.         *SymbolDesc = Bucket->buSymbolDesc;
  452.         return;
  453.         }
  454.     Bucket = Bucket->buSucc;
  455.     }
  456.     }
  457.  
  458.  
  459. int
  460. CDClose(SymbolDesc)
  461.     struct s *SymbolDesc;
  462.     /*
  463.      * Close symbol.  Free SymbolDesc.
  464.      * If malloc fails, False is returned.  Otherwise, True is returned.
  465.      */
  466.     {
  467.     struct bu *Bucket;
  468.     struct g *GenDesc;
  469.     struct o *Pointer;
  470.     struct prpty *PrptyDesc;
  471.     struct prpty PrptyCopy;
  472.     int Layer;
  473.     int Key,Int1;
  474.  
  475.     /*
  476.      * Delete symbol desc from symbol table.
  477.      */
  478.     Key = 0;
  479.     for(Int1 = 0;Int1 < strlen(SymbolDesc->sName);++Int1)
  480.     Key += SymbolDesc->sName[Int1];
  481.     Bucket = CDSymbolTable[Key % CDNUMLAYERS];
  482.     while(Bucket != NULL){
  483.     if(strcmp(Bucket->buSymbolDesc->sName,SymbolDesc->sName) == 0)
  484.         break;
  485.     Bucket = Bucket->buSucc;
  486.     }
  487.     if(Bucket == NULL)
  488.     return(True);
  489.     if(Bucket->buPred == NULL And Bucket->buSucc == NULL){
  490.     /*
  491.      * Only desc--has no pred or succ. 
  492.      */
  493.     CDSymbolTable[Key % CDNUMLAYERS] = NULL;
  494.     }
  495.     elif(Bucket->buPred == NULL){
  496.     /*
  497.      * First desc.    Has a succ, but no pred. 
  498.      */
  499.     CDSymbolTable[Key % CDNUMLAYERS] = Bucket->buSucc;
  500.     Bucket->buSucc->buPred = NULL;
  501.     }
  502.     elif(Bucket->buSucc == NULL){
  503.     /*
  504.      * Last desc--has a pred, but no succ. 
  505.      */
  506.     Bucket->buPred->buSucc = NULL; 
  507.     }
  508.     else {
  509.     /*
  510.      * Vanilla desc has a pred and a succ.
  511.      */
  512.     Bucket->buSucc->buPred = Bucket->buPred; 
  513.     Bucket->buPred->buSucc = Bucket->buSucc;
  514.     }
  515.     /*
  516.      * Free storage taken up by symbol.
  517.      */
  518.     for(Layer = 0;Layer <= CDNUMLAYERS;++Layer){
  519.     if(Not CDInitGen(SymbolDesc,Layer,(int)-INFINITY,(int)-INFINITY,
  520.         (int)INFINITY,(int)INFINITY,&GenDesc))
  521.         return(CDError(CDMALLOCFAILED));
  522.     loop {
  523.         CDGen(SymbolDesc,GenDesc,&Pointer);
  524.         if(Pointer == NULL)
  525.         break;
  526.         else{
  527.         CDDelete(SymbolDesc,Pointer);
  528.         }
  529.         }
  530.     }
  531.     /*
  532.      * Free storage of property list;
  533.      */
  534.     PrptyDesc = SymbolDesc->sPrptyList;
  535.     while(PrptyDesc != NULL){
  536.     PrptyCopy = *PrptyDesc;
  537.     if(PrptyDesc->prpty_String != NULL)
  538.         free(PrptyDesc->prpty_String);
  539.     free(PrptyDesc);
  540.     PrptyDesc = PrptyCopy.prpty_Succ;
  541.     }
  542.     free(Bucket->buSymbolDesc);
  543.     free(Bucket);
  544.     return(True);
  545.     }
  546.  
  547.  
  548. int
  549. CDReflect(SymbolDesc)
  550.     struct s *SymbolDesc;
  551.     /*
  552.      * This routine must be invoked at certain times by the CD user. 
  553.      * All bounding box information must be up-to-date if the indexing
  554.      * method is to work.
  555.      *
  556.      * CDReflect will return False if malloc fails.  Otherwise, True is
  557.      * returned.
  558.      *
  559.      * Here's the problem.
  560.      * Suppose we have a symbol called Load and there is an instance
  561.      * of it in NAND.  Then, there is a master list desc for Load in
  562.      * NAND's master list.  Suppose Load is edited and its BB changes. 
  563.      * Then, the instance desc for the instance of Load in NAND will be wrong. 
  564.      * Calling CDReflect(Load) reflects the change to Load's BB to all
  565.      * symbols that DIRECTLY or INDIRECTLY reference it. 
  566.      *
  567.      * In one sentence, here is when you must invoke CDReflect:
  568.      *     You have opened a symbol and edited it so that its bounding box
  569.      *     has changed and you are done editing it for the time being.
  570.      */
  571.     {
  572.     int Int1,L,B,R,T;
  573.     struct bu *Bucket;
  574.     struct m *MasterListDesc;
  575.  
  576.     /*
  577.      * Here's the algorithm.
  578.      * Let the name of the symbol we are reflecting be S.
  579.      *
  580.      * Recompute BB of S.
  581.      * CDUpdate does this.
  582.      *
  583.      * For each symbol named i, i != S, in CD's hash table of symbol descs, 
  584.      * do the following. 
  585.      *
  586.      * For each master named M, if any, in master list of i, do the following.
  587.      *     If M == S and M's BB != S's BB, do the following.
  588.      *            M's BB = S's BB.
  589.      *            Patch up i's instance descs that reference M.
  590.      *            Update i's BB.
  591.      *            Invoke Reflect(i) recursively.
  592.      */
  593.  
  594. #ifdef DEBUGREFLECT
  595. printf("Begin Reflect(%s).\n",SymbolDesc->sName);
  596. printf("    Old BB is %d %d %d %d.\n",SymbolDesc->sLeft,SymbolDesc->sBottom,
  597.     SymbolDesc->sRight,SymbolDesc->sTop);
  598. #endif
  599.  
  600.     /*
  601.      * Recompute BB of S.
  602.      */
  603.     if(Not CDBB(SymbolDesc,(struct o *)NULL,&L,&B,&R,&T))
  604.     return(False);
  605.  
  606. #ifdef DEBUGREFLECT
  607. printf("    New BB is %d %d %d %d.\n",SymbolDesc->sLeft,SymbolDesc->sBottom,
  608.     SymbolDesc->sRight,SymbolDesc->sTop);
  609. #endif
  610.  
  611.     for(Int1 = 0;Int1 < CDNUMLAYERS;++Int1){
  612.     Bucket = CDSymbolTable[Int1];
  613.     loop
  614.         if(Bucket == NULL)
  615.         break;
  616.         /*
  617.          * SymbolDesc is the desc for S.
  618.          * Bucket->buSymbolDesc is the desc for i.
  619.          */
  620.         elif(strcmp(Bucket->buSymbolDesc->sName,SymbolDesc->sName) == 0)
  621.         Bucket = Bucket->buSucc;
  622.         else {
  623.  
  624. #ifdef DEBUGREFLECT
  625. printf("    Begin traversing master list of %s.\n",Bucket->buSymbolDesc->sName);
  626. #endif
  627.  
  628.         MasterListDesc = Bucket->buSymbolDesc->sMasterList;
  629.         loop
  630.             if(MasterListDesc == NULL){
  631.  
  632. #ifdef DEBUGREFLECT
  633. printf("    End traversing master list of %s.\n",Bucket->buSymbolDesc->sName);
  634. #endif
  635.  
  636.             break;
  637.             }
  638.             else {
  639.             /*
  640.              * MasterListDesc->mName is M.
  641.              */
  642.  
  643. #ifdef DEBUGREFLECT
  644. printf("Considering %s.\n",MasterListDesc->mName);
  645. printf("BB is %d %d %d %d.\n",MasterListDesc->mLeft,MasterListDesc->mBottom, 
  646.     MasterListDesc->mRight,MasterListDesc->mTop); 
  647. #endif
  648.  
  649.             if(strcmp(MasterListDesc->mName,SymbolDesc->sName) == 0
  650.                 And (MasterListDesc->mLeft != SymbolDesc->sLeft Or 
  651.                 MasterListDesc->mBottom != SymbolDesc->sBottom Or 
  652.                 MasterListDesc->mRight != SymbolDesc->sRight Or 
  653.                 MasterListDesc->mTop != SymbolDesc->sTop)){
  654.  
  655. #ifdef DEBUGREFLECT
  656. printf("BB conflict.\n");
  657. #endif
  658.  
  659.                 MasterListDesc->mLeft = SymbolDesc->sLeft; 
  660.                 MasterListDesc->mBottom = SymbolDesc->sBottom; 
  661.                 MasterListDesc->mRight = SymbolDesc->sRight; 
  662.                 MasterListDesc->mTop = SymbolDesc->sTop;
  663.                 /*
  664.                  * Patch up instance descs.
  665.                  * A very big loop.
  666.                  * Warrants its own routine.
  667.                  */
  668.                 if(Not CDPatchInstances(Bucket->buSymbolDesc,
  669.                 MasterListDesc->mName)) return(False);
  670.                 /*
  671.                  * Recompute i's BB.
  672.                  */
  673.                 Bucket->buSymbolDesc->sBBValid = False;
  674.                 if(Not CDBB(Bucket->buSymbolDesc,(struct o *)NULL,
  675.                 &L,&B,&R,&T)) return(False);
  676.                 /*
  677.                  * Reflect changes up the hierarchy of
  678.                  * instance references.
  679.                  */
  680.                 if(Not CDReflect(Bucket->buSymbolDesc))
  681.                 return(False);
  682.                 }
  683.             MasterListDesc = MasterListDesc->mSucc;
  684.             };
  685.         Bucket = Bucket->buSucc;
  686.         };
  687.     }
  688.  
  689. #ifdef DEBUGREFLECT
  690. printf("End Reflect(%s).\n",SymbolDesc->sName);
  691. #endif
  692.  
  693.     return(True);
  694.     }
  695.  
  696.  
  697. int
  698. CDPatchInstances(SymbolDesc,MasterName)
  699.     struct s *SymbolDesc;
  700.     char *MasterName;
  701.     {
  702.     /*
  703.      * This routine will delete all instances of MasterName in the symbol
  704.      * pointed to by SymbolDesc, and then recreate the same instance in the
  705.      * symbol.  The result is to reflect any change in the BB of MasterName
  706.      * in the symbol.
  707.      *
  708.      * CDPatchInstances will return False if malloc fails.
  709.      * Otherwise, True is returned.
  710.      */
  711.     struct g *GenDesc;
  712.     struct o *OldPntr,*NewPntr;
  713.     struct t *TGen;
  714.     struct prpty *PrptyDesc;
  715.     char *SymbolName;
  716.     int X,Y;
  717.     int NumX,DX,NumY,DY;
  718.     int OldL,OldB,OldR,OldT;
  719.     int NewL,NewB,NewR,NewT;
  720.     char Type;
  721.  
  722. #ifdef DEBUGREFLECT
  723. printf("Begin patching instances of master %s for symbol %s.\n",MasterName,SymbolDesc->sName); 
  724. #endif
  725.  
  726.     if(MasterName == NULL)
  727.     return(True);
  728.     if(Not CDInitGen(SymbolDesc,0,(int)-INFINITY,(int)-INFINITY,(int)INFINITY,
  729.     (int)INFINITY,&GenDesc)) return(CDError(CDMALLOCFAILED));
  730.     loop {
  731.     CDGen(SymbolDesc,GenDesc,&OldPntr);
  732.     if(OldPntr == NULL)
  733.         break;
  734.     CDCall(OldPntr,&SymbolName,&NumX,&DX,&NumY,&DY);
  735.     if(SymbolName == NULL)
  736.         continue;
  737.     if(*SymbolName == NULL Or *MasterName == NULL)
  738.         continue;
  739.     if(strcmp(SymbolName,MasterName) != 0)
  740.         continue;
  741.     if(Not CDBB(SymbolDesc,OldPntr,&OldL,&OldB,&OldR,&OldT))
  742.         return(False);
  743.  
  744. #ifdef DEBUGREFLECT
  745. printf("    Old BB is %d %d %d %d.\n",OldL,OldB,OldR,OldT); 
  746. #endif
  747.  
  748.     /* we can assume here that the only error is CDMALLOCFAILED */
  749.     if(Not CDBeginMakeCall(SymbolDesc,SymbolName,NumX,DX,NumY,DY,&NewPntr))
  750.         if(CDStatusInt == CDMALLOCFAILED)
  751.         return(CDError(CDMALLOCFAILED));
  752.     CDInitTGen(OldPntr,&TGen);
  753.     loop {
  754.         CDTGen(&TGen,&Type,&X,&Y);
  755.         if(TGen == NULL)
  756.         break;
  757.         else
  758.         if(Not CDT(NewPntr,Type,X,Y))
  759.             return(CDError(CDMALLOCFAILED));
  760.         }
  761.     if(Not CDEndMakeCall(SymbolDesc,NewPntr))
  762.         return(CDError(CDMALLOCFAILED));
  763.     /* copy the property list */
  764.     CDProperty(SymbolDesc,OldPntr,&PrptyDesc);
  765.     while(PrptyDesc != NULL){
  766.         if(Not (CDAddProperty(SymbolDesc,NewPntr,PrptyDesc->prpty_Value,
  767.         PrptyDesc->prpty_String))){
  768.             return(CDError(CDMALLOCFAILED));
  769.         }
  770.         PrptyDesc = PrptyDesc->prpty_Succ;
  771.         }
  772.     if(Not CDBB(SymbolDesc,NewPntr,&NewL,&NewB,&NewR,&NewT))
  773.         return(CDError(CDMALLOCFAILED));
  774.  
  775. #ifdef DEBUGREFLECT
  776. printf("    New BB is %d %d %d %d.\n",NewL,NewB,NewR,NewT); 
  777. #endif
  778.  
  779.     /*
  780.      * The generator may return an instance desc that was created in
  781.      * this loop.  So, remove any duplicates.
  782.      */
  783.     if(OldL != NewL Or OldB != NewB Or OldR != NewR Or OldT != NewT)
  784.         /*
  785.          * Remove desc with invalid BB. 
  786.          */
  787.         CDDelete(SymbolDesc,OldPntr);
  788.     else 
  789.         /*
  790.          * Remove duplicate.
  791.          */
  792.         CDDelete(SymbolDesc,NewPntr);
  793.     }
  794.  
  795. #ifdef DEBUGREFLECT
  796. printf("End patching instances of master %s for symbol %s.\n",MasterName,SymbolDesc->sName); 
  797. #endif
  798.  
  799.     return(True);
  800.     }
  801.  
  802.  
  803.  
  804.  
  805. /*======================================================================*
  806.  *                                    *
  807.  *                OOO  BBBB      J EEEEE  CCCC TTTTT            *
  808.  *               O   O B   B     J E     C       T            *
  809.  *               O   O BBBB      J EEE   C       T            *
  810.  *               O   O B   B J   J E     C       T            *
  811.  *                OOO  BBBB   JJJ  EEEEE  CCCC   T            *
  812.  *                                    *
  813.  *          CCCC RRRR  EEEEE   A   TTTTT III  OOO  N   N        *
  814.  *         C     R   R E      A A    T    I  O   O NN  N        *
  815.  *         C     RRRR  EEE   A   A   T    I  O   O N N N        *
  816.  *         C     R R   E     AAAAA   T    I  O   O N  NN        *
  817.  *          CCCC R  R  EEEEE A   A   T   III  OOO  N   N        *
  818.  *                                    *
  819.  *                                    *
  820.  *                                    *
  821.  *    CDMakeBox(SymbolDesc,Layer,Length,Width,X,Y,Pointer)        *
  822.  *    CDMakeLabel(SymbolDesc,Layer,Label,X,Y,Pointer)            *
  823.  *    CDMakePolygon(SymbolDesc,Layer,Path,Pointer)            *
  824.  *    CDMakeWire(SymbolDesc,Layer,Width,Path,Pointer)            *
  825.  *    CDMakeRoundFlash(SymbolDesc,Layer,Width,X,Y,Pointer)        *
  826.  *    CDBeginMakeCall(SymbolDesc,SymbolName,NumX,DX,NumY,DY,Pointer)    *
  827.  *    CDEndMakeCall(SymbolDesc,Pointer)                *
  828.  *    CDInsertObjectDesc(SymbolDesc,ObjectDesc)            *
  829.  *    CDCheckPath(Path)                        *
  830.  *                                    *
  831.  *======================================================================*/
  832.  
  833. int
  834. CDMakeBox(SymbolDesc,Layer,Length,Width,X,Y,Pointer)
  835.     struct s *SymbolDesc;
  836.     int Layer,Length,Width,X,Y;
  837.     struct o **Pointer;
  838.     {
  839.     struct o *ObjectDesc;
  840.     if(Length == 0 Or Width == 0)
  841.     return(CDError(CDBADBOX));
  842.     if((ObjectDesc = (struct o *)malloc(sizeof(struct o))) == NULL)
  843.     return(CDError(CDMALLOCFAILED));
  844.     Length = abs(Length);
  845.     Width = abs(Width);
  846.     ObjectDesc->oRep = NULL;
  847.     ObjectDesc->oPrptyList = NULL;
  848.     ObjectDesc->oInfo = 0;
  849.     ObjectDesc->oType = CDBOX;
  850.     ObjectDesc->oLayer = Layer;
  851.     ObjectDesc->oLeft = X-Length/2;
  852.     ObjectDesc->oBottom = Y-Width/2;
  853.     ObjectDesc->oRight = X+Length/2;
  854.     ObjectDesc->oTop = Y+Width/2;
  855.     *Pointer = ObjectDesc; 
  856.     if(Not CDInsertObjectDesc(SymbolDesc,ObjectDesc))
  857.     return(False);
  858.     return(True);
  859.     }
  860.  
  861.  
  862. int
  863. CDMakeLabel(SymbolDesc,Layer,Label,X,Y,Pointer)
  864.     struct s *SymbolDesc;
  865.     int Layer;
  866.     char *Label;
  867.     int X,Y;
  868.     struct o **Pointer;
  869.     {
  870.     struct la *LabelDesc;
  871.     struct o *ObjectDesc;
  872.     unsigned int size;
  873.  
  874.     if((LabelDesc = (struct la *)malloc(sizeof(struct la))) == NULL)
  875.     return(CDError(CDMALLOCFAILED));
  876.     if((ObjectDesc = (struct o *)malloc(sizeof(struct o))) == NULL)
  877.     return(CDError(CDMALLOCFAILED));
  878.     size = strlen(Label) + 2;
  879.     if((LabelDesc->laLabel = malloc(size)) == NULL)
  880.     return(CDError(CDMALLOCFAILED));
  881.     strcpy(LabelDesc->laLabel,Label);
  882.     LabelDesc->laX = X;
  883.     LabelDesc->laY = Y;
  884.     ObjectDesc->oRep = (struct o *)LabelDesc;
  885.     ObjectDesc->oPrptyList = NULL;
  886.     ObjectDesc->oInfo = 0;
  887.     ObjectDesc->oType = CDLABEL;
  888.     ObjectDesc->oLayer = Layer;
  889.     ObjectDesc->oLeft = ObjectDesc->oRight = X;
  890.     ObjectDesc->oBottom = ObjectDesc->oTop = Y;
  891.     *Pointer = ObjectDesc; 
  892.     if(Not CDInsertObjectDesc(SymbolDesc,ObjectDesc))
  893.     return(False);
  894.     return(True);
  895.     }
  896.  
  897.  
  898. int
  899. CDMakePolygon(SymbolDesc,Layer,Path,Pointer)
  900.     struct s *SymbolDesc;
  901.     int Layer;
  902.     struct p *Path;
  903.     struct o **Pointer;
  904.     {
  905.     struct po *PolygonDesc;
  906.     struct o *ObjectDesc;
  907.     struct p *Pair;
  908.  
  909.     if((PolygonDesc = (struct po *)malloc(sizeof(struct po))) == NULL)
  910.     return(CDError(CDMALLOCFAILED));
  911.     if((ObjectDesc = (struct o *)malloc(sizeof(struct o))) == NULL)
  912.     return(CDError(CDMALLOCFAILED));
  913.     CDCheckPath(Path);
  914.     PolygonDesc->poPath = Path;
  915.     ObjectDesc->oRep = (struct o *)PolygonDesc;
  916.     ObjectDesc->oPrptyList = NULL;
  917.     ObjectDesc->oInfo = 0;
  918.     ObjectDesc->oType = CDPOLYGON;
  919.     ObjectDesc->oLayer = Layer;
  920.     ObjectDesc->oLeft = ObjectDesc->oBottom = INFINITY;
  921.     ObjectDesc->oRight = ObjectDesc->oTop = -INFINITY;
  922.     Pair = Path;
  923.     while(Pair != NULL){
  924.     if(ObjectDesc->oLeft > Pair->pX)
  925.         ObjectDesc->oLeft = Pair->pX;
  926.     if(ObjectDesc->oRight < Pair->pX)
  927.         ObjectDesc->oRight = Pair->pX;
  928.     if(ObjectDesc->oBottom > Pair->pY)
  929.         ObjectDesc->oBottom = Pair->pY;
  930.     if(ObjectDesc->oTop < Pair->pY)
  931.         ObjectDesc->oTop = Pair->pY;
  932.     Pair = Pair->pSucc;
  933.     }
  934.     *Pointer = ObjectDesc; 
  935.     if(Not CDInsertObjectDesc(SymbolDesc,ObjectDesc))
  936.     return(False);
  937.     return(True);
  938.     }
  939.  
  940.  
  941. int
  942. CDMakeWire(SymbolDesc,Layer,Width,Path,Pointer)
  943.     struct s *SymbolDesc;
  944.     int Layer,Width;
  945.     struct p *Path;
  946.     struct o **Pointer;
  947.     {
  948.     struct w *WireDesc;
  949.     struct o *ObjectDesc;
  950.     struct p *Pair;
  951.  
  952.     if((WireDesc = (struct w *)malloc(sizeof(struct w))) == NULL)
  953.     return(CDError(CDMALLOCFAILED));
  954.     if((ObjectDesc = (struct o *)malloc(sizeof(struct o))) == NULL)
  955.     return(CDError(CDMALLOCFAILED));
  956.     CDCheckPath(Path);
  957.     Width = abs(Width);
  958.     WireDesc->wWidth = Width;
  959.     WireDesc->wPath = Path;
  960.     ObjectDesc->oRep = (struct o *)WireDesc;
  961.     ObjectDesc->oPrptyList = NULL;
  962.     ObjectDesc->oInfo = 0;
  963.     ObjectDesc->oType = CDWIRE;
  964.     ObjectDesc->oLayer = Layer;
  965.     ObjectDesc->oLeft = ObjectDesc->oBottom = INFINITY;
  966.     ObjectDesc->oRight = ObjectDesc->oTop = -INFINITY;
  967.     Pair = Path;
  968.     while(Pair != NULL){
  969.     if(ObjectDesc->oLeft > Pair->pX-Width/2)
  970.         ObjectDesc->oLeft = Pair->pX-Width/2;
  971.     if(ObjectDesc->oRight < Pair->pX+Width/2)
  972.         ObjectDesc->oRight = Pair->pX+Width/2;
  973.     if(ObjectDesc->oBottom > Pair->pY-Width/2)
  974.         ObjectDesc->oBottom = Pair->pY-Width/2;
  975.     if(ObjectDesc->oTop < Pair->pY+Width/2)
  976.         ObjectDesc->oTop = Pair->pY+Width/2;
  977.     Pair = Pair->pSucc;
  978.     }
  979.     *Pointer = ObjectDesc; 
  980.     if(Not CDInsertObjectDesc(SymbolDesc,ObjectDesc))
  981.     return(False);
  982.     return(True);
  983.     }
  984.  
  985.  
  986. int
  987. CDMakeRoundFlash(SymbolDesc,Layer,Width,X,Y,Pointer)
  988.     struct s *SymbolDesc;
  989.     int Layer,Width,X,Y;
  990.     struct o **Pointer;
  991.     {
  992.     struct r *RoundFlashDesc;
  993.     struct o *ObjectDesc;
  994.  
  995.     if((RoundFlashDesc = (struct r *)malloc(sizeof(struct r))) == NULL)
  996.     return(CDError(CDMALLOCFAILED));
  997.     if((ObjectDesc = (struct o *)malloc(sizeof(struct o))) == NULL)
  998.     return(CDError(CDMALLOCFAILED));
  999.     RoundFlashDesc->rWidth = Width;
  1000.     RoundFlashDesc->rX = X;
  1001.     RoundFlashDesc->rY = Y;
  1002.     ObjectDesc->oRep = (struct o *)RoundFlashDesc;
  1003.     ObjectDesc->oPrptyList = NULL;
  1004.     ObjectDesc->oInfo = 0;
  1005.     ObjectDesc->oType = CDROUNDFLASH;
  1006.     ObjectDesc->oLayer = Layer;
  1007.     ObjectDesc->oLeft = X-Width/2;
  1008.     ObjectDesc->oBottom = Y-Width/2;
  1009.     ObjectDesc->oRight = X+Width/2;
  1010.     ObjectDesc->oTop = Y+Width/2;
  1011.     *Pointer = ObjectDesc; 
  1012.     if(Not CDInsertObjectDesc(SymbolDesc,ObjectDesc))
  1013.     return(False);
  1014.     return(True);
  1015.     }
  1016.  
  1017.  
  1018. int
  1019. CDBeginMakeCall(SymbolDesc,SymbolName,NumX,DX,NumY,DY,Pointer)
  1020.     struct s *SymbolDesc;
  1021.     char *SymbolName;
  1022.     struct o **Pointer;
  1023.     int NumX,DX,NumY,DY;
  1024.     {
  1025.     /*
  1026.      * CDBeginMakeCall will return False if a CDMALLOCFAILED error
  1027.      * occurs or if CDOpen fails.  Possible values for CDStatusInt
  1028.      * upon return are:
  1029.      *   (Fatal)-CDPARSEFAILED - Syntax error
  1030.      *   (Fatal)-CDMALLOCFAILED - Out of memory
  1031.      *   (Fatal)-CDNEWSYMBOL - symbol does not exist
  1032.      *           CDOLDSYMBOL - successful return, symbol exists
  1033.      * Only CDOLDSYMBOL is not a fatal return (i.e., CDBeginMakeCall
  1034.      * returns True).
  1035.      */
  1036.     struct c *CallDesc;
  1037.     struct o *ObjectDesc;
  1038.     struct m *MasterListDesc;
  1039.     struct s *MasterSymbolDesc;
  1040.     unsigned int size;
  1041.  
  1042.     /* The symbol call is inserted into the database CDEndMakeCall */
  1043.     if((CallDesc = (struct c *)malloc(sizeof(struct c))) == NULL)
  1044.     return(CDError(CDMALLOCFAILED));
  1045.     if((ObjectDesc = (struct o *)malloc(sizeof(struct o))) == NULL)
  1046.     return(CDError(CDMALLOCFAILED));
  1047.     CallDesc->cNumX = NumX;
  1048.     CallDesc->cDX = DX;
  1049.     CallDesc->cNumY = NumY;
  1050.     CallDesc->cT = NULL;
  1051.     CallDesc->cDY = DY;
  1052.     ObjectDesc->oRep = (struct o *)CallDesc;
  1053.     ObjectDesc->oPrptyList = NULL;
  1054.     ObjectDesc->oInfo = 0;
  1055.     ObjectDesc->oType = CDSYMBOLCALL;
  1056.     ObjectDesc->oLayer = 0;
  1057.     *Pointer = ObjectDesc; 
  1058.     MasterListDesc = SymbolDesc->sMasterList;
  1059.     /*
  1060.      * Search masterList for an instance of SymbolName.
  1061.      * If not found, insert into the masterList (which is a linked list).
  1062.      * An entry in the master list contains the symbol name, the bounding
  1063.      * box, and the number of references.
  1064.      */
  1065.     loop{
  1066.     if(MasterListDesc == NULL){
  1067.         /*
  1068.          * Insert into list
  1069.          * Firstly, try to allocate memory
  1070.          */
  1071.         if((MasterListDesc = (struct m *)malloc(sizeof(struct m))) == NULL)
  1072.         return(CDError(CDMALLOCFAILED));
  1073.         size = strlen(SymbolName) + 2;
  1074.         if((MasterListDesc->mName = malloc(size)) == NULL)
  1075.         return(CDError(CDMALLOCFAILED));
  1076.         /* insert new instance at end of (linked) masterList */
  1077.         if(SymbolDesc->sMasterList != NULL)
  1078.         SymbolDesc->sMasterList->mPred = MasterListDesc;
  1079.         MasterListDesc->mSucc = SymbolDesc->sMasterList;
  1080.         MasterListDesc->mPred = NULL;
  1081.         SymbolDesc->sMasterList = MasterListDesc;
  1082.         MasterListDesc->mReferenceCount = 0;
  1083.         strcpy(MasterListDesc->mName,SymbolName);
  1084.         if(CDDesc.dControl == DCONTROLVANILLA){
  1085.         /*
  1086.          * DCONTROLVANILLA tells us that CDOpen is safe to call here.
  1087.          * Because StatusInt is checked, we ignore the returned value.
  1088.          */
  1089.         CDOpen(MasterListDesc->mName,&MasterSymbolDesc,'r');
  1090.         if(CDStatusInt == CDPARSEFAILED Or CDStatusInt == CDNEWSYMBOL){
  1091.             /* CDOpen failed -- Don't put bad master in MasterList */
  1092.             if(CDStatusInt == CDNEWSYMBOL)
  1093.             sprintf(CDStatusString,"Symbol %s not found.",
  1094.                 MasterListDesc->mName);
  1095.             if(SymbolDesc->sMasterList != NULL)
  1096.             SymbolDesc->sMasterList->mPred = NULL;
  1097.             strcpy(MasterListDesc->mName,"");
  1098.             SymbolDesc->sMasterList = MasterListDesc->mSucc;
  1099.             free(MasterListDesc);
  1100.             return(False);
  1101.             }
  1102.         if(Not CDBB(MasterSymbolDesc,(struct o *)NULL,
  1103.             &(MasterListDesc->mLeft),&(MasterListDesc->mBottom),
  1104.             &(MasterListDesc->mRight),&(MasterListDesc->mTop)))
  1105.             return(False);
  1106.         if(Not CDClose(MasterSymbolDesc))
  1107.             return(False);
  1108.         }
  1109.         elif(CDDesc.dControl == DCONTROLCDOPEN Or
  1110.             CDDesc.dControl == DCONTROLPCIF){
  1111.         /*
  1112.          * We CANNOT invoke CDBB here, because if the master symbol
  1113.          * hasn't already been mapped into main memory via CDOpen,
  1114.          * CDBB will invoke CDOpen which will then invoke PCIF and
  1115.          * since PCIF CANNOT be invoked recursively, all of PCIF's
  1116.          * state will be broken.  The solution is to defer filling
  1117.          * in the bounding box information for master list descs and
  1118.          * instance descs until PCIF has returned in CDOpen.  Why not
  1119.          * write PCIF so it can be invoked recursively? For a deep
  1120.          * hierarchy, we might exceed the limit on open file
  1121.          * descriptors and we clearly don't want to limit hierarchy
  1122.          * depth.
  1123.          */
  1124.         MasterListDesc->mLeft = MasterListDesc->mBottom = 
  1125.             MasterListDesc->mRight = MasterListDesc->mTop = 0; 
  1126.         }
  1127.         break;
  1128.         }
  1129.     elif(strcmp(SymbolName,MasterListDesc->mName) == 0){
  1130.         /*
  1131.          * A match!  This symbol is already in memeory.
  1132.          */
  1133.         CDStatusInt = CDOLDSYMBOL;
  1134.         *CDStatusString = NULL;
  1135.         break;
  1136.         }
  1137.     else
  1138.         MasterListDesc = MasterListDesc->mSucc;
  1139.     }
  1140.     CallDesc->cMaster = MasterListDesc;
  1141.     MasterListDesc->mReferenceCount += 1;
  1142.     return(True);
  1143.     }
  1144.  
  1145.  
  1146. int
  1147. CDT(Pointer,Type,X,Y)
  1148.     struct o *Pointer;
  1149.     char Type;
  1150.     int X,Y;
  1151.     /*
  1152.      * After invoking BeginMakeCall, invoke T for each transformation in
  1153.      * the call.  The transformation is a linked list of transformation
  1154.      * descs headed by the ct field of the call desc.  Finally, invoke
  1155.      * EndMakeCall.
  1156.      */
  1157.     {
  1158.     struct c *CDesc;
  1159.     struct t *TDesc;
  1160.  
  1161.     CDesc = (struct c *)Pointer->oRep; 
  1162.     TDesc = CDesc->cT;    
  1163.     if(TDesc == NULL){
  1164.     if((CDesc->cT = TDesc = (struct t *)malloc(sizeof(struct t))) == NULL)
  1165.         return(CDError(CDMALLOCFAILED));
  1166.     TDesc->tSucc = NULL;
  1167.     TDesc->tX = X;
  1168.     TDesc->tY = Y;
  1169.     TDesc->tType = Type; 
  1170.     return(True);
  1171.     }
  1172.     while(TDesc->tSucc != NULL)
  1173.     TDesc = TDesc->tSucc;
  1174.     if((TDesc = TDesc->tSucc = (struct t *)malloc(sizeof(struct t))) == NULL)
  1175.     return(CDError(CDMALLOCFAILED));
  1176.     TDesc->tSucc = NULL;
  1177.     TDesc->tX = X;
  1178.     TDesc->tY = Y;
  1179.     TDesc->tType = Type;
  1180.     return(True);
  1181.     }
  1182.  
  1183.  
  1184. int
  1185. CDEndMakeCall(SymbolDesc,Pointer)
  1186.     struct s *SymbolDesc;
  1187.     struct o *Pointer;
  1188.     {
  1189.     struct c *CallDesc;
  1190.     struct o *ObjectDesc;
  1191.     struct m *MasterListDesc;
  1192.     struct t *TGen;
  1193.     int X,Y;
  1194.     char Type;
  1195.  
  1196.     ObjectDesc = Pointer;
  1197.     CallDesc = (struct c *)ObjectDesc->oRep;
  1198.     MasterListDesc = CallDesc->cMaster;
  1199.     if(TFull())
  1200.     return(CDError(CDXFORMSTACKFULL));
  1201.     TPush();
  1202.     TIdentity();
  1203.     CDInitTGen(Pointer,&TGen);
  1204.     loop {
  1205.     CDTGen(&TGen,&Type,&X,&Y);
  1206.     if(TGen == NULL)
  1207.         break;
  1208.     if(Type == CDROTATE)
  1209.         TRotate(X,Y);
  1210.     elif(Type == CDTRANSLATE)
  1211.         TTranslate(X,Y);
  1212.     elif(Type == CDMIRRORX)
  1213.         TMX();
  1214.     elif(Type == CDMIRRORY)
  1215.         TMY();
  1216.     }
  1217.  
  1218. #ifdef DEBUGREFLECT 
  1219. printf("Making call of master %s in symbol %s.\n",MasterListDesc->mName,
  1220.     SymbolDesc->sName);
  1221. printf("Untransformed (master's) BB is %d %d %d %d.\n",
  1222.     MasterListDesc->mLeft,MasterListDesc->mBottom,
  1223.     MasterListDesc->mRight,MasterListDesc->mTop);
  1224. #endif
  1225.  
  1226.     ObjectDesc->oLeft = MasterListDesc->mLeft; 
  1227.     ObjectDesc->oBottom = MasterListDesc->mBottom;
  1228.     TPoint(&(ObjectDesc->oLeft),&(ObjectDesc->oBottom));
  1229.     ObjectDesc->oRight = MasterListDesc->mRight; 
  1230.     ObjectDesc->oTop = MasterListDesc->mTop;
  1231.     TPoint(&(ObjectDesc->oRight),&(ObjectDesc->oTop));
  1232.     if(ObjectDesc->oRight < ObjectDesc->oLeft)
  1233.     SwapInts(ObjectDesc->oLeft,ObjectDesc->oRight);
  1234.     if(ObjectDesc->oTop < ObjectDesc->oBottom)
  1235.     SwapInts(ObjectDesc->oBottom,ObjectDesc->oTop);
  1236.  
  1237. #ifdef DEBUGREFLECT 
  1238. printf("Transformed, unarrayed BB is %d %d %d %d.\n",
  1239.     ObjectDesc->oLeft,ObjectDesc->oBottom,
  1240.     ObjectDesc->oRight,ObjectDesc->oTop);
  1241. #endif
  1242.  
  1243.     /*
  1244.      * Take into account array parameters.
  1245.      */
  1246.     ObjectDesc->oRight = ObjectDesc->oLeft
  1247.     + (ObjectDesc->oRight-ObjectDesc->oLeft + CallDesc->cDX)
  1248.     * CallDesc->cNumX-CallDesc->cDX;
  1249.     ObjectDesc->oTop = ObjectDesc->oBottom
  1250.     + (ObjectDesc->oTop-ObjectDesc->oBottom + CallDesc->cDY)
  1251.     * CallDesc->cNumY-CallDesc->cDY;
  1252.  
  1253. #ifdef DEBUGREFLECT 
  1254. printf("Transformed, arrayed BB is %d %d %d %d.\n",
  1255.     ObjectDesc->oLeft,ObjectDesc->oBottom,
  1256.     ObjectDesc->oRight,ObjectDesc->oTop);
  1257. #endif
  1258.  
  1259.     TPop();
  1260.     if(Not CDInsertObjectDesc(SymbolDesc,ObjectDesc))
  1261.     return(False);
  1262.     return(True);
  1263.     }
  1264.  
  1265.  
  1266. void
  1267. CDCheckPath(Path)
  1268.     struct p *Path;
  1269.     {
  1270.     /*
  1271.      * Check to see that the path does not have two identical and
  1272.      * adjacent vertices.
  1273.      */
  1274.     struct p *Pair;
  1275.     struct p *Copy;
  1276.     Pair = Path;
  1277.     while(Pair->pSucc != NULL){
  1278.     if(Pair->pX == Pair->pSucc->pX And Pair->pY == Pair->pSucc->pY){
  1279.         Copy = Pair->pSucc;
  1280.         Pair->pSucc = Copy->pSucc;
  1281.         free( Copy );
  1282.         }
  1283.     else
  1284.         Pair = Pair->pSucc;
  1285.     }
  1286.     }
  1287.  
  1288.  
  1289. int
  1290. CDInsertObjectDesc(SymbolDesc,ObjectDesc)
  1291.     struct s *SymbolDesc;
  1292.     struct o *ObjectDesc;
  1293.     {
  1294.     int Int1,Int2,Layer,X,Y;
  1295.     int BeginX,EndX,BeginY,EndY;
  1296.  
  1297.     CDIntersect(ObjectDesc->oLeft,ObjectDesc->oBottom,ObjectDesc->oRight,
  1298.     ObjectDesc->oTop,&BeginX,&EndX,&BeginY,&EndY);
  1299.     if(BeginX != EndX Or BeginY != EndY)
  1300.     X = Y = 0;
  1301.     else {
  1302.     X = BeginX; 
  1303.     Y = BeginY; 
  1304.     }
  1305.     Layer = ObjectDesc->oLayer;
  1306.     if(SymbolDesc->sBin[Layer] == (struct o ***)NULL){
  1307.     /* allocate Bin */
  1308.     if((SymbolDesc->sBin[Layer] = (struct o ***)
  1309.         malloc(sizeof(char*) * (CDNUMBINS+1))) == NULL)
  1310.         return(CDError(CDMALLOCFAILED));
  1311.     for(Int1 = 0; Int1 <= CDNUMBINS; ++Int1){
  1312.         if((SymbolDesc->sBin[Layer][Int1] = (struct o **)
  1313.             malloc(sizeof(char*) * (CDNUMBINS+1))) == NULL)
  1314.             return(CDError(CDMALLOCFAILED));
  1315.         for(Int2 = 0; Int2 <= CDNUMBINS; ++Int2){
  1316.             if((SymbolDesc->sBin[Layer][Int1][Int2] = (struct o *)
  1317.                 malloc(sizeof(char*))) == NULL)
  1318.                 return(CDError(CDMALLOCFAILED));
  1319.         SymbolDesc->sBin[Layer][Int1][Int2] = (struct o *)NULL;
  1320.             }
  1321.         }
  1322.     }
  1323.     elif(SymbolDesc->sBin[Layer][X][Y] != NULL){
  1324.     SymbolDesc->sBin[Layer][X][Y]->oPred = ObjectDesc;
  1325.     }
  1326.     ObjectDesc->oSucc = SymbolDesc->sBin[Layer][X][Y];
  1327.     SymbolDesc->sBin[Layer][X][Y] = ObjectDesc;
  1328.     ObjectDesc->oPred = NULL;
  1329.     SymbolDesc->sLeft = min(SymbolDesc->sLeft,ObjectDesc->oLeft); 
  1330.     SymbolDesc->sBottom = min(SymbolDesc->sBottom,ObjectDesc->oBottom); 
  1331.     SymbolDesc->sRight = max(SymbolDesc->sRight,ObjectDesc->oRight); 
  1332.     SymbolDesc->sTop = max(SymbolDesc->sTop,ObjectDesc->oTop); 
  1333.  
  1334. #ifdef DEBUGGEN
  1335. if(X == 0 And Y == 0)
  1336.     printf("Inserting a desc on layer %d in residual bin.\n",Layer);
  1337. else
  1338.     printf("Inserting a desc on layer %d in bin (%d,%d).\n",Layer,X,Y);
  1339. #endif
  1340.  
  1341. #ifdef DEBUGREFLECT
  1342. if(X == 0 And Y == 0)
  1343.     printf("Inserting a desc on layer %d in residual bin.\n",Layer);
  1344. else
  1345.     printf("Inserting a desc on layer %d in bin (%d,%d).\n",Layer,X,Y);
  1346. #endif
  1347.  
  1348.     return(True);
  1349.     }
  1350.  
  1351.  
  1352.  
  1353.  
  1354. /*======================================================================*
  1355.  *                                    *
  1356.  *                 OOO  BBBB      J EEEEE  CCCC TTTTT            *
  1357.  *                O   O B   B     J E     C       T            *
  1358.  *                O   O BBBB      J EEE   C       T            *
  1359.  *                O   O B   B J   J E     C       T            *
  1360.  *                 OOO  BBBB   JJJ  EEEEE  CCCC   T            *
  1361.  *                                    *
  1362.  *           DDDD  EEEEE L     EEEEE TTTTT III  OOO  N   N        *
  1363.  *           D   D E     L     E       T    I  O   O NN  N        *
  1364.  *           D   D EEE   L     EEE     T    I  O   O N N N        *
  1365.  *           D   D E     L     E       T    I  O   O N  NN        *
  1366.  *           DDDD  EEEEE LLLLL EEEEE   T   III  OOO  N   N        *
  1367.  *                                    *
  1368.  *                                    *
  1369.  *                                    *
  1370.  *    CDDeleteObjectDesc(SymbolDesc,ObjectDesc)            *
  1371.  *                                    *
  1372.  *======================================================================*/
  1373.  
  1374. void
  1375. CDDeleteObjectDesc(SymbolDesc,ObjectDesc)
  1376.     struct s *SymbolDesc;
  1377.     struct o *ObjectDesc;
  1378.     {
  1379.     int Layer,X,Y;
  1380.     int BeginX,EndX,BeginY,EndY;
  1381.     struct p PCopy;
  1382.     struct t TCopy;
  1383.     struct prpty  PrptyCopy;
  1384.     struct prpty *PrptyDesc;
  1385.  
  1386.     /* we should test the descriptors as valid pointers */
  1387.     Layer = ObjectDesc->oLayer;
  1388.     /* is the Bin allocated? */
  1389.     if(SymbolDesc->sBin[Layer] == NULL)
  1390.     return;
  1391.     CDIntersect(ObjectDesc->oLeft,ObjectDesc->oBottom,ObjectDesc->oRight,
  1392.     ObjectDesc->oTop,&BeginX,&EndX,&BeginY,&EndY);
  1393.     if(BeginX != EndX Or BeginY != EndY)
  1394.     X = Y = 0;
  1395.     else {
  1396.     X = BeginX; 
  1397.     Y = BeginY; 
  1398.     }
  1399.     if(SymbolDesc->sBin[Layer][X][Y] == NULL){
  1400.     /* Something's rotten */
  1401.     return;
  1402.     }
  1403.     elif(ObjectDesc->oPred == NULL And ObjectDesc->oSucc == NULL){
  1404.     /* Only desc--has no pred or succ */
  1405.     SymbolDesc->sBin[Layer][X][Y] = NULL;
  1406.     }
  1407.     elif(ObjectDesc->oPred == NULL){
  1408.     /* First desc.    Has a succ, but no pred */
  1409.     SymbolDesc->sBin[Layer][X][Y] = ObjectDesc->oSucc;
  1410.     ObjectDesc->oSucc->oPred = NULL;
  1411.     }
  1412.     elif(ObjectDesc->oSucc == NULL){
  1413.     /* Last desc--has a pred, but no succ */
  1414.     ObjectDesc->oPred->oSucc = NULL; 
  1415.     }
  1416.     else {
  1417.     /* Vanilla desc has a pred and a succ */
  1418.     ObjectDesc->oSucc->oPred = ObjectDesc->oPred; 
  1419.     ObjectDesc->oPred->oSucc = ObjectDesc->oSucc;
  1420.     }
  1421.     /*
  1422.      * Invalidate BB.
  1423.      */
  1424.     SymbolDesc->sBBValid = False;
  1425.     /*
  1426.      * Free storage of property list;
  1427.      */
  1428.     PrptyDesc = ObjectDesc->oPrptyList;
  1429.     while(PrptyDesc != NULL){
  1430.     PrptyCopy = *PrptyDesc;
  1431.     if(PrptyDesc->prpty_String != NULL)
  1432.         free(PrptyDesc->prpty_String);
  1433.     free(PrptyDesc);
  1434.     PrptyDesc = PrptyCopy.prpty_Succ;
  1435.     }
  1436.     /*
  1437.      * Free storage of oRep;
  1438.      */
  1439.     if(ObjectDesc->oType == CDROUNDFLASH)
  1440.     free((struct r *)ObjectDesc->oRep);
  1441.     elif(ObjectDesc->oType == CDSYMBOLCALL){
  1442.     struct c *CallDesc;
  1443.     struct t *TDesc;
  1444.  
  1445.     CallDesc = (struct c *)ObjectDesc->oRep; 
  1446.     TDesc = CallDesc->cT;
  1447.     while(TDesc != NULL){
  1448.         TCopy = *TDesc;
  1449.         free(TDesc);
  1450.         TDesc = TCopy.tSucc;
  1451.         }
  1452.     free(CallDesc);
  1453.     }
  1454.     elif(ObjectDesc->oType == CDPOLYGON){
  1455.     struct po *PolygonDesc;
  1456.     struct p *Pair;
  1457.  
  1458.     PolygonDesc = (struct po *)ObjectDesc->oRep; 
  1459.     Pair = PolygonDesc->poPath;
  1460.     while(Pair != NULL){
  1461.         PCopy = *Pair;
  1462.         free(Pair);
  1463.         Pair = PCopy.pSucc;
  1464.         }
  1465.     free(PolygonDesc);
  1466.     }
  1467.     elif(ObjectDesc->oType == CDWIRE){
  1468.     struct w *WireDesc;
  1469.     struct p *Pair;
  1470.  
  1471.     WireDesc = (struct w *)ObjectDesc->oRep; 
  1472.     Pair = WireDesc->wPath;
  1473.     while(Pair != NULL){
  1474.         PCopy = *Pair;
  1475.         free(Pair);
  1476.         Pair = PCopy.pSucc;
  1477.         }
  1478.     free(WireDesc);
  1479.     }
  1480.     free(ObjectDesc);
  1481.  
  1482. #ifdef DEBUGGEN
  1483. printf("Deleting a desc on layer %d in bin (%d,%d)\n.",Layer,X,Y);
  1484. #endif
  1485.  
  1486.     }
  1487.  
  1488.  
  1489.  
  1490.  
  1491. /*======================================================================*
  1492.  *                                    *
  1493.  *           A    CCCC  CCCC EEEEE  SSSS  SSSS III N   N  GGGG        *
  1494.  *          A A  C     C     E     S     S      I  NN  N G           *
  1495.  *         A   A C     C     EEE    SSS   SSS   I  N N N G GGG        *
  1496.  *         AAAAA C     C     E         S     S  I  N  NN G   G        *
  1497.  *         A   A  CCCC  CCCC EEEEE SSSS  SSSS  III N   N  GGG        *
  1498.  *                                    *
  1499.  *             OOO  BBBB      J EEEEE  CCCC TTTTT  SSSS            *
  1500.  *            O   O B   B     J E     C       T   S            *
  1501.  *            O   O BBBB      J EEE   C       T    SSS             *
  1502.  *            O   O B   B J   J E     C       T       S            *
  1503.  *             OOO  BBBB   JJJ  EEEEE  CCCC   T   SSSS            *
  1504.  *                                    *
  1505.  *                                    *
  1506.  *                                    *
  1507.  *    CDCall(Pointer,SymbolName,NumX,DX,NumY,DY)            *
  1508.  *    CDBox(Pointer,Layer,Length,Width,X,Y)                *
  1509.  *    CDLabel(Pointer,Layer,Label,X,Y)                *
  1510.  *    CDPolygon(Pointer,Layer,Path)                    *
  1511.  *    CDWire(Pointer,Layer,Width,Path)                *
  1512.  *    CDRoundFlash(Pointer,Layer,Width,X,Y)                *
  1513.  *                                    *
  1514.  *======================================================================*/
  1515.  
  1516. void
  1517. CDCall(Pointer,SymbolName,NumX,DX,NumY,DY)
  1518.     struct o *Pointer;
  1519.     char **SymbolName;
  1520.     int *NumX,*DX,*NumY,*DY;
  1521.     {
  1522.     struct c *CallDesc;
  1523.  
  1524.     if(Pointer == NULL)
  1525.     return;
  1526.     if(Pointer->oType != CDSYMBOLCALL){
  1527.     *SymbolName = NULL;
  1528.     *NumX = 0;
  1529.     *DX = 0;
  1530.     *NumY = 0;
  1531.     *DY = 0;
  1532.     }
  1533.     else {
  1534.     CallDesc = (struct c *)Pointer->oRep;
  1535.     *SymbolName = CallDesc->cMaster->mName;
  1536.     *NumX = CallDesc->cNumX;
  1537.     *DX = CallDesc->cDX;
  1538.     *NumY = CallDesc->cNumY;
  1539.     *DY = CallDesc->cDY;
  1540.     }
  1541.     }
  1542.  
  1543.  
  1544. void
  1545. CDBox(Pointer,Layer,Length,Width,X,Y)
  1546.     struct o *Pointer;
  1547.     int *Layer,*Length,*Width,*X,*Y;
  1548.     {
  1549.  
  1550.     if(Pointer == NULL)
  1551.     return;
  1552.     if(Pointer->oType != CDBOX){
  1553.     *Layer = *Length = *Width = *X = *Y = 0;
  1554.     }
  1555.     else {
  1556.     *Layer = Pointer->oLayer;
  1557.     *Length = Pointer->oRight - Pointer->oLeft;
  1558.     *Width = Pointer->oTop - Pointer->oBottom;
  1559.     *X = Pointer->oLeft + (*Length >> 1);
  1560.     *Y = Pointer->oBottom + (*Width >> 1);
  1561.     }
  1562.     }
  1563.  
  1564.  
  1565. void
  1566. CDLabel(Pointer,Layer,Label,X,Y)
  1567.     struct o *Pointer;
  1568.     int *Layer;
  1569.     char **Label;
  1570.     int *X,*Y;
  1571.     {
  1572.     struct la *LabelDesc;
  1573.  
  1574.     if(Pointer == NULL)
  1575.     return;
  1576.     if(Pointer->oType != CDLABEL){
  1577.     *Layer = *X = *Y = 0;
  1578.     *Label = NULL;
  1579.     }
  1580.     else {
  1581.     *Layer = Pointer->oLayer;
  1582.     LabelDesc = (struct la *)Pointer->oRep;
  1583.     *Label = LabelDesc->laLabel;
  1584.     *X = LabelDesc->laX;
  1585.     *Y = LabelDesc->laY;
  1586.     }
  1587.     }
  1588.  
  1589.  
  1590. void
  1591. CDPolygon(Pointer,Layer,Path)
  1592.     struct o *Pointer;
  1593.     int *Layer;
  1594.     struct p **Path;
  1595.     {
  1596.     struct po *PolygonDesc;
  1597.  
  1598.     if(Pointer == NULL)
  1599.     return;
  1600.     if(Pointer->oType != CDPOLYGON){
  1601.     *Layer = 0;
  1602.     *Path = NULL;
  1603.     }
  1604.     else {
  1605.     *Layer = Pointer->oLayer;
  1606.     PolygonDesc = (struct po *)Pointer->oRep;
  1607.     *Path = PolygonDesc->poPath;
  1608.     }
  1609.     }
  1610.  
  1611.  
  1612. void
  1613. CDWire(Pointer,Layer,Width,Path)
  1614.     struct o *Pointer;
  1615.     int *Layer,*Width;
  1616.     struct p **Path;
  1617.     {
  1618.     struct w *WireDesc;
  1619.  
  1620.     if(Pointer == NULL)
  1621.     return;
  1622.     if(Pointer->oType != CDWIRE){
  1623.     *Layer = *Width = 0;
  1624.     *Path = NULL;
  1625.     }
  1626.     else {
  1627.     *Layer = Pointer->oLayer;
  1628.     WireDesc = (struct w *)Pointer->oRep;
  1629.     *Width = WireDesc->wWidth;
  1630.     *Path = WireDesc->wPath;
  1631.     }
  1632.     }
  1633.  
  1634.  
  1635. void
  1636. CDRoundFlash(Pointer,Layer,Width,X,Y)
  1637.     struct o *Pointer;
  1638.     int *Layer,*Width,*X,*Y;
  1639.     {
  1640.     struct r *RoundFlashDesc;
  1641.  
  1642.     if(Pointer == NULL)
  1643.     return;
  1644.     if(Pointer->oType != CDROUNDFLASH)
  1645.     return;
  1646.     *Layer = Pointer->oLayer;
  1647.     RoundFlashDesc = (struct r *)Pointer->oRep;
  1648.     *Width = RoundFlashDesc->rWidth;
  1649.     *X = RoundFlashDesc->rX;
  1650.     *Y = RoundFlashDesc->rY;
  1651.     }
  1652.  
  1653.  
  1654.  
  1655.  
  1656. /*======================================================================*
  1657.  *                                    *
  1658.  *           A    CCCC  CCCC EEEEE  SSSS  SSSS III N   N  GGGG        *
  1659.  *          A A  C     C     E     S     S      I  NN  N G           *
  1660.  *         A   A C     C     EEE    SSS   SSS   I  N N N G GGG        *
  1661.  *         AAAAA C     C     E         S     S  I  N  NN G   G        *
  1662.  *         A   A  CCCC  CCCC EEEEE SSSS  SSSS  III N   N  GGG        *
  1663.  *                                    *
  1664.  *    III N   N FFFFF  OOO  RRRR  M   M   A   TTTTT III  OOO  N   N    *
  1665.  *     I  NN  N F     O   O R   R MM MM  A A    T    I  O   O NN  N    *
  1666.  *     I  N N N FFF   O   O RRRR  M M M A   A   T    I  O   O N N N    *
  1667.  *     I  N  NN F     O   O R R   M   M AAAAA   T    I  O   O N  NN    *
  1668.  *    III N   N F      OOO  R  R  M   M A   A   T   III  OOO  N   N    *
  1669.  *                                    *
  1670.  *                                    *
  1671.  *                                    *
  1672.  *    CDInfo(SymbolDesc,Pointer,Info)                    *
  1673.  *    CDSetInfo(SymbolDesc,Pointer,Info)                *
  1674.  *    CDProperty(SymbolDesc,Pointer,Property)                *
  1675.  *    CDAddProperty(SymbolDesc,Pointer,Value,String)            *
  1676.  *    CDRemoveProperty(SymbolDesc,Pointer,Value)            *
  1677.  *    CDType(Pointer,Type)                        *
  1678.  *    CDBB(SymbolDesc,Pointer,Left,Bottom,Right,Top)            *
  1679.  *    CDIntersect(Left,Bottom,Right,Top,BeginX,EndX,BeginY,EndY)    *
  1680.  *                                    *
  1681.  *======================================================================*/
  1682.  
  1683. void
  1684. CDInfo(SymbolDesc,Pointer,Info)
  1685.     struct s *SymbolDesc;
  1686.     struct o *Pointer;
  1687.     int *Info;
  1688.     /*
  1689.      * Return info field of object.
  1690.      * If Pointer == NULL, object is symbol itself. 
  1691.      */
  1692.     {
  1693.     if(Pointer == NULL)
  1694.     *Info = SymbolDesc->sInfo;
  1695.     else
  1696.     *Info = Pointer->oInfo; 
  1697.     }
  1698.  
  1699.  
  1700. void
  1701. CDSetInfo(SymbolDesc,Pointer,Info)
  1702.     struct s *SymbolDesc;
  1703.     struct o *Pointer;
  1704.     int Info;
  1705.     /*
  1706.      * Set info field of object.
  1707.      * If Pointer == NULL, object is symbol itself. 
  1708.      */
  1709.     {
  1710.     if(Pointer == NULL)
  1711.     SymbolDesc->sInfo = Info;
  1712.     else
  1713.     Pointer->oInfo = Info; 
  1714.     }
  1715.  
  1716.  
  1717. void
  1718. CDProperty(SymbolDesc,Pointer,Property)
  1719.     struct s *SymbolDesc;
  1720.     struct o *Pointer;
  1721.     struct prpty **Property;
  1722.     /*
  1723.      * Return info field of object.
  1724.      * If Pointer == NULL, object is symbol itself. 
  1725.      */
  1726.     {
  1727.     if(Pointer == NULL)
  1728.     *Property = SymbolDesc->sPrptyList;
  1729.     else
  1730.     *Property = Pointer->oPrptyList; 
  1731.     }
  1732.  
  1733.  
  1734. int
  1735. CDAddProperty(SymbolDesc,Pointer,Value,String)
  1736.     struct s *SymbolDesc;
  1737.     struct o *Pointer;
  1738.     char *String;
  1739.     int Value;
  1740.     {
  1741.     char * cp;
  1742.     struct prpty *prptyDesc;
  1743.     unsigned int size;
  1744.  
  1745.     if((prptyDesc = (struct prpty *) malloc(sizeof(struct prpty))) == NULL)
  1746.     return(CDError(CDMALLOCFAILED));
  1747.     size = strlen(String) + 2; 
  1748.     if((cp = prptyDesc->prpty_String = malloc(size)) == NULL)
  1749.     return(CDError(CDMALLOCFAILED));
  1750.     prptyDesc->prpty_Value = Value;
  1751.     strcpy(prptyDesc->prpty_String,String);
  1752.     /* we can't allaow semicolons because of CIF */
  1753.     while(cp != NULL && *cp != NULL){
  1754.     if(*cp == ';')
  1755.         *cp = ' ';
  1756.     ++cp;
  1757.     }
  1758.     if(Pointer == NULL){
  1759.     prptyDesc->prpty_Succ = SymbolDesc->sPrptyList;
  1760.     SymbolDesc->sPrptyList = prptyDesc;
  1761.     }
  1762.     else{
  1763.     prptyDesc->prpty_Succ = Pointer->oPrptyList;
  1764.     Pointer->oPrptyList = prptyDesc; 
  1765.     }
  1766.     return(True);
  1767.     }
  1768.  
  1769.  
  1770. int
  1771. CDRemoveProperty(SymbolDesc,Pointer,Value)
  1772.     struct s *SymbolDesc;
  1773.     struct o *Pointer;
  1774.     int Value;
  1775.     {
  1776.     struct prpty *prptyDesc;
  1777.     struct prpty *prptyHead;
  1778.     struct prpty prptyCopy;
  1779.  
  1780.     if(Pointer == NULL){
  1781.     prptyHead = prptyDesc = SymbolDesc->sPrptyList;
  1782.     SymbolDesc->sPrptyList = NULL;
  1783.     }
  1784.     else{
  1785.     prptyHead = prptyDesc = Pointer->oPrptyList; 
  1786.     Pointer->oPrptyList = NULL; 
  1787.     }
  1788.     while(prptyDesc != NULL){
  1789.     if(prptyDesc->prpty_Value != Value){
  1790.         if(Not CDAddProperty(SymbolDesc,Pointer,prptyDesc->prpty_Value,
  1791.             prptyDesc->prpty_String))
  1792.             return(False);
  1793.         }
  1794.     prptyDesc = prptyDesc->prpty_Succ;
  1795.     }
  1796.     /*
  1797.      * Free storage of property old list;
  1798.      */
  1799.     prptyDesc = prptyHead;
  1800.     while(prptyDesc != NULL){
  1801.     prptyCopy = *prptyDesc;
  1802.     if(prptyDesc->prpty_String != NULL)
  1803.         free(prptyDesc->prpty_String);
  1804.     free(prptyDesc);
  1805.     prptyDesc = prptyCopy.prpty_Succ;
  1806.     }
  1807.     return(True);
  1808.     }
  1809.  
  1810.  
  1811. void
  1812. CDType(Pointer,Type)
  1813.     struct o *Pointer;
  1814.     char *Type;
  1815.     /*
  1816.      * Returns type of object pointed to by Pointer.
  1817.      */
  1818.     {
  1819.     *Type = Pointer->oType; 
  1820.     }
  1821.  
  1822.  
  1823. int
  1824. CDBB(SymbolDesc,Pointer,Left,Bottom,Right,Top)
  1825.     struct s *SymbolDesc;
  1826.     struct o *Pointer;
  1827.     int *Left,*Bottom,*Right,*Top;
  1828.     /*
  1829.      * Return BB of object pointed to by Pointer.
  1830.      * If Pointer == NULL, return BB of symbol itself.
  1831.      * Basically, we CAN'T afford to recompute the BB of the symbol each time
  1832.      * CDDelete or an object creation routine is invoked.
  1833.      *
  1834.      * If malloc fails, CDBB will return False via CDError.  Otherwise, True
  1835.      * is returned.
  1836.      */
  1837.     {
  1838.     struct g *GenDesc;
  1839.     int Layer;
  1840.  
  1841.     if(Pointer == NULL And SymbolDesc->sBBValid){
  1842.     *Left = SymbolDesc->sLeft;
  1843.     *Bottom = SymbolDesc->sBottom;
  1844.     *Right = SymbolDesc->sRight;
  1845.     *Top = SymbolDesc->sTop;
  1846.  
  1847. #ifdef DEBUGREFLECT
  1848. printf("CDBB1(%s,%d,%d,%d,%d)\n",SymbolDesc->sName,*Left,*Bottom,*Right,*Top);
  1849. #endif 
  1850.  
  1851. #ifdef DEBUGGEN
  1852. printf("CDBB1(%s,%d,%d,%d,%d)\n",SymbolDesc->sName,*Left,*Bottom,*Right,*Top);
  1853. #endif 
  1854.  
  1855.     return(True);
  1856.     }
  1857.     elif(Pointer != NULL){
  1858.     *Left = Pointer->oLeft;
  1859.     *Bottom = Pointer->oBottom;
  1860.     *Right = Pointer->oRight;
  1861.     *Top = Pointer->oTop;
  1862.  
  1863. #ifdef DEBUGREFLECT
  1864. printf("CDBB2(%s,%d,%d,%d,%d)\n",SymbolDesc->sName,*Left,*Bottom,*Right,*Top);
  1865. #endif 
  1866.  
  1867. #ifdef DEBUGGEN
  1868. printf("CDBB2(%s,%d,%d,%d,%d)\n",SymbolDesc->sName,*Left,*Bottom,*Right,*Top);
  1869. #endif 
  1870.  
  1871.     return(True);
  1872.     }
  1873.     SymbolDesc->sLeft = SymbolDesc->sBottom = INFINITY;
  1874.     SymbolDesc->sRight = SymbolDesc->sTop = -INFINITY;
  1875.     if(Not CDInitGen(SymbolDesc,0,(int)-INFINITY,(int)-INFINITY,(int)INFINITY,
  1876.     (int)INFINITY,&GenDesc)) return(CDError(CDMALLOCFAILED));
  1877.     loop {
  1878.     CDGen(SymbolDesc,GenDesc,&Pointer);
  1879.     if(Pointer == NULL)
  1880.         break;
  1881.     SymbolDesc->sLeft = min(SymbolDesc->sLeft,Pointer->oLeft); 
  1882.     SymbolDesc->sBottom = min(SymbolDesc->sBottom,Pointer->oBottom); 
  1883.     SymbolDesc->sRight = max(SymbolDesc->sRight,Pointer->oRight); 
  1884.     SymbolDesc->sTop = max(SymbolDesc->sTop,Pointer->oTop); 
  1885.     }
  1886.     for(Layer = 1;Layer <= CDNUMLAYERS;++Layer){
  1887.     if(Not CDInitGen(SymbolDesc,Layer,(int)-INFINITY,(int)-INFINITY,
  1888.         (int)INFINITY,(int)INFINITY,&GenDesc))
  1889.         return(CDError(CDMALLOCFAILED));
  1890.     CDGen(SymbolDesc,GenDesc,&Pointer);
  1891.     if(Pointer == NULL)
  1892.         continue;
  1893.     loop {
  1894.         SymbolDesc->sLeft = min(SymbolDesc->sLeft,Pointer->oLeft); 
  1895.         SymbolDesc->sBottom = min(SymbolDesc->sBottom,Pointer->oBottom); 
  1896.         SymbolDesc->sRight = max(SymbolDesc->sRight,Pointer->oRight); 
  1897.         SymbolDesc->sTop = max(SymbolDesc->sTop,Pointer->oTop); 
  1898.         CDGen(SymbolDesc,GenDesc,&Pointer);
  1899.         if(Pointer == NULL)
  1900.         break;
  1901.         }
  1902.     }
  1903.     if(SymbolDesc->sLeft == INFINITY)
  1904.     SymbolDesc->sLeft = SymbolDesc->sBottom = SymbolDesc->sRight = 
  1905.         SymbolDesc->sTop = 0;
  1906.     SymbolDesc->sBBValid = True;
  1907.     *Left = SymbolDesc->sLeft;
  1908.     *Bottom = SymbolDesc->sBottom;
  1909.     *Right = SymbolDesc->sRight;
  1910.     *Top = SymbolDesc->sTop;
  1911.  
  1912. #ifdef DEBUGGEN
  1913. printf("CDBB3(%s,%d,%d,%d,%d)\n",SymbolDesc->sName,*Left,*Bottom,*Right,*Top);
  1914. #endif 
  1915.  
  1916. #ifdef DEBUGREFLECT
  1917. printf("CDBB3(%s,%d,%d,%d,%d)\n",SymbolDesc->sName,*Left,*Bottom,*Right,*Top);
  1918. #endif 
  1919.  
  1920.     return(True);
  1921.     }
  1922.  
  1923.  
  1924. /*
  1925.  * Test code for CDIntersect.
  1926.  * main()
  1927.  *     {
  1928.  *     int Left,Bottom,Right,Top,BeginX,EndX,BeginY,EndY;
  1929.  *
  1930.  *     printf("BB?");
  1931.  *     scanf("%d%d%d%d",&Left,&Bottom,&Right,&Top);
  1932.  *     CDIntersect(Left,Bottom,Right,Top,&BeginX,&EndX,&BeginY,&EndY);
  1933.  *     printf("Bin[.][%d..%d][%d..%d]\n",BeginX,EndX,BeginY,EndY);
  1934.  *     }
  1935.  */
  1936.  
  1937. void
  1938. CDIntersect(Left,Bottom,Right,Top,BeginX,EndX,BeginY,EndY)
  1939.     int Left,Bottom,Right,Top;
  1940.     int *BeginX,*EndX,*BeginY,*EndY;
  1941.     /*
  1942.      * Returns which bins overlap the AOI
  1943.      * The residual bin is always searched
  1944.      * Runs in constant time
  1945.      */
  1946.     {
  1947. #ifdef FLOAT
  1948.     *BeginX = (int)((float)(Left-CDBINMINX) * (float)(CDNUMBINS)/(float)(CDBINMAXX-CDBINMINX) + 1);
  1949.     if(*BeginX > CDNUMBINS)
  1950.     *BeginX = CDNUMBINS;
  1951.     elif(*BeginX < 1)
  1952.     *BeginX = 1;
  1953.     *EndX = (int)((float)(Right-CDBINMINX) * (float)(CDNUMBINS)/(float)(CDBINMAXX-CDBINMINX) + 1);
  1954.     if(*EndX > CDNUMBINS)
  1955.     *EndX = CDNUMBINS;
  1956.     elif(*EndX < 1)
  1957.     *EndX = 1;
  1958.     *BeginY = (int)((float)(Bottom-CDBINMINY) * (float)(CDNUMBINS)/(float)(CDBINMAXY-CDBINMINY) + 1);
  1959.     if(*BeginY > CDNUMBINS)
  1960.     *BeginY = CDNUMBINS;
  1961.     elif(*BeginY < 1)
  1962.     *BeginY = 1;
  1963.     *EndY = (int)((float)(Top-CDBINMINY) * (float)(CDNUMBINS)/(float)(CDBINMAXY-CDBINMINY) + 1);
  1964.     if(*EndY > CDNUMBINS)
  1965.     *EndY = CDNUMBINS;
  1966.     elif(*EndY < 1)
  1967.     *EndY = 1;
  1968. #else
  1969.     *BeginX = ((Left-CDBINMINX) * (CDNUMBINS)/(CDBINMAXX-CDBINMINX) + 1);
  1970.     if(*BeginX > CDNUMBINS)
  1971.     *BeginX = CDNUMBINS;
  1972.     elif(*BeginX < 1)
  1973.     *BeginX = 1;
  1974.     *EndX = ((Right-CDBINMINX) * (CDNUMBINS)/(CDBINMAXX-CDBINMINX) + 1);
  1975.     if(*EndX > CDNUMBINS)
  1976.     *EndX = CDNUMBINS;
  1977.     elif(*EndX < 1)
  1978.     *EndX = 1;
  1979.     *BeginY = ((Bottom-CDBINMINY) * (CDNUMBINS)/(CDBINMAXY-CDBINMINY) + 1);
  1980.     if(*BeginY > CDNUMBINS)
  1981.     *BeginY = CDNUMBINS;
  1982.     elif(*BeginY < 1)
  1983.     *BeginY = 1;
  1984.     *EndY = ((Top-CDBINMINY) * (CDNUMBINS)/(CDBINMAXY-CDBINMINY) + 1);
  1985.     if(*EndY > CDNUMBINS)
  1986.     *EndY = CDNUMBINS;
  1987.     elif(*EndY < 1)
  1988.     *EndY = 1;
  1989. #endif
  1990.     }
  1991.  
  1992.  
  1993.  
  1994.  
  1995. /*======================================================================*
  1996.  *                                    *
  1997.  *      GGGG EEEEE N   N EEEEE RRRR    A   TTTTT  OOO  RRRR   SSSS    *
  1998.  *     G     E     NN  N E     R   R  A A    T   O   O R   R S        *
  1999.  *     G GGG EEE   N N N EEE   RRRR  A   A   T   O   O RRRR   SSS    *
  2000.  *     G   G E     N  NN E     R R   AAAAA   T   O   O R R       S    *
  2001.  *      GGG  EEEEE N   N EEEEE R  R  A   A   T    OOO  R  R  SSSS    *
  2002.  *                                    *
  2003.  *                                    *
  2004.  *                                    *
  2005.  *    CDInitGen(SymbolDesc,Layer,Left,Bottom,Right,Top,GenDesc)    *
  2006.  *    CDGen(SymbolDesc,GenDesc,Pointer)                *
  2007.  *    CDInitTGen(Pointer,TGen)                    *
  2008.  *    CDTGen(TGen,Type,X,Y)                        *
  2009.  *                                    *
  2010.  *======================================================================*/
  2011.  
  2012. int
  2013. CDInitGen(SymbolDesc,Layer,Left,Bottom,Right,Top,GenDesc)
  2014.     struct s *SymbolDesc;
  2015.     int Layer,Left,Bottom,Right,Top;
  2016.     struct g **GenDesc;
  2017.     /*
  2018.      * Returns a pointer to a generator desc.
  2019.      * Layer == 0 denotes calls.
  2020.      */
  2021.     {
  2022.     int BeginX,BeginY,EndX,EndY;
  2023.  
  2024. #ifdef DEBUGGEN
  2025. printf("Begin initializing generator to search symbol %s.\n",SymbolDesc->sName);
  2026. printf("Untransformed AOI is %d %d %d %d.\n",Left,Bottom,Right,Top);
  2027. #endif
  2028.  
  2029.     /*
  2030.      * Apply inverse of current transformation to AOI.
  2031.      */
  2032.     TInverse();
  2033.     TInversePoint(&Left,&Bottom);
  2034.     TInversePoint(&Right,&Top);
  2035.     if(Right < Left)
  2036.     SwapInts(Left,Right);
  2037.     if(Top < Bottom)
  2038.     SwapInts(Bottom,Top);
  2039.  
  2040. #ifdef DEBUGGEN
  2041. printf("Transformed AOI is %d %d %d %d.\n",Left,Bottom,Right,Top);
  2042. #endif
  2043.  
  2044.     CDIntersect(Left,Bottom,Right,Top,&BeginX,&EndX,&BeginY,&EndY);
  2045.  
  2046. #ifdef DEBUGGEN
  2047. printf("Initialized generator to search bins %d..%d,%d..%d on layer %d.\n",
  2048.     BeginX,EndX,BeginY,EndY,Layer);
  2049. #endif
  2050.  
  2051.     if((*GenDesc = (struct g *)malloc(sizeof(struct g))) == NULL)
  2052.     return(CDError(CDMALLOCFAILED));
  2053.     (*GenDesc)->gLeft = Left;
  2054.     (*GenDesc)->gBottom = Bottom;
  2055.     (*GenDesc)->gRight = Right;
  2056.     (*GenDesc)->gTop = Top;
  2057.     (*GenDesc)->gLayer = Layer;
  2058.     (*GenDesc)->gX = (*GenDesc)->gBeginX = BeginX;
  2059.     (*GenDesc)->gY = (*GenDesc)->gBeginY = EndY;
  2060.     (*GenDesc)->gEndX = EndX;
  2061.     (*GenDesc)->gEndY = BeginY;
  2062.     /*
  2063.      * CDGen will ALWAYS search the residual bin FIRST.
  2064.      * The vanilla bins will be searched in the order 
  2065.      *  for Y = EndY..BeginY 
  2066.      *      for X = BeginX..EndX
  2067.      *      ...
  2068.      * so that redisplays will flow top down.
  2069.      */
  2070.     if(SymbolDesc->sBin[Layer] == NULL)
  2071.         (*GenDesc)->gPointer = NULL;
  2072.     else
  2073.         (*GenDesc)->gPointer = SymbolDesc->sBin[Layer][0][0];
  2074.  
  2075. #ifdef DEBUGGEN
  2076. printf("End initializing generator to search symbol %s.\n",SymbolDesc->sName);
  2077. #endif
  2078.  
  2079.     return(True);
  2080.     }
  2081.  
  2082.  
  2083. void
  2084. CDGen(SymbolDesc,GenDesc,Pointer)
  2085.     struct s *SymbolDesc;
  2086.     struct g *GenDesc;
  2087.     struct o **Pointer;
  2088.     /*
  2089.      * Returns pointer to next object.
  2090.      * You should invoke CDType to access object's type and dispatch off
  2091.      * of type.  See traversal code in CDUpdate.  Pointer == NULL if last
  2092.      * object at which time GenDesc is freed.
  2093.      */
  2094.     {
  2095.     int i,L,B,R,T;
  2096.  
  2097.     loop {
  2098.     if(GenDesc->gPointer != NULL){
  2099.         /*
  2100.          * gPointer points to an object desc.    Is it in the AOI?
  2101.          * This test is necessary, because of the granularity of the bins.
  2102.          * Suppose AOI lies entirely within one bin.
  2103.          * Then there may, in general, be descs in the bin whose BBs lie
  2104.          * outside the AOI. 
  2105.          */
  2106.         L = GenDesc->gPointer->oLeft;
  2107.         B = GenDesc->gPointer->oBottom;
  2108.         R = GenDesc->gPointer->oRight;
  2109.         T = GenDesc->gPointer->oTop;
  2110.  
  2111. #ifdef DEBUGGEN
  2112. printf("Generator intersecting %d %d %d %d to AOI.\n",L,B,R,T);
  2113. #endif
  2114.  
  2115.         if(L > GenDesc->gRight Or B > GenDesc->gTop Or
  2116.         R < GenDesc->gLeft Or T < GenDesc->gBottom){
  2117.         /*
  2118.          * Object isn't visible, so consider the next one, if any, in
  2119.          * the bin currently being searched.
  2120.          */
  2121.         GenDesc->gPointer = GenDesc->gPointer->oSucc;
  2122.  
  2123. #ifdef DEBUGGEN
  2124. printf("Invisible.\n");
  2125. #endif
  2126.  
  2127.         }
  2128.         else {
  2129.  
  2130. #ifdef DEBUGGEN
  2131. printf("Visible.\n");
  2132. #endif
  2133.  
  2134.         /*
  2135.          * Object is visible, so return object desc.
  2136.          */
  2137.         *Pointer = GenDesc->gPointer;
  2138.         GenDesc->gPointer = GenDesc->gPointer->oSucc;
  2139.         return;
  2140.         } 
  2141.         }
  2142.     else {
  2143.         if(GenDesc->gY < GenDesc->gEndY){
  2144.         /* The generator is done */
  2145.         free(GenDesc);
  2146.         *Pointer = NULL;
  2147.         return;
  2148.         }
  2149.         /*
  2150.          * Consider first object in next bin.
  2151.          * If the bin is empty, we will pass through the loop again.
  2152.          */
  2153.         i = GenDesc->gLayer;
  2154.         if(SymbolDesc->sBin[i] == NULL){
  2155.         /* The generator is done */
  2156.         free(GenDesc);
  2157.         *Pointer = NULL;
  2158.         return;
  2159.         }
  2160.         GenDesc->gPointer = SymbolDesc->sBin[i][GenDesc->gX][GenDesc->gY];
  2161.         ++(GenDesc->gX);
  2162.         if(GenDesc->gX > GenDesc->gEndX){
  2163.         GenDesc->gX = GenDesc->gBeginX;
  2164.         --(GenDesc->gY);
  2165.         }
  2166.         }
  2167.     }
  2168.     }
  2169.  
  2170.  
  2171. void
  2172. CDInitTGen(Pointer,TGen)
  2173.     struct o *Pointer;
  2174.     struct t **TGen;
  2175.     {
  2176.     struct c *CallDesc;
  2177.  
  2178.     if(Pointer == NULL)
  2179.     return;
  2180.     if(Pointer->oType != CDSYMBOLCALL)
  2181.     return;
  2182.     CallDesc = (struct c *)Pointer->oRep;
  2183.     *TGen = CallDesc->cT;
  2184.     }
  2185.  
  2186.  
  2187. void
  2188. CDTGen(TGen,Type,X,Y)
  2189.     struct t **TGen;
  2190.     char *Type;
  2191.     int *X,*Y;
  2192.     {
  2193.     static FirstDesc = True;
  2194.  
  2195.     if(*TGen == NULL)
  2196.     return;
  2197.     elif(FirstDesc){
  2198.     FirstDesc = False;
  2199.     *X = (*TGen)->tX;
  2200.     *Y = (*TGen)->tY;
  2201.     *Type = (*TGen)->tType;
  2202.     }
  2203.     else {
  2204.     *TGen = (*TGen)->tSucc;
  2205.     if(*TGen == NULL){
  2206.         FirstDesc = True;
  2207.         return;
  2208.         }
  2209.     *X = (*TGen)->tX;
  2210.     *Y = (*TGen)->tY;
  2211.     *Type = (*TGen)->tType;
  2212.     }
  2213.     }
  2214.  
  2215.  
  2216.  
  2217.  
  2218. /*======================================================================*
  2219.  *                                    *
  2220.  *                          CCCC III FFFFF                *
  2221.  *                         C      I  F                   *
  2222.  *                         C      I  FFFF                *
  2223.  *                         C      I  F                  *
  2224.  *                          CCCC III F                     *
  2225.  *                                    *
  2226.  *  TTTTT RRRR    A   N   N  SSSS L       A   TTTTT III  OOO  N   N    *
  2227.  *    T   R   R  A A  NN  N S     L      A A    T    I  O   O NN  N    *
  2228.  *    T   RRRR  A   A N N N  SSS  L     A   A   T    I  O   O N N N    *
  2229.  *    T   R R   AAAAA N  NN     S L     AAAAA   T    I  O   O N  NN    *
  2230.  *    T   R  R  A   A N   N SSSS  LLLLL A   A   T   III  OOO  N   N    *
  2231.  *                                    *
  2232.  *                                    *
  2233.  *                                    *
  2234.  *    CDUpdate(SymbolDesc,SymbolFile)                    *
  2235.  *    CDGenCIF(FileDesc,SymbolDesc,SymbolNum,A,B)            *
  2236.  *    CDTo(CIFFile,Root,A,B,Program)                    *
  2237.  *    CDFrom(Root,CIFFile,A,B,Layers,NumLayers,Program)        *
  2238.  *    CDUnmark(SymbolDesc)                        *
  2239.  *                                    *
  2240.  *======================================================================*/
  2241.  
  2242. int
  2243. CDUpdate(SymbolDesc,SymbolFile)
  2244.     struct s *SymbolDesc;
  2245.     char *SymbolFile;
  2246.     /*
  2247.      * Update symbol to symbol file.
  2248.      * If SymbolFile == NULL, update to file SymbolDesc->sName.
  2249.      * Returns True if success, else returns False.
  2250.      */
  2251.     {
  2252.     FILE *FileDesc;
  2253.     struct g *GenDesc;
  2254.     struct o *Pointer;
  2255.     struct t *TGen;
  2256.     struct p *Path;
  2257.     struct prpty *PrptyDesc;
  2258.     char *Label;
  2259.     char *SymbolName;
  2260.     int Layer,X,Y,Length,Width;
  2261.     int NumX,DX,NumY,DY;
  2262.     char Type;
  2263.  
  2264.     if(SymbolFile == NULL){
  2265.     if((FileDesc = POpen(SymbolDesc->sName,"w",(char *)NULL,(char **)NULL))
  2266.         == NULL) return(False);
  2267.     fprintf(FileDesc,"(Symbol %s);\n",SymbolDesc->sName); }
  2268.     else {
  2269.     if((FileDesc = POpen(SymbolFile,"w",(char *)NULL,(char **)NULL))
  2270.         == NULL) return(False); 
  2271.     fprintf(FileDesc,"(Symbol %s);\n",SymbolFile); } 
  2272.     fprintf(FileDesc,"9 %s;\n",SymbolDesc->sName);
  2273.     /* add property list info */
  2274.     CDProperty(SymbolDesc,(struct o *)NULL,&PrptyDesc);
  2275.     while(PrptyDesc != NULL){
  2276.     fprintf(FileDesc,"5 %d %s;\n",PrptyDesc->prpty_Value,
  2277.         PrptyDesc->prpty_String);
  2278.     PrptyDesc = PrptyDesc->prpty_Succ;
  2279.     }
  2280.     GenBeginSymbol(FileDesc,0,1,1);
  2281.     SymbolDesc->sLeft = SymbolDesc->sBottom = INFINITY;
  2282.     SymbolDesc->sRight = SymbolDesc->sTop = -INFINITY;
  2283.     if(Not CDInitGen(SymbolDesc,0,(int)-INFINITY,(int)-INFINITY,(int)INFINITY,
  2284.     (int)INFINITY,&GenDesc)) return(CDError(CDMALLOCFAILED));
  2285.     loop {
  2286.     CDGen(SymbolDesc,GenDesc,&Pointer);
  2287.     if(Pointer == NULL)
  2288.         break;
  2289.     CDCall(Pointer,&SymbolName,&NumX,&DX,&NumY,&DY);
  2290.     /* add symbol name extension */
  2291.     fprintf(FileDesc,"9 %s;\n",SymbolName);
  2292.     /* add property list info */
  2293.     CDProperty(SymbolDesc,Pointer,&PrptyDesc);
  2294.     while(PrptyDesc != NULL){
  2295.         fprintf(FileDesc,"5 %d %s;\n",PrptyDesc->prpty_Value,
  2296.         PrptyDesc->prpty_String);
  2297.         PrptyDesc = PrptyDesc->prpty_Succ;
  2298.         }
  2299.     /* add symbol array extension */
  2300.     if(NumX != 1 Or NumY != 1)
  2301.         fprintf(FileDesc,"1 Array %d %d %d %d;\n",NumX,DX,NumY,DY);
  2302.     fprintf(FileDesc,"C 0");
  2303.     CDInitTGen(Pointer,&TGen);
  2304.     loop {
  2305.         CDTGen(&TGen,&Type,&X,&Y);
  2306.         if(TGen == NULL){
  2307.         fprintf(FileDesc,";\n");
  2308.         break;
  2309.         }
  2310.         elif(Type == CDROTATE)
  2311.         fprintf(FileDesc," R %d %d",X,Y);
  2312.         elif(Type == CDTRANSLATE)
  2313.         fprintf(FileDesc," T %d %d",X,Y);
  2314.         elif(Type == CDMIRRORX)
  2315.         fprintf(FileDesc," MX");
  2316.         elif(Type == CDMIRRORY)
  2317.         fprintf(FileDesc," MY");
  2318.         }
  2319.     SymbolDesc->sLeft = min(SymbolDesc->sLeft,Pointer->oLeft); 
  2320.     SymbolDesc->sBottom = min(SymbolDesc->sBottom,Pointer->oBottom); 
  2321.     SymbolDesc->sRight = max(SymbolDesc->sRight,Pointer->oRight); 
  2322.     SymbolDesc->sTop = max(SymbolDesc->sTop,Pointer->oTop); 
  2323.     }
  2324.     for(Layer = 1;Layer <= CDNUMLAYERS;++Layer){
  2325.     if(Not CDInitGen(SymbolDesc,Layer,(int)-INFINITY,(int)-INFINITY,
  2326.         (int)INFINITY,(int)INFINITY,&GenDesc))
  2327.         return(CDError(CDMALLOCFAILED));
  2328.     CDGen(SymbolDesc,GenDesc,&Pointer);
  2329.     if(Pointer == NULL)
  2330.         continue;
  2331.     GenLayer(FileDesc,CDLayer[Layer].lTechnology,CDLayer[Layer].lMask);
  2332.     loop{
  2333.         CDProperty(SymbolDesc,Pointer,&PrptyDesc);
  2334.         while(PrptyDesc != NULL){
  2335.         fprintf(FileDesc,"5 %d %s;\n",PrptyDesc->prpty_Value,
  2336.             PrptyDesc->prpty_String);
  2337.         PrptyDesc = PrptyDesc->prpty_Succ;
  2338.         }
  2339.         CDType(Pointer,&Type);
  2340.         if(Type == CDWIRE){
  2341.         CDWire(Pointer,&Layer,&Width,&Path);
  2342.         GenWire(FileDesc,Width,Path);
  2343.         }
  2344.         elif(Type == CDPOLYGON){
  2345.         CDPolygon(Pointer,&Layer,&Path);
  2346.         GenPolygon(FileDesc,Path);
  2347.         }
  2348.         elif(Type == CDLABEL){
  2349.         CDLabel(Pointer,&Layer,&Label,&X,&Y);
  2350.         fprintf(FileDesc,"94 %s %d %d",Label,X,Y);
  2351.         fprintf(FileDesc,";\n");
  2352.         }
  2353.         elif(Type == CDBOX){
  2354.         CDBox(Pointer,&Layer,&Length,&Width,&X,&Y);
  2355.         GenBox(FileDesc,Length,Width,X,Y,1,0);
  2356.         }
  2357.         SymbolDesc->sLeft = min(SymbolDesc->sLeft,Pointer->oLeft); 
  2358.         SymbolDesc->sBottom = min(SymbolDesc->sBottom,Pointer->oBottom); 
  2359.         SymbolDesc->sRight = max(SymbolDesc->sRight,Pointer->oRight); 
  2360.         SymbolDesc->sTop = max(SymbolDesc->sTop,Pointer->oTop); 
  2361.         CDGen(SymbolDesc,GenDesc,&Pointer);
  2362.         if(Pointer == NULL)
  2363.         break;
  2364.         }
  2365.     }
  2366.     if(SymbolDesc->sLeft == INFINITY)
  2367.     SymbolDesc->sLeft = SymbolDesc->sBottom = SymbolDesc->sRight = 
  2368.         SymbolDesc->sTop = 0;
  2369.     GenEndSymbol(FileDesc);
  2370.     GenEnd(FileDesc);
  2371.     fclose(FileDesc);
  2372.     CDDesc.dSymbolDesc->sBBValid = True; 
  2373.     return(True);
  2374.     }
  2375.  
  2376.  
  2377. int
  2378. CDGenCIF(FileDesc,SymbolDesc,SymbolNum,A,B,Program)
  2379.     FILE *FileDesc;
  2380.     struct s *SymbolDesc;
  2381.     int *SymbolNum,A,B;
  2382.     char Program;
  2383.     {
  2384.     struct g *GenDesc;
  2385.     struct o *Pointer;
  2386.     struct s *MasterDesc;
  2387.     struct p *Pair,*Path;
  2388.     struct t *TGen;
  2389.     struct prpty *PrptyDesc;
  2390.     char *SymbolName;
  2391.     char *Label;
  2392.     int Layer,X,Y,Length,Width;
  2393.     int NumX,DX,NumY,DY;
  2394.     int Info;
  2395.     int i,j,FirstT;
  2396.     int Left,Bottom,Right,Top;
  2397.     int OutputLayer;
  2398.     char Type;
  2399.  
  2400.     *SymbolNum += 1; 
  2401.     /*
  2402.      * Mark symbol associated withSymbolDesc as visited by storing
  2403.      * its symbol # in its info field.  VERY NICE.
  2404.      */
  2405.     CDSetInfo(SymbolDesc,(struct o *)NULL,*SymbolNum);
  2406.  
  2407.     /*
  2408.      * First write to the CIF file any symbol definitions below
  2409.      * the symbol associated with SymbolDesc.
  2410.      */
  2411.     if(Not CDInitGen(SymbolDesc,0,(int)-INFINITY,(int)-INFINITY,(int)INFINITY,
  2412.     (int)INFINITY,&GenDesc)) return(CDError(CDMALLOCFAILED));
  2413.     loop {
  2414.     CDGen(SymbolDesc,GenDesc,&Pointer);
  2415.     if(Pointer == NULL)
  2416.         break;
  2417.     CDCall(Pointer,&SymbolName,&NumX,&DX,&NumY,&DY);
  2418.     if(Not CDOpen(SymbolName,&MasterDesc,'w'))
  2419.         return(False);
  2420.     CDInfo(MasterDesc,(struct o *)NULL,&Info);
  2421.     if(Info == 0)
  2422.         /* Write master's definition to CIF file. */
  2423.         if(Not CDGenCIF(FileDesc,MasterDesc,SymbolNum,A,B,Program))
  2424.         return(False);
  2425.     }
  2426.  
  2427.     /*
  2428.      * Write to the CIF file the definition of the symbol associated with
  2429.      * SymbolDesc.  Instance calls first--then geometries.
  2430.      */
  2431.     if(Program == 'e'){
  2432.     CDProperty(SymbolDesc,(struct o *)NULL,&PrptyDesc);
  2433.     while(PrptyDesc != NULL){
  2434.         fprintf(FileDesc,"5 %d %s;\n",PrptyDesc->prpty_Value,
  2435.         PrptyDesc->prpty_String);
  2436.         PrptyDesc = PrptyDesc->prpty_Succ;
  2437.         }
  2438.     }
  2439.     CDInfo(SymbolDesc,(struct o *)NULL,&Info);
  2440.     fprintf(FileDesc,"DS %d 1 1;\n",Info);
  2441.     /* write symbol rename extension */
  2442.     if(Program == 'b' Or Program == 'a')
  2443.     fprintf(FileDesc,"( %s );\n",SymbolDesc->sName);
  2444.     elif(Program == 'i')
  2445.     fprintf(FileDesc,"(9 %s );\n",SymbolDesc->sName);
  2446.     elif(Program == 's')
  2447.     fprintf(FileDesc,"(Name: %s );\n",SymbolDesc->sName);
  2448.     else
  2449.     fprintf(FileDesc,"9 %s;\n",SymbolDesc->sName);
  2450.     if(Not CDInitGen(SymbolDesc,0,(int)-INFINITY,(int)-INFINITY,(int)INFINITY,
  2451.     (int)INFINITY,&GenDesc)) return(CDError(CDMALLOCFAILED));
  2452.     loop {
  2453.     CDGen(SymbolDesc,GenDesc,&Pointer);
  2454.     if(Pointer == NULL)
  2455.         break;
  2456.     CDCall(Pointer,&SymbolName,&NumX,&DX,&NumY,&DY);
  2457.     if(Not CDOpen(SymbolName,&MasterDesc,'w'))
  2458.         return(False);
  2459.     CDInfo(MasterDesc,(struct o *)NULL,&Info);
  2460.     if(Not CDBB(MasterDesc,(struct o *)NULL,&Left,&Bottom,&Right,&Top))
  2461.         return(False);
  2462.     for(i = 1;i <= NumY;++i){
  2463.         for(j = 1;j <= NumX;++j){
  2464.         Width = Right - Left;
  2465.         Length = Top - Bottom;
  2466.         /* write property list extension */
  2467.         if(Program == 'e'){
  2468.             CDProperty(SymbolDesc,Pointer,&PrptyDesc);
  2469.             while(PrptyDesc != NULL){
  2470.             fprintf(FileDesc,"5 %d %s;\n",PrptyDesc->prpty_Value,
  2471.                 PrptyDesc->prpty_String);
  2472.             PrptyDesc = PrptyDesc->prpty_Succ;
  2473.             }
  2474.             }
  2475.         fprintf(FileDesc,"C %d",Info);
  2476.         FirstT = True;
  2477.         CDInitTGen(Pointer,&TGen);
  2478.         loop {
  2479.             CDTGen(&TGen,&Type,&X,&Y);
  2480.             if(TGen == NULL){
  2481.             fprintf(FileDesc,";\n");
  2482.             break;
  2483.             }
  2484.             elif(Type == CDROTATE){
  2485.             fprintf(FileDesc," R %d %d",X,Y);
  2486.             if(X == 0)
  2487.                 SwapInts(Width,Length);
  2488.             }
  2489.             elif(Type == CDTRANSLATE And FirstT){
  2490.             fprintf(FileDesc," T %d %d",
  2491.                 (X+(j-1)*(Width+DX))*A/B,(Y+(i-1)*(Length+DY))*A/B);
  2492.             FirstT = False;
  2493.             }
  2494.             elif(Type == CDTRANSLATE) 
  2495.             fprintf(FileDesc," T %d %d",X*A/B,Y*A/B);
  2496.             elif(Type == CDMIRRORX)
  2497.             fprintf(FileDesc," MX");
  2498.             elif(Type == CDMIRRORY)
  2499.             fprintf(FileDesc," MY");
  2500.             }
  2501.         }
  2502.         }
  2503.     }
  2504.     for(Layer = 1;Layer <= CDNUMLAYERS;++Layer){
  2505.     if(CDLayer[Layer-1].lCDFrom){
  2506.         if(Program == 'b'){
  2507.             fprintf(FileDesc,"L %d;\n",Layer);
  2508.         }
  2509.         else{
  2510.             GenLayer(FileDesc,CDLayer[Layer].lTechnology,
  2511.             CDLayer[Layer].lMask);
  2512.         }
  2513.         OutputLayer = True;
  2514.         }
  2515.     else
  2516.         OutputLayer = False;
  2517.     if(Not CDInitGen(SymbolDesc,Layer,(int)-INFINITY,(int)-INFINITY,
  2518.         (int)INFINITY,(int)INFINITY,&GenDesc))
  2519.         return(CDError(CDMALLOCFAILED));
  2520.     loop {
  2521.         CDGen(SymbolDesc,GenDesc,&Pointer);
  2522.         if(Pointer == NULL)
  2523.             break;
  2524.         /* write property list extension */
  2525.         if(Program == 'e'){
  2526.         CDProperty(SymbolDesc,Pointer,&PrptyDesc);
  2527.         while(PrptyDesc != NULL And Program == 'e'){
  2528.             fprintf(FileDesc,"5 %d %s;\n",PrptyDesc->prpty_Value,
  2529.             PrptyDesc->prpty_String);
  2530.             PrptyDesc = PrptyDesc->prpty_Succ;
  2531.             }
  2532.         }
  2533.         CDType(Pointer,&Type);
  2534.         if(!OutputLayer && Type != CDLABEL){
  2535.         /* output all labels */
  2536.         }
  2537.         elif(Type == CDBOX){
  2538.         CDBox(Pointer,&Layer,&Length,&Width,&X,&Y);
  2539.         GenBox(FileDesc,Length*A/B,Width*A/B,X*A/B,Y*A/B,1,0);
  2540.         }
  2541.         elif(Type == CDWIRE){
  2542.         CDWire(Pointer,&Layer,&Width,&Path);
  2543.         if(Path->pSucc == NULL)
  2544.             fprintf(FileDesc,"W %d %d %d",Width*A/B,
  2545.             Path->pX*A/B,Path->pY*A/B);
  2546.         else {
  2547.             fprintf(FileDesc,"W %d",Width*A/B);
  2548.             Pair = Path;
  2549.             while(Pair != NULL){
  2550.             fprintf(FileDesc," %d %d",Pair->pX*A/B,Pair->pY*A/B);
  2551.             Pair = Pair->pSucc;
  2552.             }
  2553.             }
  2554.         fprintf(FileDesc,";\n");
  2555.         }
  2556.         elif(Type == CDPOLYGON){
  2557.         CDPolygon(Pointer,&Layer,&Path);
  2558.         fprintf(FileDesc,"P");
  2559.         Pair = Path;
  2560.         while(Pair != NULL){
  2561.             fprintf(FileDesc," %d %d",Pair->pX*A/B,Pair->pY*A/B);
  2562.             Pair = Pair->pSucc;
  2563.             }
  2564.         fprintf(FileDesc,";\n");
  2565.         }
  2566.         elif(Type == CDLABEL){
  2567.         CDLabel(Pointer,&Layer,&Label,&X,&Y);
  2568.         if(Program == 'k' Or Program == 'e')
  2569.             fprintf(FileDesc,"94 %s %d %d;\n",Label,X*A/B,Y*A/B);
  2570.         elif(Program == 'm'){
  2571.             fprintf(FileDesc,"94 %s %d %d",Label,X*A/B,Y*A/B);
  2572.             if(CDLayer[Layer].lTechnology != ' '){
  2573.             fprintf(FileDesc," %c",CDLayer[Layer].lTechnology);
  2574.             i = 0;
  2575.             while(i < 3 And CDLayer[Layer].lMask[i] > 040){
  2576.                     fprintf(FileDesc,"%c",CDLayer[Layer].lMask[i]);
  2577.                 i++;
  2578.                 }
  2579.             }
  2580.             fprintf(FileDesc,";\n");
  2581.             }
  2582.         }
  2583.         }
  2584.     }
  2585.     GenEndSymbol(FileDesc);
  2586.     return(True);
  2587.     }
  2588.  
  2589.  
  2590. int
  2591. CDTo(CIFFile,Root,A,B,Program)
  2592.     char *CIFFile,*Root;
  2593.     char Program;
  2594.     int A,B;
  2595.     /*
  2596.      * Translate from CIF file into symbol files.
  2597.      * Each time we see a symbol definition, we write it in its own file.
  2598.      * The problem is that commands may be in the file that aren't part of a
  2599.      * symbol definition.  The solution is to have a file named Root for
  2600.      * the commands. 
  2601.      */
  2602.     {
  2603.     int Int1;
  2604.     int StatusInt;
  2605.     char *StatusString;
  2606.     CDDesc.dControl = DCONTROLCDTO;
  2607.     
  2608.     /*
  2609.      * On the first pass, we just fill the symbol name table.
  2610.      */
  2611.     CDDesc.dFirstPass = True;
  2612.     CDDesc.dNumSymbolTable = 0;
  2613.     if((CDDesc.dProgram = Program) != 'n'){
  2614.     for(Int1 = 0;Int1 < CDNUMREMEMBER;++Int1){
  2615.         CDDesc.dSymTabNames[Int1][0] = EOS;
  2616.         CDDesc.dSymTabNumbers[Int1] = -1; 
  2617.         }
  2618.     PCIF(CIFFile,&StatusString,&StatusInt);
  2619.     if(StatusInt == PFAILED){
  2620.         CDStatusInt = CDPARSEFAILED;
  2621.         strcpy(CDStatusString,StatusString);
  2622.         return(False);
  2623.         }
  2624.     }
  2625.     /*
  2626.      * On the second pass, we do the sequential translation. 
  2627.      */
  2628.     CDDesc.dFirstPass = False;
  2629.     CDDesc.dPrptyList = NULL;
  2630.     CDDesc.dA = A;
  2631.     CDDesc.dB = B;
  2632.     CDDesc.dDSA = CDDesc.dDSB = 1;
  2633.     CDDesc.dRoot = True;
  2634.     if((CDDesc.dRootFileDesc = POpen(Root,"w",(char *)NULL,(char **)NULL))
  2635.     == NULL){
  2636.     sprintf(CDStatusString,"Can't open file Root.");
  2637.     CDStatusInt = CDPARSEFAILED;
  2638.     return(False);
  2639.     }
  2640.     fprintf(CDDesc.dRootFileDesc,"(Symbol %s.);\n",Root);
  2641.     fprintf(CDDesc.dRootFileDesc,"(Microns/lambda = %d/%d);\n",A,B);
  2642.     fprintf(CDDesc.dRootFileDesc,"9 %s;\n",Root);
  2643.     GenBeginSymbol(CDDesc.dRootFileDesc,0,1,1);
  2644.     PCIF(CIFFile,&StatusString,&StatusInt);
  2645.     if(StatusInt == PFAILED){
  2646.     CDStatusInt = CDPARSEFAILED;
  2647.     strcpy(CDStatusString,StatusString);
  2648.     return(False);
  2649.     }
  2650.     else
  2651.     CDStatusInt = CDSUCCEEDED;
  2652.     GenEndSymbol(CDDesc.dRootFileDesc);
  2653.     GenEnd(CDDesc.dRootFileDesc);
  2654.     fclose(CDDesc.dRootFileDesc);
  2655.     CDDesc.dControl = DCONTROLVANILLA;
  2656.     return(True);
  2657.     }
  2658.  
  2659.  
  2660. int
  2661. CDFrom(Root,CIFFile,A,B,Layers,NumLayers,Program)
  2662.     char *Root,*CIFFile,Program;
  2663.     int Layers[],NumLayers;
  2664.     int A,B;
  2665.     /*
  2666.      * Translate symbol hierarchy rooted with symbol named Root into
  2667.      * CIF file named CIFFile. 
  2668.      */
  2669.     {
  2670.     struct s *SymbolDesc;
  2671.     FILE *FileDesc;
  2672.     int SymbolNum = 0;
  2673.     int Info;
  2674.     int Layer;
  2675.  
  2676.     for(Layer = 0;Layer < NumLayers;++Layer)
  2677.     if(Layers[Layer])
  2678.         CDLayer[Layer].lCDFrom = True;
  2679.     else
  2680.         CDLayer[Layer].lCDFrom = False;
  2681.     if((FileDesc = POpen(CIFFile,"w",(char *)NULL,(char **)NULL)) == NULL){    
  2682.     CDStatusInt = CDPARSEFAILED;
  2683.     sprintf(CDStatusString,"Can't open CIF file.");
  2684.     return(False);
  2685.     }
  2686.     if(Not CDOpen(Root,&SymbolDesc,'r')){
  2687.     CDStatusInt = CDPARSEFAILED;
  2688.     return(False);
  2689.     }
  2690.     fprintf(FileDesc,"(CIF file of symbol hierarchy rooted at %s);\n",Root);
  2691.     if(Not CDGenCIF(FileDesc,SymbolDesc,&SymbolNum,A,B,Program))
  2692.     return(False);
  2693.     CDInfo(SymbolDesc,(struct o *)NULL,&Info);
  2694.     fprintf(FileDesc,"C %d;\nE\n",Info);
  2695.     fclose(FileDesc);
  2696.     /*
  2697.      * Really should set all of the info fields in all symbol descs to 0.
  2698.      * CDUnmark(SymbolDesc);
  2699.      */
  2700.     return(True);
  2701.     }
  2702.  
  2703.  
  2704. int
  2705. CDParseCIF(Root,CIFFile,Program)
  2706.     char *Root,*CIFFile,Program;
  2707.     /*
  2708.      * Construct CD database from a CIF file rather than a hierarchy
  2709.      * of cell files.
  2710.      */
  2711.     {
  2712.     struct m *MasterListDesc1;
  2713.     struct m *MasterListDesc2;
  2714.     struct s *MasterSymbolDesc1;
  2715.     struct s *MasterSymbolDesc2;
  2716.     struct bu *Bucket;
  2717.     char *StatusString;
  2718.     int StatusInt;
  2719.     int Int1;
  2720.  
  2721.     CDDesc.dProgram = Program;
  2722.     CDDesc.dA = CDDesc.dB = 1;
  2723.     CDDesc.dDSA = CDDesc.dDSB = 1;
  2724.     CDDesc.dRoot = True;
  2725.     CDDesc.dControl = DCONTROLPCIF;
  2726.     CDDesc.dSymbolDesc = CDDesc.dRootCellDesc;
  2727.     if(Not CDOpen(Root,&CDDesc.dRootCellDesc,'n')){
  2728.     CDStatusInt = CDMALLOCFAILED;
  2729.         return(False);
  2730.         }
  2731.     CDDesc.dControl = DCONTROLPCIF;
  2732.  
  2733.     /*
  2734.      * On the first pass, we just fill the symbol name table.
  2735.      */
  2736.     CDDesc.dFirstPass = True;
  2737.     CDDesc.dNumSymbolTable = 0;
  2738.     for(Int1 = 0;Int1 < CDNUMREMEMBER;++Int1){
  2739.     CDDesc.dSymTabNames[Int1][0] = EOS;
  2740.     CDDesc.dSymTabNumbers[Int1] = -1;
  2741.     }
  2742.     PCIF(CIFFile,&StatusString,&StatusInt);
  2743.     if(StatusInt == PFAILED){
  2744.     CDStatusInt = CDPARSEFAILED;
  2745.         strcpy(CDStatusString,StatusString);
  2746.         return(False);
  2747.     }
  2748.     
  2749.     /*
  2750.      * On the second pass, we do the sequential translation. 
  2751.      */
  2752.     CDDesc.dFirstPass = False;
  2753.     PCIF(CIFFile,&StatusString,&StatusInt);
  2754.     if(StatusInt == PFAILED){
  2755.     CDStatusInt = CDPARSEFAILED;
  2756.         strcpy(CDStatusString,StatusString);
  2757.         return(False);
  2758.     }
  2759.     MasterListDesc1 = CDDesc.dRootCellDesc->sMasterList;
  2760.     while(MasterListDesc1 != NULL){
  2761.     CDOpen(MasterListDesc1->mName,&MasterSymbolDesc1,'r');
  2762.     if(CDStatusInt == CDNEWSYMBOL Or CDStatusInt == CDPARSEFAILED){
  2763.         if(CDStatusInt == CDNEWSYMBOL){
  2764.         CDStatusInt = CDPARSEFAILED;
  2765.         sprintf(CDStatusString,
  2766.             "Master %s doesn't seem to be around.\n",
  2767.             MasterListDesc2->mName);
  2768.         }
  2769.         return(False);
  2770.         }
  2771.     MasterListDesc2 = MasterSymbolDesc1->sMasterList;
  2772.         while(MasterListDesc2 != NULL){
  2773.         CDOpen(MasterListDesc2->mName,&MasterSymbolDesc2,'r');
  2774.         if(CDStatusInt == CDNEWSYMBOL Or CDStatusInt == CDPARSEFAILED){
  2775.         if(CDStatusInt == CDNEWSYMBOL){
  2776.             CDStatusInt = CDPARSEFAILED;
  2777.             sprintf(CDStatusString,
  2778.             "Master %s doesn't seem to be around.\n",
  2779.             MasterListDesc2->mName);
  2780.             }
  2781.         return(False);
  2782.         }
  2783.         if(Not CDReflect(MasterSymbolDesc2)){
  2784.         CDStatusInt = CDPARSEFAILED;
  2785.         return(CDError(CDMALLOCFAILED));
  2786.         }
  2787.         MasterListDesc2 = MasterListDesc2->mSucc;
  2788.         }
  2789.     if(Not CDReflect(MasterSymbolDesc1)){
  2790.         CDStatusInt = CDPARSEFAILED;
  2791.         return(CDError(CDMALLOCFAILED));
  2792.         }
  2793.     MasterListDesc1 = MasterListDesc1->mSucc;
  2794.     }
  2795.     if(Not CDReflect(CDDesc.dRootCellDesc)){
  2796.     CDStatusInt = CDPARSEFAILED;
  2797.     return(CDError(CDMALLOCFAILED));
  2798.     }
  2799.     return(True);
  2800.     }
  2801.  
  2802.  
  2803. int
  2804. CDUnmark(SymbolDesc)
  2805.     struct s *SymbolDesc;
  2806.     {
  2807.     struct g *GenDesc;
  2808.     struct o *Pointer;
  2809.     char *SymbolName;
  2810.     int NumX,DX,NumY,DY;
  2811.     int Info;
  2812.     int Layer;
  2813.     struct s *MasterDesc;
  2814.  
  2815.     if(Not CDInitGen(SymbolDesc,0,(int)-INFINITY,(int)-INFINITY,(int)INFINITY,
  2816.     (int)INFINITY,&GenDesc)) return(CDError(CDMALLOCFAILED));
  2817.     loop {
  2818.     CDGen(SymbolDesc,GenDesc,&Pointer);
  2819.     if(Pointer == NULL)
  2820.         break;
  2821.     CDCall(Pointer,&SymbolName,&NumX,&DX,&NumY,&DY);
  2822.     /*
  2823.      * Cell has already been mapped into memory.  Therefore,
  2824.      * we can assume that CDOpen does not fail in the parse.
  2825.      */
  2826.     if(Not CDOpen(SymbolName,&MasterDesc,'r'))
  2827.         return(CDError(CDMALLOCFAILED));
  2828.     CDInfo(MasterDesc,(struct o *)NULL,&Info);
  2829.     if(Info != 0){
  2830.         /* Unmark master */
  2831.         CDSetInfo(MasterDesc,(struct o *)NULL,0);
  2832.         if(Not CDUnmark(MasterDesc))
  2833.         return(False);
  2834.         }
  2835.     }
  2836.     for(Layer = 1; Layer <= CDNUMLAYERS; ++Layer){
  2837.     if(Not CDInitGen(SymbolDesc,Layer,(int)-INFINITY,(int)-INFINITY,
  2838.         (int)INFINITY,(int)INFINITY,&GenDesc))
  2839.         return(CDError(CDMALLOCFAILED));
  2840.     loop{
  2841.         CDGen(SymbolDesc,GenDesc,&Pointer);
  2842.         if(Pointer == NULL)
  2843.             break;
  2844.         CDInfo(MasterDesc,(struct o *)NULL,&Info);
  2845.         if(Info != 0){
  2846.             /* Unmark geometry */
  2847.             CDSetInfo(MasterDesc,Pointer,0);
  2848.         }
  2849.         }
  2850.     }
  2851.     return(True);
  2852.     }
  2853.  
  2854.  
  2855.  
  2856.  
  2857. /*======================================================================*
  2858.  *                                    *
  2859.  *  EEEEE RRRR  RRRR   OOO  RRRR                    *
  2860.  *  E     R   R R   R O   O R   R                    *
  2861.  *  EEE   RRRR  RRRR  O   O RRRR                    *
  2862.  *  E     R R   R R   O   O R R                     *
  2863.  *  EEEEE R  R  R  R   OOO  R  R                     *
  2864.  *                                    *
  2865.  *  RRRR   OOO  U   U TTTTT III N   N EEEEE  SSSS            *
  2866.  *  R   R O   O U   U   T    I  NN  N E     S                *
  2867.  *  RRRR  O   O U   U   T    I  N N N EEE    SSS            *
  2868.  *  R R   O   O U   U   T    I  N  NN E         S            *
  2869.  *  R  R   OOO   UUU    T   III N   N EEEEE SSSS            *
  2870.  *                                    *
  2871.  *                                    *
  2872.  *                                    *
  2873.  *    CDError(ID)                            *
  2874.  *                                    *
  2875.  *======================================================================*/
  2876.  
  2877. int
  2878. CDError(ID)
  2879.     int ID;
  2880.     {
  2881.     CDStatusInt = ID;
  2882.     switch(ID){
  2883.  
  2884.     case CDMALLOCFAILED:
  2885.         sprintf(CDStatusString,"CD Out of memory.");
  2886.         return(False);
  2887.  
  2888.     case CDBADBOX:
  2889.         sprintf(CDStatusString,"Can't allow a zero width box.");
  2890.         /* not a fatal error */
  2891.         return(True);
  2892.  
  2893.     case CDXFORMSTACKFULL:
  2894.         sprintf(CDStatusString,"Transform stack is full.");
  2895.         return(False);
  2896.  
  2897.     case CDBADPATH:
  2898.         sprintf(CDStatusString,"Can't set search path.");
  2899.         return(False);
  2900.  
  2901.     default:
  2902.         sprintf(CDStatusString,"Unknown Error.");
  2903.         return(False);
  2904.  
  2905.     }
  2906.     }
  2907.