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