missing NULL terminator in set_config_x
[geda-gaf.git] / gnetlist-legacy / src / s_net.c
blob2a5ff84b962909423adc99ce87d0f7e4287dabfd
1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2020 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
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"
39 #include "../include/gettext.h"
41 static int unnamed_net_counter = 1;
42 static int unnamed_bus_counter = 1;
43 static int unnamed_pin_counter = 1;
45 #define MAX_UNNAMED_NETS 99999999
46 #define MAX_UNNAMED_PINS 99999999
48 NET *s_net_add(NET * ptr)
50 NET *new_node;
52 new_node = (NET *) g_malloc(sizeof(NET));
54 /* setup node information */
55 new_node->net_name = NULL;
56 new_node->pin_label = NULL;
57 new_node->net_name_has_priority = FALSE;
58 new_node->nid = 0;
59 new_node->connected_to = NULL;
61 /* Setup link list stuff */
62 new_node->next = NULL;
64 if (ptr == NULL) {
65 new_node->prev = NULL; /* setup previous link */
66 return (new_node);
67 } else {
68 new_node->prev = ptr; /* setup previous link */
69 ptr->next = new_node;
70 return (ptr->next);
74 void s_net_print(NET * ptr)
76 NET *n_current = NULL;
78 n_current = ptr;
80 if (n_current == NULL) {
81 return;
84 while (n_current != NULL) {
86 if (n_current->nid != -1) {
88 #if DEBUG
89 if (n_current->net_name) {
90 printf(" %s [%d]\n", n_current->net_name, n_current->nid);
92 #endif
94 if (n_current->connected_to) {
95 printf(" %s [%d]\n", n_current->connected_to, n_current->nid);
99 n_current = n_current->next;
104 /* object being a pin */
105 char *s_net_return_connected_string(TOPLEVEL * pr_current, OBJECT * object,
106 char *hierarchy_tag)
108 OBJECT *o_current;
109 char *pinnum = NULL;
110 char *uref = NULL;
111 SCM scm_uref;
112 char *temp_uref = NULL;
113 char *string;
114 char *misc;
116 o_current = object;
118 pinnum = o_attrib_search_object_attribs_by_name (o_current, "pinnumber", 0);
120 #if DEBUG
121 printf("found pinnum: %s\n", pinnum);
122 #endif
124 scm_uref = g_scm_c_get_uref(o_current->parent);
126 if (scm_is_string( scm_uref )) {
127 temp_uref = scm_to_utf8_string (scm_uref);
130 /* apply the hierarchy name to the uref */
131 uref = s_hierarchy_create_uref(pr_current, temp_uref, hierarchy_tag);
133 if (uref && pinnum) {
134 string = g_strdup_printf("%s %s", uref, pinnum);
135 s_netattrib_check_connected_string (string);
137 } else {
138 if (pinnum) {
139 string = s_netattrib_pinnum_get_connected_string (pinnum);
140 } else {
141 if (hierarchy_tag) {
142 misc =
143 s_hierarchy_create_uref(pr_current, "U?",
144 hierarchy_tag);
145 string = g_strdup_printf("%s ?", misc);
146 g_free(misc);
147 } else {
148 string = g_strdup("U? ?");
151 fprintf(stderr, _("Missing Attributes (refdes and pin number)\n"));
155 g_free(pinnum);
157 g_free(uref);
159 g_free(temp_uref);
161 return (string);
164 int s_net_find(NET * net_head, NET * node)
166 NET *n_current;
168 n_current = net_head;
169 while (n_current != NULL) {
170 if (n_current->nid == node->nid) {
171 return (TRUE);
174 n_current = n_current->next;
176 return (FALSE);
179 char *s_net_name_search(TOPLEVEL * pr_current, NET * net_head)
181 NET *n_current;
182 char *name = NULL;
184 n_current = net_head;
187 while (n_current != NULL) {
189 if (n_current->net_name) {
191 if (name == NULL) {
193 name = n_current->net_name;
195 } else if (strcmp(name, n_current->net_name) != 0) {
198 #if DEBUG
199 fprintf(stderr, "Found a net with two names!\n");
200 fprintf(stderr, "Net called: [%s] and [%s]\n",
201 name, n_current->net_name);
202 #endif
205 /* only rename if this net name has priority */
206 /* AND, you are using net= attributes as the */
207 /* netnames which have priority */
208 if (pr_current->net_naming_priority == NETATTRIB_ATTRIBUTE) {
210 #if DEBUG
211 printf("\nNETATTRIB_ATTRIBUTE\n");
212 #endif
213 if (n_current->net_name_has_priority) {
215 #if DEBUG
216 fprintf(stderr, "Net is now called: [%s]\n",
217 n_current->net_name);
219 /* this show how to rename nets */
220 printf("\nRENAME all nets: %s -> %s\n", name,
221 n_current->net_name);
222 #endif
223 s_rename_add(name, n_current->net_name);
225 name = n_current->net_name;
227 } else {
229 #if DEBUG
230 printf
231 ("\nFound a net name called [%s], but it doesn't have priority\n",
232 n_current->net_name);
233 #endif
235 /* do the rename anyways, this might cause problems */
236 /* this will rename net which have the same label= */
237 if (!s_rename_search
238 (name, n_current->net_name, TRUE)) {
239 fprintf(stderr,
240 _("Found duplicate net name, renaming [%s] to [%s]\n"),
241 name, n_current->net_name);
242 s_rename_add(name, n_current->net_name);
243 name = n_current->net_name;
247 } else { /* NETNAME_ATTRIBUTE */
249 #if DEBUG
250 printf("\nNETNAME_ATTRIBUTE\n");
251 #endif
253 /* here we want to rename the net */
254 /* that has priority to the label */
255 /* name */
256 if (n_current->net_name_has_priority) {
258 #if DEBUG /* this shows how to rename nets */
259 printf("\nRENAME all nets: %s -> %s (priority)\n",
260 n_current->net_name, name);
261 #endif
263 s_rename_add(n_current->net_name, name);
265 } else {
267 #if DEBUG /* this shows how to rename nets */
268 printf
269 ("\nRENAME all nets: %s -> %s (not priority)\n",
270 name, n_current->net_name);
271 #endif
272 /* do the rename anyways, this might cause problems */
273 /* this will rename net which have the same label= */
274 if (!s_rename_search
275 (name, n_current->net_name, TRUE)) {
276 fprintf(stderr,
277 _("Found duplicate net name, renaming [%s] to [%s]\n"),
278 name, n_current->net_name);
280 s_rename_add(name, n_current->net_name);
281 name = n_current->net_name;
285 #if DEBUG
286 fprintf(stderr, "Net is now called: [%s]\n", name);
287 #endif
293 n_current = n_current->next;
296 if (name) {
297 return (name);
298 } else {
299 return (NULL);
303 char *s_net_name (TOPLEVEL * pr_current, NETLIST * netlist_head,
304 NET * net_head, char *hierarchy_tag, int type)
306 char *string = NULL;
307 NET *n_start;
308 NETLIST *nl_current;
309 CPINLIST *pl_current;
310 char *net_name = NULL;
311 int found = 0;
312 char *temp;
313 int *unnamed_counter;
314 char *unnamed_string;
316 net_name = s_net_name_search(pr_current, net_head);
318 if (net_name) {
319 return (net_name);
322 #if DEBUG
323 printf("didn't find named net\n");
324 #endif
326 /* didn't find a name */
327 /* go looking for another net which might have already been named */
328 /* ie you don't want to create a new unnamed net if the net has */
329 /* already been named */
330 nl_current = netlist_head;
331 while (nl_current != NULL) {
332 if (nl_current->cpins) {
333 pl_current = nl_current->cpins;
334 while (pl_current != NULL) {
335 if (pl_current->nets) {
336 n_start = pl_current->nets;
337 if (n_start->next && net_head->next) {
338 found = s_net_find(n_start->next, net_head->next);
340 if (found) {
341 net_name =
342 s_net_name_search(pr_current, n_start);
343 if (net_name) {
344 return (net_name);
351 pl_current = pl_current->next;
354 nl_current = nl_current->next;
358 #if DEBUG
359 printf("didn't find previously named\n");
360 #endif
362 /* AND we don't want to assign a dangling pin */
363 /* which is signified by having only a head node */
364 /* which is just a place holder */
365 /* and the head node shows up here */
367 if (net_head->nid == -1 && net_head->prev == NULL
368 && net_head->next == NULL) {
369 string = g_strdup_printf("unconnected_pin-%d",
370 unnamed_pin_counter++);
372 return (string);
376 switch (type) {
377 case PIN_TYPE_NET:
378 unnamed_counter = &unnamed_net_counter;
379 unnamed_string = pr_current->unnamed_netname;
380 break;
381 case PIN_TYPE_BUS:
382 unnamed_counter = &unnamed_bus_counter;
383 unnamed_string = pr_current->unnamed_busname;
384 break;
385 default:
386 g_critical (_("s_net_name: incorrect connectivity type %i\n"), type);
387 return NULL;
390 /* have we exceeded the number of unnamed nets? */
391 if (*unnamed_counter < MAX_UNNAMED_NETS) {
393 if (netlist_mode == SPICE) {
394 string = g_strdup_printf("%d", (*unnamed_counter)++);
395 } else {
396 temp = g_strdup_printf ("%s%d", unnamed_string, (*unnamed_counter)++);
397 if (hierarchy_tag) {
398 string = s_hierarchy_create_netname (pr_current, temp, hierarchy_tag);
399 g_free (temp);
400 } else {
401 string = temp;
405 } else {
406 fprintf(stderr, _("Increase number of unnamed nets (s_net.c)\n"));
407 exit(-1);
410 return string;