Updated copyright text/header in most source files.
[geda-gaf.git] / gnetlist / src / s_hierarchy.c
blob7b8f07a47a2e629a46dd0189e1465df22206afec
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., 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_attached_attribs_by_name (o_current, "source", 0);
57 /* if above is null, then look inside symbol */
58 if (attrib == NULL) {
59 attrib = o_attrib_search_inherited_attribs_by_name (o_current,
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) {
80 /* look for source=filename,filename, ... */
81 pcount = 0;
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",
88 current_filename);
90 /* guts here */
91 /* guts for a single filename */
92 p_current = pr_current->page_current;
93 #if DEBUG
94 printf("Going down %s\n", current_filename);
95 #endif
96 page_control =
97 s_hierarchy_down_schematic_single(pr_current,
98 current_filename,
99 pr_current->page_current,
100 page_control,
101 HIERARCHY_FORCE_LOAD);
103 if (page_control == -1) {
104 fprintf(stderr, "Could not open [%s]\n", current_filename);
105 } else {
107 loaded_flag = TRUE;
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 s_page_objects (pr_current->page_current),
117 netlist->component_uref);
119 verbose_print("^");
122 pr_current->page_current = p_current;
124 g_free(current_filename);
125 pcount++;
126 current_filename = u_basic_breakup_string(attrib, ',', pcount);
129 g_free(attrib);
131 g_free(current_filename);
133 count++;
135 /* continue looking outside first */
136 if (!looking_inside) {
137 attrib =
138 o_attrib_search_attached_attribs_by_name (o_current, "source",
139 count);
142 /* okay we were looking outside and didn't */
143 /* find anything, so now we need to look */
144 /* inside the symbol */
145 if (!looking_inside && attrib == NULL && !loaded_flag) {
146 looking_inside = TRUE;
147 #if DEBUG
148 printf("switching to go to look inside\n");
149 #endif
152 if (looking_inside) {
153 #if DEBUG
154 printf("looking inside\n");
155 #endif
156 attrib =
157 o_attrib_search_inherited_attribs_by_name (o_current,
158 "source", count);
161 graphical = s_hierarchy_graphical_search(o_current, count);
162 if (graphical) {
163 /* Do not bother looking further in the hierarchy if the symbol */
164 /* has an graphical attribute attached to it. */
165 if (attrib) {
166 g_free(attrib);
167 attrib = NULL;
174 void s_hierarchy_post_process(TOPLEVEL * pr_current, NETLIST * head)
176 NETLIST *nl_current;
177 CPINLIST *pl_current;
178 char *source_net_name = NULL;
179 int did_work = FALSE;
181 s_rename_next_set();
183 nl_current = head;
184 while (nl_current != NULL) {
185 if (nl_current->composite_component) {
186 #if DEBUG
187 printf("Found composite %s\n", nl_current->component_uref);
188 #endif
190 if (nl_current->cpins) {
191 pl_current = nl_current->cpins;
193 while (pl_current != NULL) {
195 if (pl_current->plid != -1) {
196 verbose_print("p");
199 if (pl_current->pin_label == NULL
200 && pl_current->plid != -1) {
201 fprintf(stderr,
202 "Found a pin [%s] on component [%s] which does not have a label!\n",
203 nl_current->component_uref,
204 pl_current->pin_number);
205 } else if (pl_current->plid != -1) {
207 #if DEBUG
208 printf("# L: %s %s\n", pl_current->pin_number,
209 pl_current->pin_label);
210 #endif
211 /* get source net name, all nets are named already */
212 source_net_name =
213 s_net_name_search(pr_current,
214 pl_current->nets);
215 #if DEBUG
216 printf("name: %s\n", source_net_name);
217 printf("Now we need to search for: %s/%s\n",
218 nl_current->component_uref,
219 pl_current->pin_label);
220 #endif
222 did_work =
223 s_hierarchy_setup_rename(pr_current, head,
224 nl_current->component_uref,
225 pl_current->pin_label,
226 source_net_name);
227 if (!did_work) {
228 fprintf(stderr,
229 "Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n",
230 pl_current->pin_label,
231 nl_current->component_uref);
235 pl_current = pl_current->next;
239 nl_current = nl_current->next;
242 s_rename_all(pr_current, head);
243 s_hierarchy_remove_compsite_all(head);
247 s_hierarchy_setup_rename(TOPLEVEL * pr_current, NETLIST * head, char *uref,
248 char *label, char *new_name)
250 NETLIST *nl_current;
251 CPINLIST *pl_current;
252 char *wanted_uref = NULL;
253 int did_work = FALSE;
255 /* this is questionable, because I'm not sure if it's exactly the */
256 /* same as the #if 0'ed out line */
257 /* search for the uref which has the name: label/uref (or whatever the */
258 /* hierarchy tag/separator order is) */
259 wanted_uref = s_hierarchy_create_uref(pr_current, label, uref);
261 #if DEBUG
262 printf("label: %s, uref: %s, wanted_uref: %s\n", label, uref,
263 wanted_uref);
264 #endif
266 nl_current = head;
267 while (nl_current != NULL) {
268 if (nl_current->component_uref) {
269 pl_current = nl_current->cpins;
270 if (strcmp(nl_current->component_uref, wanted_uref) == 0) {
271 if (nl_current->cpins) {
272 /* skip over head of special io symbol */
273 pl_current = nl_current->cpins->next;;
274 #if DEBUG
275 printf("net to be renamed: %s\n",
276 pl_current->net_name);
277 printf("%s -> %s\n", pl_current->net_name, new_name);
278 #endif
279 s_rename_add(pl_current->net_name, new_name);
281 #if DEBUG
282 printf("Going to remove %s\n",
283 nl_current->component_uref);
284 #endif
285 s_hierarchy_remove_urefconn(head,
286 nl_current->
287 component_uref);
288 did_work = TRUE;
292 nl_current = nl_current->next;
295 return (did_work);
298 void s_hierarchy_remove_urefconn(NETLIST * head, char *uref_disable)
300 NETLIST *nl_current;
301 CPINLIST *pl_current;
302 NET *n_current;
303 char uref[80], pin[10];
305 nl_current = head;
306 while (nl_current != NULL) {
307 pl_current = nl_current->cpins;
308 while (pl_current != NULL) {
309 n_current = pl_current->nets;
310 while (n_current != NULL) {
311 if (n_current->connected_to != NULL) {
312 sscanf(n_current->connected_to, "%s %s", uref, pin);
313 #if DEBUG
314 printf(" looking at : %s %s\n", uref, pin);
315 #endif
316 if (strcmp(uref_disable, uref) == 0) {
317 #if DEBUG
318 printf("conn disabling %s\n",
319 n_current->connected_to);
320 #endif
321 /* can't do frees, since some names are links */
322 /* g_free(n_current->connected_to);*/
323 n_current->connected_to = NULL;
326 n_current = n_current->next;
329 pl_current = pl_current->next;
332 if (nl_current->component_uref) {
333 if (strcmp(nl_current->component_uref, uref_disable) == 0) {
334 #if DEBUG
335 printf("refdes disabling: %s\n", nl_current->component_uref);
336 #endif
337 /* can't do frees, since some names are links */
338 /*free(nl_current->component_uref); */
339 nl_current->component_uref = NULL;
342 nl_current = nl_current->next;
346 void s_hierarchy_remove_compsite_all(NETLIST * head)
348 NETLIST *nl_current;
350 nl_current = head;
351 while (nl_current != NULL) {
352 if (nl_current->composite_component) {
353 if (nl_current->component_uref != NULL) {
354 s_hierarchy_remove_urefconn(head,
355 nl_current->component_uref);
358 nl_current = nl_current->next;
363 char *s_hierarchy_create_uref(TOPLEVEL * pr_current, char *basename,
364 char *hierarchy_tag)
366 char *return_value = NULL;
368 if (hierarchy_tag) {
369 if (basename) {
371 if (pr_current->hierarchy_uref_separator) {
372 switch (pr_current->hierarchy_uref_order) {
373 case (APPEND):
374 return_value =
375 g_strconcat (hierarchy_tag,
376 pr_current->hierarchy_uref_separator,
377 basename, NULL);
378 break;
379 case (PREPEND):
380 return_value =
381 g_strconcat (basename,
382 pr_current->hierarchy_uref_separator,
383 hierarchy_tag, NULL);
385 break;
387 } else {
388 switch (pr_current->hierarchy_uref_order) {
389 case (APPEND):
390 return_value =
391 g_strconcat (hierarchy_tag, basename, NULL);
392 break;
393 case (PREPEND):
394 return_value =
395 g_strconcat (basename, hierarchy_tag, NULL);
396 break;
400 } else {
401 return_value = NULL;
403 } else {
404 if (basename) {
405 return_value = g_strdup (basename);
406 } else {
407 return_value = NULL;
411 return (return_value);
414 char *s_hierarchy_create_netname(TOPLEVEL * pr_current, char *basename,
415 char *hierarchy_tag)
417 char *return_value = NULL;
419 if (pr_current->hierarchy_netname_mangle == FALSE) {
420 if (basename) {
421 return (g_strdup (basename));
422 } else {
423 return (NULL);
427 if (hierarchy_tag) {
428 if (basename) {
430 if (pr_current->hierarchy_netname_separator) {
431 switch (pr_current->hierarchy_netname_order) {
432 case (APPEND):
433 return_value =
434 g_strconcat (hierarchy_tag,
435 pr_current->hierarchy_netname_separator,
436 basename, NULL);
438 break;
440 case (PREPEND):
441 return_value =
442 g_strconcat (basename,
443 pr_current->hierarchy_netname_separator,
444 hierarchy_tag, NULL);
446 break;
449 } else {
450 switch (pr_current->hierarchy_netname_order) {
451 case (APPEND):
453 return_value =
454 g_strconcat (hierarchy_tag, basename, NULL);
455 break;
456 case (PREPEND):
457 return_value =
458 g_strconcat (basename, hierarchy_tag, NULL);
460 break;
464 } else {
465 return_value = NULL;
467 } else {
468 if (basename) {
469 return_value = g_strdup (basename);
470 } else {
471 return_value = NULL;
475 return (return_value);
478 char *s_hierarchy_create_netattrib(TOPLEVEL * pr_current, char *basename,
479 char *hierarchy_tag)
481 char *return_value = NULL;
483 if (pr_current->hierarchy_netattrib_mangle == FALSE) {
484 if (basename) {
485 return (g_strdup (basename));
486 } else {
487 return (NULL);
491 if (hierarchy_tag) {
492 if (basename) {
494 if (pr_current->hierarchy_netattrib_separator) {
495 switch (pr_current->hierarchy_netattrib_order) {
496 case (APPEND):
497 return_value =
498 g_strconcat (hierarchy_tag,
499 pr_current->hierarchy_netattrib_separator,
500 basename, NULL);
501 break;
502 case (PREPEND):
503 return_value =
504 g_strconcat (basename,
505 pr_current->hierarchy_netattrib_separator,
506 hierarchy_tag, NULL);
508 break;
510 } else {
511 switch (pr_current->hierarchy_netattrib_order) {
512 case (APPEND):
513 return_value =
514 g_strconcat (hierarchy_tag, basename, NULL);
515 case (PREPEND):
516 return_value =
517 g_strconcat (basename, hierarchy_tag, NULL);
518 break;
521 } else {
522 return_value = NULL;
524 } else {
525 if (basename) {
526 return_value = g_strdup (basename);
527 } else {
528 return_value = NULL;
532 return (return_value);
535 void
536 s_hierarchy_remove_uref_mangling(TOPLEVEL * pr_current, NETLIST * head)
538 NETLIST *nl_current;
539 CPINLIST *pl_current;
540 NET *n_current;
541 char uref[80], pin[10];
542 char *new_uref = NULL;
543 char *new_connected_to = NULL;
545 nl_current = head;
546 while (nl_current != NULL) {
548 if (nl_current->component_uref) {
549 verbose_print("u");
550 new_uref =
551 s_hierarchy_return_baseuref(pr_current,
552 nl_current->component_uref);
553 g_free(nl_current->component_uref);
554 nl_current->component_uref = new_uref;
557 pl_current = nl_current->cpins;
559 while (pl_current != NULL) {
560 n_current = pl_current->nets;
561 while (n_current != NULL) {
563 if (n_current->connected_to) {
564 verbose_print("U");
565 sscanf(n_current->connected_to, "%s %s", uref, pin);
566 new_uref =
567 s_hierarchy_return_baseuref(pr_current, uref);
568 new_connected_to = g_strdup_printf("%s %s", new_uref, pin);
569 g_free(n_current->connected_to);
570 n_current->connected_to = new_connected_to;
572 n_current = n_current->next;
575 pl_current = pl_current->next;
577 nl_current = nl_current->next;
582 char *s_hierarchy_return_baseuref(TOPLEVEL * pr_current, char *uref)
584 char *return_value = NULL;
585 char *start_of_base = NULL;
586 char *end_of_base = NULL;
587 char *cptr = NULL;
589 /* use hierarchy separator */
591 if (uref == NULL) {
592 return (NULL);
594 #if DEBUG
595 printf("Got uref: _%s_\n", uref);
596 #endif
599 if (pr_current->hierarchy_uref_order == APPEND) {
601 start_of_base = strrchr(uref, '/'); /* separator is always '/' */
603 if (start_of_base == NULL) {
604 return (g_strdup (uref));
607 return_value = g_strdup (start_of_base + 1);
609 } else if (pr_current->hierarchy_uref_order == PREPEND) {
611 end_of_base = strchr(uref, '/');
613 if (end_of_base == NULL) {
614 return (g_strdup (uref));
617 cptr = uref;
619 return_value = g_strndup(uref, end_of_base - uref);
622 #if DEBUG
623 printf("new uref return_value = %s\n\n\n", return_value);
624 #endif
626 return (return_value);
629 int s_hierarchy_graphical_search (OBJECT* o_current, int count)
631 char *graphical_attrib;
632 graphical_attrib =
633 o_attrib_search_object_attribs_by_name (o_current, "graphical", count);
635 if (graphical_attrib) {
636 g_free (graphical_attrib);
637 return TRUE;
640 return FALSE;