Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gnetlist / src / s_net.c
blob85412aec59fa695a4ec329a37bf954c349bbbfc3
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 #include <config.h>
23 #include <stdio.h>
24 #include <ctype.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 #ifdef HAVE_STDLIB_H
29 #include <stdlib.h>
30 #endif
31 #ifdef HAVE_ASSERT_H
32 #include <assert.h>
33 #endif
35 #include <libgeda/libgeda.h>
37 #include "../include/globals.h"
38 #include "../include/prototype.h"
40 #ifdef HAVE_LIBDMALLOC
41 #include <dmalloc.h>
42 #endif
44 static int unnamed_net_counter = 1;
45 static int unnamed_bus_counter = 1;
46 static int unnamed_pin_counter = 1;
48 #define MAX_UNNAMED_NETS 99999999
49 #define MAX_UNNAMED_PINS 99999999
51 /* hack rename this to be s_return_tail */
52 /* update object_tail or any list of that matter */
53 NET *s_net_return_tail(NET * head)
55 NET *n_current = NULL;
56 NET *ret_struct = NULL;
58 n_current = head;
59 while (n_current != NULL) { /* goto end of list */
60 ret_struct = n_current;
61 n_current = n_current->next;
64 return (ret_struct);
67 /* hack rename this to be s_return_head */
68 /* update object_tail or any list of that matter */
69 NET *s_net_return_head(NET * tail)
71 NET *n_current = NULL;
72 NET *ret_struct = NULL;
74 n_current = tail;
75 while (n_current != NULL) { /* goto end of list */
76 ret_struct = n_current;
77 n_current = n_current->prev;
80 return (ret_struct);
84 NET *s_net_add(NET * ptr)
86 NET *new_node;
88 new_node = (NET *) g_malloc(sizeof(NET));
90 /* setup node information */
91 new_node->net_name = NULL;
92 new_node->pin_label = NULL;
93 new_node->net_name_has_priority = FALSE;
94 new_node->nid = 0;
95 new_node->connected_to = NULL;
97 /* Setup link list stuff */
98 new_node->next = NULL;
100 if (ptr == NULL) {
101 new_node->prev = NULL; /* setup previous link */
102 return (new_node);
103 } else {
104 new_node->prev = ptr; /* setup previous link */
105 ptr->next = new_node;
106 return (ptr->next);
110 void s_net_print(NET * ptr)
112 NET *n_current = NULL;
114 n_current = ptr;
116 if (n_current == NULL) {
117 return;
120 while (n_current != NULL) {
122 if (n_current->nid != -1) {
124 #if DEBUG
125 if (n_current->net_name) {
126 printf(" %s [%d]\n", n_current->net_name, n_current->nid);
128 #endif
130 if (n_current->connected_to) {
131 printf(" %s [%d]\n", n_current->connected_to, n_current->nid);
135 n_current = n_current->next;
140 /* object being a pin */
141 char *s_net_return_connected_string(TOPLEVEL * pr_current, OBJECT * object,
142 char *hierarchy_tag)
144 OBJECT *o_current;
145 char *pinnum = NULL;
146 char *uref = NULL;
147 SCM scm_uref;
148 char *temp_uref = NULL;
149 char *string;
150 char *misc;
151 int hierarchy_tag_len = 0;
154 o_current = object;
156 pinnum = o_attrib_search_object_attribs_by_name (o_current, "pinnumber", 0);
158 #if DEBUG
159 printf("found pinnum: %s\n", pinnum);
160 #endif
162 scm_uref = g_scm_c_get_uref(pr_current, o_current->parent);
164 if (scm_is_string( scm_uref )) {
165 temp_uref = scm_to_locale_string( scm_uref );
168 if (hierarchy_tag) {
169 hierarchy_tag_len = strlen(hierarchy_tag)+1;
170 } else {
171 hierarchy_tag_len = 0;
174 /* apply the hierarchy name to the uref */
175 uref = s_hierarchy_create_uref(pr_current, temp_uref, hierarchy_tag);
177 if (uref && pinnum) {
178 string = g_strdup_printf("%s %s", uref, pinnum);
179 } else {
180 if (pinnum) {
181 string = g_strdup_printf("POWER %s", pinnum);
182 } else {
183 if (hierarchy_tag) {
184 misc =
185 s_hierarchy_create_uref(pr_current, "U?",
186 hierarchy_tag);
187 string = g_strdup_printf("%s ?", misc);
188 g_free(misc);
189 } else {
190 string = g_strdup("U? ?");
193 fprintf(stderr, "Missing Attributes (refdes and pin number)\n");
197 g_free(pinnum);
199 g_free(uref);
201 g_free(temp_uref);
203 return (string);
206 int s_net_find(NET * net_head, NET * node)
208 NET *n_current;
210 n_current = net_head;
211 while (n_current != NULL) {
212 if (n_current->nid == node->nid) {
213 return (TRUE);
216 n_current = n_current->next;
218 return (FALSE);
221 char *s_net_name_search(TOPLEVEL * pr_current, NET * net_head)
223 NET *n_current;
224 char *name = NULL;
226 n_current = net_head;
229 while (n_current != NULL) {
231 if (n_current->net_name) {
233 if (name == NULL) {
235 name = n_current->net_name;
237 } else if (strcmp(name, n_current->net_name) != 0) {
240 #if DEBUG
241 fprintf(stderr, "Found a net with two names!\n");
242 fprintf(stderr, "Net called: [%s] and [%s]\n",
243 name, n_current->net_name);
244 #endif
247 /* only rename if this net name has priority */
248 /* AND, you are using net= attributes as the */
249 /* netnames which have priority */
250 if (pr_current->net_naming_priority == NETATTRIB_ATTRIBUTE) {
252 #if DEBUG
253 printf("\nNETATTRIB_ATTRIBUTE\n");
254 #endif
255 if (n_current->net_name_has_priority) {
257 #if DEBUG
258 fprintf(stderr, "Net is now called: [%s]\n",
259 n_current->net_name);
261 /* this show how to rename nets */
262 printf("\nRENAME all nets: %s -> %s\n", name,
263 n_current->net_name);
264 #endif
265 s_rename_add(name, n_current->net_name);
267 name = n_current->net_name;
269 } else {
271 #if DEBUG
272 printf
273 ("\nFound a net name called [%s], but it doesn't have priority\n",
274 n_current->net_name);
275 #endif
277 /* do the rename anyways, this might cause problems */
278 /* this will rename net which have the same label= */
279 if (!s_rename_search
280 (name, n_current->net_name, TRUE)) {
281 fprintf(stderr,
282 "Found duplicate net name, renaming [%s] to [%s]\n",
283 name, n_current->net_name);
284 s_rename_add(name, n_current->net_name);
285 name = n_current->net_name;
289 } else { /* NETNAME_ATTRIBUTE */
291 #if DEBUG
292 printf("\nNETNAME_ATTRIBUTE\n");
293 #endif
295 /* here we want to rename the net */
296 /* that has priority to the label */
297 /* name */
298 if (n_current->net_name_has_priority) {
300 #if DEBUG /* this shows how to rename nets */
301 printf("\nRENAME all nets: %s -> %s (priority)\n",
302 n_current->net_name, name);
303 #endif
305 s_rename_add(n_current->net_name, name);
307 } else {
309 #if DEBUG /* this shows how to rename nets */
310 printf
311 ("\nRENAME all nets: %s -> %s (not priority)\n",
312 name, n_current->net_name);
313 #endif
314 /* do the rename anyways, this might cause problems */
315 /* this will rename net which have the same label= */
316 if (!s_rename_search
317 (name, n_current->net_name, TRUE)) {
318 fprintf(stderr,
319 "Found duplicate net name, renaming [%s] to [%s]\n",
320 name, n_current->net_name);
322 s_rename_add(name, n_current->net_name);
323 name = n_current->net_name;
327 #if DEBUG
328 fprintf(stderr, "Net is now called: [%s]\n", name);
329 #endif
335 n_current = n_current->next;
338 if (name) {
339 return (name);
340 } else {
341 return (NULL);
345 char *s_net_name (TOPLEVEL * pr_current, NETLIST * netlist_head,
346 NET * net_head, char *hierarchy_tag, int type)
348 char *string = NULL;
349 NET *n_start;
350 NETLIST *nl_current;
351 CPINLIST *pl_current;
352 char *net_name = NULL;
353 int found = 0;
354 int hierarchy_tag_len;
355 char *temp;
356 int *unnamed_counter;
357 char *unnamed_string;
359 net_name = s_net_name_search(pr_current, net_head);
361 if (net_name) {
362 return (net_name);
365 #if DEBUG
366 printf("didn't find named net\n");
367 #endif
369 /* didn't find a name */
370 /* go looking for another net which might have already been named */
371 /* ie you don't want to create a new unnamed net if the net has */
372 /* already been named */
373 nl_current = netlist_head;
374 while (nl_current != NULL) {
375 if (nl_current->cpins) {
376 pl_current = nl_current->cpins;
377 while (pl_current != NULL) {
378 if (pl_current->nets) {
379 n_start = pl_current->nets;
380 if (n_start->next && net_head->next) {
381 found = s_net_find(n_start->next, net_head->next);
383 if (found) {
384 net_name =
385 s_net_name_search(pr_current, n_start);
386 if (net_name) {
387 return (net_name);
394 pl_current = pl_current->next;
397 nl_current = nl_current->next;
401 #if DEBUG
402 printf("didn't find previously named\n");
403 #endif
405 /* AND we don't want to assign a dangling pin */
406 /* which is signified by having only a head node */
407 /* which is just a place holder */
408 /* and the head node shows up here */
410 if (net_head->nid == -1 && net_head->prev == NULL
411 && net_head->next == NULL) {
412 string = g_strdup_printf("unconnected_pin-%d",
413 unnamed_pin_counter++);
415 return (string);
419 if (hierarchy_tag) {
420 /* + 1 is for the '/' character */
421 hierarchy_tag_len = strlen(hierarchy_tag) + 1;
422 } else {
423 hierarchy_tag_len = 0;
426 switch (type) {
427 case PIN_TYPE_NET:
428 unnamed_counter = &unnamed_net_counter;
429 unnamed_string = pr_current->unnamed_netname;
430 break;
431 case PIN_TYPE_BUS:
432 unnamed_counter = &unnamed_bus_counter;
433 unnamed_string = pr_current->unnamed_busname;
434 break;
435 default:
436 g_critical ("Incorrect connectivity type %i in s_name_nets()\n", type);
437 return NULL;
440 /* have we exceeded the number of unnamed nets? */
441 if (*unnamed_counter < MAX_UNNAMED_NETS) {
443 if (netlist_mode == SPICE) {
444 string = g_strdup_printf("%d", (*unnamed_counter)++);
445 } else {
446 temp = g_strdup_printf ("%s%d", unnamed_string, (*unnamed_counter)++);
447 if (hierarchy_tag) {
448 string = s_hierarchy_create_netname (pr_current, temp, hierarchy_tag);
449 g_free (temp);
450 } else {
451 string = temp;
455 } else {
456 fprintf(stderr, "Increase number of unnamed nets (s_net.c)\n");
457 exit(-1);
460 return string;