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_object(o_current
, "source", count
);
61 looking_inside
= TRUE
;
63 printf("going to look inside now\n");
67 graphical
= s_hierarchy_graphical_search(o_current
, count
);
69 /* Do not bother traversing the hierarchy if the symbol has an */
70 /* graphical attribute attached to it. */
78 /* look for source=filename,filename, ... */
80 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
82 /* loop over all filenames */
83 while (current_filename
!= NULL
) {
84 s_log_message("Going to traverse source [%s]\n",
88 /* guts for a single filename */
89 p_current
= pr_current
->page_current
;
91 printf("Going down %s\n", current_filename
);
94 s_hierarchy_down_schematic_single(pr_current
,
96 pr_current
->page_current
,
98 HIERARCHY_FORCE_LOAD
);
100 if (page_control
== -1) {
101 fprintf(stderr
, "Could not open [%s]\n", current_filename
);
105 verbose_print("v\n");
106 verbose_reset_index();
108 netlist
->composite_component
= TRUE
;
109 /* can't do the following, don't know why... HACK TODO */
110 /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/
111 s_traverse_sheet(pr_current
,
112 pr_current
->page_current
,
113 netlist
->component_uref
);
118 /* XXX Does this require s_toplevel_goto_page to get the right cwd? */
119 pr_current
->page_current
= p_current
;
121 g_free(current_filename
);
123 current_filename
= u_basic_breakup_string(attrib
, ',', pcount
);
128 g_free(current_filename
);
132 /* continue looking outside first */
133 if (!looking_inside
) {
135 o_attrib_search_name_single_count(o_current
, "source",
139 /* okay we were looking outside and didn't */
140 /* find anything, so now we need to look */
141 /* inside the symbol */
142 if (!looking_inside
&& attrib
== NULL
&& !loaded_flag
) {
143 looking_inside
= TRUE
;
145 printf("switching to go to look inside\n");
149 if (looking_inside
) {
151 printf("looking inside\n");
153 attrib
= o_attrib_search_object(o_current
, "source", count
);
156 graphical
= s_hierarchy_graphical_search(o_current
, count
);
158 /* Do not bother looking further in the hierarchy if the symbol */
159 /* has an graphical attribute attached to it. */
169 void s_hierarchy_post_process(TOPLEVEL
* pr_current
, NETLIST
* head
)
172 CPINLIST
*pl_current
;
173 char *source_net_name
= NULL
;
174 int did_work
= FALSE
;
179 while (nl_current
!= NULL
) {
180 if (nl_current
->composite_component
) {
182 printf("Found composite %s\n", nl_current
->component_uref
);
185 if (nl_current
->cpins
) {
186 pl_current
= nl_current
->cpins
;
188 while (pl_current
!= NULL
) {
189 if (pl_current
->plid
!= -1) {
193 if (pl_current
->pin_label
== NULL
194 && pl_current
->plid
!= -1) {
196 "Found a pin [%s] on component [%s] which does not have a label!\n",
197 nl_current
->component_uref
,
198 pl_current
->pin_number
);
199 } else if (pl_current
->plid
!= -1) {
201 printf("# L: %s %s\n", pl_current
->pin_number
,
202 pl_current
->pin_label
);
204 /* get source net name, all nets are named already */
206 s_net_name_search(pr_current
,
209 printf("name: %s\n", source_net_name
);
210 printf("Now we need to search for: %s/%s\n",
211 nl_current
->component_uref
,
212 pl_current
->pin_label
);
216 s_hierarchy_setup_rename(pr_current
, head
,
217 nl_current
->component_uref
,
218 pl_current
->pin_label
,
222 "Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n",
223 pl_current
->pin_label
,
224 nl_current
->component_uref
);
228 pl_current
= pl_current
->next
;
232 nl_current
= nl_current
->next
;
235 s_rename_all(pr_current
, head
);
236 s_hierarchy_remove_compsite_all(head
);
240 s_hierarchy_setup_rename(TOPLEVEL
* pr_current
, NETLIST
* head
, char *uref
,
241 char *label
, char *new_name
)
244 CPINLIST
*pl_current
;
245 char *wanted_uref
= NULL
;
246 int did_work
= FALSE
;
248 /* this is questionable, because I'm not sure if it's exactly the */
249 /* same as the #if 0'ed out line */
250 /* search for the uref which has the name: label/uref (or whatever the */
251 /* hierarchy tag/separator order is) */
252 wanted_uref
= s_hierarchy_create_uref(pr_current
, label
, uref
);
255 printf("label: %s, uref: %s, wanted_uref: %s\n", label
, uref
,
260 while (nl_current
!= NULL
) {
261 if (nl_current
->component_uref
) {
262 pl_current
= nl_current
->cpins
;
263 if (strcmp(nl_current
->component_uref
, wanted_uref
) == 0) {
264 if (nl_current
->cpins
) {
265 /* skip over head of special io symbol */
266 pl_current
= nl_current
->cpins
->next
;;
268 printf("net to be renamed: %s\n",
269 pl_current
->net_name
);
270 printf("%s -> %s\n", pl_current
->net_name
, new_name
);
272 s_rename_add(pl_current
->net_name
, new_name
);
275 printf("Going to remove %s\n",
276 nl_current
->component_uref
);
278 s_hierarchy_remove_urefconn(head
,
285 nl_current
= nl_current
->next
;
291 void s_hierarchy_remove_urefconn(NETLIST
* head
, char *uref_disable
)
294 CPINLIST
*pl_current
;
296 char uref
[80], pin
[10];
299 while (nl_current
!= NULL
) {
300 pl_current
= nl_current
->cpins
;
301 while (pl_current
!= NULL
) {
302 n_current
= pl_current
->nets
;
303 while (n_current
!= NULL
) {
304 if (n_current
->connected_to
!= NULL
) {
305 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
307 printf(" looking at : %s %s\n", uref
, pin
);
309 if (strcmp(uref_disable
, uref
) == 0) {
311 printf("conn disabling %s\n",
312 n_current
->connected_to
);
314 /* can't do frees, since some names are links */
315 /* g_free(n_current->connected_to); */
316 n_current
->connected_to
= NULL
;
319 n_current
= n_current
->next
;
322 pl_current
= pl_current
->next
;
325 if (nl_current
->component_uref
) {
326 if (strcmp(nl_current
->component_uref
, uref_disable
) == 0) {
328 printf("refdes disabling: %s\n", nl_current
->component_uref
);
330 /* can't do frees, since some names are links */
331 /*free(nl_current->component_uref); */
332 nl_current
->component_uref
= NULL
;
335 nl_current
= nl_current
->next
;
339 void s_hierarchy_remove_compsite_all(NETLIST
* head
)
344 while (nl_current
!= NULL
) {
345 if (nl_current
->composite_component
) {
346 if (nl_current
->component_uref
!= NULL
) {
347 s_hierarchy_remove_urefconn(head
,
348 nl_current
->component_uref
);
351 nl_current
= nl_current
->next
;
355 char *s_hierarchy_create_uref(TOPLEVEL
* pr_current
, char *basename
,
356 char const *hierarchy_tag
)
358 char *return_value
= NULL
;
363 if (pr_current
->hierarchy_uref_separator
) {
364 switch (pr_current
->hierarchy_uref_order
) {
367 g_strconcat (hierarchy_tag
,
368 pr_current
->hierarchy_uref_separator
,
373 g_strconcat (basename
,
374 pr_current
->hierarchy_uref_separator
,
375 hierarchy_tag
, NULL
);
380 switch (pr_current
->hierarchy_uref_order
) {
383 g_strconcat (hierarchy_tag
, basename
, NULL
);
387 g_strconcat (basename
, hierarchy_tag
, NULL
);
397 return_value
= g_strdup (basename
);
403 return (return_value
);
406 char *s_hierarchy_create_netname(TOPLEVEL
* pr_current
, char *basename
,
407 char const *hierarchy_tag
)
409 char *return_value
= NULL
;
411 if (pr_current
->hierarchy_netname_mangle
== FALSE
) {
413 return (g_strdup (basename
));
421 if (pr_current
->hierarchy_netname_separator
) {
422 switch (pr_current
->hierarchy_netname_order
) {
425 g_strconcat (hierarchy_tag
,
426 pr_current
->hierarchy_netname_separator
,
432 g_strconcat (basename
,
433 pr_current
->hierarchy_netname_separator
,
434 hierarchy_tag
, NULL
);
438 switch (pr_current
->hierarchy_netname_order
) {
441 g_strconcat (hierarchy_tag
, basename
, NULL
);
445 g_strconcat (basename
, hierarchy_tag
, NULL
);
454 return_value
= g_strdup (basename
);
460 return (return_value
);
463 char *s_hierarchy_create_netattrib(TOPLEVEL
* pr_current
, char *basename
,
464 char const *hierarchy_tag
)
466 char *return_value
= NULL
;
468 if (pr_current
->hierarchy_netattrib_mangle
== FALSE
) {
470 return (g_strdup (basename
));
478 if (pr_current
->hierarchy_netattrib_separator
) {
479 switch (pr_current
->hierarchy_netattrib_order
) {
482 g_strconcat (hierarchy_tag
,
483 pr_current
->hierarchy_netattrib_separator
,
488 g_strconcat (basename
,
489 pr_current
->hierarchy_netattrib_separator
,
490 hierarchy_tag
, NULL
);
495 switch (pr_current
->hierarchy_netattrib_order
) {
498 g_strconcat (hierarchy_tag
, basename
, NULL
);
501 g_strconcat (basename
, hierarchy_tag
, NULL
);
510 return_value
= g_strdup (basename
);
516 return (return_value
);
520 s_hierarchy_remove_uref_mangling(TOPLEVEL
* pr_current
, NETLIST
* head
)
523 CPINLIST
*pl_current
;
525 char uref
[80], pin
[10];
526 char *new_uref
= NULL
;
527 char *new_connected_to
= NULL
;
530 while (nl_current
!= NULL
) {
532 if (nl_current
->component_uref
) {
535 s_hierarchy_return_baseuref(pr_current
,
536 nl_current
->component_uref
);
537 g_free(nl_current
->component_uref
);
538 nl_current
->component_uref
= new_uref
;
541 pl_current
= nl_current
->cpins
;
543 while (pl_current
!= NULL
) {
544 n_current
= pl_current
->nets
;
545 while (n_current
!= NULL
) {
547 if (n_current
->connected_to
) {
549 sscanf(n_current
->connected_to
, "%s %s", uref
, pin
);
551 s_hierarchy_return_baseuref(pr_current
, uref
);
552 new_connected_to
= g_strdup_printf("%s %s", new_uref
, pin
);
553 g_free(n_current
->connected_to
);
554 n_current
->connected_to
= new_connected_to
;
556 n_current
= n_current
->next
;
559 pl_current
= pl_current
->next
;
561 nl_current
= nl_current
->next
;
565 char *s_hierarchy_return_baseuref(TOPLEVEL
* pr_current
, char *uref
)
567 char *return_value
= NULL
;
568 char *start_of_base
= NULL
;
569 char *end_of_base
= NULL
;
571 /* use hierarchy separator */
577 printf("Got uref: _%s_\n", uref
);
580 if (pr_current
->hierarchy_uref_order
== APPEND
) {
581 start_of_base
= strrchr(uref
, '/'); /* separator is always '/' */
583 if (start_of_base
== NULL
) {
584 return (g_strdup (uref
));
587 return_value
= g_strdup (start_of_base
+ 1);
588 } else if (pr_current
->hierarchy_uref_order
== PREPEND
) {
589 end_of_base
= strchr(uref
, '/');
591 if (end_of_base
== NULL
) {
592 return (g_strdup (uref
));
595 return_value
= g_strndup(uref
, end_of_base
- uref
);
599 printf("new uref return_value = %s\n\n\n", return_value
);
602 return (return_value
);
606 s_hierarchy_graphical_search(OBJECT
* o_current
, int count
)
608 char *graphical_attrib
;
609 graphical_attrib
= o_attrib_search_name_single_count(o_current
,
612 if (graphical_attrib
== NULL
) {
613 graphical_attrib
= o_attrib_search_object(o_current
, "graphical", count
);
616 if (graphical_attrib
) {
617 g_free(graphical_attrib
);