Fix for Bug#1776547: graphical versus source
[geda-gaf/peter-b.git] / gnetlist / src / s_hierarchy.c
blobcc29d7d1326ff18ff7582d812aa0814925753ebe
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_name(o_current->complex->prim_objs,
60 "source", count);
62 looking_inside = TRUE;
63 #if DEBUG
64 printf("going to look inside now\n");
65 #endif
68 graphical = s_hierarchy_graphical_search(o_current, count);
69 if (graphical) {
70 /* Do not bother traversing the hierarchy if the symbol has an */
71 /* graphical attribute attached to it. */
72 if (attrib) {
73 g_free(attrib);
74 attrib = NULL;
78 while (attrib) {
80 /* look for source=filename,filename, ... */
81 pcount = 0;
82 current_filename = u_basic_breakup_string(attrib, ',', pcount);
84 /* loop over all filenames */
85 while (current_filename != NULL) {
87 s_log_message("Going to traverse source [%s]\n",
88 current_filename);
90 /* guts here */
91 /* guts for a single filename */
92 p_current = pr_current->page_current;
93 #if DEBUG
94 printf("Going down %s\n", current_filename);
95 #endif
96 page_control =
97 s_hierarchy_down_schematic_single(pr_current,
98 current_filename,
99 pr_current->page_current,
100 page_control,
101 HIERARCHY_FORCE_LOAD);
103 if (page_control == -1) {
104 fprintf(stderr, "Could not open [%s]\n", current_filename);
105 } else {
107 loaded_flag = TRUE;
109 verbose_print("v\n");
110 verbose_reset_index();
112 netlist->composite_component = TRUE;
113 /* can't do the following, don't know why... HACK TODO */
114 /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/
115 s_traverse_sheet(pr_current,
116 pr_current->page_current->object_head,
117 netlist->component_uref);
119 verbose_print("^");
122 pr_current->page_current = p_current;
124 g_free(current_filename);
125 pcount++;
126 current_filename = u_basic_breakup_string(attrib, ',', pcount);
129 if (attrib) {
130 g_free(attrib);
133 if (current_filename) {
134 g_free(current_filename);
137 count++;
139 /* continue looking outside first */
140 if (!looking_inside) {
141 attrib =
142 o_attrib_search_name_single_count(o_current, "source",
143 count);
146 /* okay we were looking outside and didn't */
147 /* find anything, so now we need to look */
148 /* inside the symbol */
149 if (!looking_inside && attrib == NULL && !loaded_flag) {
150 looking_inside = TRUE;
151 #if DEBUG
152 printf("switching to go to look inside\n");
153 #endif
156 if (looking_inside) {
157 #if DEBUG
158 printf("looking inside\n");
159 #endif
160 attrib = o_attrib_search_name(o_current->complex->prim_objs,
161 "source", count);
164 graphical = s_hierarchy_graphical_search(o_current, count);
165 if (graphical) {
166 /* Do not bother looking further in the hierarchy if the symbol */
167 /* has an graphical attribute attached to it. */
168 if (attrib) {
169 g_free(attrib);
170 attrib = NULL;
177 void s_hierarchy_post_process(TOPLEVEL * pr_current, NETLIST * head)
179 NETLIST *nl_current;
180 CPINLIST *pl_current;
181 char *source_net_name = NULL;
182 int did_work = FALSE;
184 s_rename_next_set();
186 nl_current = head;
187 while (nl_current != NULL) {
188 if (nl_current->composite_component) {
189 #if DEBUG
190 printf("Found composite %s\n", nl_current->component_uref);
191 #endif
193 if (nl_current->cpins) {
194 pl_current = nl_current->cpins;
196 while (pl_current != NULL) {
198 if (pl_current->plid != -1) {
199 verbose_print("p");
202 if (pl_current->pin_label == NULL
203 && pl_current->plid != -1) {
204 fprintf(stderr,
205 "Found a pin [%s] on component [%s] which does not have a label!\n",
206 nl_current->component_uref,
207 pl_current->pin_number);
208 } else if (pl_current->plid != -1) {
210 #if DEBUG
211 printf("# L: %s %s\n", pl_current->pin_number,
212 pl_current->pin_label);
213 #endif
214 /* get source net name, all nets are named already */
215 source_net_name =
216 s_net_name_search(pr_current,
217 pl_current->nets);
218 #if DEBUG
219 printf("name: %s\n", source_net_name);
220 printf("Now we need to search for: %s/%s\n",
221 nl_current->component_uref,
222 pl_current->pin_label);
223 #endif
225 did_work =
226 s_hierarchy_setup_rename(pr_current, head,
227 nl_current->component_uref,
228 pl_current->pin_label,
229 source_net_name);
230 if (!did_work) {
231 fprintf(stderr,
232 "Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n",
233 pl_current->pin_label,
234 nl_current->component_uref);
238 pl_current = pl_current->next;
242 nl_current = nl_current->next;
245 s_rename_all(pr_current, head);
246 s_hierarchy_remove_compsite_all(head);
250 s_hierarchy_setup_rename(TOPLEVEL * pr_current, NETLIST * head, char *uref,
251 char *label, char *new_name)
253 NETLIST *nl_current;
254 CPINLIST *pl_current;
255 char *wanted_uref = NULL;
256 int did_work = FALSE;
258 /* this is questionable, because I'm not sure if it's exactly the */
259 /* same as the #if 0'ed out line */
260 /* search for the uref which has the name: label/uref (or whatever the */
261 /* hierarchy tag/separator order is) */
262 wanted_uref = s_hierarchy_create_uref(pr_current, label, uref);
264 #if DEBUG
265 printf("label: %s, uref: %s, wanted_uref: %s\n", label, uref,
266 wanted_uref);
267 #endif
269 nl_current = head;
270 while (nl_current != NULL) {
271 if (nl_current->component_uref) {
272 pl_current = nl_current->cpins;
273 if (strcmp(nl_current->component_uref, wanted_uref) == 0) {
274 if (nl_current->cpins) {
275 /* skip over head of special io symbol */
276 pl_current = nl_current->cpins->next;;
277 #if DEBUG
278 printf("net to be renamed: %s\n",
279 pl_current->net_name);
280 printf("%s -> %s\n", pl_current->net_name, new_name);
281 #endif
282 s_rename_add(pl_current->net_name, new_name);
284 #if DEBUG
285 printf("Going to remove %s\n",
286 nl_current->component_uref);
287 #endif
288 s_hierarchy_remove_urefconn(head,
289 nl_current->
290 component_uref);
291 did_work = TRUE;
295 nl_current = nl_current->next;
298 return (did_work);
301 void s_hierarchy_remove_urefconn(NETLIST * head, char *uref_disable)
303 NETLIST *nl_current;
304 CPINLIST *pl_current;
305 NET *n_current;
306 char uref[80], pin[10];
308 nl_current = head;
309 while (nl_current != NULL) {
310 pl_current = nl_current->cpins;
311 while (pl_current != NULL) {
312 n_current = pl_current->nets;
313 while (n_current != NULL) {
314 if (n_current->connected_to != NULL) {
315 sscanf(n_current->connected_to, "%s %s", uref, pin);
316 #if DEBUG
317 printf(" looking at : %s %s\n", uref, pin);
318 #endif
319 if (strcmp(uref_disable, uref) == 0) {
320 #if DEBUG
321 printf("conn disabling %s\n",
322 n_current->connected_to);
323 #endif
324 /* can't do frees, since some names are links */
325 /* g_free(n_current->connected_to);*/
326 n_current->connected_to = NULL;
329 n_current = n_current->next;
332 pl_current = pl_current->next;
335 if (nl_current->component_uref) {
336 if (strcmp(nl_current->component_uref, uref_disable) == 0) {
337 #if DEBUG
338 printf("refdes disabling: %s\n", nl_current->component_uref);
339 #endif
340 /* can't do frees, since some names are links */
341 /*free(nl_current->component_uref); */
342 nl_current->component_uref = NULL;
345 nl_current = nl_current->next;
349 void s_hierarchy_remove_compsite_all(NETLIST * head)
351 NETLIST *nl_current;
353 nl_current = head;
354 while (nl_current != NULL) {
355 if (nl_current->composite_component) {
356 if (nl_current->component_uref != NULL) {
357 s_hierarchy_remove_urefconn(head,
358 nl_current->component_uref);
361 nl_current = nl_current->next;
366 char *s_hierarchy_create_uref(TOPLEVEL * pr_current, char *basename,
367 char *hierarchy_tag)
369 char *return_value = NULL;
371 if (hierarchy_tag) {
372 if (basename) {
374 if (pr_current->hierarchy_uref_separator) {
375 switch (pr_current->hierarchy_uref_order) {
376 case (APPEND):
377 return_value =
378 g_strconcat (hierarchy_tag,
379 pr_current->hierarchy_uref_separator,
380 basename, NULL);
381 break;
382 case (PREPEND):
383 return_value =
384 g_strconcat (basename,
385 pr_current->hierarchy_uref_separator,
386 hierarchy_tag, NULL);
388 break;
390 } else {
391 switch (pr_current->hierarchy_uref_order) {
392 case (APPEND):
393 return_value =
394 g_strconcat (hierarchy_tag, basename, NULL);
395 break;
396 case (PREPEND):
397 return_value =
398 g_strconcat (basename, hierarchy_tag, NULL);
399 break;
403 } else {
404 return_value = NULL;
406 } else {
407 if (basename) {
408 return_value = g_strdup (basename);
409 } else {
410 return_value = NULL;
414 return (return_value);
417 char *s_hierarchy_create_netname(TOPLEVEL * pr_current, char *basename,
418 char *hierarchy_tag)
420 char *return_value = NULL;
422 if (pr_current->hierarchy_netname_mangle == FALSE) {
423 if (basename) {
424 return (g_strdup (basename));
425 } else {
426 return (NULL);
430 if (hierarchy_tag) {
431 if (basename) {
433 if (pr_current->hierarchy_netname_separator) {
434 switch (pr_current->hierarchy_netname_order) {
435 case (APPEND):
436 return_value =
437 g_strconcat (hierarchy_tag,
438 pr_current->hierarchy_netname_separator,
439 basename, NULL);
441 break;
443 case (PREPEND):
444 return_value =
445 g_strconcat (basename,
446 pr_current->hierarchy_netname_separator,
447 hierarchy_tag, NULL);
449 break;
452 } else {
453 switch (pr_current->hierarchy_netname_order) {
454 case (APPEND):
456 return_value =
457 g_strconcat (hierarchy_tag, basename, NULL);
458 break;
459 case (PREPEND):
460 return_value =
461 g_strconcat (basename, hierarchy_tag, NULL);
463 break;
467 } else {
468 return_value = NULL;
470 } else {
471 if (basename) {
472 return_value = g_strdup (basename);
473 } else {
474 return_value = NULL;
478 return (return_value);
481 char *s_hierarchy_create_netattrib(TOPLEVEL * pr_current, char *basename,
482 char *hierarchy_tag)
484 char *return_value = NULL;
486 if (pr_current->hierarchy_netattrib_mangle == FALSE) {
487 if (basename) {
488 return (g_strdup (basename));
489 } else {
490 return (NULL);
494 if (hierarchy_tag) {
495 if (basename) {
497 if (pr_current->hierarchy_netattrib_separator) {
498 switch (pr_current->hierarchy_netattrib_order) {
499 case (APPEND):
500 return_value =
501 g_strconcat (hierarchy_tag,
502 pr_current->hierarchy_netattrib_separator,
503 basename, NULL);
504 break;
505 case (PREPEND):
506 return_value =
507 g_strconcat (basename,
508 pr_current->hierarchy_netattrib_separator,
509 hierarchy_tag, NULL);
511 break;
513 } else {
514 switch (pr_current->hierarchy_netattrib_order) {
515 case (APPEND):
516 return_value =
517 g_strconcat (hierarchy_tag, basename, NULL);
518 case (PREPEND):
519 return_value =
520 g_strconcat (basename, hierarchy_tag, NULL);
521 break;
524 } else {
525 return_value = NULL;
527 } else {
528 if (basename) {
529 return_value = g_strdup (basename);
530 } else {
531 return_value = NULL;
535 return (return_value);
538 void
539 s_hierarchy_remove_uref_mangling(TOPLEVEL * pr_current, NETLIST * head)
541 NETLIST *nl_current;
542 CPINLIST *pl_current;
543 NET *n_current;
544 char uref[80], pin[10];
545 char *new_uref = NULL;
546 char *new_connected_to = NULL;
548 nl_current = head;
549 while (nl_current != NULL) {
551 if (nl_current->component_uref) {
552 verbose_print("u");
553 new_uref =
554 s_hierarchy_return_baseuref(pr_current,
555 nl_current->component_uref);
556 g_free(nl_current->component_uref);
557 nl_current->component_uref = new_uref;
560 pl_current = nl_current->cpins;
562 while (pl_current != NULL) {
563 n_current = pl_current->nets;
564 while (n_current != NULL) {
566 if (n_current->connected_to) {
567 verbose_print("U");
568 sscanf(n_current->connected_to, "%s %s", uref, pin);
569 new_uref =
570 s_hierarchy_return_baseuref(pr_current, uref);
571 new_connected_to =
572 g_strdup(n_current->connected_to);
573 sprintf(new_connected_to, "%s %s", new_uref, pin);
574 g_free(n_current->connected_to);
575 n_current->connected_to = new_connected_to;
577 n_current = n_current->next;
580 pl_current = pl_current->next;
582 nl_current = nl_current->next;
587 char *s_hierarchy_return_baseuref(TOPLEVEL * pr_current, char *uref)
589 char *return_value = NULL;
590 char *start_of_base = NULL;
591 char *end_of_base = NULL;
592 char *cptr = NULL;
593 int i = 0;
595 /* use hierarchy separator */
597 if (uref == NULL) {
598 return (NULL);
600 #if DEBUG
601 printf("Got uref: _%s_\n", uref);
602 #endif
605 if (pr_current->hierarchy_uref_order == APPEND) {
607 start_of_base = rindex(uref, '/'); /* separator is always '/' */
609 if (start_of_base == NULL) {
610 return (g_strdup (uref));
613 return_value = g_strdup (start_of_base + 1);
615 } else if (pr_current->hierarchy_uref_order == PREPEND) {
617 end_of_base = index(uref, '/');
619 if (end_of_base == NULL) {
620 return (g_strdup (uref));
623 cptr = uref;
625 return_value = (char *) g_malloc(sizeof(char) * (strlen(uref)));
626 i = 0;
627 while (cptr != end_of_base) {
628 return_value[i] = *cptr;
629 i++;
630 cptr++;
632 return_value[i] = '\0';
635 #if DEBUG
636 printf("new uref return_value = %s\n\n\n", return_value);
637 #endif
639 return (return_value);
642 int
643 s_hierarchy_graphical_search(OBJECT* o_current, int count)
645 char *graphical_attrib;
646 graphical_attrib = o_attrib_search_name_single_count(o_current,
647 "graphical", count);
649 if (graphical_attrib == NULL) {
650 graphical_attrib = o_attrib_search_name(o_current->complex->prim_objs,
651 "graphical", count);
654 if (graphical_attrib) {
655 g_free(graphical_attrib);
656 return TRUE;
659 return FALSE;