gnetlist

s_rename.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  /*
00022   * 2005/05/02  Almost totally reimplemented to support dynamic allocation.
00023   *
00024   * Changes are Copyright (C) 2005 Carlos A. R. Azevedo
00025   */
00026   
00027 #include <config.h>
00028 #include <missing.h>
00029 
00030 #include <stdio.h>
00031 #include <ctype.h>
00032 #ifdef HAVE_STRING_H
00033 #include <string.h>
00034 #endif
00035 #ifdef HAVE_STDLIB_H
00036 #include <stdlib.h>
00037 #endif
00038 #ifdef HAVE_ASSERT_H
00039 #include <assert.h>
00040 #endif
00041 
00042 #include <libgeda/libgeda.h>
00043 
00044 #include "../include/globals.h"
00045 #include "../include/prototype.h"
00046 
00047 #ifdef HAVE_LIBDMALLOC
00048 #include <dmalloc.h>
00049 #endif
00050 
00051 typedef struct {
00052     void * next;
00053     char * src;
00054     char * dest;
00055 } RENAME;
00056 
00057 typedef struct {
00058     void * next_set;
00059     RENAME * first_rename;
00060     RENAME * last_rename;
00061 } SET;
00062 
00063 static SET * first_set = NULL;
00064 static SET * last_set = NULL;
00065 
00066 void s_rename_init(void)
00067 {
00068     if (first_set)
00069     {
00070         fprintf(stderr,"ERROR: Overwriting a valid rename list.\n");
00071         exit(-1);
00072     }
00073 }
00074 
00075 void s_rename_destroy_all(void)
00076 {
00077     RENAME * temp;
00078     void * to_free;
00079     
00080     for (; first_set;)
00081     {
00082         for (temp = first_set->first_rename; temp;)
00083         {
00084             g_free(temp->src);
00085             g_free(temp->dest);
00086         to_free = temp;
00087         temp = temp->next;
00088         g_free(to_free);
00089         }
00090     to_free = first_set;
00091     first_set = first_set->next_set;
00092     g_free(to_free);
00093     }
00094     last_set = NULL;
00095 }
00096 
00097 void s_rename_next_set(void)
00098 {
00099     SET * new_set;
00100     
00101     new_set = g_malloc(sizeof(SET));
00102     memset(new_set,0,sizeof(SET));
00103     if (first_set)
00104     {
00105         last_set->next_set = new_set;
00106     last_set = new_set;
00107     }
00108     else
00109     {
00110         first_set = last_set = new_set;
00111     }
00112 }
00113 
00114 void s_rename_print(void)
00115 {
00116     SET * temp_set;
00117     RENAME * temp_rename;
00118     int i;
00119 
00120     for (i = 0, temp_set = first_set; temp_set; temp_set = temp_set->next_set, i++)
00121     {
00122         for (temp_rename = temp_set->first_rename; temp_rename; temp_rename = temp_rename->next)
00123         {
00124             printf("%d) Source: _%s_", i, temp_rename->src);
00125             printf(" -> Dest: _%s_\n", temp_rename->dest);
00126         } 
00127     }
00128 }
00129 
00130 /* if the src is found, return true */
00131 /* if the dest is found, also return true, but warn user */
00132 /* If quiet_flag is true than don't print anything */
00133 int s_rename_search(char *src, char *dest, int quiet_flag)
00134 {
00135     RENAME * temp;
00136 
00137     if (last_set)
00138     {
00139         for (temp = last_set->first_rename; temp; temp = temp->next)
00140         {
00141             if (strcmp(src, temp->src) == 0) 
00142             {
00143                 return (TRUE);
00144             }
00145 
00146             if (strcmp(dest, temp->src) == 0) 
00147         {
00148                 if (!quiet_flag) 
00149             {
00150                     fprintf(stderr,"WARNING: Trying to rename something twice:\n\t%s and %s\nare both a src and dest name\n", dest, temp->src);
00151                     fprintf(stderr,"This warning is okay if you have multiple levels of hierarchy!\n");
00152                 }
00153                 return (TRUE);
00154             }
00155     }
00156     }
00157     return (FALSE);
00158 }
00159 
00160 static void s_rename_add_lowlevel (const char *src, const char *dest)
00161 {
00162     RENAME *new_rename;
00163 
00164     g_return_if_fail(last_set != NULL);
00165 
00166     new_rename = g_malloc(sizeof (RENAME));
00167 
00168     g_return_if_fail(new_rename != NULL);
00169 
00170     new_rename->next = NULL;
00171     new_rename->src = g_strdup(src);
00172     new_rename->dest = g_strdup(dest);
00173 
00174     if (last_set->first_rename == NULL)
00175     {
00176         last_set->first_rename = last_set->last_rename = new_rename;
00177     }
00178     else
00179     {
00180         last_set->last_rename->next = new_rename;
00181         last_set->last_rename = new_rename;
00182     }
00183 }
00184 
00185 void s_rename_add(char *src, char *dest)
00186 {
00187     int flag;
00188     RENAME * last;
00189     RENAME * temp;
00190     RENAME * new_rename;
00191     SET * new_set;
00192 
00193     if (src == NULL || dest == NULL) 
00194     {
00195         return;
00196     }
00197 
00198     flag = s_rename_search(src, dest, FALSE);
00199 
00200     if (flag) 
00201     {
00202         /* If found follow the original behaviour, limiting the operation to the current end-of-list */
00203     last = last_set->last_rename;
00204     for (temp = last_set->first_rename; ; temp = temp->next)
00205     {
00206         if ((strcmp(dest, temp->src) == 0)
00207             && (strcmp(src, temp->dest) != 0))
00208         {
00209             /* we found a -> b, while adding c -> a.
00210              * hence we would have c -> a -> b, so add c -> b.
00211              * avoid renaming if b is same as c!
00212              */
00213 #if DEBUG
00214             printf("Found dest [%s] in src [%s] and that had a dest as: [%s]\n"
00215                    "So you want rename [%s] to [%s]\n",
00216                    dest, temp->src, temp->dest, src, temp->dest);
00217 #endif
00218             s_rename_add_lowlevel(src, temp->dest);
00219 
00220         }
00221         else if ((strcmp(src, temp->src) == 0)
00222                  && (strcmp(dest, temp->dest) != 0))
00223         {
00224             /* we found a -> b, while adding a -> c.
00225              * hence b <==> c, so add c -> b.
00226              * avoid renaming if b is same as c!
00227              */
00228 #if DEBUG
00229             printf("Found src [%s] that had a dest as: [%s]\n"
00230                    "Unify nets by renaming [%s] to [%s]\n",
00231                    src, temp->dest, dest, temp->dest);
00232 #endif
00233             s_rename_add_lowlevel(dest, temp->dest);
00234         }
00235             if (temp == last)
00236             {
00237                 break;
00238             }
00239         }
00240     } 
00241     else 
00242     {
00243         /* Check for a valid set */
00244     if (first_set == NULL)
00245     {
00246         new_set = g_malloc(sizeof(SET));
00247             memset(new_set,0,sizeof(SET));
00248         first_set = last_set = new_set;
00249     }    
00250         new_rename = g_malloc(sizeof(RENAME));
00251          new_rename->next = NULL;
00252              new_rename->src = g_strdup(src);
00253              new_rename->dest = g_strdup(dest);
00254          if (last_set->first_rename == NULL)
00255          {
00256              last_set->first_rename = last_set->last_rename = new_rename;
00257          }
00258          else
00259          {
00260              last_set->last_rename->next = new_rename;
00261          last_set->last_rename = new_rename;
00262          } 
00263     }
00264 }
00265 
00266 void s_rename_all_lowlevel(NETLIST * netlist_head, char *src, char *dest)
00267 {
00268     NETLIST *nl_current = NULL;
00269     CPINLIST *pl_current;
00270 
00271     nl_current = netlist_head;
00272 
00273     while (nl_current != NULL) 
00274     {
00275         if (nl_current->cpins) 
00276     {
00277             pl_current = nl_current->cpins;
00278             while (pl_current != NULL) 
00279         {
00280                 if (pl_current->net_name != NULL) 
00281         {
00282                     if (strcmp(pl_current->net_name, src) == 0) 
00283             {
00284                         pl_current->net_name = g_strdup(dest);
00285                     }
00286                 }
00287                 pl_current = pl_current->next;
00288             }
00289         }
00290         nl_current = nl_current->next;
00291     }
00292 }
00293 
00294 void s_rename_all(TOPLEVEL * pr_current, NETLIST * netlist_head)
00295 {
00296     RENAME * temp;
00297     
00298 #if DEBUG
00299     s_rename_print();
00300 #endif
00301 
00302     if (last_set)
00303     {
00304         for (temp = last_set->first_rename; temp; temp = temp->next)
00305         {
00306             verbose_print("R");
00307             s_rename_all_lowlevel(netlist_head, temp->src, temp->dest);
00308     }
00309     }
00310 }
00311 
00312 
00313 SCM g_get_renamed_nets(SCM scm_level)
00314 {
00315     SCM pairlist = SCM_EOL;
00316     SCM outerlist = SCM_EOL;
00317     SET * temp_set;
00318     RENAME * temp_rename;
00319     char *level;
00320 
00321     level = scm_to_utf8_string (scm_level);
00322 
00323     for (temp_set = first_set; temp_set; temp_set = temp_set->next_set)
00324     {
00325         for (temp_rename = temp_set->first_rename; temp_rename; temp_rename = temp_rename->next)
00326         {
00327             pairlist = scm_list_n (scm_from_utf8_string (temp_rename->src),
00328                                    scm_from_utf8_string (temp_rename->dest),
00329                                    SCM_UNDEFINED);
00330             outerlist = scm_cons (pairlist, outerlist);
00331         }
00332     }
00333 
00334     free (level);
00335     return (outerlist);
00336 }
 All Data Structures Files Functions Variables Defines