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 /* 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 }