Fix o_net_consolidate_segments() to consolidate with all joined lines
[geda-gaf/pcjc2.git] / gnetlist / src / s_rename.c
blob7bc0695f7b5b20aedc18b552cc7f7646c854bae1
1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * 2005/05/02 Almost totally reimplemented to support dynamic allocation.
24 * Changes are Copyright (C) 2005 Carlos A. R. Azevedo
27 #include <config.h>
28 #include <missing.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 #ifdef HAVE_STRING_H
33 #include <string.h>
34 #endif
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38 #ifdef HAVE_ASSERT_H
39 #include <assert.h>
40 #endif
42 #include <libgeda/libgeda.h>
44 #include "../include/globals.h"
45 #include "../include/prototype.h"
46 #include "../include/gettext.h"
48 #ifdef HAVE_LIBDMALLOC
49 #include <dmalloc.h>
50 #endif
52 typedef struct {
53 void * next;
54 char * src;
55 char * dest;
56 } RENAME;
58 typedef struct {
59 void * next_set;
60 RENAME * first_rename;
61 RENAME * last_rename;
62 } SET;
64 static SET * first_set = NULL;
65 static SET * last_set = NULL;
67 void s_rename_init(void)
69 if (first_set)
71 fprintf(stderr, _("ERROR: Overwriting a valid rename list.\n"));
72 exit(-1);
76 void s_rename_destroy_all(void)
78 RENAME * temp;
79 void * to_free;
81 for (; first_set;)
83 for (temp = first_set->first_rename; temp;)
85 g_free(temp->src);
86 g_free(temp->dest);
87 to_free = temp;
88 temp = temp->next;
89 g_free(to_free);
91 to_free = first_set;
92 first_set = first_set->next_set;
93 g_free(to_free);
95 last_set = NULL;
98 void s_rename_next_set(void)
100 SET * new_set;
102 new_set = g_malloc(sizeof(SET));
103 memset(new_set,0,sizeof(SET));
104 if (first_set)
106 last_set->next_set = new_set;
107 last_set = new_set;
109 else
111 first_set = last_set = new_set;
115 void s_rename_print(void)
117 SET * temp_set;
118 RENAME * temp_rename;
119 int i;
121 for (i = 0, temp_set = first_set; temp_set; temp_set = temp_set->next_set, i++)
123 for (temp_rename = temp_set->first_rename; temp_rename; temp_rename = temp_rename->next)
125 printf("%d) Source: _%s_", i, temp_rename->src);
126 printf(" -> Dest: _%s_\n", temp_rename->dest);
131 /* if the src is found, return true */
132 /* if the dest is found, also return true, but warn user */
133 /* If quiet_flag is true than don't print anything */
134 int s_rename_search(char *src, char *dest, int quiet_flag)
136 RENAME * temp;
138 if (last_set)
140 for (temp = last_set->first_rename; temp; temp = temp->next)
142 if (strcmp(src, temp->src) == 0)
144 return (TRUE);
147 if (strcmp(dest, temp->src) == 0)
149 if (!quiet_flag)
151 fprintf(stderr, _("WARNING: Trying to rename something twice:\n\t%s and %s\nare both a src and dest name\n"), dest, temp->src);
152 fprintf(stderr, _("This warning is okay if you have multiple levels of hierarchy!\n"));
154 return (TRUE);
158 return (FALSE);
161 static void s_rename_add_lowlevel (const char *src, const char *dest)
163 RENAME *new_rename;
165 g_return_if_fail(last_set != NULL);
167 new_rename = g_malloc(sizeof (RENAME));
169 g_return_if_fail(new_rename != NULL);
171 new_rename->next = NULL;
172 new_rename->src = g_strdup(src);
173 new_rename->dest = g_strdup(dest);
175 if (last_set->first_rename == NULL)
177 last_set->first_rename = last_set->last_rename = new_rename;
179 else
181 last_set->last_rename->next = new_rename;
182 last_set->last_rename = new_rename;
186 void s_rename_add(char *src, char *dest)
188 int flag;
189 RENAME * last;
190 RENAME * temp;
191 RENAME * new_rename;
192 SET * new_set;
194 if (src == NULL || dest == NULL)
196 return;
199 flag = s_rename_search(src, dest, FALSE);
201 if (flag)
203 /* If found follow the original behaviour, limiting the operation to the current end-of-list */
204 last = last_set->last_rename;
205 for (temp = last_set->first_rename; ; temp = temp->next)
207 if ((strcmp(dest, temp->src) == 0)
208 && (strcmp(src, temp->dest) != 0))
210 /* we found a -> b, while adding c -> a.
211 * hence we would have c -> a -> b, so add c -> b.
212 * avoid renaming if b is same as c!
214 #if DEBUG
215 printf("Found dest [%s] in src [%s] and that had a dest as: [%s]\n"
216 "So you want rename [%s] to [%s]\n",
217 dest, temp->src, temp->dest, src, temp->dest);
218 #endif
219 s_rename_add_lowlevel(src, temp->dest);
222 else if ((strcmp(src, temp->src) == 0)
223 && (strcmp(dest, temp->dest) != 0))
225 /* we found a -> b, while adding a -> c.
226 * hence b <==> c, so add c -> b.
227 * avoid renaming if b is same as c!
229 #if DEBUG
230 printf("Found src [%s] that had a dest as: [%s]\n"
231 "Unify nets by renaming [%s] to [%s]\n",
232 src, temp->dest, dest, temp->dest);
233 #endif
234 s_rename_add_lowlevel(dest, temp->dest);
236 if (temp == last)
238 break;
242 else
244 /* Check for a valid set */
245 if (first_set == NULL)
247 new_set = g_malloc(sizeof(SET));
248 memset(new_set,0,sizeof(SET));
249 first_set = last_set = new_set;
251 new_rename = g_malloc(sizeof(RENAME));
252 new_rename->next = NULL;
253 new_rename->src = g_strdup(src);
254 new_rename->dest = g_strdup(dest);
255 if (last_set->first_rename == NULL)
257 last_set->first_rename = last_set->last_rename = new_rename;
259 else
261 last_set->last_rename->next = new_rename;
262 last_set->last_rename = new_rename;
267 void s_rename_all_lowlevel(NETLIST * netlist_head, char *src, char *dest)
269 NETLIST *nl_current = NULL;
270 CPINLIST *pl_current;
272 nl_current = netlist_head;
274 while (nl_current != NULL)
276 if (nl_current->cpins)
278 pl_current = nl_current->cpins;
279 while (pl_current != NULL)
281 if (pl_current->net_name != NULL)
283 if (strcmp(pl_current->net_name, src) == 0)
285 pl_current->net_name = g_strdup(dest);
288 pl_current = pl_current->next;
291 nl_current = nl_current->next;
295 void s_rename_all(TOPLEVEL * pr_current, NETLIST * netlist_head)
297 RENAME * temp;
299 #if DEBUG
300 s_rename_print();
301 #endif
303 if (last_set)
305 for (temp = last_set->first_rename; temp; temp = temp->next)
307 verbose_print("R");
308 s_rename_all_lowlevel(netlist_head, temp->src, temp->dest);
314 SCM g_get_renamed_nets(SCM scm_level)
316 SCM pairlist = SCM_EOL;
317 SCM outerlist = SCM_EOL;
318 SET * temp_set;
319 RENAME * temp_rename;
320 char *level;
322 level = scm_to_utf8_string (scm_level);
324 for (temp_set = first_set; temp_set; temp_set = temp_set->next_set)
326 for (temp_rename = temp_set->first_rename; temp_rename; temp_rename = temp_rename->next)
328 pairlist = scm_list_n (scm_from_utf8_string (temp_rename->src),
329 scm_from_utf8_string (temp_rename->dest),
330 SCM_UNDEFINED);
331 outerlist = scm_cons (pairlist, outerlist);
335 free (level);
336 return (outerlist);