Reduce visibility of functions used in only one file.
[geda-gaf/berndj.git] / gnetlist / src / s_hierarchy.c
blob1556dddf3e740e614f564890ae128ba8e06a97cf
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
21 #include <config.h>
23 #include <stdio.h>
24 #include <math.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 #ifdef HAVE_STRINGS_H
29 #include <strings.h>
30 #endif
32 #include <libgeda/libgeda.h>
34 #include "../include/globals.h"
35 #include "../include/prototype.h"
37 #ifdef HAVE_LIBDMALLOC
38 #include <dmalloc.h>
39 #endif
41 void
42 s_hierarchy_traverse(TOPLEVEL * pr_current, OBJECT * o_current,
43 NETLIST * netlist)
45 char *attrib;
46 int page_control=-1;
47 PAGE *p_current;
48 int count = 0;
49 int pcount = 0;
50 int looking_inside = FALSE;
51 int loaded_flag = FALSE;
52 char *current_filename;
53 int graphical=FALSE;
55 attrib = o_attrib_search_name_single_count(o_current, "source", 0);
57 /* if above is null, then look inside symbol */
58 if (attrib == NULL) {
59 attrib = o_attrib_search_name(o_current->complex->prim_objs,
60 "source", count);
62 looking_inside = TRUE;
63 #if DEBUG
64 printf("going to look inside now\n");
65 #endif
68 graphical = s_hierarchy_graphical_search(o_current, count);
69 if (graphical) {
70 /* Do not bother traversing the hierarchy if the symbol has an */
71 /* graphical attribute attached to it. */
72 if (attrib) {
73 g_free(attrib);
74 attrib = NULL;
78 while (attrib) {
79 /* look for source=filename,filename, ... */
80 pcount = 0;
81 current_filename = u_basic_breakup_string(attrib, ',', pcount);
83 /* loop over all filenames */
84 while (current_filename != NULL) {
85 s_log_message("Going to traverse source [%s]\n",
86 current_filename);
88 /* guts here */
89 /* guts for a single filename */
90 p_current = pr_current->page_current;
91 #if DEBUG
92 printf("Going down %s\n", current_filename);
93 #endif
94 page_control =
95 s_hierarchy_down_schematic_single(pr_current,
96 current_filename,
97 pr_current->page_current,
98 page_control,
99 HIERARCHY_FORCE_LOAD);
101 if (page_control == -1) {
102 fprintf(stderr, "Could not open [%s]\n", current_filename);
103 } else {
104 loaded_flag = TRUE;
106 verbose_print("v\n");
107 verbose_reset_index();
109 netlist->composite_component = TRUE;
110 /* can't do the following, don't know why... HACK TODO */
111 /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/
112 s_traverse_sheet(pr_current,
113 pr_current->page_current,
114 netlist->component_uref);
116 verbose_print("^");
119 /* XXX Does this require s_toplevel_goto_page to get the right cwd? */
120 pr_current->page_current = p_current;
122 g_free(current_filename);
123 pcount++;
124 current_filename = u_basic_breakup_string(attrib, ',', pcount);
127 g_free(attrib);
129 g_free(current_filename);
131 count++;
133 /* continue looking outside first */
134 if (!looking_inside) {
135 attrib =
136 o_attrib_search_name_single_count(o_current, "source",
137 count);
140 /* okay we were looking outside and didn't */
141 /* find anything, so now we need to look */
142 /* inside the symbol */
143 if (!looking_inside && attrib == NULL && !loaded_flag) {
144 looking_inside = TRUE;
145 #if DEBUG
146 printf("switching to go to look inside\n");
147 #endif
150 if (looking_inside) {
151 #if DEBUG
152 printf("looking inside\n");
153 #endif
154 attrib = o_attrib_search_name(o_current->complex->prim_objs,
155 "source", count);
158 graphical = s_hierarchy_graphical_search(o_current, count);
159 if (graphical) {
160 /* Do not bother looking further in the hierarchy if the symbol */
161 /* has an graphical attribute attached to it. */
162 if (attrib) {
163 g_free(attrib);
164 attrib = NULL;
171 void s_hierarchy_post_process(TOPLEVEL * pr_current, NETLIST * head)
173 NETLIST *nl_current;
174 CPINLIST *pl_current;
175 char *source_net_name = NULL;
176 int did_work = FALSE;
178 s_rename_next_set();
180 nl_current = head;
181 while (nl_current != NULL) {
182 if (nl_current->composite_component) {
183 #if DEBUG
184 printf("Found composite %s\n", nl_current->component_uref);
185 #endif
187 if (nl_current->cpins) {
188 pl_current = nl_current->cpins;
190 while (pl_current != NULL) {
192 if (pl_current->plid != -1) {
193 verbose_print("p");
196 if (pl_current->pin_label == NULL
197 && pl_current->plid != -1) {
198 fprintf(stderr,
199 "Found a pin [%s] on component [%s] which does not have a label!\n",
200 nl_current->component_uref,
201 pl_current->pin_number);
202 } else if (pl_current->plid != -1) {
204 #if DEBUG
205 printf("# L: %s %s\n", pl_current->pin_number,
206 pl_current->pin_label);
207 #endif
208 /* get source net name, all nets are named already */
209 source_net_name =
210 s_net_name_search(pr_current,
211 pl_current->nets);
212 #if DEBUG
213 printf("name: %s\n", source_net_name);
214 printf("Now we need to search for: %s/%s\n",
215 nl_current->component_uref,
216 pl_current->pin_label);
217 #endif
219 did_work =
220 s_hierarchy_setup_rename(pr_current, head,
221 nl_current->component_uref,
222 pl_current->pin_label,
223 source_net_name);
224 if (!did_work) {
225 fprintf(stderr,
226 "Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n",
227 pl_current->pin_label,
228 nl_current->component_uref);
232 pl_current = pl_current->next;
236 nl_current = nl_current->next;
239 s_rename_all(pr_current, head);
240 s_hierarchy_remove_compsite_all(head);
244 s_hierarchy_setup_rename(TOPLEVEL * pr_current, NETLIST * head, char *uref,
245 char *label, char *new_name)
247 NETLIST *nl_current;
248 CPINLIST *pl_current;
249 char *wanted_uref = NULL;
250 int did_work = FALSE;
252 /* this is questionable, because I'm not sure if it's exactly the */
253 /* same as the #if 0'ed out line */
254 /* search for the uref which has the name: label/uref (or whatever the */
255 /* hierarchy tag/separator order is) */
256 wanted_uref = s_hierarchy_create_uref(pr_current, label, uref);
258 #if DEBUG
259 printf("label: %s, uref: %s, wanted_uref: %s\n", label, uref,
260 wanted_uref);
261 #endif
263 nl_current = head;
264 while (nl_current != NULL) {
265 if (nl_current->component_uref) {
266 pl_current = nl_current->cpins;
267 if (strcmp(nl_current->component_uref, wanted_uref) == 0) {
268 if (nl_current->cpins) {
269 /* skip over head of special io symbol */
270 pl_current = nl_current->cpins->next;;
271 #if DEBUG
272 printf("net to be renamed: %s\n",
273 pl_current->net_name);
274 printf("%s -> %s\n", pl_current->net_name, new_name);
275 #endif
276 s_rename_add(pl_current->net_name, new_name);
278 #if DEBUG
279 printf("Going to remove %s\n",
280 nl_current->component_uref);
281 #endif
282 s_hierarchy_remove_urefconn(head,
283 nl_current->
284 component_uref);
285 did_work = TRUE;
289 nl_current = nl_current->next;
292 return (did_work);
295 void s_hierarchy_remove_urefconn(NETLIST * head, char *uref_disable)
297 NETLIST *nl_current;
298 CPINLIST *pl_current;
299 NET *n_current;
300 char uref[80], pin[10];
302 nl_current = head;
303 while (nl_current != NULL) {
304 pl_current = nl_current->cpins;
305 while (pl_current != NULL) {
306 n_current = pl_current->nets;
307 while (n_current != NULL) {
308 if (n_current->connected_to != NULL) {
309 sscanf(n_current->connected_to, "%s %s", uref, pin);
310 #if DEBUG
311 printf(" looking at : %s %s\n", uref, pin);
312 #endif
313 if (strcmp(uref_disable, uref) == 0) {
314 #if DEBUG
315 printf("conn disabling %s\n",
316 n_current->connected_to);
317 #endif
318 /* can't do frees, since some names are links */
319 /* g_free(n_current->connected_to);*/
320 n_current->connected_to = NULL;
323 n_current = n_current->next;
326 pl_current = pl_current->next;
329 if (nl_current->component_uref) {
330 if (strcmp(nl_current->component_uref, uref_disable) == 0) {
331 #if DEBUG
332 printf("refdes disabling: %s\n", nl_current->component_uref);
333 #endif
334 /* can't do frees, since some names are links */
335 /*free(nl_current->component_uref); */
336 nl_current->component_uref = NULL;
339 nl_current = nl_current->next;
343 void s_hierarchy_remove_compsite_all(NETLIST * head)
345 NETLIST *nl_current;
347 nl_current = head;
348 while (nl_current != NULL) {
349 if (nl_current->composite_component) {
350 if (nl_current->component_uref != NULL) {
351 s_hierarchy_remove_urefconn(head,
352 nl_current->component_uref);
355 nl_current = nl_current->next;
359 char *s_hierarchy_create_uref(TOPLEVEL * pr_current, char *basename,
360 char const *hierarchy_tag)
362 char *return_value = NULL;
364 if (hierarchy_tag) {
365 if (basename) {
367 if (pr_current->hierarchy_uref_separator) {
368 switch (pr_current->hierarchy_uref_order) {
369 case (APPEND):
370 return_value =
371 g_strconcat (hierarchy_tag,
372 pr_current->hierarchy_uref_separator,
373 basename, NULL);
374 break;
375 case (PREPEND):
376 return_value =
377 g_strconcat (basename,
378 pr_current->hierarchy_uref_separator,
379 hierarchy_tag, NULL);
381 break;
383 } else {
384 switch (pr_current->hierarchy_uref_order) {
385 case (APPEND):
386 return_value =
387 g_strconcat (hierarchy_tag, basename, NULL);
388 break;
389 case (PREPEND):
390 return_value =
391 g_strconcat (basename, hierarchy_tag, NULL);
392 break;
396 } else {
397 return_value = NULL;
399 } else {
400 if (basename) {
401 return_value = g_strdup (basename);
402 } else {
403 return_value = NULL;
407 return (return_value);
410 char *s_hierarchy_create_netname(TOPLEVEL * pr_current, char *basename,
411 char const *hierarchy_tag)
413 char *return_value = NULL;
415 if (pr_current->hierarchy_netname_mangle == FALSE) {
416 if (basename) {
417 return (g_strdup (basename));
418 } else {
419 return (NULL);
423 if (hierarchy_tag) {
424 if (basename) {
425 if (pr_current->hierarchy_netname_separator) {
426 switch (pr_current->hierarchy_netname_order) {
427 case (APPEND):
428 return_value =
429 g_strconcat (hierarchy_tag,
430 pr_current->hierarchy_netname_separator,
431 basename, NULL);
432 break;
434 case (PREPEND):
435 return_value =
436 g_strconcat (basename,
437 pr_current->hierarchy_netname_separator,
438 hierarchy_tag, NULL);
439 break;
441 } else {
442 switch (pr_current->hierarchy_netname_order) {
443 case (APPEND):
444 return_value =
445 g_strconcat (hierarchy_tag, basename, NULL);
446 break;
447 case (PREPEND):
448 return_value =
449 g_strconcat (basename, hierarchy_tag, NULL);
450 break;
453 } else {
454 return_value = NULL;
456 } else {
457 if (basename) {
458 return_value = g_strdup (basename);
459 } else {
460 return_value = NULL;
464 return (return_value);
467 char *s_hierarchy_create_netattrib(TOPLEVEL * pr_current, char *basename,
468 char const *hierarchy_tag)
470 char *return_value = NULL;
472 if (pr_current->hierarchy_netattrib_mangle == FALSE) {
473 if (basename) {
474 return (g_strdup (basename));
475 } else {
476 return (NULL);
480 if (hierarchy_tag) {
481 if (basename) {
482 if (pr_current->hierarchy_netattrib_separator) {
483 switch (pr_current->hierarchy_netattrib_order) {
484 case (APPEND):
485 return_value =
486 g_strconcat (hierarchy_tag,
487 pr_current->hierarchy_netattrib_separator,
488 basename, NULL);
489 break;
490 case (PREPEND):
491 return_value =
492 g_strconcat (basename,
493 pr_current->hierarchy_netattrib_separator,
494 hierarchy_tag, NULL);
496 break;
498 } else {
499 switch (pr_current->hierarchy_netattrib_order) {
500 case (APPEND):
501 return_value =
502 g_strconcat (hierarchy_tag, basename, NULL);
503 case (PREPEND):
504 return_value =
505 g_strconcat (basename, hierarchy_tag, NULL);
506 break;
509 } else {
510 return_value = NULL;
512 } else {
513 if (basename) {
514 return_value = g_strdup (basename);
515 } else {
516 return_value = NULL;
520 return (return_value);
523 void
524 s_hierarchy_remove_uref_mangling(TOPLEVEL * pr_current, NETLIST * head)
526 NETLIST *nl_current;
527 CPINLIST *pl_current;
528 NET *n_current;
529 char uref[80], pin[10];
530 char *new_uref = NULL;
531 char *new_connected_to = NULL;
533 nl_current = head;
534 while (nl_current != NULL) {
536 if (nl_current->component_uref) {
537 verbose_print("u");
538 new_uref =
539 s_hierarchy_return_baseuref(pr_current,
540 nl_current->component_uref);
541 g_free(nl_current->component_uref);
542 nl_current->component_uref = new_uref;
545 pl_current = nl_current->cpins;
547 while (pl_current != NULL) {
548 n_current = pl_current->nets;
549 while (n_current != NULL) {
551 if (n_current->connected_to) {
552 verbose_print("U");
553 sscanf(n_current->connected_to, "%s %s", uref, pin);
554 new_uref =
555 s_hierarchy_return_baseuref(pr_current, uref);
556 new_connected_to = g_strdup_printf("%s %s", new_uref, pin);
557 g_free(n_current->connected_to);
558 n_current->connected_to = new_connected_to;
560 n_current = n_current->next;
563 pl_current = pl_current->next;
565 nl_current = nl_current->next;
569 char *s_hierarchy_return_baseuref(TOPLEVEL * pr_current, char *uref)
571 char *return_value = NULL;
572 char *start_of_base = NULL;
573 char *end_of_base = NULL;
575 /* use hierarchy separator */
577 if (uref == NULL) {
578 return (NULL);
580 #if DEBUG
581 printf("Got uref: _%s_\n", uref);
582 #endif
584 if (pr_current->hierarchy_uref_order == APPEND) {
585 start_of_base = strrchr(uref, '/'); /* separator is always '/' */
587 if (start_of_base == NULL) {
588 return (g_strdup (uref));
591 return_value = g_strdup (start_of_base + 1);
592 } else if (pr_current->hierarchy_uref_order == PREPEND) {
593 end_of_base = strchr(uref, '/');
595 if (end_of_base == NULL) {
596 return (g_strdup (uref));
599 return_value = g_strndup(uref, end_of_base - uref);
602 #if DEBUG
603 printf("new uref return_value = %s\n\n\n", return_value);
604 #endif
606 return (return_value);
609 int
610 s_hierarchy_graphical_search(OBJECT* o_current, int count)
612 char *graphical_attrib;
613 graphical_attrib = o_attrib_search_name_single_count(o_current,
614 "graphical", count);
616 if (graphical_attrib == NULL) {
617 graphical_attrib = o_attrib_search_name(o_current->complex->prim_objs,
618 "graphical", count);
621 if (graphical_attrib) {
622 g_free(graphical_attrib);
623 return TRUE;
626 return FALSE;