1 /*
2  * gdsreader - simple Calma parser/printer tool
3  * Copyright (C) 1999 Serban-Mihai Popescu, serbanp@ix.netcom.com
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <math.h>
28 
29 #include <GDSstructs.h>
30 #include <GDSconsts.h>
31 #include <GDSaux.h>
32 #include <GDSboundary.h>
33 #include <GDSpath.h>
34 #include <GDSsref.h>
35 #include <GDSaref.h>
36 #include <GDStext.h>
37 #include <GDStext.h>
38 #include <GDSnode.h>
39 #include <GDSbox.h>
40 #include <GDStransf.h>
41 
42 bbox
GDSgetStructBBox(GDSstruct * structptr)43 GDSgetStructBBox(GDSstruct *structptr)
44 {
45   GDScell *cellptr;
46   bbox bbx, bbx1;
47 
48   bbx.ll.x = BIGVAL;
49   bbx.ll.y = BIGVAL;
50   bbx.ur.x = -BIGVAL;
51   bbx.ur.y = -BIGVAL;
52 
53   for(cellptr = structptr->cells; cellptr != NULL; cellptr = cellptr->next)
54   {
55     switch(cellptr->type)
56     {
57       case BOUNDARY:
58         bbx1 = GDSgetBoundaryBBox(cellptr->detail.boundary);
59         break;
60       case PATH:
61         bbx1 = GDSgetPathBBox(cellptr->detail.path);
62         break;
63       case TEXT:
64         bbx1 = GDSgetTextBBox(cellptr->detail.text);
65         break;
66       case SREF:
67         bbx1 = GDSgetSrefBBox(cellptr->detail.sref, &Ident);
68         break;
69       case AREF:
70         bbx1 = GDSgetArefBBox(cellptr->detail.aref, &Ident);
71         break;
72       default:
73         bbx1.ll.x = BIGVAL;
74         bbx1.ll.y = BIGVAL;
75         bbx1.ur.x = -BIGVAL;
76         bbx1.ur.y = -BIGVAL;
77         break;
78     }
79     if(bbx.ll.x > bbx1.ll.x)
80       bbx.ll.x = bbx1.ll.x;
81     if(bbx.ll.y > bbx1.ll.y)
82       bbx.ll.y = bbx1.ll.y;
83     if(bbx.ur.x < bbx1.ur.x)
84       bbx.ur.x = bbx1.ur.x;
85     if(bbx.ur.y < bbx1.ur.y)
86       bbx.ur.y = bbx1.ur.y;
87   }
88   fprintf(stderr, "minx = %d, miny = %d, maxx = %d, maxy = %d\n",
89           bbx.ll.x, bbx.ll.y, bbx.ur.x, bbx.ur.y);
90   return bbx;
91 }
92 
93 GDSstruct *
GDSreadStruct(int gdsfildes,GDSlibrary * libptr)94 GDSreadStruct(int gdsfildes, GDSlibrary *libptr)
95 {
96   unsigned char *record;
97   int nbytes;
98   GDSstruct *structptr;
99   GDScell *newcell;
100 
101   if(GDSreadRecord(gdsfildes, &record, &nbytes) != BGNSTR)
102   {
103     FREE(record);
104     GDSunreadRecord(gdsfildes, nbytes);
105     if(GDSreadRecord(gdsfildes, &record, &nbytes) == ENDLIB)
106       return NULL;
107     else
108     {
109       fprintf(stderr, "Missing ENDLIB field. Abort!\n");
110       exit(1);
111     }
112   }
113   else
114     FREE(record);
115 
116   structptr = (GDSstruct *)MALLOC(sizeof(GDSstruct));
117   structptr->cells = NULL;
118   structptr->layers = NULL;
119 
120   while(1)
121   {
122     switch(GDSreadRecord(gdsfildes, &record, &nbytes))
123     {
124       case STRNAME:
125         if((structptr->name = GDSreadString(record + 2, nbytes - 4)) == NULL)
126         {
127           fprintf(stderr, "Bad STRNAME record. Aborting\n");
128           exit(1);
129         }
130         fprintf(stdout, "strname = %s\n", structptr->name);
131         break;
132       case BOUNDARY:
133         if((newcell = GDSreadBoundary(gdsfildes, structptr)) == NULL)
134           return NULL;
135         newcell->next = structptr->cells;
136         structptr->cells = newcell;
137         break;
138       case PATH:
139         if((newcell = GDSreadPath(gdsfildes, structptr)) == NULL)
140           return NULL;
141         newcell->next = structptr->cells;
142         structptr->cells = newcell;
143         break;
144       case SREF:
145         if((newcell = GDSreadSref(gdsfildes, structptr)) == NULL)
146           return NULL;
147         newcell->next = structptr->cells;
148         structptr->cells = newcell;
149         break;
150       case AREF:
151         if((newcell = GDSreadAref(gdsfildes, structptr)) == NULL)
152           return NULL;
153         newcell->next = structptr->cells;
154         structptr->cells = newcell;
155         break;
156       case TEXT:
157         if((newcell = GDSreadText(gdsfildes, structptr)) == NULL)
158           return NULL;
159         newcell->next = structptr->cells;
160         structptr->cells = newcell;
161         break;
162       case NODE:
163         if((newcell = GDSreadNode(gdsfildes, structptr)) == NULL)
164           return NULL;
165         newcell->next = structptr->cells;
166         structptr->cells = newcell;
167         break;
168       case BOX:
169         if((newcell = GDSreadBox(gdsfildes, structptr)) == NULL)
170           return NULL;
171         newcell->next = structptr->cells;
172         structptr->cells = newcell;
173         break;
174 /* These two cases may be reworked.
175    Probably the return statement should be at ENDSTR. */
176       case ENDSTR:
177         FREE(record);
178         return structptr;
179       case BGNSTR:
180       case ENDLIB:
181         fprintf(stderr, "Incorrect record type in GDSreadStruct()\n");
182         FREE(record);
183         return NULL;
184       default:
185         fprintf(stderr, "Unknown record type\n");
186         break;
187     }
188     FREE(record);
189   }
190 }
191 
192 GDSstruct *
GDSsrefToStruct(srefEl * sref)193 GDSsrefToStruct(srefEl *sref)
194 {
195   GDSstruct *structptr;
196   GDScell *cellptr, *newcell;
197   char string[2048];
198   int flag;
199 
200   structptr = (GDSstruct *)MALLOC(sizeof(GDSstruct));
201   structptr->next = NULL;
202   structptr->cells = NULL;
203   structptr->layers = NULL; /* will be added later */
204   sprintf(string, "%s_flatten", sref->refname);
205   structptr->name = strdup(string);
206   for(cellptr = sref->strptr->cells; cellptr != NULL; cellptr = cellptr->next)
207   {
208     switch(cellptr->type)
209     {
210       case BOUNDARY:
211         flag = 1;
212         newcell = GDSdupBoundary(cellptr->detail.boundary);
213         break;
214       case PATH:
215         flag = 1;
216         newcell = GDSdupPath(cellptr->detail.path);
217         break;
218       case TEXT:
219         flag = 1;
220         newcell = GDSdupText(cellptr->detail.text);
221         break;
222       case SREF:
223         flag = 0;
224         /* still a lot of work to do */
225         break;
226       case AREF:
227         flag = 0;
228         /* still a lot of work to do */
229         break;
230       default:
231         flag = 0;
232         break;
233     }
234     if(flag)
235     {
236       newcell->next = structptr->cells;
237       structptr->cells = newcell;
238     }
239   }
240   return structptr;
241 }
242