1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 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_attached_attribs_by_name (o_current
, "source", 0);
57 /* if above is null, then look inside symbol */
59 attrib
= o_attrib_search_inherited_attribs_by_name (o_current
,
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. */
80 /* look for source=filename,filename, ... */
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",
91 /* guts for a single filename */
92 p_current
= pr_current
->page_current
;
94 printf("Going down %s\n", current_filename
);
97 s_hierarchy_down_schematic_single(pr_current
,
99 pr_current
->page_current
,
101 HIERARCHY_FORCE_LOAD
);
103 if (page_control
== -1) {
104 fprintf(stderr
, "Could not open [%s]\n", current_filename
);
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 s_page_objects (pr_current
->page_current
),
117 netlist
->component_uref
);
122 pr_current
->page_current
= p_current
;
124 g_free(current_filename
);
126 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
131 g_free(current_filename
);
135 /* continue looking outside first */
136 if (!looking_inside
) {
138 o_attrib_search_attached_attribs_by_name (o_current
, "source",
142 /* okay we were looking outside and didn't */
143 /* find anything, so now we need to look */
144 /* inside the symbol */
145 if (!looking_inside
&& attrib
== NULL
&& !loaded_flag
) {
146 looking_inside
= TRUE
;
148 printf("switching to go to look inside\n");
152 if (looking_inside
) {
154 printf("looking inside\n");
157 o_attrib_search_inherited_attribs_by_name (o_current
,
161 graphical
= s_hierarchy_graphical_search(o_current
, count
);
163 /* Do not bother looking further in the hierarchy if the symbol */
164 /* has an graphical attribute attached to it. */
174 void s_hierarchy_post_process(TOPLEVEL
* pr_current
, NETLIST
* head
)
177 CPINLIST
*pl_current
;
178 char *source_net_name
= NULL
;
179 int did_work
= FALSE
;
184 while (nl_current
!= NULL
) {
185 if (nl_current
->composite_component
) {
187 printf("Found composite %s\n", nl_current
->component_uref
);
190 if (nl_current
->cpins
) {
191 pl_current
= nl_current
->cpins
;
193 while (pl_current
!= NULL
) {
195 if (pl_current
->plid
!= -1) {
199 if (pl_current
->pin_label
== NULL
200 && pl_current
->plid
!= -1) {
202 "Found a pin [%s] on component [%s] which does not have a label!\n",
203 nl_current
->component_uref
,
204 pl_current
->pin_number
);
205 } else if (pl_current
->plid
!= -1) {
208 printf("# L: %s %s\n", pl_current
->pin_number
,
209 pl_current
->pin_label
);
211 /* get source net name, all nets are named already */
213 s_net_name_search(pr_current
,
216 printf("name: %s\n", source_net_name
);
217 printf("Now we need to search for: %s/%s\n",
218 nl_current
->component_uref
,
219 pl_current
->pin_label
);
223 s_hierarchy_setup_rename(pr_current
, head
,
224 nl_current
->component_uref
,
225 pl_current
->pin_label
,
229 "Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n",
230 pl_current
->pin_label
,
231 nl_current
->component_uref
);
235 pl_current
= pl_current
->next
;
239 nl_current
= nl_current
->next
;
242 s_rename_all(pr_current
, head
);
243 s_hierarchy_remove_compsite_all(head
);
247 s_hierarchy_setup_rename(TOPLEVEL
* pr_current
, NETLIST
* head
, char *uref
,
248 char *label
, char *new_name
)
251 CPINLIST
*pl_current
;
252 char *wanted_uref
= NULL
;
253 int did_work
= FALSE
;
255 /* this is questionable, because I'm not sure if it's exactly the */
256 /* same as the #if 0'ed out line */
257 /* search for the uref which has the name: label/uref (or whatever the */
258 /* hierarchy tag/separator order is) */
259 wanted_uref
= s_hierarchy_create_uref(pr_current
, label
, uref
);
262 printf("label: %s, uref: %s, wanted_uref: %s\n", label
, uref
,
267 while (nl_current
!= NULL
) {
268 if (nl_current
->component_uref
) {
269 pl_current
= nl_current
->cpins
;
270 if (strcmp(nl_current
->component_uref
, wanted_uref
) == 0) {
271 if (nl_current
->cpins
) {
272 /* skip over head of special io symbol */
273 pl_current
= nl_current
->cpins
->next
;;
275 printf("net to be renamed: %s\n",
276 pl_current
->net_name
);
277 printf("%s -> %s\n", pl_current
->net_name
, new_name
);
279 s_rename_add(pl_current
->net_name
, new_name
);
282 printf("Going to remove %s\n",
283 nl_current
->component_uref
);
285 s_hierarchy_remove_urefconn(head
,
292 nl_current
= nl_current
->next
;
298 void s_hierarchy_remove_urefconn(NETLIST
* head
, char *uref_disable
)
301 CPINLIST
*pl_current
;
303 char uref
[80], pin
[10];
306 while (nl_current
!= NULL
) {
307 pl_current
= nl_current
->cpins
;
308 while (pl_current
!= NULL
) {
309 n_current
= pl_current
->nets
;
310 while (n_current
!= NULL
) {
311 if (n_current
->connected_to
!= NULL
) {
312 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
314 printf(" looking at : %s %s\n", uref
, pin
);
316 if (strcmp(uref_disable
, uref
) == 0) {
318 printf("conn disabling %s\n",
319 n_current
->connected_to
);
321 /* can't do frees, since some names are links */
322 /* g_free(n_current->connected_to);*/
323 n_current
->connected_to
= NULL
;
326 n_current
= n_current
->next
;
329 pl_current
= pl_current
->next
;
332 if (nl_current
->component_uref
) {
333 if (strcmp(nl_current
->component_uref
, uref_disable
) == 0) {
335 printf("refdes disabling: %s\n", nl_current
->component_uref
);
337 /* can't do frees, since some names are links */
338 /*free(nl_current->component_uref); */
339 nl_current
->component_uref
= NULL
;
342 nl_current
= nl_current
->next
;
346 void s_hierarchy_remove_compsite_all(NETLIST
* head
)
351 while (nl_current
!= NULL
) {
352 if (nl_current
->composite_component
) {
353 if (nl_current
->component_uref
!= NULL
) {
354 s_hierarchy_remove_urefconn(head
,
355 nl_current
->component_uref
);
358 nl_current
= nl_current
->next
;
363 char *s_hierarchy_create_uref(TOPLEVEL
* pr_current
, char *basename
,
366 char *return_value
= NULL
;
371 if (pr_current
->hierarchy_uref_separator
) {
372 switch (pr_current
->hierarchy_uref_order
) {
375 g_strconcat (hierarchy_tag
,
376 pr_current
->hierarchy_uref_separator
,
381 g_strconcat (basename
,
382 pr_current
->hierarchy_uref_separator
,
383 hierarchy_tag
, NULL
);
388 switch (pr_current
->hierarchy_uref_order
) {
391 g_strconcat (hierarchy_tag
, basename
, NULL
);
395 g_strconcat (basename
, hierarchy_tag
, NULL
);
405 return_value
= g_strdup (basename
);
411 return (return_value
);
414 char *s_hierarchy_create_netname(TOPLEVEL
* pr_current
, char *basename
,
417 char *return_value
= NULL
;
419 if (pr_current
->hierarchy_netname_mangle
== FALSE
) {
421 return (g_strdup (basename
));
430 if (pr_current
->hierarchy_netname_separator
) {
431 switch (pr_current
->hierarchy_netname_order
) {
434 g_strconcat (hierarchy_tag
,
435 pr_current
->hierarchy_netname_separator
,
442 g_strconcat (basename
,
443 pr_current
->hierarchy_netname_separator
,
444 hierarchy_tag
, NULL
);
450 switch (pr_current
->hierarchy_netname_order
) {
454 g_strconcat (hierarchy_tag
, basename
, NULL
);
458 g_strconcat (basename
, hierarchy_tag
, NULL
);
469 return_value
= g_strdup (basename
);
475 return (return_value
);
478 char *s_hierarchy_create_netattrib(TOPLEVEL
* pr_current
, char *basename
,
481 char *return_value
= NULL
;
483 if (pr_current
->hierarchy_netattrib_mangle
== FALSE
) {
485 return (g_strdup (basename
));
494 if (pr_current
->hierarchy_netattrib_separator
) {
495 switch (pr_current
->hierarchy_netattrib_order
) {
498 g_strconcat (hierarchy_tag
,
499 pr_current
->hierarchy_netattrib_separator
,
504 g_strconcat (basename
,
505 pr_current
->hierarchy_netattrib_separator
,
506 hierarchy_tag
, NULL
);
511 switch (pr_current
->hierarchy_netattrib_order
) {
514 g_strconcat (hierarchy_tag
, basename
, NULL
);
517 g_strconcat (basename
, hierarchy_tag
, NULL
);
526 return_value
= g_strdup (basename
);
532 return (return_value
);
536 s_hierarchy_remove_uref_mangling(TOPLEVEL
* pr_current
, NETLIST
* head
)
539 CPINLIST
*pl_current
;
541 char uref
[80], pin
[10];
542 char *new_uref
= NULL
;
543 char *new_connected_to
= NULL
;
546 while (nl_current
!= NULL
) {
548 if (nl_current
->component_uref
) {
551 s_hierarchy_return_baseuref(pr_current
,
552 nl_current
->component_uref
);
553 g_free(nl_current
->component_uref
);
554 nl_current
->component_uref
= new_uref
;
557 pl_current
= nl_current
->cpins
;
559 while (pl_current
!= NULL
) {
560 n_current
= pl_current
->nets
;
561 while (n_current
!= NULL
) {
563 if (n_current
->connected_to
) {
565 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
567 s_hierarchy_return_baseuref(pr_current
, uref
);
568 new_connected_to
= g_strdup_printf("%s %s", new_uref
, pin
);
569 g_free(n_current
->connected_to
);
570 n_current
->connected_to
= new_connected_to
;
572 n_current
= n_current
->next
;
575 pl_current
= pl_current
->next
;
577 nl_current
= nl_current
->next
;
582 char *s_hierarchy_return_baseuref(TOPLEVEL
* pr_current
, char *uref
)
584 char *return_value
= NULL
;
585 char *start_of_base
= NULL
;
586 char *end_of_base
= NULL
;
589 /* use hierarchy separator */
595 printf("Got uref: _%s_\n", uref
);
599 if (pr_current
->hierarchy_uref_order
== APPEND
) {
601 start_of_base
= strrchr(uref
, '/'); /* separator is always '/' */
603 if (start_of_base
== NULL
) {
604 return (g_strdup (uref
));
607 return_value
= g_strdup (start_of_base
+ 1);
609 } else if (pr_current
->hierarchy_uref_order
== PREPEND
) {
611 end_of_base
= strchr(uref
, '/');
613 if (end_of_base
== NULL
) {
614 return (g_strdup (uref
));
619 return_value
= g_strndup(uref
, end_of_base
- uref
);
623 printf("new uref return_value = %s\n\n\n", return_value
);
626 return (return_value
);
629 int s_hierarchy_graphical_search (OBJECT
* o_current
, int count
)
631 char *graphical_attrib
;
633 o_attrib_search_object_attribs_by_name (o_current
, "graphical", count
);
635 if (graphical_attrib
) {
636 g_free (graphical_attrib
);