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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include <libgeda/libgeda.h>
34 #include "../include/globals.h"
35 #include "../include/prototype.h"
36 #include "../include/gettext.h"
38 #ifdef HAVE_LIBDMALLOC
43 s_hierarchy_traverse(TOPLEVEL
* pr_current
, OBJECT
* o_current
,
52 int looking_inside
= FALSE
;
53 int loaded_flag
= FALSE
;
54 char *current_filename
;
57 attrib
= o_attrib_search_attached_attribs_by_name (o_current
, "source", 0);
59 /* if above is null, then look inside symbol */
61 attrib
= o_attrib_search_inherited_attribs_by_name (o_current
,
64 looking_inside
= TRUE
;
66 printf("going to look inside now\n");
70 graphical
= s_hierarchy_graphical_search(o_current
, count
);
72 /* Do not bother traversing the hierarchy if the symbol has an */
73 /* graphical attribute attached to it. */
82 /* look for source=filename,filename, ... */
84 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
86 /* loop over all filenames */
87 while (current_filename
!= NULL
) {
89 s_log_message(_("Going to traverse source [%s]\n"),
93 /* guts for a single filename */
94 p_current
= pr_current
->page_current
;
96 printf("Going down %s\n", current_filename
);
100 s_hierarchy_down_schematic_single(pr_current
,
102 pr_current
->page_current
,
104 HIERARCHY_FORCE_LOAD
,
107 if (child_page
== NULL
) {
108 g_warning (_("Failed to load subcircuit '%s': %s\n"),
109 current_filename
, err
->message
);
110 fprintf(stderr
, _("ERROR: Failed to load subcircuit '%s': %s\n"),
111 current_filename
, err
->message
);
116 page_control
= child_page
->page_control
;
117 s_page_goto (pr_current
, child_page
);
121 verbose_print("v\n");
122 verbose_reset_index();
124 netlist
->composite_component
= TRUE
;
125 /* can't do the following, don't know why... HACK TODO */
126 /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/
127 s_traverse_sheet (pr_current
,
128 s_page_objects (pr_current
->page_current
),
129 netlist
->component_uref
);
134 pr_current
->page_current
= p_current
;
136 g_free(current_filename
);
138 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
143 g_free(current_filename
);
147 /* continue looking outside first */
148 if (!looking_inside
) {
150 o_attrib_search_attached_attribs_by_name (o_current
, "source",
154 /* okay we were looking outside and didn't */
155 /* find anything, so now we need to look */
156 /* inside the symbol */
157 if (!looking_inside
&& attrib
== NULL
&& !loaded_flag
) {
158 looking_inside
= TRUE
;
160 printf("switching to go to look inside\n");
164 if (looking_inside
) {
166 printf("looking inside\n");
169 o_attrib_search_inherited_attribs_by_name (o_current
,
173 graphical
= s_hierarchy_graphical_search(o_current
, count
);
175 /* Do not bother looking further in the hierarchy if the symbol */
176 /* has an graphical attribute attached to it. */
186 void s_hierarchy_post_process(TOPLEVEL
* pr_current
, NETLIST
* head
)
189 CPINLIST
*pl_current
;
190 char *source_net_name
= NULL
;
191 int did_work
= FALSE
;
196 while (nl_current
!= NULL
) {
197 if (nl_current
->composite_component
) {
199 printf("Found composite %s\n", nl_current
->component_uref
);
202 if (nl_current
->cpins
) {
203 pl_current
= nl_current
->cpins
;
205 while (pl_current
!= NULL
) {
207 if (pl_current
->plid
!= -1) {
211 if (pl_current
->pin_label
== NULL
212 && pl_current
->plid
!= -1) {
214 _("Found a pin [%s] on component [%s] which does not have a label!\n"),
215 nl_current
->component_uref
,
216 pl_current
->pin_number
);
217 } else if (pl_current
->plid
!= -1) {
220 printf("# L: %s %s\n", pl_current
->pin_number
,
221 pl_current
->pin_label
);
223 /* get source net name, all nets are named already */
225 s_net_name_search(pr_current
,
228 printf("name: %s\n", source_net_name
);
229 printf("Now we need to search for: %s/%s\n",
230 nl_current
->component_uref
,
231 pl_current
->pin_label
);
235 s_hierarchy_setup_rename(pr_current
, head
,
236 nl_current
->component_uref
,
237 pl_current
->pin_label
,
241 _("Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n"),
242 pl_current
->pin_label
,
243 nl_current
->component_uref
);
247 pl_current
= pl_current
->next
;
251 nl_current
= nl_current
->next
;
254 s_rename_all(pr_current
, head
);
255 s_hierarchy_remove_compsite_all(head
);
259 s_hierarchy_setup_rename(TOPLEVEL
* pr_current
, NETLIST
* head
, char *uref
,
260 char *label
, char *new_name
)
263 CPINLIST
*pl_current
;
264 char *wanted_uref
= NULL
;
265 int did_work
= FALSE
;
267 /* this is questionable, because I'm not sure if it's exactly the */
268 /* same as the #if 0'ed out line */
269 /* search for the uref which has the name: label/uref (or whatever the */
270 /* hierarchy tag/separator order is) */
271 wanted_uref
= s_hierarchy_create_uref(pr_current
, label
, uref
);
274 printf("label: %s, uref: %s, wanted_uref: %s\n", label
, uref
,
279 while (nl_current
!= NULL
) {
280 if (nl_current
->component_uref
) {
281 pl_current
= nl_current
->cpins
;
282 if (strcmp(nl_current
->component_uref
, wanted_uref
) == 0) {
283 if (nl_current
->cpins
) {
284 /* skip over head of special io symbol */
285 pl_current
= nl_current
->cpins
->next
;;
287 printf("net to be renamed: %s\n",
288 pl_current
->net_name
);
289 printf("%s -> %s\n", pl_current
->net_name
, new_name
);
291 s_rename_add(pl_current
->net_name
, new_name
);
294 printf("Going to remove %s\n",
295 nl_current
->component_uref
);
297 s_hierarchy_remove_urefconn(head
,
304 nl_current
= nl_current
->next
;
310 void s_hierarchy_remove_urefconn(NETLIST
* head
, char *uref_disable
)
313 CPINLIST
*pl_current
;
315 char uref
[80], pin
[10];
318 while (nl_current
!= NULL
) {
319 pl_current
= nl_current
->cpins
;
320 while (pl_current
!= NULL
) {
321 n_current
= pl_current
->nets
;
322 while (n_current
!= NULL
) {
323 if (n_current
->connected_to
!= NULL
) {
324 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
326 printf(" looking at : %s %s\n", uref
, pin
);
328 if (strcmp(uref_disable
, uref
) == 0) {
330 printf("conn disabling %s\n",
331 n_current
->connected_to
);
333 /* can't do frees, since some names are links */
334 /* g_free(n_current->connected_to);*/
335 n_current
->connected_to
= NULL
;
338 n_current
= n_current
->next
;
341 pl_current
= pl_current
->next
;
344 if (nl_current
->component_uref
) {
345 if (strcmp(nl_current
->component_uref
, uref_disable
) == 0) {
347 printf("refdes disabling: %s\n", nl_current
->component_uref
);
349 /* can't do frees, since some names are links */
350 /*free(nl_current->component_uref); */
351 nl_current
->component_uref
= NULL
;
354 nl_current
= nl_current
->next
;
358 void s_hierarchy_remove_compsite_all(NETLIST
* head
)
363 while (nl_current
!= NULL
) {
364 if (nl_current
->composite_component
) {
365 if (nl_current
->component_uref
!= NULL
) {
366 s_hierarchy_remove_urefconn(head
,
367 nl_current
->component_uref
);
370 nl_current
= nl_current
->next
;
375 char *s_hierarchy_create_uref(TOPLEVEL
* pr_current
, char *basename
,
378 char *return_value
= NULL
;
383 if (pr_current
->hierarchy_uref_separator
) {
384 switch (pr_current
->hierarchy_uref_order
) {
387 g_strconcat (hierarchy_tag
,
388 pr_current
->hierarchy_uref_separator
,
393 g_strconcat (basename
,
394 pr_current
->hierarchy_uref_separator
,
395 hierarchy_tag
, NULL
);
400 switch (pr_current
->hierarchy_uref_order
) {
403 g_strconcat (hierarchy_tag
, basename
, NULL
);
407 g_strconcat (basename
, hierarchy_tag
, NULL
);
417 return_value
= g_strdup (basename
);
423 return (return_value
);
426 char *s_hierarchy_create_netname(TOPLEVEL
* pr_current
, char *basename
,
429 char *return_value
= NULL
;
431 if (pr_current
->hierarchy_netname_mangle
== FALSE
) {
433 return (g_strdup (basename
));
442 if (pr_current
->hierarchy_netname_separator
) {
443 switch (pr_current
->hierarchy_netname_order
) {
446 g_strconcat (hierarchy_tag
,
447 pr_current
->hierarchy_netname_separator
,
454 g_strconcat (basename
,
455 pr_current
->hierarchy_netname_separator
,
456 hierarchy_tag
, NULL
);
462 switch (pr_current
->hierarchy_netname_order
) {
466 g_strconcat (hierarchy_tag
, basename
, NULL
);
470 g_strconcat (basename
, hierarchy_tag
, NULL
);
481 return_value
= g_strdup (basename
);
487 return (return_value
);
490 char *s_hierarchy_create_netattrib(TOPLEVEL
* pr_current
, char *basename
,
493 char *return_value
= NULL
;
495 if (pr_current
->hierarchy_netattrib_mangle
== FALSE
) {
497 return (g_strdup (basename
));
506 if (pr_current
->hierarchy_netattrib_separator
) {
507 switch (pr_current
->hierarchy_netattrib_order
) {
510 g_strconcat (hierarchy_tag
,
511 pr_current
->hierarchy_netattrib_separator
,
516 g_strconcat (basename
,
517 pr_current
->hierarchy_netattrib_separator
,
518 hierarchy_tag
, NULL
);
523 switch (pr_current
->hierarchy_netattrib_order
) {
526 g_strconcat (hierarchy_tag
, basename
, NULL
);
530 g_strconcat (basename
, hierarchy_tag
, NULL
);
539 return_value
= g_strdup (basename
);
545 return (return_value
);
549 s_hierarchy_remove_uref_mangling(TOPLEVEL
* pr_current
, NETLIST
* head
)
552 CPINLIST
*pl_current
;
554 char uref
[80], pin
[10];
555 char *new_uref
= NULL
;
556 char *new_connected_to
= NULL
;
559 while (nl_current
!= NULL
) {
561 if (nl_current
->component_uref
) {
564 s_hierarchy_return_baseuref(pr_current
,
565 nl_current
->component_uref
);
566 g_free(nl_current
->component_uref
);
567 nl_current
->component_uref
= new_uref
;
570 pl_current
= nl_current
->cpins
;
572 while (pl_current
!= NULL
) {
573 n_current
= pl_current
->nets
;
574 while (n_current
!= NULL
) {
576 if (n_current
->connected_to
) {
578 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
580 s_hierarchy_return_baseuref(pr_current
, uref
);
581 new_connected_to
= g_strdup_printf("%s %s", new_uref
, pin
);
582 g_free(n_current
->connected_to
);
583 n_current
->connected_to
= new_connected_to
;
585 n_current
= n_current
->next
;
588 pl_current
= pl_current
->next
;
590 nl_current
= nl_current
->next
;
595 char *s_hierarchy_return_baseuref(TOPLEVEL
* pr_current
, char *uref
)
597 char *return_value
= NULL
;
598 char *start_of_base
= NULL
;
599 char *end_of_base
= NULL
;
601 /* use hierarchy separator */
607 printf("Got uref: _%s_\n", uref
);
611 if (pr_current
->hierarchy_uref_order
== APPEND
) {
613 start_of_base
= strrchr(uref
, '/'); /* separator is always '/' */
615 if (start_of_base
== NULL
) {
616 return (g_strdup (uref
));
619 return_value
= g_strdup (start_of_base
+ 1);
621 } else if (pr_current
->hierarchy_uref_order
== PREPEND
) {
623 end_of_base
= strchr(uref
, '/');
625 if (end_of_base
== NULL
) {
626 return (g_strdup (uref
));
629 return_value
= g_strndup(uref
, end_of_base
- uref
);
633 printf("new uref return_value = %s\n\n\n", return_value
);
636 return (return_value
);
639 int s_hierarchy_graphical_search (OBJECT
* o_current
, int count
)
641 char *graphical_attrib
;
643 o_attrib_search_object_attribs_by_name (o_current
, "graphical", count
);
645 if (graphical_attrib
) {
646 g_free (graphical_attrib
);