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. */
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 pr_current
->page_current
->object_head
,
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
);
133 if (current_filename
) {
134 g_free(current_filename
);
139 /* continue looking outside first */
140 if (!looking_inside
) {
142 o_attrib_search_name_single_count(o_current
, "source",
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
;
152 printf("switching to go to look inside\n");
156 if (looking_inside
) {
158 printf("looking inside\n");
160 attrib
= o_attrib_search_name(o_current
->complex->prim_objs
,
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
);
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
;
595 /* use hierarchy separator */
601 printf("Got uref: _%s_\n", uref
);
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
));
625 return_value
= (char *) g_malloc(sizeof(char) * (strlen(uref
)));
627 while (cptr
!= end_of_base
) {
628 return_value
[i
] = *cptr
;
632 return_value
[i
] = '\0';
636 printf("new uref return_value = %s\n\n\n", return_value
);
639 return (return_value
);
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
,
649 if (graphical_attrib
== NULL
) {
650 graphical_attrib
= o_attrib_search_name(o_current
->complex->prim_objs
,
654 if (graphical_attrib
) {
655 g_free(graphical_attrib
);