gnetlist

s_net.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 #include <missing.h>
00023 
00024 #include <stdio.h>
00025 #include <ctype.h>
00026 #ifdef HAVE_STRING_H
00027 #include <string.h>
00028 #endif
00029 #ifdef HAVE_STDLIB_H
00030 #include <stdlib.h>
00031 #endif
00032 #ifdef HAVE_ASSERT_H
00033 #include <assert.h>
00034 #endif
00035 
00036 #include <libgeda/libgeda.h>
00037 
00038 #include "../include/globals.h"
00039 #include "../include/prototype.h"
00040 
00041 #ifdef HAVE_LIBDMALLOC
00042 #include <dmalloc.h>
00043 #endif
00044 
00045 static int unnamed_net_counter = 1;
00046 static int unnamed_bus_counter = 1;
00047 static int unnamed_pin_counter = 1;
00048 
00049 #define MAX_UNNAMED_NETS 99999999
00050 #define MAX_UNNAMED_PINS 99999999
00051 
00052 /* hack rename this to be s_return_tail */
00053 /* update object_tail or any list of that matter */
00054 NET *s_net_return_tail(NET * head)
00055 {
00056     NET *n_current = NULL;
00057     NET *ret_struct = NULL;
00058 
00059     n_current = head;
00060     while (n_current != NULL) { /* goto end of list */
00061     ret_struct = n_current;
00062     n_current = n_current->next;
00063     }
00064 
00065     return (ret_struct);
00066 }
00067 
00068 /* hack rename this to be s_return_head */
00069 /* update object_tail or any list of that matter */
00070 NET *s_net_return_head(NET * tail)
00071 {
00072     NET *n_current = NULL;
00073     NET *ret_struct = NULL;
00074 
00075     n_current = tail;
00076     while (n_current != NULL) { /* goto end of list */
00077     ret_struct = n_current;
00078     n_current = n_current->prev;
00079     }
00080 
00081     return (ret_struct);
00082 }
00083 
00084 
00085 NET *s_net_add(NET * ptr)
00086 {
00087     NET *new_node;
00088 
00089     new_node = (NET *) g_malloc(sizeof(NET));
00090 
00091     /* setup node information */
00092     new_node->net_name = NULL;
00093     new_node->pin_label = NULL;
00094     new_node->net_name_has_priority = FALSE;
00095     new_node->nid = 0;
00096     new_node->connected_to = NULL;
00097 
00098     /* Setup link list stuff */
00099     new_node->next = NULL;
00100 
00101     if (ptr == NULL) {
00102     new_node->prev = NULL;  /* setup previous link */
00103     return (new_node);
00104     } else {
00105     new_node->prev = ptr;   /* setup previous link */
00106     ptr->next = new_node;
00107     return (ptr->next);
00108     }
00109 }
00110 
00111 void s_net_print(NET * ptr)
00112 {
00113     NET *n_current = NULL;
00114 
00115     n_current = ptr;
00116 
00117     if (n_current == NULL) {
00118     return;
00119     }
00120 
00121     while (n_current != NULL) {
00122 
00123     if (n_current->nid != -1) {
00124 
00125 #if DEBUG
00126         if (n_current->net_name) {
00127         printf("    %s [%d]\n", n_current->net_name, n_current->nid);
00128         }
00129 #endif
00130 
00131         if (n_current->connected_to) {
00132         printf("        %s [%d]\n", n_current->connected_to, n_current->nid);
00133         }
00134     }
00135 
00136     n_current = n_current->next;
00137     }
00138 }
00139 
00140 
00141 /* object being a pin */
00142 char *s_net_return_connected_string(TOPLEVEL * pr_current, OBJECT * object,
00143                     char *hierarchy_tag)
00144 {
00145     OBJECT *o_current;
00146     char *pinnum = NULL;
00147     char *uref = NULL;
00148     SCM scm_uref;
00149     char *temp_uref = NULL;
00150     char *string;
00151     char *misc;
00152 
00153     o_current = object;
00154 
00155     pinnum = o_attrib_search_object_attribs_by_name (o_current, "pinnumber", 0);
00156 
00157 #if DEBUG
00158     printf("found pinnum: %s\n", pinnum);
00159 #endif
00160 
00161     scm_uref = g_scm_c_get_uref(pr_current, o_current->parent);
00162 
00163     if (scm_is_string( scm_uref )) {
00164       temp_uref = scm_to_utf8_string (scm_uref);
00165     }
00166 
00167     /* apply the hierarchy name to the uref */
00168     uref = s_hierarchy_create_uref(pr_current, temp_uref, hierarchy_tag);
00169 
00170     if (uref && pinnum) {
00171     string = g_strdup_printf("%s %s", uref, pinnum);
00172     } else {
00173     if (pinnum) {
00174         string = g_strdup_printf("POWER %s", pinnum);
00175     } else {
00176         if (hierarchy_tag) {
00177         misc =
00178             s_hierarchy_create_uref(pr_current, "U?",
00179                         hierarchy_tag);
00180         string = g_strdup_printf("%s ?", misc);
00181         g_free(misc);
00182         } else {
00183         string = g_strdup("U? ?");
00184         }
00185 
00186         fprintf(stderr, "Missing Attributes (refdes and pin number)\n");
00187     }
00188     }
00189 
00190     g_free(pinnum);
00191 
00192     g_free(uref);
00193 
00194     g_free(temp_uref);
00195 
00196     return (string);
00197 }
00198 
00199 int s_net_find(NET * net_head, NET * node)
00200 {
00201     NET *n_current;
00202 
00203     n_current = net_head;
00204     while (n_current != NULL) {
00205     if (n_current->nid == node->nid) {
00206         return (TRUE);
00207     }
00208 
00209     n_current = n_current->next;
00210     }
00211     return (FALSE);
00212 }
00213 
00214 char *s_net_name_search(TOPLEVEL * pr_current, NET * net_head)
00215 {
00216     NET *n_current;
00217     char *name = NULL;
00218 
00219     n_current = net_head;
00220 
00221 
00222     while (n_current != NULL) {
00223 
00224     if (n_current->net_name) {
00225 
00226         if (name == NULL) {
00227 
00228         name = n_current->net_name;
00229 
00230         } else if (strcmp(name, n_current->net_name) != 0) {
00231 
00232 
00233 #if DEBUG
00234         fprintf(stderr, "Found a net with two names!\n");
00235         fprintf(stderr, "Net called: [%s] and [%s]\n",
00236             name, n_current->net_name);
00237 #endif
00238 
00239 
00240         /* only rename if this net name has priority */
00241         /* AND, you are using net= attributes as the */
00242         /* netnames which have priority */
00243         if (pr_current->net_naming_priority == NETATTRIB_ATTRIBUTE) {
00244 
00245 #if DEBUG
00246             printf("\nNETATTRIB_ATTRIBUTE\n");
00247 #endif
00248             if (n_current->net_name_has_priority) {
00249 
00250 #if DEBUG
00251             fprintf(stderr, "Net is now called: [%s]\n",
00252                 n_current->net_name);
00253 
00254 /* this show how to rename nets */
00255             printf("\nRENAME all nets: %s -> %s\n", name,
00256                    n_current->net_name);
00257 #endif
00258             s_rename_add(name, n_current->net_name);
00259 
00260             name = n_current->net_name;
00261 
00262             } else {
00263 
00264 #if DEBUG
00265             printf
00266                 ("\nFound a net name called [%s], but it doesn't have priority\n",
00267                  n_current->net_name);
00268 #endif
00269 
00270             /* do the rename anyways, this might cause problems */
00271             /* this will rename net which have the same label= */
00272             if (!s_rename_search
00273                 (name, n_current->net_name, TRUE)) {
00274                 fprintf(stderr,
00275                     "Found duplicate net name, renaming [%s] to [%s]\n",
00276                     name, n_current->net_name);
00277                 s_rename_add(name, n_current->net_name);
00278                 name = n_current->net_name;
00279             }
00280             }
00281 
00282         } else {    /* NETNAME_ATTRIBUTE */
00283 
00284 #if DEBUG
00285             printf("\nNETNAME_ATTRIBUTE\n");
00286 #endif
00287 
00288             /* here we want to rename the net */
00289             /* that has priority to the label */
00290             /* name */
00291             if (n_current->net_name_has_priority) {
00292 
00293 #if DEBUG           /* this shows how to rename nets */
00294             printf("\nRENAME all nets: %s -> %s (priority)\n",
00295                    n_current->net_name, name);
00296 #endif
00297 
00298             s_rename_add(n_current->net_name, name);
00299 
00300             } else {
00301 
00302 #if DEBUG           /* this shows how to rename nets */
00303             printf
00304                 ("\nRENAME all nets: %s -> %s (not priority)\n",
00305                  name, n_current->net_name);
00306 #endif
00307             /* do the rename anyways, this might cause problems */
00308             /* this will rename net which have the same label= */
00309             if (!s_rename_search
00310                 (name, n_current->net_name, TRUE)) {
00311                 fprintf(stderr,
00312                     "Found duplicate net name, renaming [%s] to [%s]\n",
00313                     name, n_current->net_name);
00314 
00315                 s_rename_add(name, n_current->net_name);
00316                 name = n_current->net_name;
00317             }
00318             }
00319 
00320 #if DEBUG
00321             fprintf(stderr, "Net is now called: [%s]\n", name);
00322 #endif
00323 
00324         }
00325         }
00326     }
00327 
00328     n_current = n_current->next;
00329     }
00330 
00331     if (name) {
00332     return (name);
00333     } else {
00334     return (NULL);
00335     }
00336 }
00337 
00338 char *s_net_name (TOPLEVEL * pr_current, NETLIST * netlist_head,
00339                   NET * net_head, char *hierarchy_tag, int type)
00340 {
00341     char *string = NULL;
00342     NET *n_start;
00343     NETLIST *nl_current;
00344     CPINLIST *pl_current;
00345     char *net_name = NULL;
00346     int found = 0;
00347     char *temp;
00348     int *unnamed_counter;
00349     char *unnamed_string;
00350 
00351     net_name = s_net_name_search(pr_current, net_head);
00352 
00353     if (net_name) {
00354     return (net_name);
00355     }
00356 
00357 #if DEBUG
00358     printf("didn't find named net\n");
00359 #endif
00360     
00361     /* didn't find a name */
00362     /* go looking for another net which might have already been named */
00363     /* ie you don't want to create a new unnamed net if the net has */
00364     /* already been named */
00365     nl_current = netlist_head;
00366     while (nl_current != NULL) {
00367     if (nl_current->cpins) {
00368         pl_current = nl_current->cpins;
00369         while (pl_current != NULL) {
00370         if (pl_current->nets) {
00371             n_start = pl_current->nets;
00372             if (n_start->next && net_head->next) {
00373             found = s_net_find(n_start->next, net_head->next);
00374 
00375             if (found) {
00376                 net_name =
00377                 s_net_name_search(pr_current, n_start);
00378                 if (net_name) {
00379                 return (net_name);
00380                 }
00381 
00382             }
00383             }
00384         }
00385 
00386         pl_current = pl_current->next;
00387         }
00388     }
00389     nl_current = nl_current->next;
00390     }
00391 
00392 
00393 #if DEBUG
00394     printf("didn't find previously named\n");
00395 #endif
00396 
00397     /* AND we don't want to assign a dangling pin */
00398     /* which is signified by having only a head node */
00399     /* which is just a place holder */
00400     /* and the head node shows up here */
00401 
00402     if (net_head->nid == -1 && net_head->prev == NULL
00403     && net_head->next == NULL) {
00404     string = g_strdup_printf("unconnected_pin-%d",
00405                            unnamed_pin_counter++);
00406 
00407     return (string);
00408 
00409     }
00410 
00411     switch (type) {
00412       case PIN_TYPE_NET:
00413         unnamed_counter = &unnamed_net_counter;
00414         unnamed_string = pr_current->unnamed_netname;
00415         break;
00416       case PIN_TYPE_BUS:
00417         unnamed_counter = &unnamed_bus_counter;
00418         unnamed_string = pr_current->unnamed_busname;
00419         break;
00420       default:
00421         g_critical ("Incorrect connectivity type %i in s_name_nets()\n", type);
00422         return NULL;
00423     }
00424 
00425     /* have we exceeded the number of unnamed nets? */
00426     if (*unnamed_counter < MAX_UNNAMED_NETS) {
00427 
00428         if (netlist_mode == SPICE) {
00429           string = g_strdup_printf("%d", (*unnamed_counter)++);
00430         } else {
00431           temp = g_strdup_printf ("%s%d", unnamed_string, (*unnamed_counter)++);
00432           if (hierarchy_tag) {
00433             string = s_hierarchy_create_netname (pr_current, temp, hierarchy_tag);
00434             g_free (temp);
00435           } else {
00436             string = temp;
00437           }
00438         }
00439 
00440     } else {
00441       fprintf(stderr, "Increase number of unnamed nets (s_net.c)\n");
00442       exit(-1);
00443     }
00444 
00445     return string;
00446 
00447 }
 All Data Structures Files Functions Variables Defines