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
32 #include <libgeda/libgeda.h>
34 #include "../include/globals.h"
35 #include "../include/prototype.h"
37 #ifdef HAVE_LIBDMALLOC
42 s_hierarchy_traverse(TOPLEVEL
* pr_current
, OBJECT
* o_current
,
50 int looking_inside
= FALSE
;
51 int loaded_flag
= FALSE
;
52 char *current_filename
;
55 attrib
= o_attrib_search_name_single_count(o_current
, "source", 0);
57 /* if above is null, then look inside symbol */
59 attrib
= o_attrib_search_name(o_current
->complex->prim_objs
,
62 looking_inside
= TRUE
;
64 printf("going to look inside now\n");
68 graphical
= s_hierarchy_graphical_search(o_current
, count
);
70 /* Do not bother traversing the hierarchy if the symbol has an */
71 /* graphical attribute attached to it. */
79 /* look for source=filename,filename, ... */
81 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
83 /* loop over all filenames */
84 while (current_filename
!= NULL
) {
85 s_log_message("Going to traverse source [%s]\n",
89 /* guts for a single filename */
90 p_current
= pr_current
->page_current
;
92 printf("Going down %s\n", current_filename
);
95 s_hierarchy_down_schematic_single(pr_current
,
97 pr_current
->page_current
,
99 HIERARCHY_FORCE_LOAD
);
101 if (page_control
== -1) {
102 fprintf(stderr
, "Could not open [%s]\n", current_filename
);
106 verbose_print("v\n");
107 verbose_reset_index();
109 netlist
->composite_component
= TRUE
;
110 /* can't do the following, don't know why... HACK TODO */
111 /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/
112 s_traverse_sheet(pr_current
,
113 pr_current
->page_current
,
114 netlist
->component_uref
);
119 /* XXX Does this require s_toplevel_goto_page to get the right cwd? */
120 pr_current
->page_current
= p_current
;
122 g_free(current_filename
);
124 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
129 g_free(current_filename
);
133 /* continue looking outside first */
134 if (!looking_inside
) {
136 o_attrib_search_name_single_count(o_current
, "source",
140 /* okay we were looking outside and didn't */
141 /* find anything, so now we need to look */
142 /* inside the symbol */
143 if (!looking_inside
&& attrib
== NULL
&& !loaded_flag
) {
144 looking_inside
= TRUE
;
146 printf("switching to go to look inside\n");
150 if (looking_inside
) {
152 printf("looking inside\n");
154 attrib
= o_attrib_search_name(o_current
->complex->prim_objs
,
158 graphical
= s_hierarchy_graphical_search(o_current
, count
);
160 /* Do not bother looking further in the hierarchy if the symbol */
161 /* has an graphical attribute attached to it. */
171 void s_hierarchy_post_process(TOPLEVEL
* pr_current
, NETLIST
* head
)
174 CPINLIST
*pl_current
;
175 char *source_net_name
= NULL
;
176 int did_work
= FALSE
;
181 while (nl_current
!= NULL
) {
182 if (nl_current
->composite_component
) {
184 printf("Found composite %s\n", nl_current
->component_uref
);
187 if (nl_current
->cpins
) {
188 pl_current
= nl_current
->cpins
;
190 while (pl_current
!= NULL
) {
192 if (pl_current
->plid
!= -1) {
196 if (pl_current
->pin_label
== NULL
197 && pl_current
->plid
!= -1) {
199 "Found a pin [%s] on component [%s] which does not have a label!\n",
200 nl_current
->component_uref
,
201 pl_current
->pin_number
);
202 } else if (pl_current
->plid
!= -1) {
205 printf("# L: %s %s\n", pl_current
->pin_number
,
206 pl_current
->pin_label
);
208 /* get source net name, all nets are named already */
210 s_net_name_search(pr_current
,
213 printf("name: %s\n", source_net_name
);
214 printf("Now we need to search for: %s/%s\n",
215 nl_current
->component_uref
,
216 pl_current
->pin_label
);
220 s_hierarchy_setup_rename(pr_current
, head
,
221 nl_current
->component_uref
,
222 pl_current
->pin_label
,
226 "Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n",
227 pl_current
->pin_label
,
228 nl_current
->component_uref
);
232 pl_current
= pl_current
->next
;
236 nl_current
= nl_current
->next
;
239 s_rename_all(pr_current
, head
);
240 s_hierarchy_remove_compsite_all(head
);
244 s_hierarchy_setup_rename(TOPLEVEL
* pr_current
, NETLIST
* head
, char *uref
,
245 char *label
, char *new_name
)
248 CPINLIST
*pl_current
;
249 char *wanted_uref
= NULL
;
250 int did_work
= FALSE
;
252 /* this is questionable, because I'm not sure if it's exactly the */
253 /* same as the #if 0'ed out line */
254 /* search for the uref which has the name: label/uref (or whatever the */
255 /* hierarchy tag/separator order is) */
256 wanted_uref
= s_hierarchy_create_uref(pr_current
, label
, uref
);
259 printf("label: %s, uref: %s, wanted_uref: %s\n", label
, uref
,
264 while (nl_current
!= NULL
) {
265 if (nl_current
->component_uref
) {
266 pl_current
= nl_current
->cpins
;
267 if (strcmp(nl_current
->component_uref
, wanted_uref
) == 0) {
268 if (nl_current
->cpins
) {
269 /* skip over head of special io symbol */
270 pl_current
= nl_current
->cpins
->next
;;
272 printf("net to be renamed: %s\n",
273 pl_current
->net_name
);
274 printf("%s -> %s\n", pl_current
->net_name
, new_name
);
276 s_rename_add(pl_current
->net_name
, new_name
);
279 printf("Going to remove %s\n",
280 nl_current
->component_uref
);
282 s_hierarchy_remove_urefconn(head
,
289 nl_current
= nl_current
->next
;
295 void s_hierarchy_remove_urefconn(NETLIST
* head
, char *uref_disable
)
298 CPINLIST
*pl_current
;
300 char uref
[80], pin
[10];
303 while (nl_current
!= NULL
) {
304 pl_current
= nl_current
->cpins
;
305 while (pl_current
!= NULL
) {
306 n_current
= pl_current
->nets
;
307 while (n_current
!= NULL
) {
308 if (n_current
->connected_to
!= NULL
) {
309 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
311 printf(" looking at : %s %s\n", uref
, pin
);
313 if (strcmp(uref_disable
, uref
) == 0) {
315 printf("conn disabling %s\n",
316 n_current
->connected_to
);
318 /* can't do frees, since some names are links */
319 /* g_free(n_current->connected_to);*/
320 n_current
->connected_to
= NULL
;
323 n_current
= n_current
->next
;
326 pl_current
= pl_current
->next
;
329 if (nl_current
->component_uref
) {
330 if (strcmp(nl_current
->component_uref
, uref_disable
) == 0) {
332 printf("refdes disabling: %s\n", nl_current
->component_uref
);
334 /* can't do frees, since some names are links */
335 /*free(nl_current->component_uref); */
336 nl_current
->component_uref
= NULL
;
339 nl_current
= nl_current
->next
;
343 void s_hierarchy_remove_compsite_all(NETLIST
* head
)
348 while (nl_current
!= NULL
) {
349 if (nl_current
->composite_component
) {
350 if (nl_current
->component_uref
!= NULL
) {
351 s_hierarchy_remove_urefconn(head
,
352 nl_current
->component_uref
);
355 nl_current
= nl_current
->next
;
359 char *s_hierarchy_create_uref(TOPLEVEL
* pr_current
, char *basename
,
360 char const *hierarchy_tag
)
362 char *return_value
= NULL
;
367 if (pr_current
->hierarchy_uref_separator
) {
368 switch (pr_current
->hierarchy_uref_order
) {
371 g_strconcat (hierarchy_tag
,
372 pr_current
->hierarchy_uref_separator
,
377 g_strconcat (basename
,
378 pr_current
->hierarchy_uref_separator
,
379 hierarchy_tag
, NULL
);
384 switch (pr_current
->hierarchy_uref_order
) {
387 g_strconcat (hierarchy_tag
, basename
, NULL
);
391 g_strconcat (basename
, hierarchy_tag
, NULL
);
401 return_value
= g_strdup (basename
);
407 return (return_value
);
410 char *s_hierarchy_create_netname(TOPLEVEL
* pr_current
, char *basename
,
411 char const *hierarchy_tag
)
413 char *return_value
= NULL
;
415 if (pr_current
->hierarchy_netname_mangle
== FALSE
) {
417 return (g_strdup (basename
));
425 if (pr_current
->hierarchy_netname_separator
) {
426 switch (pr_current
->hierarchy_netname_order
) {
429 g_strconcat (hierarchy_tag
,
430 pr_current
->hierarchy_netname_separator
,
436 g_strconcat (basename
,
437 pr_current
->hierarchy_netname_separator
,
438 hierarchy_tag
, NULL
);
442 switch (pr_current
->hierarchy_netname_order
) {
445 g_strconcat (hierarchy_tag
, basename
, NULL
);
449 g_strconcat (basename
, hierarchy_tag
, NULL
);
458 return_value
= g_strdup (basename
);
464 return (return_value
);
467 char *s_hierarchy_create_netattrib(TOPLEVEL
* pr_current
, char *basename
,
468 char const *hierarchy_tag
)
470 char *return_value
= NULL
;
472 if (pr_current
->hierarchy_netattrib_mangle
== FALSE
) {
474 return (g_strdup (basename
));
482 if (pr_current
->hierarchy_netattrib_separator
) {
483 switch (pr_current
->hierarchy_netattrib_order
) {
486 g_strconcat (hierarchy_tag
,
487 pr_current
->hierarchy_netattrib_separator
,
492 g_strconcat (basename
,
493 pr_current
->hierarchy_netattrib_separator
,
494 hierarchy_tag
, NULL
);
499 switch (pr_current
->hierarchy_netattrib_order
) {
502 g_strconcat (hierarchy_tag
, basename
, NULL
);
505 g_strconcat (basename
, hierarchy_tag
, NULL
);
514 return_value
= g_strdup (basename
);
520 return (return_value
);
524 s_hierarchy_remove_uref_mangling(TOPLEVEL
* pr_current
, NETLIST
* head
)
527 CPINLIST
*pl_current
;
529 char uref
[80], pin
[10];
530 char *new_uref
= NULL
;
531 char *new_connected_to
= NULL
;
534 while (nl_current
!= NULL
) {
536 if (nl_current
->component_uref
) {
539 s_hierarchy_return_baseuref(pr_current
,
540 nl_current
->component_uref
);
541 g_free(nl_current
->component_uref
);
542 nl_current
->component_uref
= new_uref
;
545 pl_current
= nl_current
->cpins
;
547 while (pl_current
!= NULL
) {
548 n_current
= pl_current
->nets
;
549 while (n_current
!= NULL
) {
551 if (n_current
->connected_to
) {
553 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
555 s_hierarchy_return_baseuref(pr_current
, uref
);
556 new_connected_to
= g_strdup_printf("%s %s", new_uref
, pin
);
557 g_free(n_current
->connected_to
);
558 n_current
->connected_to
= new_connected_to
;
560 n_current
= n_current
->next
;
563 pl_current
= pl_current
->next
;
565 nl_current
= nl_current
->next
;
569 char *s_hierarchy_return_baseuref(TOPLEVEL
* pr_current
, char *uref
)
571 char *return_value
= NULL
;
572 char *start_of_base
= NULL
;
573 char *end_of_base
= NULL
;
575 /* use hierarchy separator */
581 printf("Got uref: _%s_\n", uref
);
584 if (pr_current
->hierarchy_uref_order
== APPEND
) {
585 start_of_base
= strrchr(uref
, '/'); /* separator is always '/' */
587 if (start_of_base
== NULL
) {
588 return (g_strdup (uref
));
591 return_value
= g_strdup (start_of_base
+ 1);
592 } else if (pr_current
->hierarchy_uref_order
== PREPEND
) {
593 end_of_base
= strchr(uref
, '/');
595 if (end_of_base
== NULL
) {
596 return (g_strdup (uref
));
599 return_value
= g_strndup(uref
, end_of_base
- uref
);
603 printf("new uref return_value = %s\n\n\n", return_value
);
606 return (return_value
);
610 s_hierarchy_graphical_search(OBJECT
* o_current
, int count
)
612 char *graphical_attrib
;
613 graphical_attrib
= o_attrib_search_name_single_count(o_current
,
616 if (graphical_attrib
== NULL
) {
617 graphical_attrib
= o_attrib_search_name(o_current
->complex->prim_objs
,
621 if (graphical_attrib
) {
622 g_free(graphical_attrib
);