Jspice3
actions.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 /*
10  * Action routines for fast CIF parser.
11  *
12  * These routines handle both conversion from and to CIF.
13  * AEnd will be the last routine invoked in a successful parse.
14  */
15 
16 #include "cddefs.h"
17 #include "cdparser.h"
18 #include <sys/types.h>
19 #include <time.h>
20 
21 #ifdef __STDC__
22 extern int a_malloc_failed(void);
23 #else
24 extern int a_malloc_failed();
25 #endif
26 
27 #define RADTODEG 57.29577951
28 
29 static int CurrentLayer;
30 static char TypeOut[200];
31 
32 
33 void
35 {
36  /*
37  * The CIF parsing has ended.
38  */
39 #ifdef TRACEPARSER
40 GenEnd(stderr);
41 #endif
42 }
43 
44 int
45 ABeginSymbol(SymbolNum,A,B)
46 int SymbolNum;
47 long A,B;
48 {
49  /*
50  * This routine begins the parsing action for a symbol definition
51  * and performs all necessary initialization for the new symbol.
52  *
53  * DCONTROLCDTO:
54  * On the first pass, we add the symbol name to the symbol table
55  * which is in CDDesc.dSymTabNames. To do this we have to switch
56  * according to the value of 'CDDesc.dProgram' which specifies
57  * the style of the CIF. On the second pass, we open the FILE
58  * descriptor for the KIC cell that coresponds to the respective
59  * CIF symbol and write the header information in the KIC cell.
60  *
61  * DCONTROLPCIF:
62  * On the first pass, we add the symbol name to the symbol table
63  * which is in CDDesc.dSymTabNames. To do this we have to switch
64  * according to the value of 'CDDesc.dProgram' which specifies
65  * the style of the CIF. Also, we open the symbol in the database
66  * via CDOpen() which places the symbol name in the hash table
67  * which is in CDSymbolTable. We must not invoke CDClose since
68  * that will remove the symbol from memory; the purpose of
69  * DCONTROLPCIF is to construct the database in memory without
70  * relying on a KIC cell directory in the current search path.
71  * On the second pass, we need only invoke CDSymbol() to obtain
72  * the symbol desc. for the respective symbol.
73  *
74  * DCONTROLCDOPEN
75  * No action. It is assumed that the file being parsed is a KIC
76  * cell which will always contain exactly one CIF symbol.
77  */
78 
79  time_t Long1;
80  int Int1 = 0;
81 
82 #ifdef TRACEPARSER
83 GenBeginSymbol(stderr,SymbolNum,A,B);
84 #endif
85  CurrentLayer = 0;
87  CDDesc.dRoot = False;
88  CDDesc.dDSA = A;
89  CDDesc.dDSB = B;
90  /*
91  * We switch on the following:
92  * k KIC: A KIC symbol name follows a DS command as in 9 PadIn;
93  * a Stanford: Stanford symbol name follows a DS command as in (PadIn);
94  * b NCA: An NCA symbol name follows a DS command as in (PadIn);
95  * h IGS: An IGS symbol name follows a DS command as in 9 PadIn;
96  * i Icarus: An Icarus name follows a DS command as in (9 PadIn);
97  * s Sif: A Sif name follows a DS command as in (Name: PadIn);
98  * n none of the above
99  */
100  if(CDDesc.dProgram == 'i'){
101  /*
102  * Icarus files have the symbol name in a comment of the form
103  * (9 SymbolName); after the DS command.
104  */
105  loop {
107  if(PReturned == PFAILED)
108  return(PFAILED);
109  elif(PChar == '9')
110  break;
111  }
112  loop {
114  if(PReturned == PFAILED)
115  return(PFAILED);
116  elif(PChar == ')'){
117  CDDesc.dSymbolName[Int1] = EOS;
122  = SymbolNum;
124  }
125  }
126  elif(PChar == ';')
127  break;
128  else
129  if(Int1 < FILENAMESIZE)
130  CDDesc.dSymbolName[Int1++] = PChar;
131  }
132  }
133  elif(CDDesc.dProgram == 'a' Or CDDesc.dProgram == 'b'){
134  /*
135  * Some files have the symbol name in a comment of the form
136  * (SymbolName); after the DS command.
137  */
138  loop {
140  if(PReturned == PFAILED)
141  return(PFAILED);
142  elif(PChar == '(')
143  break;
144  }
145  loop {
147  if(PReturned == PFAILED)
148  return(PFAILED);
149  elif(PChar == ')'){
150  CDDesc.dSymbolName[Int1] = EOS;
155  = SymbolNum;
157  }
158  }
159  elif(PChar == ';')
160  break;
161  else {
162  if(Int1 < FILENAMESIZE)
163  CDDesc.dSymbolName[Int1++] = PChar;
164  }
165  }
166  }
167  elif(CDDesc.dProgram == 's'){
168  /*
169  * Sif files have the symbol name in a comment of the form
170  * ( Name: SymbolName); after the DS command.
171  */
172  loop {
174  if(PReturned == PFAILED)
175  return(PFAILED);
176  elif(PChar == ':')
177  break;
178  }
179  loop {
181  if(PReturned == PFAILED)
182  return(PFAILED);
183  elif(PChar == ')'){
184  CDDesc.dSymbolName[Int1] = EOS;
189  = SymbolNum;
191  }
192  }
193  elif(PChar == ';')
194  break;
195  else
196  if(Int1 < FILENAMESIZE)
197  CDDesc.dSymbolName[Int1++] = PChar;
198  }
199  }
200  elif(CDDesc.dProgram == 'q'){
201  /*
202  * SQUID files have the symbol name in the form
203  * 9 FullName; after the DS command where FullName
204  * is the full pathname to the cell or directory.
205  *
206  * NOTE: This code only works for UNIX file names.
207  */
208  char PrevName[FILENAMESIZE];
209  loop {
211  if(PReturned == PFAILED)
212  return(PFAILED);
213  elif(PChar == '9')
214  break;
215  }
216  loop {
218  if(PReturned == PFAILED)
219  return(PFAILED);
220  elif(PChar == ';'){
221  CDDesc.dSymbolName[Int1] = EOS;
222  if(Int1 == 1 And CDDesc.dSymbolName[0] == '.')
223  strcpy(CDDesc.dSymbolName,PrevName);
228  = SymbolNum;
230  }
231  break;
232  }
233  elif(PChar == '/'){
234  /* begin new name; last name was a directory */
235  Int1 = 0;
236  strcpy(PrevName,CDDesc.dSymbolName);
237  }
238  else
239  if(Int1 < FILENAMESIZE)
240  CDDesc.dSymbolName[Int1++] = PChar;
241  }
242  }
243  elif(CDDesc.dProgram == 'h' Or CDDesc.dProgram == 'k'){
244  /*
245  * IGS and KIC files have the symbol name in the form
246  * 9 SymbolName; after the DS command.
247  */
248  loop {
250  if(PReturned == PFAILED)
251  return(PFAILED);
252  elif(PChar == '9')
253  break;
254  }
255  loop {
257  if(PReturned == PFAILED)
258  return(PFAILED);
259  elif(PChar == ';'){
260  CDDesc.dSymbolName[Int1] = EOS;
265  = SymbolNum;
267  }
268  break;
269  }
270  else
271  if(Int1 < FILENAMESIZE)
272  CDDesc.dSymbolName[Int1++] = PChar;
273  }
274  }
276  if(CDDesc.dFirstPass){
277  /*
278  * Open the symbol, but don't search the current directory
279  * for a KIC cell. Also, don't close the symbol since
280  * that would remove the symbol from memory.
281  */
282  for(Int1 = 0; Int1 < CDDesc.dNumSymbolTable; ++Int1)
283  if(CDDesc.dSymTabNumbers[Int1] == SymbolNum) break;
284  if(Int1 == CDDesc.dNumSymbolTable){
287  "Symbol%d",SymbolNum);
289  = SymbolNum;
291  }
292  else
293  return(PFAILED);
294  }
295  if(!CDOpen(CDDesc.dSymTabNames[Int1],&CDDesc.dSymbolDesc,'n'))
296  return(PFAILED);
297  }
298  else{
299  /*
300  * Symbol is already open. Just get the desc for it.
301  */
302  for(Int1 = 0; Int1 < CDDesc.dNumSymbolTable; ++Int1)
303  if(CDDesc.dSymTabNumbers[Int1] == SymbolNum) break;
304  if(Int1 == CDDesc.dNumSymbolTable)
305  return(PFAILED);
307  if(CDDesc.dSymbolDesc == NULL)
308  return(PFAILED);
309  }
311  }
313  if(CDDesc.dFirstPass)
314  return(PSUCCEEDED);
315  if(CDDesc.dSymbolName[0] == EOS)
316  sprintf(CDDesc.dSymbolName,"Symbol%d",SymbolNum);
317  if((CDDesc.dSymbolFileDesc =
318  POpen(CDDesc.dSymbolName,"w",(char **)NULL)) == NULL)
319  return(PFAILED);
320  sprintf(TypeOut," Symbol %s ",CDDesc.dSymbolName);
322  Long1 = time((time_t *)NULL);
323  sprintf(TypeOut," Creation Date: %.24s ",ctime((time_t *)&Long1));
327  CDDesc.dSymbolName[0] = EOS;
328  }
329  }
331  /* add property list information */
332  while(CDDesc.dPrptyList != NULL){
333  struct prpty PrptyCopy;
334  if(Not CDAddProperty(CDDesc.dSymbolDesc,(struct o *)NULL,
336  return(PFAILED);
337  /* free storage of CDDesc.dPrptyList */
338  PrptyCopy = *CDDesc.dPrptyList;
341  CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
342  }
343  }
344  return(PSUCCEEDED);
345 }
346 
347 void
349 {
350  /*
351  * This routine performs the necessary actions to close a symbol
352  * definition.
353  *
354  * DCONTROLCDTO:
355  * Return on first pass (we are only building the symbol table).
356  * On the second pass, we terminate and close the KIC cell
357  * containing the respective CIF symbol.
358  *
359  * DCONTROLPCIF:
360  * We set the current cell desc in CDDesc.dSymbolDesc to that of
361  * the root symbol.
362  *
363  * DCONTROLCDOPEN:
364  * No action.
365  */
366 #ifdef TRACEPARSER
367 GenEndSymbol(stderr);
368 #endif
370  if(CDDesc.dFirstPass)
371  return;
374  fclose(CDDesc.dSymbolFileDesc);
375  CDDesc.dRoot = True;
376  }
379  CDDesc.dRoot = True;
380  }
385  /*
386  * Force the dummy call command at the end of the symbol
387  * to be ignored by ABeginCall.
388  */
389  CDDesc.dSymbolName[0] = EOS;
390  }
391 }
392 
393 void
394 ADeleteSymbol(SymbolNum)
395 int SymbolNum;
396 {
397  /*
398  * We do not deal with definition deletes.
399  * It could be handled by using the symbol table to obtain the
400  * respective symbol numbers, and invoking CDClose on those cell
401  * definitions to be deleted.
402  */
403 
404 #ifdef TRACEPARSER
405 fprintf(stderr,"DD %d;\n",SymbolNum);
406 #endif
407  /*
408  *Ignore DD commands.
409  */
410  fprintf(stderr,"Definition Delete of Symbol %d - ignored\n",SymbolNum);
411 }
412 
413 int
415 {
416 #ifdef TRACEPARSER
417 fprintf(stderr,";\n");
418 #endif
420  if(CDDesc.dFirstPass)
421  return(PSUCCEEDED);
422  if(CDDesc.dRoot)
424  else
426  }
429  return(PSUCCEEDED);
431  return(PFAILED);
432  while(CDDesc.dPrptyList != NULL){
433  struct prpty PrptyCopy;
436  return(PFAILED);
437  /* free storage of CDDesc.dPrptyList */
438  PrptyCopy = *CDDesc.dPrptyList;
441  CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
442  }
443  }
444  return(PSUCCEEDED);
445 }
446 
447 int
448 AT(Type,X,Y)
449 char Type;
450 long X,Y;
451 {
452 #ifdef TRACEPARSER
453 fprintf(stderr," T:%c %ld %ld",Type,X,Y);
454 #endif
456  if(CDDesc.dFirstPass)
457  return(PSUCCEEDED);
458  if(Type == CDTRANSLATE)
459  if(CDDesc.dRoot)
466  elif(Type == CDROTATE){
467  if(Abs(X) > 1 Or Abs(Y) > 1){
470  }
471  if(CDDesc.dRoot)
473  else
475  }
476  elif(Type == CDMIRRORX)
477  if(CDDesc.dRoot)
479  else
481  elif(Type == CDMIRRORY)
482  if(CDDesc.dRoot)
484  else
486  }
489  return(PSUCCEEDED);
490  return(CDT(CDDesc.dPointer,Type,X,Y));
491  }
492  return(PSUCCEEDED);
493 }
494 
495 int
496 ABeginCall(SymbolNum)
497 int SymbolNum;
498 {
499  int Int1;
500 #ifdef TRACEPARSER
501 fprintf(stderr,"C %d ",SymbolNum);
502 #endif
504  if(CDDesc.dFirstPass)
505  return(PSUCCEEDED);
506  if(CDDesc.dProgram != 'n'){
507  for(Int1 = 0; Int1 < CDDesc.dNumSymbolTable; ++Int1)
508  if(CDDesc.dSymTabNumbers[Int1] == SymbolNum) break;
509  }
510  }
512  if(CDDesc.dProgram != 'n' And Int1 < CDDesc.dNumSymbolTable){
513  sprintf(TypeOut," %s",CDDesc.dSymTabNames[Int1]);
514  if(CDDesc.dRoot)
516  else
518  }
519  elif(CDDesc.dSymbolName[0] != EOS){
520  sprintf(TypeOut," %s",CDDesc.dSymbolName);
521  if(CDDesc.dRoot)
523  else
525  }
526  else {
527  sprintf(CDDesc.dSymbolName,"Symbol%d",SymbolNum);
528  sprintf(TypeOut," Symbol%d",SymbolNum);
529  if(CDDesc.dRoot)
531  else
533  }
534  if(CDDesc.dRoot)
536  else
538  CDDesc.dSymbolName[0] = EOS;
539  }
541  if(CDDesc.dProgram != 'n' And Int1 < CDDesc.dNumSymbolTable)
543  else
544  sprintf(CDDesc.dSymbolName,"Symbol%d",SymbolNum);
547  &CDDesc.dPointer))
548  return(PFAILED);
549  CDDesc.dSymbolName[0] = EOS;
550  CDDesc.dNumX = CDDesc.dNumY = 1;
551  CDDesc.dDX = CDDesc.dDY = 0;
553  }
555  if(CDDesc.dSymbolName[0] != EOS)
558  &CDDesc.dPointer))
559  return(PFAILED);
560  CDDesc.dSymbolName[0] = EOS;
561  CDDesc.dNumX = CDDesc.dNumY = 1;
562  CDDesc.dDX = CDDesc.dDY = 0;
563  }
564  return(PSUCCEEDED);
565 }
566 
567 int
568 APolygon(Path)
569 struct p *Path;
570 {
571  struct p *Pair;
572 #ifdef TRACEPARSER
573 GenPolygon(stderr,Path);
574 #endif
576  int NumVertices;
577  long Left,Bottom,Right,Top;
578  if(CDDesc.dFirstPass)
579  return(PSUCCEEDED);
580  Pair = Path;
581  NumVertices = 0;
582  Left = Bottom = CDINFINITY;
583  Right = Top = -CDINFINITY;
584  while(Pair != NULL){
585  if(Pair->pX < Left)
586  Left = Pair->pX;
587  if(Pair->pX > Right)
588  Right = Pair->pX;
589  if(Pair->pY < Bottom)
590  Bottom = Pair->pY;
591  if(Pair->pY > Top)
592  Top = Pair->pY;
593  ++NumVertices;
594  Pair = Pair->pSucc;
595  }
596  if(NumVertices == 4){
597  if((Path->pX == Path->pSucc->pX And
598  Path->pSucc->pY == Path->pSucc->pSucc->pY And
599  Path->pSucc->pSucc->pX == Path->pSucc->pSucc->pSucc->pX And
600  Path->pY == Path->pSucc->pSucc->pSucc->pY)
601  Or
602  (Path->pY == Path->pSucc->pY And
603  Path->pSucc->pX == Path->pSucc->pSucc->pX And
604  Path->pSucc->pSucc->pY == Path->pSucc->pSucc->pSucc->pY And
605  Path->pX == Path->pSucc->pSucc->pSucc->pX))
606  {
607  return(ABox(Right-Left,Top-Bottom,Left+((Right-Left)/2),
608  Bottom+((Top-Bottom)/2),1,0));
609  }
610  }
611  Pair = Path;
612  while(Pair != NULL){
613  Pair->pX = Pair->pX*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
614  Pair->pY = Pair->pY*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
615  Pair = Pair->pSucc;
616  }
617  if(CDDesc.dRoot)
619  else
621  }
624  return(PSUCCEEDED);
626  &CDDesc.dPointer))
627  return(PFAILED);
628  while(CDDesc.dPrptyList != NULL){
629  struct prpty PrptyCopy;
632  return(PFAILED);
633  /* free storage of CDDesc.dPrptyList */
634  PrptyCopy = *CDDesc.dPrptyList;
637  CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
638  }
639  }
640  return(PSUCCEEDED);
641 }
642 
643 int
644 AWire(Width,Path)
645 long Width;
646 struct p *Path;
647 {
648  struct p *Pair;
649 #ifdef TRACEPARSER
650 GenWire(stderr,Width,Path);
651 #endif
653  if(CDDesc.dFirstPass)
654  return(PSUCCEEDED);
655  Pair = Path;
656  while(Pair != NULL){
657  Pair->pX = Pair->pX*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
658  Pair->pY = Pair->pY*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
659  Pair = Pair->pSucc;
660  }
661  if(CDDesc.dRoot)
663  else
665  }
668  return(PSUCCEEDED);
670  &CDDesc.dPointer))
671  return(PFAILED);
672  while(CDDesc.dPrptyList != NULL){
673  struct prpty PrptyCopy;
676  return(PFAILED);
677  /* free storage of CDDesc.dPrptyList */
678  PrptyCopy = *CDDesc.dPrptyList;
681  CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
682  }
683  }
684  return(PSUCCEEDED);
685 }
686 
687 int
688 ABox(Length,Width,X,Y,XDirection,YDirection)
689 long Length,Width,X,Y;
690 int XDirection,YDirection;
691 {
692 #ifdef TRACEPARSER
693 GenBox(stderr,Length,Width,X,Y,XDirection,YDirection);
694 #endif
696  if(CDDesc.dFirstPass)
697  return(PSUCCEEDED);
698  Length = Length*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
699  Width = Width*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
702  if(XDirection == 1 And YDirection == 0){
703  if(CDDesc.dRoot)
704  GenBox(CDDesc.dRootFileDesc,Length,Width,X,Y,
705  XDirection,YDirection);
706  else
707  GenBox(CDDesc.dSymbolFileDesc,Length,Width,X,Y,
708  XDirection,YDirection);
709  }
710  else {
711  /*
712  * Transform non-Manhattan box to polygon.
713  */
714  float C;
715  long Left,Bottom,Right,Top;
716  struct p *Path,*Pair;
717 
718  Left = X-(Length >> 1);
719  Right = X+(Length >> 1);
720  Bottom = Y-(Width >> 1);
721  Top = Y+(Width >> 1);
722  C = sqrt((double)(XDirection*XDirection+YDirection*YDirection));
723  if((Pair = Path = alloc(p)) == NULL)
724  return(a_malloc_failed());
725  Pair->pX = (Left*XDirection-Bottom*YDirection-
726  XDirection*X+YDirection*Y)/C+X;
727  Pair->pY = (Left*YDirection+Bottom*XDirection-
728  YDirection*X-XDirection*Y)/C+Y;
729  if((Pair = Pair->pSucc = alloc(p)) == NULL)
730  return(a_malloc_failed());
731  Pair->pX = (Left*XDirection-Top*YDirection-
732  XDirection*X+YDirection*Y)/C+X;
733  Pair->pY = (Left*YDirection+Top*XDirection-
734  YDirection*X-XDirection*Y)/C+Y;
735  if((Pair = Pair->pSucc = alloc(p)) == NULL)
736  return(a_malloc_failed());
737  Pair->pX = (Right*XDirection-Top*YDirection-
738  XDirection*X+YDirection*Y)/C+X;
739  Pair->pY = (Right*YDirection+Top*XDirection-
740  YDirection*X-XDirection*Y)/C+Y;
741  if((Pair = Pair->pSucc = alloc(p)) == NULL)
742  return(a_malloc_failed());
743  Pair->pX = (Right*XDirection-Bottom*YDirection-
744  XDirection*X+YDirection*Y)/C+X;
745  Pair->pY = (Right*YDirection+Bottom*XDirection-
746  YDirection*X-XDirection*Y)/C+Y;
747  Pair->pSucc = NULL;
748  if(CDDesc.dRoot)
750  else
752  }
753  }
756  return(PSUCCEEDED);
757  if(Not CDMakeBox(CDDesc.dSymbolDesc,CurrentLayer,Length,Width,
758  X,Y,&CDDesc.dPointer))
759  return(PFAILED);
760  while(CDDesc.dPrptyList != NULL){
761  struct prpty PrptyCopy;
764  return(PFAILED);
765  /* free storage of CDDesc.dPrptyList */
766  PrptyCopy = *CDDesc.dPrptyList;
769  CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
770  }
771  }
772  return(PSUCCEEDED);
773 }
774 
775 int
777 long Width,X,Y;
778 {
779  struct p *Path, *NewPath;
780  struct p Pair;
781  /*
782  *KIC DOES NOT SUPPORT ROUND FLASHES: convert to a wire with one vertex.
783  *Therefore, KIC will never try to generate a Roundflash.
784  */
786  if(CDDesc.dFirstPass)
787  return(PSUCCEEDED);
790  Pair.pSucc = NULL;
791  if(CDDesc.dRoot)
793  else
795  }
798  return(PSUCCEEDED);
799  if((NewPath = Path = alloc(p)) != NULL)
800  return(a_malloc_failed());
801  NewPath->pX = X;
802  NewPath->pY = Y;
803  NewPath->pSucc = NULL;
805  &CDDesc.dPointer))
806  return(PFAILED);
807  while(CDDesc.dPrptyList != NULL){
808  struct prpty PrptyCopy;
811  return(PFAILED);
812  /* free storage of CDDesc.dPrptyList */
813  PrptyCopy = *CDDesc.dPrptyList;
816  CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
817  }
818  }
819  return(PSUCCEEDED);
820 }
821 
822 int
823 ALayer(Technology,Mask)
824 char Technology,Mask[];
825 {
826  int Layer;
827 #ifdef TRACEPARSER
828 GenLayer(stderr,Technology,Mask);
829 #endif
831  if(CDDesc.dFirstPass)
832  return(PSUCCEEDED);
833  if(CDDesc.dRoot)
834  GenLayer(CDDesc.dRootFileDesc,Technology,Mask);
835  else
836  GenLayer(CDDesc.dSymbolFileDesc,Technology,Mask);
837  return(PSUCCEEDED);
838  }
840  for(Layer = 1;Layer <= CDNUMLAYERS;++Layer){
841  if(CDLayer[Layer].lTechnology == Technology And
842  CDLayer[Layer].lMask[0] == Mask[0] And
843  CDLayer[Layer].lMask[1] == Mask[1] And
844  CDLayer[Layer].lMask[2] == Mask[2]){
846  return(PSUCCEEDED);
847  }
848  }
849  /*
850  * Layer is not defined in CD layer table!
851  * If parsing CIF and layer is unknown, put it in the layer table.
852  * If opening a cell and layer is unknown, complain about it.
853  */
855  for(Layer = 1;Layer <= CDNUMLAYERS;++Layer){
856  if(CDLayer[Layer].lTechnology == ' ') {
857  CDSetLayer(Layer, Technology, Mask);
859  return(PSUCCEEDED);
860  }
861  }
862  }
863  CurrentLayer = 1;
864  }
865  return(PFAILED);
866 }
867 
868 int
869 AUserExtension(Digit,Text)
870 char Digit;
871 char *Text;
872 {
873  long X,Y;
874  int Layer,Xform;
875  char Label[81];
876 
877 #ifdef TRACEPARSER
878 GenUserExtension(stderr,Digit,Text);
879 #endif
881  if(CDDesc.dFirstPass Or CDDesc.dProgram == 'n')
882  return(PSUCCEEDED);
883  /*
884  * When converting to KIC format, we pass CD user extensions only.
885  * If we find an illegal extension, we ignore it.
886  */
887  if(Digit == '9'){
888  if(Text[0] == '4'){
889  if(CDDesc.dProgram == 'm'){ /* mextra text label */
890  if(sscanf(&(Text[1]),"%s%ld%ld%s",Label,&X,&Y,TypeOut) < 4)
891  return(PFAILED);
892  if(CDDesc.dRoot)
894  else
896  }
897  else /* normal CD label */
898  sscanf(&(Text[1]),"%s%ld%ld",Label,&X,&Y);
899  sprintf(TypeOut,"4 %s %d %d",Label,
902  if(CDDesc.dRoot)
904  else
906  }
907  elif(Text[0] == '2'){ /* NCA Label */
908  sscanf(&(Text[1]),"%s%ld%ld%d",Label,&X,&Y,&Layer);
909  sprintf(TypeOut,"%d ",Layer);
910  if(CDDesc.dRoot)
912  else
914  sprintf(TypeOut,"4 %s %d %d",Label,
917  if(CDDesc.dRoot)
919  else
921  }
922  else {
923  /* symbol name */
924  if(Text[0] == ' ')
925  strcpy(CDDesc.dSymbolName,&(Text[1]));
926  else strcpy(CDDesc.dSymbolName,Text);
927  if(CDDesc.dRoot)
929  else
931  }
932  }
933  elif(Digit == '5' And (Text[0] < '0' Or Text[0] > '9')){
934  /* Reserved for CD property list extensions */
935  if(CDDesc.dRoot)
937  else
939  }
940  }
942  /*
943  * When parsing CIF, we accept only CD user extensions and
944  * ignore any illegal extensions.
945  */
946  if(Digit == '9'){
947  if(Text[0] == '4'){
948  /* Label */
949  Xform = 0;
950  sscanf(&(Text[1]),"%s%ld%ld%d",Label,&X,&Y,&Xform);
952  return(PSUCCEEDED);
953 #ifdef TRACEPARSER
954 fprintf(stderr,"Making label on layer %d\n",CurrentLayer);
955 #endif
957  X,Y,(char)Xform,&CDDesc.dPointer))
958  return(PFAILED);
959  while(CDDesc.dPrptyList != NULL){
960  struct prpty PrptyCopy;
964  /* free storage of CDDesc.dPrptyList */
965  PrptyCopy = *CDDesc.dPrptyList;
968  CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
969  }
970  }
971  elif(Text[0] < '0' Or Text[0] > '9'){
972  /* Symbol name */
973  X = 0;
974  while(Text[X] <= ' ') ++X;
975  strcpy(CDDesc.dSymbolName,Text+X);
976  }
977  }
978  elif(Digit == '1' And (Text[0] < '0' Or Text[0] > '9')){
979  /* Reserved for CD Array extensions */
980  sscanf(Text,"%s",TypeOut);
981  if(strcmp(TypeOut,"Array") == 0){
982  sscanf(Text,"%s%d%ld%d%ld",TypeOut,&CDDesc.dNumX,&CDDesc.dDX,
983  &CDDesc.dNumY,&CDDesc.dDY);
984  }
985  }
986  elif(Digit == '5' And (Text[0] < '0' Or Text[0] > '9')){
987  /* Reserved for CD Property List extensions */
988  struct prpty *PDesc;
989  unsigned int size;
990  int i;
991 
992  if((PDesc = alloc(prpty))==NULL)
993  return(PFAILED);
994  if(sscanf(Text,"%d",&PDesc->prpty_Value) < 1)
995  return(PFAILED);
996  i = 0;
997  /* skip white space before property integer */
998  while((Text[i] < '0' Or Text[i] > '9') And Text[i] != '\0') ++i;
999  /* skip property integer */
1000  while(Text[i] >= '0' And Text[i] <= '9') ++i;
1001  /* skip white space and control chars after property integer */
1002  while(Text[i] <= ' ' And Text[i] != '\0') ++i;
1003  size = strlen(&(Text[i])) + 2;
1004  if((PDesc->prpty_String = tmalloc(size)) == NULL)
1005  return(PFAILED);
1006  strcpy(PDesc->prpty_String,&(Text[i]));
1007  PDesc->prpty_Succ = CDDesc.dPrptyList;
1008  CDDesc.dPrptyList = PDesc;
1009  }
1010  }
1011  return(PSUCCEEDED);
1012 }
1013 
1014 void
1016 char *Text;
1017 {
1018 #ifdef TRACEPARSER
1019 GenComment(stderr,Text);
1020 #endif
1021  if(CDDesc.dControl == DCONTROLCDTO){
1022  if(Not CDDesc.dFirstPass){
1023  if(CDDesc.dRoot)
1025  else
1027  }
1028  }
1029 }
1030 
1031 int
1033 {
1034  sprintf(CDStatusString,"Out of memory.");
1036  return(PFAILED);
1037 }
1038 
char dControl
Definition: cddefs.h:296
FILE * dSymbolFileDesc
Definition: cddefs.h:253
long dDSB
Definition: cddefs.h:247
struct l CDLayer[CDNUMLAYERS+1]
Definition: cd.c:74
#define loop
Definition: cdmacs.h:11
#define DCONTROLPCIF
Definition: cddefs.h:62
int AWire(long Width, struct p *Path)
Definition: actions.c:644
#define DCONTROLCDOPEN
Definition: cddefs.h:61
#define Or
Definition: cdmacs.h:15
int prpty_Value
Definition: cdprpty.h:67
long dDY
Definition: cddefs.h:241
static char TypeOut[200]
Definition: actions.c:30
#define CDINFINITY
Definition: cddefs.h:70
int CDMakeBox()
void CDSetLayer()
char * strcpy()
int CDMakeLabel()
void GenUserExtension()
void AEndSymbol()
Definition: actions.c:348
int AEndCall()
Definition: actions.c:414
#define PFAILED
Definition: cdparser.h:51
#define DCONTROLCDTO
Definition: cddefs.h:63
#define Not
Definition: cdmacs.h:16
long sLeft
Definition: cddefs.h:120
int CDStatusInt
Definition: cd.c:75
int CDMakePolygon()
struct d CDDesc
Definition: cd.c:73
int CDMakeWire()
int ABeginCall(int SymbolNum)
Definition: actions.c:496
long sBottom
Definition: cddefs.h:120
int dRoot
Definition: cddefs.h:260
void GenBeginSymbol()
long sTop
Definition: cddefs.h:120
long dA
Definition: cddefs.h:244
int CDOpen()
#define PSTRIPWHITESPACE1
Definition: cdparser.h:63
void AEnd()
Definition: actions.c:34
int CDEndMakeCall()
Definition: cddefs.h:215
struct o * dPointer
Definition: cddefs.h:249
#define PFAILONEOF
Definition: cdparser.h:57
int PCharacter()
#define alloc(type)
Definition: cdmacs.h:21
void GenEndSymbol()
int CDT()
int * dSymTabNumbers
Definition: cddefs.h:273
long * Left
Definition: cd.c:1907
long pY
Definition: cddefs.h:216
long sRight
Definition: cddefs.h:120
char * tmalloc()
long X
Definition: actions.c:450
char(* dSymTabNames)[FILENAMESIZE]
Definition: cddefs.h:272
int dNumX
Definition: cddefs.h:240
#define tfree(x)
Definition: cdmacs.h:22
int CDAddProperty()
#define NULL
Definition: spdefs.h:121
#define CDNUMREMEMBER
Definition: cddefs.h:98
int APolygon(struct p *Path)
Definition: actions.c:568
void GenRotation()
long * Top
Definition: cd.c:1907
#define elif
Definition: cdmacs.h:10
int PChar
Definition: parser.c:46
long * Right
Definition: cd.c:1907
void GenWire()
void GenComment()
#define True
Definition: scedstub.c:16
#define CDROTATE
Definition: cddefs.h:55
int ABeginSymbol(int SymbolNum, long A, long B)
Definition: actions.c:45
#define CDMALLOCFAILED
Definition: cddefs.h:35
#define Abs(Dragon)
Definition: cdmacs.h:19
Definition: cddefs.h:142
#define CDNUMLAYERS
Definition: cddefs.h:93
char * prpty_String
Definition: cdprpty.h:63
void GenTranslation()
void GenBeginCall()
long pX
Definition: cddefs.h:216
void GenBox()
void ADeleteSymbol(int SymbolNum)
Definition: actions.c:394
int Layer
Definition: cd.c:1908
int ABox(long Length, long Width, long X, long Y, int XDirection, int YDirection)
Definition: actions.c:688
#define PSUCCEEDED
Definition: cdparser.h:50
char * CDStatusString
Definition: cd.c:77
void Label()
char dSymbolName[FILENAMESIZE]
Definition: cddefs.h:305
long * Bottom
Definition: cd.c:1907
struct prpty * prpty_Succ
Definition: cdprpty.h:66
void GenMirrorX()
#define EOS
Definition: cdmacs.h:9
char dProgram
Definition: cddefs.h:304
void CDSymbol()
int ARoundFlash(long Width, long X, long Y)
Definition: actions.c:776
#define And
Definition: cdmacs.h:14
void GenMirrorY()
int ALayer(char Technology, Mask)
Definition: actions.c:823
#define CDTRANSLATE
Definition: cddefs.h:56
int char Type
Definition: actions.c:449
int dNumY
Definition: cddefs.h:240
static int CurrentLayer
Definition: actions.c:29
#define False
Definition: scedstub.c:15
void GenEndCall()
long dB
Definition: cddefs.h:244
#define FILENAMESIZE
Definition: cddefs.h:21
int CDBeginMakeCall()
int dFirstPass
Definition: cddefs.h:282
int PReturned
Definition: parser.c:48
long dDSA
Definition: cddefs.h:247
#define CDMIRRORY
Definition: cddefs.h:54
FILE * POpen()
#define CDMIRRORX
Definition: cddefs.h:53
struct p * pSucc
Definition: cddefs.h:217
long Y
Definition: actions.c:450
int dNumSymbolTable
Definition: cddefs.h:274
Definition: cdprpty.h:62
void AComment(char *Text)
Definition: actions.c:1015
struct s * dSymbolDesc
Definition: cddefs.h:250
void GenLayer()
char * ctime()
void GenEnd()
void GenPolygon()
struct prpty * dPrptyList
Definition: cddefs.h:266
long dDX
Definition: cddefs.h:241
struct s * dRootCellDesc
Definition: cddefs.h:251
int AUserExtension(char Digit, char *Text)
Definition: actions.c:869
int AT()
int a_malloc_failed()
Definition: actions.c:1032
FILE * dRootFileDesc
Definition: cddefs.h:263