gnetlist
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gnetlist - gEDA Netlist 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <config.h> 00022 00023 #include <stdio.h> 00024 #include <math.h> 00025 #ifdef HAVE_STRING_H 00026 #include <string.h> 00027 #endif 00028 #ifdef HAVE_STRINGS_H 00029 #include <strings.h> 00030 #endif 00031 00032 #include <libgeda/libgeda.h> 00033 00034 #include "../include/globals.h" 00035 #include "../include/prototype.h" 00036 00037 #ifdef HAVE_LIBDMALLOC 00038 #include <dmalloc.h> 00039 #endif 00040 00041 void 00042 s_hierarchy_traverse(TOPLEVEL * pr_current, OBJECT * o_current, 00043 NETLIST * netlist) 00044 { 00045 char *attrib; 00046 int page_control=-1; 00047 PAGE *p_current; 00048 PAGE *child_page; 00049 int count = 0; 00050 int pcount = 0; 00051 int looking_inside = FALSE; 00052 int loaded_flag = FALSE; 00053 char *current_filename; 00054 int graphical=FALSE; 00055 00056 attrib = o_attrib_search_attached_attribs_by_name (o_current, "source", 0); 00057 00058 /* if above is null, then look inside symbol */ 00059 if (attrib == NULL) { 00060 attrib = o_attrib_search_inherited_attribs_by_name (o_current, 00061 "source", count); 00062 00063 looking_inside = TRUE; 00064 #if DEBUG 00065 printf("going to look inside now\n"); 00066 #endif 00067 } 00068 00069 graphical = s_hierarchy_graphical_search(o_current, count); 00070 if (graphical) { 00071 /* Do not bother traversing the hierarchy if the symbol has an */ 00072 /* graphical attribute attached to it. */ 00073 if (attrib) { 00074 g_free(attrib); 00075 attrib = NULL; 00076 } 00077 } 00078 00079 while (attrib) { 00080 00081 /* look for source=filename,filename, ... */ 00082 pcount = 0; 00083 current_filename = u_basic_breakup_string(attrib, ',', pcount); 00084 00085 /* loop over all filenames */ 00086 while (current_filename != NULL) { 00087 00088 s_log_message("Going to traverse source [%s]\n", 00089 current_filename); 00090 00091 /* guts here */ 00092 /* guts for a single filename */ 00093 p_current = pr_current->page_current; 00094 #if DEBUG 00095 printf("Going down %s\n", current_filename); 00096 #endif 00097 child_page = 00098 s_hierarchy_down_schematic_single(pr_current, 00099 current_filename, 00100 pr_current->page_current, 00101 page_control, 00102 HIERARCHY_FORCE_LOAD); 00103 00104 if (child_page == NULL) { 00105 fprintf(stderr, "Could not open [%s]\n", current_filename); 00106 } else { 00107 page_control = child_page->page_control; 00108 s_page_goto (pr_current, child_page); 00109 00110 loaded_flag = TRUE; 00111 00112 verbose_print("v\n"); 00113 verbose_reset_index(); 00114 00115 netlist->composite_component = TRUE; 00116 /* can't do the following, don't know why... HACK TODO */ 00117 /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/ 00118 s_traverse_sheet (pr_current, 00119 s_page_objects (pr_current->page_current), 00120 netlist->component_uref); 00121 00122 verbose_print("^"); 00123 } 00124 00125 pr_current->page_current = p_current; 00126 00127 g_free(current_filename); 00128 pcount++; 00129 current_filename = u_basic_breakup_string(attrib, ',', pcount); 00130 } 00131 00132 g_free(attrib); 00133 00134 g_free(current_filename); 00135 00136 count++; 00137 00138 /* continue looking outside first */ 00139 if (!looking_inside) { 00140 attrib = 00141 o_attrib_search_attached_attribs_by_name (o_current, "source", 00142 count); 00143 } 00144 00145 /* okay we were looking outside and didn't */ 00146 /* find anything, so now we need to look */ 00147 /* inside the symbol */ 00148 if (!looking_inside && attrib == NULL && !loaded_flag) { 00149 looking_inside = TRUE; 00150 #if DEBUG 00151 printf("switching to go to look inside\n"); 00152 #endif 00153 } 00154 00155 if (looking_inside) { 00156 #if DEBUG 00157 printf("looking inside\n"); 00158 #endif 00159 attrib = 00160 o_attrib_search_inherited_attribs_by_name (o_current, 00161 "source", count); 00162 } 00163 00164 graphical = s_hierarchy_graphical_search(o_current, count); 00165 if (graphical) { 00166 /* Do not bother looking further in the hierarchy if the symbol */ 00167 /* has an graphical attribute attached to it. */ 00168 if (attrib) { 00169 g_free(attrib); 00170 attrib = NULL; 00171 } 00172 } 00173 } 00174 } 00175 00176 00177 void s_hierarchy_post_process(TOPLEVEL * pr_current, NETLIST * head) 00178 { 00179 NETLIST *nl_current; 00180 CPINLIST *pl_current; 00181 char *source_net_name = NULL; 00182 int did_work = FALSE; 00183 00184 s_rename_next_set(); 00185 00186 nl_current = head; 00187 while (nl_current != NULL) { 00188 if (nl_current->composite_component) { 00189 #if DEBUG 00190 printf("Found composite %s\n", nl_current->component_uref); 00191 #endif 00192 00193 if (nl_current->cpins) { 00194 pl_current = nl_current->cpins; 00195 00196 while (pl_current != NULL) { 00197 00198 if (pl_current->plid != -1) { 00199 verbose_print("p"); 00200 } 00201 00202 if (pl_current->pin_label == NULL 00203 && pl_current->plid != -1) { 00204 fprintf(stderr, 00205 "Found a pin [%s] on component [%s] which does not have a label!\n", 00206 nl_current->component_uref, 00207 pl_current->pin_number); 00208 } else if (pl_current->plid != -1) { 00209 00210 #if DEBUG 00211 printf("# L: %s %s\n", pl_current->pin_number, 00212 pl_current->pin_label); 00213 #endif 00214 /* get source net name, all nets are named already */ 00215 source_net_name = 00216 s_net_name_search(pr_current, 00217 pl_current->nets); 00218 #if DEBUG 00219 printf("name: %s\n", source_net_name); 00220 printf("Now we need to search for: %s/%s\n", 00221 nl_current->component_uref, 00222 pl_current->pin_label); 00223 #endif 00224 00225 did_work = 00226 s_hierarchy_setup_rename(pr_current, head, 00227 nl_current->component_uref, 00228 pl_current->pin_label, 00229 source_net_name); 00230 if (!did_work) { 00231 fprintf(stderr, 00232 "Missing I/O symbol with refdes [%s] inside schematic for symbol [%s]\n", 00233 pl_current->pin_label, 00234 nl_current->component_uref); 00235 00236 } 00237 } 00238 pl_current = pl_current->next; 00239 } 00240 } 00241 } 00242 nl_current = nl_current->next; 00243 } 00244 00245 s_rename_all(pr_current, head); 00246 s_hierarchy_remove_compsite_all(head); 00247 } 00248 00249 int 00250 s_hierarchy_setup_rename(TOPLEVEL * pr_current, NETLIST * head, char *uref, 00251 char *label, char *new_name) 00252 { 00253 NETLIST *nl_current; 00254 CPINLIST *pl_current; 00255 char *wanted_uref = NULL; 00256 int did_work = FALSE; 00257 00258 /* this is questionable, because I'm not sure if it's exactly the */ 00259 /* same as the #if 0'ed out line */ 00260 /* search for the uref which has the name: label/uref (or whatever the */ 00261 /* hierarchy tag/separator order is) */ 00262 wanted_uref = s_hierarchy_create_uref(pr_current, label, uref); 00263 00264 #if DEBUG 00265 printf("label: %s, uref: %s, wanted_uref: %s\n", label, uref, 00266 wanted_uref); 00267 #endif 00268 00269 nl_current = head; 00270 while (nl_current != NULL) { 00271 if (nl_current->component_uref) { 00272 pl_current = nl_current->cpins; 00273 if (strcmp(nl_current->component_uref, wanted_uref) == 0) { 00274 if (nl_current->cpins) { 00275 /* skip over head of special io symbol */ 00276 pl_current = nl_current->cpins->next;; 00277 #if DEBUG 00278 printf("net to be renamed: %s\n", 00279 pl_current->net_name); 00280 printf("%s -> %s\n", pl_current->net_name, new_name); 00281 #endif 00282 s_rename_add(pl_current->net_name, new_name); 00283 00284 #if DEBUG 00285 printf("Going to remove %s\n", 00286 nl_current->component_uref); 00287 #endif 00288 s_hierarchy_remove_urefconn(head, 00289 nl_current-> 00290 component_uref); 00291 did_work = TRUE; 00292 } 00293 } 00294 } 00295 nl_current = nl_current->next; 00296 } 00297 00298 return (did_work); 00299 } 00300 00301 void s_hierarchy_remove_urefconn(NETLIST * head, char *uref_disable) 00302 { 00303 NETLIST *nl_current; 00304 CPINLIST *pl_current; 00305 NET *n_current; 00306 char uref[80], pin[10]; 00307 00308 nl_current = head; 00309 while (nl_current != NULL) { 00310 pl_current = nl_current->cpins; 00311 while (pl_current != NULL) { 00312 n_current = pl_current->nets; 00313 while (n_current != NULL) { 00314 if (n_current->connected_to != NULL) { 00315 sscanf(n_current->connected_to, "%s %s", uref, pin); 00316 #if DEBUG 00317 printf(" looking at : %s %s\n", uref, pin); 00318 #endif 00319 if (strcmp(uref_disable, uref) == 0) { 00320 #if DEBUG 00321 printf("conn disabling %s\n", 00322 n_current->connected_to); 00323 #endif 00324 /* can't do frees, since some names are links */ 00325 /* g_free(n_current->connected_to);*/ 00326 n_current->connected_to = NULL; 00327 } 00328 } 00329 n_current = n_current->next; 00330 } 00331 00332 pl_current = pl_current->next; 00333 } 00334 00335 if (nl_current->component_uref) { 00336 if (strcmp(nl_current->component_uref, uref_disable) == 0) { 00337 #if DEBUG 00338 printf("refdes disabling: %s\n", nl_current->component_uref); 00339 #endif 00340 /* can't do frees, since some names are links */ 00341 /*free(nl_current->component_uref); */ 00342 nl_current->component_uref = NULL; 00343 } 00344 } 00345 nl_current = nl_current->next; 00346 } 00347 } 00348 00349 void s_hierarchy_remove_compsite_all(NETLIST * head) 00350 { 00351 NETLIST *nl_current; 00352 00353 nl_current = head; 00354 while (nl_current != NULL) { 00355 if (nl_current->composite_component) { 00356 if (nl_current->component_uref != NULL) { 00357 s_hierarchy_remove_urefconn(head, 00358 nl_current->component_uref); 00359 } 00360 } 00361 nl_current = nl_current->next; 00362 } 00363 00364 } 00365 00366 char *s_hierarchy_create_uref(TOPLEVEL * pr_current, char *basename, 00367 char *hierarchy_tag) 00368 { 00369 char *return_value = NULL; 00370 00371 if (hierarchy_tag) { 00372 if (basename) { 00373 00374 if (pr_current->hierarchy_uref_separator) { 00375 switch (pr_current->hierarchy_uref_order) { 00376 case (APPEND): 00377 return_value = 00378 g_strconcat (hierarchy_tag, 00379 pr_current->hierarchy_uref_separator, 00380 basename, NULL); 00381 break; 00382 case (PREPEND): 00383 return_value = 00384 g_strconcat (basename, 00385 pr_current->hierarchy_uref_separator, 00386 hierarchy_tag, NULL); 00387 00388 break; 00389 } 00390 } else { 00391 switch (pr_current->hierarchy_uref_order) { 00392 case (APPEND): 00393 return_value = 00394 g_strconcat (hierarchy_tag, basename, NULL); 00395 break; 00396 case (PREPEND): 00397 return_value = 00398 g_strconcat (basename, hierarchy_tag, NULL); 00399 break; 00400 00401 } 00402 } 00403 } else { 00404 return_value = NULL; 00405 } 00406 } else { 00407 if (basename) { 00408 return_value = g_strdup (basename); 00409 } else { 00410 return_value = NULL; 00411 } 00412 } 00413 00414 return (return_value); 00415 } 00416 00417 char *s_hierarchy_create_netname(TOPLEVEL * pr_current, char *basename, 00418 char *hierarchy_tag) 00419 { 00420 char *return_value = NULL; 00421 00422 if (pr_current->hierarchy_netname_mangle == FALSE) { 00423 if (basename) { 00424 return (g_strdup (basename)); 00425 } else { 00426 return (NULL); 00427 } 00428 } 00429 00430 if (hierarchy_tag) { 00431 if (basename) { 00432 00433 if (pr_current->hierarchy_netname_separator) { 00434 switch (pr_current->hierarchy_netname_order) { 00435 case (APPEND): 00436 return_value = 00437 g_strconcat (hierarchy_tag, 00438 pr_current->hierarchy_netname_separator, 00439 basename, NULL); 00440 00441 break; 00442 00443 case (PREPEND): 00444 return_value = 00445 g_strconcat (basename, 00446 pr_current->hierarchy_netname_separator, 00447 hierarchy_tag, NULL); 00448 00449 break; 00450 00451 } 00452 } else { 00453 switch (pr_current->hierarchy_netname_order) { 00454 case (APPEND): 00455 00456 return_value = 00457 g_strconcat (hierarchy_tag, basename, NULL); 00458 break; 00459 case (PREPEND): 00460 return_value = 00461 g_strconcat (basename, hierarchy_tag, NULL); 00462 00463 break; 00464 } 00465 00466 } 00467 } else { 00468 return_value = NULL; 00469 } 00470 } else { 00471 if (basename) { 00472 return_value = g_strdup (basename); 00473 } else { 00474 return_value = NULL; 00475 } 00476 } 00477 00478 return (return_value); 00479 } 00480 00481 char *s_hierarchy_create_netattrib(TOPLEVEL * pr_current, char *basename, 00482 char *hierarchy_tag) 00483 { 00484 char *return_value = NULL; 00485 00486 if (pr_current->hierarchy_netattrib_mangle == FALSE) { 00487 if (basename) { 00488 return (g_strdup (basename)); 00489 } else { 00490 return (NULL); 00491 } 00492 } 00493 00494 if (hierarchy_tag) { 00495 if (basename) { 00496 00497 if (pr_current->hierarchy_netattrib_separator) { 00498 switch (pr_current->hierarchy_netattrib_order) { 00499 case (APPEND): 00500 return_value = 00501 g_strconcat (hierarchy_tag, 00502 pr_current->hierarchy_netattrib_separator, 00503 basename, NULL); 00504 break; 00505 case (PREPEND): 00506 return_value = 00507 g_strconcat (basename, 00508 pr_current->hierarchy_netattrib_separator, 00509 hierarchy_tag, NULL); 00510 00511 break; 00512 } 00513 } else { 00514 switch (pr_current->hierarchy_netattrib_order) { 00515 case (APPEND): 00516 return_value = 00517 g_strconcat (hierarchy_tag, basename, NULL); 00518 break; 00519 case (PREPEND): 00520 return_value = 00521 g_strconcat (basename, hierarchy_tag, NULL); 00522 break; 00523 } 00524 } 00525 } else { 00526 return_value = NULL; 00527 } 00528 } else { 00529 if (basename) { 00530 return_value = g_strdup (basename); 00531 } else { 00532 return_value = NULL; 00533 } 00534 } 00535 00536 return (return_value); 00537 } 00538 00539 void 00540 s_hierarchy_remove_uref_mangling(TOPLEVEL * pr_current, NETLIST * head) 00541 { 00542 NETLIST *nl_current; 00543 CPINLIST *pl_current; 00544 NET *n_current; 00545 char uref[80], pin[10]; 00546 char *new_uref = NULL; 00547 char *new_connected_to = NULL; 00548 00549 nl_current = head; 00550 while (nl_current != NULL) { 00551 00552 if (nl_current->component_uref) { 00553 verbose_print("u"); 00554 new_uref = 00555 s_hierarchy_return_baseuref(pr_current, 00556 nl_current->component_uref); 00557 g_free(nl_current->component_uref); 00558 nl_current->component_uref = new_uref; 00559 } 00560 00561 pl_current = nl_current->cpins; 00562 00563 while (pl_current != NULL) { 00564 n_current = pl_current->nets; 00565 while (n_current != NULL) { 00566 00567 if (n_current->connected_to) { 00568 verbose_print("U"); 00569 sscanf(n_current->connected_to, "%s %s", uref, pin); 00570 new_uref = 00571 s_hierarchy_return_baseuref(pr_current, uref); 00572 new_connected_to = g_strdup_printf("%s %s", new_uref, pin); 00573 g_free(n_current->connected_to); 00574 n_current->connected_to = new_connected_to; 00575 } 00576 n_current = n_current->next; 00577 } 00578 00579 pl_current = pl_current->next; 00580 } 00581 nl_current = nl_current->next; 00582 } 00583 } 00584 00585 00586 char *s_hierarchy_return_baseuref(TOPLEVEL * pr_current, char *uref) 00587 { 00588 char *return_value = NULL; 00589 char *start_of_base = NULL; 00590 char *end_of_base = NULL; 00591 00592 /* use hierarchy separator */ 00593 00594 if (uref == NULL) { 00595 return (NULL); 00596 } 00597 #if DEBUG 00598 printf("Got uref: _%s_\n", uref); 00599 #endif 00600 00601 00602 if (pr_current->hierarchy_uref_order == APPEND) { 00603 00604 start_of_base = strrchr(uref, '/'); /* separator is always '/' */ 00605 00606 if (start_of_base == NULL) { 00607 return (g_strdup (uref)); 00608 } 00609 00610 return_value = g_strdup (start_of_base + 1); 00611 00612 } else if (pr_current->hierarchy_uref_order == PREPEND) { 00613 00614 end_of_base = strchr(uref, '/'); 00615 00616 if (end_of_base == NULL) { 00617 return (g_strdup (uref)); 00618 } 00619 00620 return_value = g_strndup(uref, end_of_base - uref); 00621 } 00622 00623 #if DEBUG 00624 printf("new uref return_value = %s\n\n\n", return_value); 00625 #endif 00626 00627 return (return_value); 00628 } 00629 00630 int s_hierarchy_graphical_search (OBJECT* o_current, int count) 00631 { 00632 char *graphical_attrib; 00633 graphical_attrib = 00634 o_attrib_search_object_attribs_by_name (o_current, "graphical", count); 00635 00636 if (graphical_attrib) { 00637 g_free (graphical_attrib); 00638 return TRUE; 00639 } 00640 00641 return FALSE; 00642 } 00643