Expose permanent debugging code to the C compiler.
[geda-gaf/berndj.git] / gnetlist / src / s_hierarchy.c
blob71f26089bd584598081d803efa7cdeea776b7118
1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 #include <config.h>
23 #include <stdio.h>
24 #include <math.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 #ifdef HAVE_STRINGS_H
29 #include <strings.h>
30 #endif
32 #include <libgeda/libgeda.h>
34 #include "../include/globals.h"
35 #include "../include/prototype.h"
37 #ifdef HAVE_LIBDMALLOC
38 #include <dmalloc.h>
39 #endif
41 void
42 s_hierarchy_traverse(TOPLEVEL * pr_current, OBJECT * o_current,
43 NETLIST * netlist)
45 char *attrib;
46 int page_control=-1;
47 PAGE *p_current;
48 int count = 0;
49 int pcount = 0;
50 int looking_inside = FALSE;
51 int loaded_flag = FALSE;
52 char *current_filename;
53 int graphical=FALSE;
55 attrib = o_attrib_search_name_single_count(o_current, "source", 0);
57 /* if above is null, then look inside symbol */
58 if (attrib == NULL) {
59 attrib = o_attrib_search_object(o_current, "source", count);
61 looking_inside = TRUE;
62 if (GEDA_DEBUG) {
63 printf("going to look inside now\n");
67 graphical = s_hierarchy_graphical_search(o_current, count);
68 if (graphical) {
69 /* Do not bother traversing the hierarchy if the symbol has an */
70 /* graphical attribute attached to it. */
71 if (attrib) {
72 g_free(attrib);
73 attrib = NULL;
77 while (attrib) {
78 /* look for source=filename,filename, ... */
79 pcount = 0;
80 current_filename = u_basic_breakup_string(attrib, ',', pcount);
82 /* loop over all filenames */
83 while (current_filename != NULL) {
84 s_log_message("Going to traverse source [%s]\n",
85 current_filename);
87 /* guts here */
88 /* guts for a single filename */
89 p_current = pr_current->page_current;
90 if (GEDA_DEBUG) {
91 printf("Going down %s\n", current_filename);
93 page_control =
94 s_hierarchy_down_schematic_single(pr_current,
95 current_filename,
96 pr_current->page_current,
97 page_control,
98 HIERARCHY_FORCE_LOAD);
100 if (page_control == -1) {
101 fprintf(stderr, "Could not open [%s]\n", current_filename);
102 } else {
103 loaded_flag = TRUE;
105 verbose_print("v\n");
106 verbose_reset_index();
108 netlist->composite_component = TRUE;
109 /* can't do the following, don't know why... HACK TODO */
110 /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/
111 s_traverse_sheet(pr_current,
112 pr_current->page_current,
113 netlist->component_uref);
115 verbose_print("^");
118 /* XXX Does this require s_toplevel_goto_page to get the right cwd? */
119 pr_current->page_current = p_current;
121 g_free(current_filename);
122 pcount++;
123 current_filename = u_basic_breakup_string(attrib, ',', pcount);
126 g_free(attrib);
128 g_free(current_filename);
130 count++;
132 /* continue looking outside first */
133 if (!looking_inside) {
134 attrib =
135 o_attrib_search_name_single_count(o_current, "source",
136 count);
139 /* okay we were looking outside and didn't */
140 /* find anything, so now we need to look */
141 /* inside the symbol */
142 if (!looking_inside && attrib == NULL && !loaded_flag) {
143 looking_inside = TRUE;
144 if (GEDA_DEBUG) {
145 printf("switching to go to look inside\n");
149 if (looking_inside) {
150 if (GEDA_DEBUG) {
151 printf("looking inside\n");
153 attrib = o_attrib_search_object(o_current, "source", count);
156 graphical = s_hierarchy_graphical_search(o_current, count);
157 if (graphical) {
158 /* Do not bother looking further in the hierarchy if the symbol */
159 /* has an graphical attribute attached to it. */
160 if (attrib) {
161 g_free(attrib);
162 attrib = NULL;
169 void s_hierarchy_post_process(TOPLEVEL * pr_current, NETLIST * head)
171 NETLIST *nl_current;
172 CPINLIST *pl_current;
173 char *source_net_name = NULL;
174 int did_work = FALSE;
176 s_rename_next_set();
178 nl_current = head;
179 while (nl_current != NULL) {
180 if (nl_current->composite_component) {
181 if (GEDA_DEBUG) {
182 printf("Found composite %s\n", nl_current->component_uref);
185 if (nl_current->cpins) {
186 pl_current = nl_current->cpins;
188 while (pl_current != NULL) {
189 if (pl_current->plid != -1) {
190 verbose_print("p");
193 if (pl_current->pin_label == NULL
194 && pl_current->plid != -1) {
195 fprintf(stderr,
196 "Found a pin [%s] on component [%s] which does not have a label!\n",
197 nl_current->component_uref,
198 pl_current->pin_number);
199 } else if (pl_current->plid != -1) {
200 if (GEDA_DEBUG) {
201 printf("# L: %s %s\n", pl_current->pin_number,
202 pl_current->pin_label);
204 /* get source net name, all nets are named already */
205 source_net_name =
206 s_net_name_search(pr_current,
207 pl_current->nets);
208 if (GEDA_DEBUG) {
209 printf("name: %s\n", source_net_name);
210 printf("Now we need to search for: %s/%s\n",
211 nl_current->component_uref,
212 pl_current->pin_label);
215 did_work =
216 s_hierarchy_setup_rename(pr_current, head,
217 nl_current->component_uref,
218 pl_current->pin_label,
219 source_net_name);
220 if (!did_work) {
221 fprintf(stderr,
222 "Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n",
223 pl_current->pin_label,
224 nl_current->component_uref);
228 pl_current = pl_current->next;
232 nl_current = nl_current->next;
235 s_rename_all(pr_current, head);
236 s_hierarchy_remove_compsite_all(head);
240 s_hierarchy_setup_rename(TOPLEVEL * pr_current, NETLIST * head, char *uref,
241 char *label, char *new_name)
243 NETLIST *nl_current;
244 CPINLIST *pl_current;
245 char *wanted_uref = NULL;
246 int did_work = FALSE;
248 /* this is questionable, because I'm not sure if it's exactly the */
249 /* same as the #if 0'ed out line */
250 /* search for the uref which has the name: label/uref (or whatever the */
251 /* hierarchy tag/separator order is) */
252 wanted_uref = s_hierarchy_create_uref(pr_current, label, uref);
254 if (GEDA_DEBUG) {
255 printf("label: %s, uref: %s, wanted_uref: %s\n", label, uref,
256 wanted_uref);
259 nl_current = head;
260 while (nl_current != NULL) {
261 if (nl_current->component_uref) {
262 pl_current = nl_current->cpins;
263 if (strcmp(nl_current->component_uref, wanted_uref) == 0) {
264 if (nl_current->cpins) {
265 /* skip over head of special io symbol */
266 pl_current = nl_current->cpins->next;;
267 if (GEDA_DEBUG) {
268 printf("net to be renamed: %s\n",
269 pl_current->net_name);
270 printf("%s -> %s\n", pl_current->net_name, new_name);
272 s_rename_add(pl_current->net_name, new_name);
274 if (GEDA_DEBUG) {
275 printf("Going to remove %s\n",
276 nl_current->component_uref);
278 s_hierarchy_remove_urefconn(head,
279 nl_current->
280 component_uref);
281 did_work = TRUE;
285 nl_current = nl_current->next;
288 return (did_work);
291 void s_hierarchy_remove_urefconn(NETLIST * head, char *uref_disable)
293 NETLIST *nl_current;
294 CPINLIST *pl_current;
295 NET *n_current;
296 char uref[80], pin[10];
298 nl_current = head;
299 while (nl_current != NULL) {
300 pl_current = nl_current->cpins;
301 while (pl_current != NULL) {
302 n_current = pl_current->nets;
303 while (n_current != NULL) {
304 if (n_current->connected_to != NULL) {
305 sscanf(n_current->connected_to, "%s %s", uref, pin);
306 if (GEDA_DEBUG) {
307 printf(" looking at : %s %s\n", uref, pin);
309 if (strcmp(uref_disable, uref) == 0) {
310 if (GEDA_DEBUG) {
311 printf("conn disabling %s\n",
312 n_current->connected_to);
314 /* can't do frees, since some names are links */
315 /* g_free(n_current->connected_to); */
316 n_current->connected_to = NULL;
319 n_current = n_current->next;
322 pl_current = pl_current->next;
325 if (nl_current->component_uref) {
326 if (strcmp(nl_current->component_uref, uref_disable) == 0) {
327 if (GEDA_DEBUG) {
328 printf("refdes disabling: %s\n", nl_current->component_uref);
330 /* can't do frees, since some names are links */
331 /*free(nl_current->component_uref); */
332 nl_current->component_uref = NULL;
335 nl_current = nl_current->next;
339 void s_hierarchy_remove_compsite_all(NETLIST * head)
341 NETLIST *nl_current;
343 nl_current = head;
344 while (nl_current != NULL) {
345 if (nl_current->composite_component) {
346 if (nl_current->component_uref != NULL) {
347 s_hierarchy_remove_urefconn(head,
348 nl_current->component_uref);
351 nl_current = nl_current->next;
355 char *s_hierarchy_create_uref(TOPLEVEL * pr_current, char *basename,
356 char const *hierarchy_tag)
358 char *return_value = NULL;
360 if (hierarchy_tag) {
361 if (basename) {
363 if (pr_current->hierarchy_uref_separator) {
364 switch (pr_current->hierarchy_uref_order) {
365 case (APPEND):
366 return_value =
367 g_strconcat (hierarchy_tag,
368 pr_current->hierarchy_uref_separator,
369 basename, NULL);
370 break;
371 case (PREPEND):
372 return_value =
373 g_strconcat (basename,
374 pr_current->hierarchy_uref_separator,
375 hierarchy_tag, NULL);
377 break;
379 } else {
380 switch (pr_current->hierarchy_uref_order) {
381 case (APPEND):
382 return_value =
383 g_strconcat (hierarchy_tag, basename, NULL);
384 break;
385 case (PREPEND):
386 return_value =
387 g_strconcat (basename, hierarchy_tag, NULL);
388 break;
392 } else {
393 return_value = NULL;
395 } else {
396 if (basename) {
397 return_value = g_strdup (basename);
398 } else {
399 return_value = NULL;
403 return (return_value);
406 char *s_hierarchy_create_netname(TOPLEVEL * pr_current, char *basename,
407 char const *hierarchy_tag)
409 char *return_value = NULL;
411 if (pr_current->hierarchy_netname_mangle == FALSE) {
412 if (basename) {
413 return (g_strdup (basename));
414 } else {
415 return (NULL);
419 if (hierarchy_tag) {
420 if (basename) {
421 if (pr_current->hierarchy_netname_separator) {
422 switch (pr_current->hierarchy_netname_order) {
423 case (APPEND):
424 return_value =
425 g_strconcat (hierarchy_tag,
426 pr_current->hierarchy_netname_separator,
427 basename, NULL);
428 break;
430 case (PREPEND):
431 return_value =
432 g_strconcat (basename,
433 pr_current->hierarchy_netname_separator,
434 hierarchy_tag, NULL);
435 break;
437 } else {
438 switch (pr_current->hierarchy_netname_order) {
439 case (APPEND):
440 return_value =
441 g_strconcat (hierarchy_tag, basename, NULL);
442 break;
443 case (PREPEND):
444 return_value =
445 g_strconcat (basename, hierarchy_tag, NULL);
446 break;
449 } else {
450 return_value = NULL;
452 } else {
453 if (basename) {
454 return_value = g_strdup (basename);
455 } else {
456 return_value = NULL;
460 return (return_value);
463 char *s_hierarchy_create_netattrib(TOPLEVEL * pr_current, char *basename,
464 char const *hierarchy_tag)
466 char *return_value = NULL;
468 if (pr_current->hierarchy_netattrib_mangle == FALSE) {
469 if (basename) {
470 return (g_strdup (basename));
471 } else {
472 return (NULL);
476 if (hierarchy_tag) {
477 if (basename) {
478 if (pr_current->hierarchy_netattrib_separator) {
479 switch (pr_current->hierarchy_netattrib_order) {
480 case (APPEND):
481 return_value =
482 g_strconcat (hierarchy_tag,
483 pr_current->hierarchy_netattrib_separator,
484 basename, NULL);
485 break;
486 case (PREPEND):
487 return_value =
488 g_strconcat (basename,
489 pr_current->hierarchy_netattrib_separator,
490 hierarchy_tag, NULL);
492 break;
494 } else {
495 switch (pr_current->hierarchy_netattrib_order) {
496 case (APPEND):
497 return_value =
498 g_strconcat (hierarchy_tag, basename, NULL);
499 case (PREPEND):
500 return_value =
501 g_strconcat (basename, hierarchy_tag, NULL);
502 break;
505 } else {
506 return_value = NULL;
508 } else {
509 if (basename) {
510 return_value = g_strdup (basename);
511 } else {
512 return_value = NULL;
516 return (return_value);
519 void
520 s_hierarchy_remove_uref_mangling(TOPLEVEL * pr_current, NETLIST * head)
522 NETLIST *nl_current;
523 CPINLIST *pl_current;
524 NET *n_current;
525 char uref[80], pin[10];
526 char *new_uref = NULL;
527 char *new_connected_to = NULL;
529 nl_current = head;
530 while (nl_current != NULL) {
532 if (nl_current->component_uref) {
533 verbose_print("u");
534 new_uref =
535 s_hierarchy_return_baseuref(pr_current,
536 nl_current->component_uref);
537 g_free(nl_current->component_uref);
538 nl_current->component_uref = new_uref;
541 pl_current = nl_current->cpins;
543 while (pl_current != NULL) {
544 n_current = pl_current->nets;
545 while (n_current != NULL) {
547 if (n_current->connected_to) {
548 verbose_print("U");
549 sscanf(n_current->connected_to, "%s %s", uref, pin);
550 new_uref =
551 s_hierarchy_return_baseuref(pr_current, uref);
552 new_connected_to = g_strdup_printf("%s %s", new_uref, pin);
553 g_free(n_current->connected_to);
554 n_current->connected_to = new_connected_to;
556 n_current = n_current->next;
559 pl_current = pl_current->next;
561 nl_current = nl_current->next;
565 char *s_hierarchy_return_baseuref(TOPLEVEL * pr_current, char *uref)
567 char *return_value = NULL;
568 char *start_of_base = NULL;
569 char *end_of_base = NULL;
571 /* use hierarchy separator */
573 if (uref == NULL) {
574 return (NULL);
576 if (GEDA_DEBUG) {
577 printf("Got uref: _%s_\n", uref);
580 if (pr_current->hierarchy_uref_order == APPEND) {
581 start_of_base = strrchr(uref, '/'); /* separator is always '/' */
583 if (start_of_base == NULL) {
584 return (g_strdup (uref));
587 return_value = g_strdup (start_of_base + 1);
588 } else if (pr_current->hierarchy_uref_order == PREPEND) {
589 end_of_base = strchr(uref, '/');
591 if (end_of_base == NULL) {
592 return (g_strdup (uref));
595 return_value = g_strndup(uref, end_of_base - uref);
598 if (GEDA_DEBUG) {
599 printf("new uref return_value = %s\n\n\n", return_value);
602 return (return_value);
605 int
606 s_hierarchy_graphical_search(OBJECT* o_current, int count)
608 char *graphical_attrib;
609 graphical_attrib = o_attrib_search_name_single_count(o_current,
610 "graphical", count);
612 if (graphical_attrib == NULL) {
613 graphical_attrib = o_attrib_search_object(o_current, "graphical", count);
616 if (graphical_attrib) {
617 g_free(graphical_attrib);
618 return TRUE;
621 return FALSE;