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