comparison ueda/libuschem/graphnets.c @ 0:cd92449fdb51

initial import of ueda and ifctf-part-lib from ifctfvax CVS
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 20 Jul 2015 00:24:37 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:cd92449fdb51
1 /*
2 * preen_graphnets() functionality
3 */
4
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <strings.h>
8 #include "schemstruct.h"
9 #include "graphsym.h"
10
11 extern char *malloc();
12
13 extern struct graphsym_pininst *find_comp_pininst();
14 extern struct graphsym_pininst *find_pin_by_coord();
15
16 static struct schem *schem_being_preened;
17 static int dowarn, docorrect, severe_err;
18
19 static int
20 tjoin_hit_check(obj, tjoin)
21 struct schemobj *obj;
22 register struct netpoint *tjoin;
23 {
24 register struct netpoint *netpt, *nextpt;
25
26 for (netpt = obj->netobj_points; netpt && (nextpt = netpt->netpt_next);
27 netpt = nextpt) {
28 if (!netpt->netpt_coord_valid || !nextpt->netpt_coord_valid) {
29 fprintf(stderr,
30 "%s: line %d: Pin w/o coordinates impedes search for Tjoin antecedent\n",
31 schem_being_preened->orig_filename,
32 obj->obj_lineno);
33 severe_err = -1;
34 return(-1);
35 }
36 /* check for horizontal segments */
37 if (netpt->netpt_y == tjoin->netpt_y &&
38 nextpt->netpt_y == tjoin->netpt_y) {
39 if (tjoin->netpt_x > netpt->netpt_x &&
40 tjoin->netpt_x < nextpt->netpt_x)
41 return(1);
42 if (tjoin->netpt_x < netpt->netpt_x &&
43 tjoin->netpt_x > nextpt->netpt_x)
44 return(1);
45 }
46 /* check for vertical segments */
47 if (netpt->netpt_x == tjoin->netpt_x &&
48 nextpt->netpt_x == tjoin->netpt_x) {
49 if (tjoin->netpt_y > netpt->netpt_y &&
50 tjoin->netpt_y < nextpt->netpt_y)
51 return(1);
52 if (tjoin->netpt_y < netpt->netpt_y &&
53 tjoin->netpt_y > nextpt->netpt_y)
54 return(1);
55 }
56 }
57 return(0);
58 }
59
60 static struct schemobj *
61 find_grouphead_tail(ghead)
62 register struct schemobj *ghead;
63 {
64 register struct schemobj *obj, *next;
65
66 for (obj = ghead; ; obj = next) {
67 next = obj->obj_next;
68 if (next->obj_type != OBJTYPE_GRAPHNET)
69 return(obj);
70 if (next->netobj_grouphead != ghead)
71 return(obj);
72 }
73 }
74
75 static
76 preen_tjoin(obj, netpt, first, got_tjoin)
77 struct schemobj *obj;
78 register struct netpoint *netpt;
79 int first, *got_tjoin;
80 {
81 register struct schem *schem;
82 register struct schemobj *prevobj;
83 struct schemobj *ghead;
84 register int c;
85
86 schem = schem_being_preened;
87 if (first)
88 *got_tjoin = 1;
89 else if (!netpt->netpt_next) {
90 if (*got_tjoin) {
91 fprintf(stderr,
92 "%s: line %d: Tjoin on both ends of a GraphNet is illegal\n",
93 schem->orig_filename, obj->obj_lineno);
94 severe_err = -1;
95 return;
96 }
97 *got_tjoin = 1;
98 } else {
99 fprintf(stderr,
100 "%s: line %d: Tjoin in the middle of a GraphNet is meaningless\n",
101 schem->orig_filename, obj->obj_lineno);
102 severe_err = -1;
103 return;
104 }
105 for (prevobj = obj->obj_prev, c = 0;
106 prevobj != (struct schemobj *)schem; prevobj = prevobj->obj_prev)
107 if (prevobj->obj_type == OBJTYPE_GRAPHNET) {
108 c = tjoin_hit_check(prevobj, netpt);
109 if (c < 0)
110 return;
111 if (c)
112 break;
113 }
114 if (!c) {
115 fprintf(stderr, "%s: line %d: Tjoin antecedent not found\n",
116 schem->orig_filename, obj->obj_lineno);
117 severe_err = -1;
118 return;
119 }
120 netpt->netpt_tjoin_to = prevobj;
121 obj->netobj_grouphead = ghead = prevobj->netobj_grouphead;
122 /* netname logic */
123 if (obj->netobj_netname) {
124 /* accumulate on the group head */
125 if (!ghead->netobj_netname)
126 ghead->netobj_netname = obj->netobj_netname;
127 else if (strcmp(ghead->netobj_netname, obj->netobj_netname)) {
128 fprintf(stderr,
129 "%s: line %d: Tjoin connects two netnames: %s and %s\n",
130 schem->orig_filename, obj->obj_lineno,
131 ghead->netobj_netname, obj->netobj_netname);
132 severe_err = -1;
133 return;
134 }
135 }
136 /* shuffling around to bring groups together */
137 prevobj = obj->obj_prev;
138 if (prevobj->obj_type != OBJTYPE_GRAPHNET ||
139 prevobj->netobj_grouphead != ghead) {
140 prevobj = find_grouphead_tail(ghead);
141 schemobj_unlink(obj);
142 schemobj_insert_after(prevobj, obj);
143 }
144 }
145
146 static
147 preen_pin(obj, netpt)
148 struct schemobj *obj;
149 register struct netpoint *netpt;
150 {
151 register int i = 0, c;
152 struct graphsym_pininst *pinc, *pinn;
153 struct schemobj *comp;
154 char *soughtpin;
155 int bynum;
156
157 if (netpt->netpt_coord_valid) {
158 i |= 2;
159 pinc = find_pin_by_coord(schem_being_preened, netpt->netpt_x,
160 netpt->netpt_y);
161 }
162 if (netpt->netpt_pin_nameref) {
163 i |= 1;
164 c = parse_pin_nameref(schem_being_preened, obj->obj_lineno,
165 netpt->netpt_pin_nameref, &comp,
166 &soughtpin, &bynum);
167 if (c < 0)
168 severe_err = -1;
169 }
170 switch (i) {
171 case 1:
172 if (dowarn)
173 fprintf(stderr,
174 "%s: line %d: Pin w/o coordinates, run uschem-rewrite -g to fix\n",
175 schem_being_preened->orig_filename,
176 obj->obj_lineno);
177 if (c < 0)
178 return;
179 if (!comp->compobj_isgraph) {
180 nograph: fprintf(stderr,
181 "%s: line %d: %s: GraphNet refers to a non-graphical component\n",
182 schem_being_preened->orig_filename,
183 obj->obj_lineno, netpt->netpt_pin_nameref);
184 severe_err = -1;
185 return;
186 }
187 pinn = find_comp_pininst(comp, soughtpin, bynum);
188 if (!pinn) {
189 pinnotfound: fprintf(stderr, "%s: line %d: %s: pin not found\n",
190 schem_being_preened->orig_filename,
191 obj->obj_lineno, netpt->netpt_pin_nameref);
192 severe_err = -1;
193 return;
194 }
195 /* fix it */
196 netpt->netpt_x = pinn->x;
197 netpt->netpt_y = pinn->y;
198 netpt->netpt_coord_valid = 1;
199 return;
200 case 2:
201 if (dowarn)
202 fprintf(stderr,
203 "%s: line %d: Pin given by coordinates only, run uschem-rewrite -g to fix\n",
204 schem_being_preened->orig_filename,
205 obj->obj_lineno);
206 if (!pinc) {
207 fprintf(stderr,
208 "%s: line %d: no pin found at (%d,%d)\n",
209 schem_being_preened->orig_filename,
210 obj->obj_lineno, netpt->netpt_x,
211 netpt->netpt_y);
212 severe_err = -1;
213 return;
214 }
215 comp = pinc->compinst;
216 if (comp->obj_type != OBJTYPE_COMPINST) {
217 fprintf(stderr,
218 "%s: line %d: Pin refers to a non-component\n",
219 schem_being_preened->orig_filename,
220 obj->obj_lineno);
221 severe_err = -1;
222 return;
223 }
224 if (!docorrect)
225 return;
226 if (pinc->pindef->gspd_pinname) {
227 soughtpin = pinc->pindef->gspd_pinname;
228 bynum = 0;
229 } else if (pinc->pindef->gspd_pinnumber) {
230 soughtpin = pinc->pindef->gspd_pinnumber;
231 bynum = 1;
232 } else {
233 fprintf(stderr,
234 "%s: %s pin at (%d,%d) has no pinname or pinnumber attribute\n",
235 schem_being_preened->orig_filename,
236 comp->compobj_instname, netpt->netpt_x,
237 netpt->netpt_y);
238 severe_err = -1;
239 return;
240 }
241 netpt->netpt_pin_nameref =
242 malloc(strlen(comp->compobj_instname) +
243 strlen(soughtpin) + 2);
244 if (!netpt->netpt_pin_nameref) {
245 perror("malloc");
246 exit(1);
247 }
248 sprintf(netpt->netpt_pin_nameref, "%s%c%s",
249 comp->compobj_instname, bynum ? '-' : '.', soughtpin);
250 return;
251 case 3:
252 if (!dowarn || c < 0)
253 return;
254 if (!comp->compobj_isgraph)
255 goto nograph;
256 pinn = find_comp_pininst(comp, soughtpin, bynum);
257 if (!pinn)
258 goto pinnotfound;
259 if (pinc != pinn)
260 fprintf(stderr,
261 "%s: line %d: Pin(%d,%d)=%s: pin name and coordinates don't match\n",
262 schem_being_preened->orig_filename,
263 obj->obj_lineno, netpt->netpt_x, netpt->netpt_y,
264 netpt->netpt_pin_nameref);
265 return;
266 }
267 }
268
269 static
270 preen_pseudopin(obj, netpt)
271 struct schemobj *obj;
272 register struct netpoint *netpt;
273 {
274 register struct graphsym_pininst *pin;
275 register struct schemobj *ghead;
276
277 pin = find_pin_by_coord(schem_being_preened, netpt->netpt_x,
278 netpt->netpt_y);
279 if (!pin) {
280 fprintf(stderr, "%s: line %d: no pin found at (%d,%d)\n",
281 schem_being_preened->orig_filename, obj->obj_lineno,
282 netpt->netpt_x, netpt->netpt_y);
283 severe_err = -1;
284 return;
285 }
286 if (pin->compinst->obj_type != OBJTYPE_GRAPHSYM) {
287 fprintf(stderr,
288 "%s: line %d: Pseudo refers to a real component pin (use Pin instead)\n",
289 schem_being_preened->orig_filename, obj->obj_lineno);
290 severe_err = -1;
291 return;
292 }
293 if (!pin->pindef->gspd_forcenet)
294 return;
295 obj->netobj_forcenets++;
296 ghead = obj->netobj_grouphead;
297 if (!ghead)
298 ghead = obj;
299 if (!ghead->netobj_netname) {
300 if (dowarn)
301 fprintf(stderr,
302 "%s: line %d: GraphNet needs to be forced to net %s (run uschem-rewrite -g to fix)\n",
303 schem_being_preened->orig_filename,
304 obj->obj_lineno, pin->pindef->gspd_forcenet);
305 if (docorrect)
306 ghead->netobj_netname = pin->pindef->gspd_forcenet;
307 } else if (strcmp(ghead->netobj_netname, pin->pindef->gspd_forcenet)) {
308 fprintf(stderr,
309 "%s: line %d: Graphnet %s is forced to net %s by a special symbol connection\n",
310 schem_being_preened->orig_filename, obj->obj_lineno,
311 ghead->netobj_netname, pin->pindef->gspd_forcenet);
312 severe_err = -1;
313 }
314 }
315
316 static
317 do_graphnet(obj, do_tjoin, do_pins)
318 struct schemobj *obj;
319 {
320 register struct netpoint *netpt;
321 register int first;
322 int got_tjoin = 0;
323
324 if (do_tjoin)
325 obj->netobj_grouphead = obj; /* for now at least */
326 for (netpt = obj->netobj_points, first = 1; netpt;
327 netpt = netpt->netpt_next, first = 0) {
328 if (dowarn && first && !netpt->netpt_next)
329 fprintf(stderr, "%s: line %d: singular GraphNet\n",
330 schem_being_preened->orig_filename,
331 obj->obj_lineno);
332 switch (netpt->netpt_type) {
333 case NETPT_TYPE_TJOIN:
334 if (do_tjoin)
335 preen_tjoin(obj, netpt, first, &got_tjoin);
336 continue;
337 case NETPT_TYPE_PIN:
338 if (do_pins)
339 preen_pin(obj, netpt);
340 continue;
341 case NETPT_TYPE_PSEUDO:
342 if (do_pins)
343 preen_pseudopin(obj, netpt);
344 continue;
345 }
346 }
347 }
348
349 preen_graphnets(schem, do_tjoin, do_pins, warn, correct)
350 struct schem *schem;
351 {
352 register struct schemobj *obj, *next;
353
354 schem_being_preened = schem;
355 dowarn = warn;
356 docorrect = correct;
357 severe_err = 0;
358 for (obj = schem->obj_next; obj != (struct schemobj *)schem;
359 obj = next) {
360 next = obj->obj_next;
361 if (obj->obj_type == OBJTYPE_GRAPHNET)
362 do_graphnet(obj, do_tjoin, do_pins);
363 }
364 return(severe_err);
365 }