Fixed offset in o_complex_translate_all to be relative to bottom left of world bounds.
[geda-gaf/werner.git] / gnetlist / src / s_traverse.c
blobeccb69c65f95d3a06bcfc9d22bdcd9df326a6b64
1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2000 Ales V. Hvezda
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 #include <config.h>
22 #include <stdio.h>
23 #ifdef HAVE_STRING_H
24 #include <string.h>
25 #endif
26 #include <math.h>
28 #include <libgeda/libgeda.h>
30 #include "../include/globals.h"
31 #include "../include/prototype.h"
33 #ifdef HAVE_LIBDMALLOC
34 #include <dmalloc.h>
35 #endif
37 void s_traverse_init(void)
39 netlist_head = s_netlist_add(NULL);
40 netlist_head->nlid = -1; /* head node */
42 graphical_netlist_head = s_netlist_add(NULL);
43 graphical_netlist_head->nlid = -1; /* head node */
45 if (verbose_mode) {
46 printf
47 ("\n\n------------------------------------------------------\n");
48 printf("Verbose mode legend\n\n");
49 printf("n : Found net\n");
50 printf("C : Found component (staring to traverse component)\n");
51 printf
52 ("p : Found pin (starting to traverse pin / or examining pin)\n");
53 printf("P : Found end pin connection (end of this net)\n");
54 printf("R : Starting to rename a net\n");
55 printf("v : Found source attribute, traversing down\n");
56 printf("^ : Finished underlying source, going back up\n");
57 printf("u : Found a refdes which needs to be demangle\n");
58 printf
59 ("U : Found a connected_to refdes which needs to be demangle\n");
60 printf
61 ("------------------------------------------------------\n\n");
66 void s_traverse_start(TOPLEVEL * pr_current)
68 PAGE *p_current;
70 p_current = pr_current->page_head;
72 while (p_current != NULL) {
73 if (p_current->pid != -1) {
75 /* only traverse pages which are toplevel, ie not underneath */
76 if (p_current->object_head && p_current->page_control == 0) {
77 pr_current->page_current = p_current;
78 s_traverse_sheet(pr_current, p_current->object_head, NULL);
83 p_current = p_current->next;
86 /* now that all the sheets have been read, go through and do the */
87 /* post processing work */
88 s_netlist_post_process(pr_current, netlist_head);
90 /* Now match the graphical netlist with the net names already assigned */
91 s_netlist_name_named_nets(pr_current, netlist_head,
92 graphical_netlist_head);
94 if (verbose_mode) {
95 printf("\nInternal netlist representation:\n\n");
96 s_netlist_print(netlist_head);
101 void
102 s_traverse_sheet(TOPLEVEL * pr_current, OBJECT * start,
103 char *hierarchy_tag)
105 OBJECT *o_current;
106 NETLIST *netlist;
107 char *temp;
108 char *temp_uref;
109 gboolean is_graphical=FALSE;
111 if (verbose_mode) {
112 printf("- Starting internal netlist creation\n");
115 o_current = start;
117 while (o_current != NULL) {
119 netlist = s_netlist_return_tail(netlist_head);
121 if (o_current->type == OBJ_PLACEHOLDER) {
122 printf("WARNING: Found a placeholder/missing component, are you missing a symbol file? [%s]\n", o_current->complex_basename);
125 if (o_current->type == OBJ_COMPLEX) {
127 #if DEBUG
128 printf("starting NEW component\n\n");
129 #endif
131 verbose_print(" C");
133 /* look for special tag */
134 temp = o_attrib_search_component(o_current, "graphical");
135 if (temp) {
136 /* traverse graphical elements, but adding them to the
137 graphical netlist */
138 g_free(temp);
140 netlist = s_netlist_return_tail(graphical_netlist_head);
141 is_graphical = TRUE;
145 netlist = s_netlist_add(netlist);
146 netlist->nlid = o_current->sid;
148 /* search the single object only.... */
149 temp_uref =
150 o_attrib_search_name_single(o_current, "refdes", NULL);
152 if (!temp_uref) {
153 temp_uref =
154 o_attrib_search_name_single(o_current, "uref", NULL); /* deprecated */
156 if (temp_uref) {
157 printf("WARNING: Found uref=%s, uref= is deprecated, please use refdes=\n", temp_uref);
161 if (temp_uref) {
162 netlist->component_uref =
163 s_hierarchy_create_uref(pr_current, temp_uref,
164 hierarchy_tag);
165 } else {
166 netlist->component_uref = NULL;
169 if (hierarchy_tag) {
170 netlist->hierarchy_tag = g_strdup (hierarchy_tag);
173 if (temp_uref) {
174 g_free(temp_uref);
177 netlist->object_ptr = o_current;
179 if (!netlist->component_uref) {
181 /* search of net attribute */
182 /* maybe symbol is not a component */
183 /* but a power / gnd symbol */
184 temp =
185 o_attrib_search_name(o_current->complex->prim_objs,
186 "net", 0);
188 /* nope net attribute not found */
189 if ( (!temp) && (!is_graphical) ) {
191 fprintf(stderr,
192 "Could not find refdes on component and could not find any special attributes!\n");
194 netlist->component_uref =
195 (char *) g_malloc(sizeof(char) * strlen("U?") +
197 strcpy(netlist->component_uref, "U?");
198 } else {
200 #if DEBUG
201 printf("yeah... found a power symbol\n");
202 #endif
203 /* it's a power or some other special symbol */
204 netlist->component_uref = NULL;
205 g_free(temp);
210 netlist->cpins =
211 s_traverse_component(pr_current, o_current,
212 hierarchy_tag);
214 /* here is where you deal with the */
215 /* net attribute */
216 s_netattrib_handle(pr_current, o_current, netlist,
217 hierarchy_tag);
219 /* now you need to traverse any underlying schematics */
220 if (pr_current->hierarchy_traversal == TRUE) {
221 s_hierarchy_traverse(pr_current, o_current, netlist);
225 o_current = o_current->next;
228 verbose_done();
231 CPINLIST *s_traverse_component(TOPLEVEL * pr_current, OBJECT * component,
232 char *hierarchy_tag)
234 CPINLIST *cpinlist_head = NULL;
235 CPINLIST *cpins = NULL;
236 OBJECT *o_current = NULL;
237 NET *nets_head = NULL;
238 NET *nets = NULL;
239 char *temp;
240 CONN *c_current;
241 GList *cl_current;
243 o_current = component->complex->prim_objs;
245 cpinlist_head = cpins = s_cpinlist_add(NULL);
246 cpins->plid = -1;
248 while (o_current != NULL) {
249 if (o_current->type == OBJ_PIN) {
251 verbose_print("p");
253 o_current->visited = 1;
255 /* add cpin node */
256 cpins = s_cpinlist_add(cpins);
257 cpins->plid = o_current->sid;
259 /* search the object only */
260 cpins->pin_number = o_attrib_search_name_single(o_current, "pinnumber",
261 NULL);
263 temp =
264 o_attrib_search_name_single_count(o_current, "pinlabel",
267 if (temp) {
268 cpins->pin_label = temp;
271 /* head nets node */
272 /* is this really need */
273 nets_head = nets = s_net_add(NULL);
274 nets->nid = -1;
277 cl_current = o_current->conn_list;
278 while (cl_current != NULL) {
280 c_current = (CONN *) cl_current->data;
283 if (c_current->other_object != NULL) {
285 #if DEBUG
286 printf("c_current other_object, not NULL\n");
287 #endif
289 if (!c_current->other_object->visited &&
290 c_current->other_object != o_current) {
292 nets = s_net_add(nets);
293 nets->nid = o_current->sid;
295 nets->connected_to =
296 s_net_return_connected_string(pr_current,
297 o_current,
298 hierarchy_tag);
300 /* net= new */
301 if (strstr(nets->connected_to, "POWER")) {
302 #if DEBUG
303 printf("going to find netname %s\n",
304 nets->connected_to);
305 #endif
306 nets->net_name =
307 s_netattrib_return_netname(pr_current,
308 o_current,
309 nets->
310 connected_to,
311 hierarchy_tag);
312 nets->net_name_has_priority = TRUE;
313 g_free(nets->connected_to);
314 nets->connected_to = NULL;
316 #if DEBUG
317 printf("%s\n", nets->connected_to);
318 #endif
319 nets =
320 s_traverse_net(pr_current, o_current, nets,
321 c_current->other_object,
322 hierarchy_tag);
324 s_traverse_clear_all_visited(pr_current->
325 page_current->object_head);
329 cl_current = cl_current->next;
332 cpins->nets = nets_head;
333 /* s_net_print(nets); */
335 /* this is iffy */
336 /* should pass in page_current in top level func */
338 s_traverse_clear_all_visited(pr_current->page_current->
339 object_head);
341 o_current = o_current->next;
345 return (cpinlist_head);
349 void s_traverse_clear_all_visited(OBJECT * object_head)
351 OBJECT *o_current;
353 o_current = object_head;
355 while (o_current != NULL) {
357 #if DEBUG
358 if (o_current->visited) {
359 printf("%s\n", o_current->name);
361 #endif
363 o_current->visited = 0;
365 if (o_current->type == OBJ_COMPLEX
366 && o_current->complex->prim_objs) {
367 s_traverse_clear_all_visited(o_current->complex->prim_objs);
370 o_current = o_current->next;
375 NET *s_traverse_net(TOPLEVEL * pr_current, OBJECT * previous_object,
376 NET * nets, OBJECT * object, char *hierarchy_tag)
378 OBJECT *o_current;
379 NET *new_net;
380 CONN *c_current;
381 GList *cl_current;
382 char *temp;
384 o_current = object;
386 new_net = nets = s_net_add(nets);
387 new_net->nid = object->sid;
389 /* pins are not allowed to have the netname attribute attached to them */
390 if (o_current->type != OBJ_PIN) {
391 temp = o_attrib_search_name_single(o_current, "netname", NULL);
393 if (temp) {
394 new_net->net_name =
395 s_hierarchy_create_netname(pr_current, temp,
396 hierarchy_tag);
397 g_free(temp);
398 } else {
400 /* search for the old label= attribute */
401 temp = o_attrib_search_name_single(o_current, "label", NULL);
402 if (temp) {
403 printf("WARNING: Found label=%s. label= is deprecated, please use netname=\n", temp);
404 new_net->net_name =
405 s_hierarchy_create_netname(pr_current, temp,
406 hierarchy_tag);
407 g_free(temp);
411 #if DEBUG
412 printf("inside traverse: %s\n", object->name);
413 #endif
415 if (object->type == OBJ_PIN) {
417 verbose_print("P");
419 new_net->connected_to =
420 s_net_return_connected_string(pr_current, o_current,
421 hierarchy_tag);
423 temp = o_attrib_search_name_single_count(o_current, "pinlabel", 0);
425 if (temp) {
426 new_net->pin_label = temp;
429 /* net= new */
430 if (strstr(nets->connected_to, "POWER")) {
432 #if DEBUG
433 printf("going to find netname %s \n", nets->connected_to);
434 #endif
435 nets->net_name =
436 s_netattrib_return_netname(pr_current, o_current,
437 nets->connected_to,
438 hierarchy_tag);
439 nets->net_name_has_priority = TRUE;
440 g_free(nets->connected_to);
441 nets->connected_to = NULL;
443 #if DEBUG
444 printf("traverse connected_to: %s\n", new_net->connected_to);
445 #endif
446 return (nets);
450 /*printf("Found net %s\n", object->name); */
451 verbose_print("n");
453 object->visited++;
455 /* this is not perfect yet and won't detect a loop... */
456 if (object->visited > 100) {
457 fprintf(stderr, "Found a possible net/pin infinite connection\n");
458 exit(-1);
461 cl_current = object->conn_list;
462 while (cl_current != NULL) {
464 c_current = (CONN *) cl_current->data;
466 if (c_current->other_object != NULL) {
468 #if DEBUG
469 printf("c_current %s visited: %d\n",
470 c_current->other_object->name,
471 c_current->other_object->visited);
472 #endif
474 if (!c_current->other_object->visited &&
475 c_current->other_object != o_current &&
476 c_current->other_object->type != OBJ_BUS) {
478 nets =
479 s_traverse_net(pr_current, object, nets,
480 c_current->other_object, hierarchy_tag);
484 cl_current = cl_current->next;
487 return (nets);