gnetlist

s_hierarchy.c

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Defines