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"
37 #ifdef HAVE_LIBDMALLOC
42 s_hierarchy_traverse(TOPLEVEL
* pr_current
, OBJECT
* o_current
,
51 int looking_inside
= FALSE
;
52 int loaded_flag
= FALSE
;
53 char *current_filename
;
56 attrib
= o_attrib_search_attached_attribs_by_name (o_current
, "source", 0);
58 /* if above is null, then look inside symbol */
60 attrib
= o_attrib_search_inherited_attribs_by_name (o_current
,
63 looking_inside
= TRUE
;
65 printf("going to look inside now\n");
69 graphical
= s_hierarchy_graphical_search(o_current
, count
);
71 /* Do not bother traversing the hierarchy if the symbol has an */
72 /* graphical attribute attached to it. */
81 /* look for source=filename,filename, ... */
83 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
85 /* loop over all filenames */
86 while (current_filename
!= NULL
) {
88 s_log_message("Going to traverse source [%s]\n",
92 /* guts for a single filename */
93 p_current
= pr_current
->page_current
;
95 printf("Going down %s\n", current_filename
);
98 s_hierarchy_down_schematic_single(pr_current
,
100 pr_current
->page_current
,
102 HIERARCHY_FORCE_LOAD
);
104 if (child_page
== NULL
) {
105 fprintf(stderr
, "Could not open [%s]\n", current_filename
);
107 page_control
= child_page
->page_control
;
108 s_page_goto (pr_current
, child_page
);
112 verbose_print("v\n");
113 verbose_reset_index();
115 netlist
->composite_component
= TRUE
;
116 /* can't do the following, don't know why... HACK TODO */
117 /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/
118 s_traverse_sheet (pr_current
,
119 s_page_objects (pr_current
->page_current
),
120 netlist
->component_uref
);
125 pr_current
->page_current
= p_current
;
127 g_free(current_filename
);
129 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
134 g_free(current_filename
);
138 /* continue looking outside first */
139 if (!looking_inside
) {
141 o_attrib_search_attached_attribs_by_name (o_current
, "source",
145 /* okay we were looking outside and didn't */
146 /* find anything, so now we need to look */
147 /* inside the symbol */
148 if (!looking_inside
&& attrib
== NULL
&& !loaded_flag
) {
149 looking_inside
= TRUE
;
151 printf("switching to go to look inside\n");
155 if (looking_inside
) {
157 printf("looking inside\n");
160 o_attrib_search_inherited_attribs_by_name (o_current
,
164 graphical
= s_hierarchy_graphical_search(o_current
, count
);
166 /* Do not bother looking further in the hierarchy if the symbol */
167 /* has an graphical attribute attached to it. */
177 void s_hierarchy_post_process(TOPLEVEL
* pr_current
, NETLIST
* head
)
180 CPINLIST
*pl_current
;
181 char *source_net_name
= NULL
;
182 int did_work
= FALSE
;
187 while (nl_current
!= NULL
) {
188 if (nl_current
->composite_component
) {
190 printf("Found composite %s\n", nl_current
->component_uref
);
193 if (nl_current
->cpins
) {
194 pl_current
= nl_current
->cpins
;
196 while (pl_current
!= NULL
) {
198 if (pl_current
->plid
!= -1) {
202 if (pl_current
->pin_label
== NULL
203 && pl_current
->plid
!= -1) {
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) {
211 printf("# L: %s %s\n", pl_current
->pin_number
,
212 pl_current
->pin_label
);
214 /* get source net name, all nets are named already */
216 s_net_name_search(pr_current
,
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
);
226 s_hierarchy_setup_rename(pr_current
, head
,
227 nl_current
->component_uref
,
228 pl_current
->pin_label
,
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
)
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
);
265 printf("label: %s, uref: %s, wanted_uref: %s\n", label
, uref
,
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
;;
278 printf("net to be renamed: %s\n",
279 pl_current
->net_name
);
280 printf("%s -> %s\n", pl_current
->net_name
, new_name
);
282 s_rename_add(pl_current
->net_name
, new_name
);
285 printf("Going to remove %s\n",
286 nl_current
->component_uref
);
288 s_hierarchy_remove_urefconn(head
,
295 nl_current
= nl_current
->next
;
301 void s_hierarchy_remove_urefconn(NETLIST
* head
, char *uref_disable
)
304 CPINLIST
*pl_current
;
306 char uref
[80], pin
[10];
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
);
317 printf(" looking at : %s %s\n", uref
, pin
);
319 if (strcmp(uref_disable
, uref
) == 0) {
321 printf("conn disabling %s\n",
322 n_current
->connected_to
);
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) {
338 printf("refdes disabling: %s\n", nl_current
->component_uref
);
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
)
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
,
369 char *return_value
= NULL
;
374 if (pr_current
->hierarchy_uref_separator
) {
375 switch (pr_current
->hierarchy_uref_order
) {
378 g_strconcat (hierarchy_tag
,
379 pr_current
->hierarchy_uref_separator
,
384 g_strconcat (basename
,
385 pr_current
->hierarchy_uref_separator
,
386 hierarchy_tag
, NULL
);
391 switch (pr_current
->hierarchy_uref_order
) {
394 g_strconcat (hierarchy_tag
, basename
, NULL
);
398 g_strconcat (basename
, hierarchy_tag
, NULL
);
408 return_value
= g_strdup (basename
);
414 return (return_value
);
417 char *s_hierarchy_create_netname(TOPLEVEL
* pr_current
, char *basename
,
420 char *return_value
= NULL
;
422 if (pr_current
->hierarchy_netname_mangle
== FALSE
) {
424 return (g_strdup (basename
));
433 if (pr_current
->hierarchy_netname_separator
) {
434 switch (pr_current
->hierarchy_netname_order
) {
437 g_strconcat (hierarchy_tag
,
438 pr_current
->hierarchy_netname_separator
,
445 g_strconcat (basename
,
446 pr_current
->hierarchy_netname_separator
,
447 hierarchy_tag
, NULL
);
453 switch (pr_current
->hierarchy_netname_order
) {
457 g_strconcat (hierarchy_tag
, basename
, NULL
);
461 g_strconcat (basename
, hierarchy_tag
, NULL
);
472 return_value
= g_strdup (basename
);
478 return (return_value
);
481 char *s_hierarchy_create_netattrib(TOPLEVEL
* pr_current
, char *basename
,
484 char *return_value
= NULL
;
486 if (pr_current
->hierarchy_netattrib_mangle
== FALSE
) {
488 return (g_strdup (basename
));
497 if (pr_current
->hierarchy_netattrib_separator
) {
498 switch (pr_current
->hierarchy_netattrib_order
) {
501 g_strconcat (hierarchy_tag
,
502 pr_current
->hierarchy_netattrib_separator
,
507 g_strconcat (basename
,
508 pr_current
->hierarchy_netattrib_separator
,
509 hierarchy_tag
, NULL
);
514 switch (pr_current
->hierarchy_netattrib_order
) {
517 g_strconcat (hierarchy_tag
, basename
, NULL
);
520 g_strconcat (basename
, hierarchy_tag
, NULL
);
529 return_value
= g_strdup (basename
);
535 return (return_value
);
539 s_hierarchy_remove_uref_mangling(TOPLEVEL
* pr_current
, NETLIST
* head
)
542 CPINLIST
*pl_current
;
544 char uref
[80], pin
[10];
545 char *new_uref
= NULL
;
546 char *new_connected_to
= NULL
;
549 while (nl_current
!= NULL
) {
551 if (nl_current
->component_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
) {
568 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
570 s_hierarchy_return_baseuref(pr_current
, uref
);
571 new_connected_to
= g_strdup_printf("%s %s", new_uref
, pin
);
572 g_free(n_current
->connected_to
);
573 n_current
->connected_to
= new_connected_to
;
575 n_current
= n_current
->next
;
578 pl_current
= pl_current
->next
;
580 nl_current
= nl_current
->next
;
585 char *s_hierarchy_return_baseuref(TOPLEVEL
* pr_current
, char *uref
)
587 char *return_value
= NULL
;
588 char *start_of_base
= NULL
;
589 char *end_of_base
= NULL
;
591 /* use hierarchy separator */
597 printf("Got uref: _%s_\n", uref
);
601 if (pr_current
->hierarchy_uref_order
== APPEND
) {
603 start_of_base
= strrchr(uref
, '/'); /* separator is always '/' */
605 if (start_of_base
== NULL
) {
606 return (g_strdup (uref
));
609 return_value
= g_strdup (start_of_base
+ 1);
611 } else if (pr_current
->hierarchy_uref_order
== PREPEND
) {
613 end_of_base
= strchr(uref
, '/');
615 if (end_of_base
== NULL
) {
616 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
);