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
36 #include <libgeda/libgeda.h>
38 #include "../include/globals.h"
39 #include "../include/prototype.h"
40 #include "../include/gettext.h"
42 #ifdef HAVE_LIBDMALLOC
46 static int unnamed_net_counter
= 1;
47 static int unnamed_bus_counter
= 1;
48 static int unnamed_pin_counter
= 1;
50 #define MAX_UNNAMED_NETS 99999999
51 #define MAX_UNNAMED_PINS 99999999
53 /* hack rename this to be s_return_tail */
54 /* update object_tail or any list of that matter */
55 NET
*s_net_return_tail(NET
* head
)
57 NET
*n_current
= NULL
;
58 NET
*ret_struct
= NULL
;
61 while (n_current
!= NULL
) { /* goto end of list */
62 ret_struct
= n_current
;
63 n_current
= n_current
->next
;
69 /* hack rename this to be s_return_head */
70 /* update object_tail or any list of that matter */
71 NET
*s_net_return_head(NET
* tail
)
73 NET
*n_current
= NULL
;
74 NET
*ret_struct
= NULL
;
77 while (n_current
!= NULL
) { /* goto end of list */
78 ret_struct
= n_current
;
79 n_current
= n_current
->prev
;
86 NET
*s_net_add(NET
* ptr
)
90 new_node
= (NET
*) g_malloc(sizeof(NET
));
92 /* setup node information */
93 new_node
->net_name
= NULL
;
94 new_node
->pin_label
= NULL
;
95 new_node
->net_name_has_priority
= FALSE
;
97 new_node
->connected_to
= NULL
;
99 /* Setup link list stuff */
100 new_node
->next
= NULL
;
103 new_node
->prev
= NULL
; /* setup previous link */
106 new_node
->prev
= ptr
; /* setup previous link */
107 ptr
->next
= new_node
;
112 void s_net_print(NET
* ptr
)
114 NET
*n_current
= NULL
;
118 if (n_current
== NULL
) {
122 while (n_current
!= NULL
) {
124 if (n_current
->nid
!= -1) {
127 if (n_current
->net_name
) {
128 printf(" %s [%d]\n", n_current
->net_name
, n_current
->nid
);
132 if (n_current
->connected_to
) {
133 printf(" %s [%d]\n", n_current
->connected_to
, n_current
->nid
);
137 n_current
= n_current
->next
;
142 /* object being a pin */
143 char *s_net_return_connected_string(TOPLEVEL
* pr_current
, OBJECT
* object
,
150 char *temp_uref
= NULL
;
156 pinnum
= o_attrib_search_object_attribs_by_name (o_current
, "pinnumber", 0);
159 printf("found pinnum: %s\n", pinnum
);
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_utf8_string (scm_uref
);
168 /* apply the hierarchy name to the uref */
169 uref
= s_hierarchy_create_uref(pr_current
, temp_uref
, hierarchy_tag
);
171 if (uref
&& pinnum
) {
172 string
= g_strdup_printf("%s %s", uref
, pinnum
);
175 string
= g_strdup_printf("POWER %s", pinnum
);
179 s_hierarchy_create_uref(pr_current
, "U?",
181 string
= g_strdup_printf("%s ?", misc
);
184 string
= g_strdup("U? ?");
187 fprintf(stderr
, _("Missing Attributes (refdes and pin number)\n"));
200 int s_net_find(NET
* net_head
, NET
* node
)
204 n_current
= net_head
;
205 while (n_current
!= NULL
) {
206 if (n_current
->nid
== node
->nid
) {
210 n_current
= n_current
->next
;
215 char *s_net_name_search(TOPLEVEL
* pr_current
, NET
* net_head
)
220 gint net_naming_priority
;
223 enum NetNamingPriority
{
228 cfg
= eda_config_get_context_for_file (NULL
);
229 str
= eda_config_get_string (cfg
, "gnetlist", "net-naming-priority", NULL
);
230 if (g_strcmp0 (str
, "netname-attribute") == 0) {
231 net_naming_priority
= NETNAME_ATTRIBUTE
;
233 net_naming_priority
= NETATTRIB_ATTRIBUTE
;
237 n_current
= net_head
;
240 while (n_current
!= NULL
) {
242 if (n_current
->net_name
) {
246 name
= n_current
->net_name
;
248 } else if (strcmp(name
, n_current
->net_name
) != 0) {
252 fprintf(stderr
, "Found a net with two names!\n");
253 fprintf(stderr
, "Net called: [%s] and [%s]\n",
254 name
, n_current
->net_name
);
258 /* only rename if this net name has priority */
259 /* AND, you are using net= attributes as the */
260 /* netnames which have priority */
261 if (net_naming_priority
== NETATTRIB_ATTRIBUTE
) {
264 printf("\nNETATTRIB_ATTRIBUTE\n");
266 if (n_current
->net_name_has_priority
) {
269 fprintf(stderr
, "Net is now called: [%s]\n",
270 n_current
->net_name
);
272 /* this show how to rename nets */
273 printf("\nRENAME all nets: %s -> %s\n", name
,
274 n_current
->net_name
);
276 s_rename_add(name
, n_current
->net_name
);
278 name
= n_current
->net_name
;
284 ("\nFound a net name called [%s], but it doesn't have priority\n",
285 n_current
->net_name
);
288 /* do the rename anyways, this might cause problems */
289 /* this will rename net which have the same label= */
291 (name
, n_current
->net_name
, TRUE
)) {
293 _("Found duplicate net name, renaming [%s] to [%s]\n"),
294 name
, n_current
->net_name
);
295 s_rename_add(name
, n_current
->net_name
);
296 name
= n_current
->net_name
;
300 } else { /* NETNAME_ATTRIBUTE */
303 printf("\nNETNAME_ATTRIBUTE\n");
306 /* here we want to rename the net */
307 /* that has priority to the label */
309 if (n_current
->net_name_has_priority
) {
311 #if DEBUG /* this shows how to rename nets */
312 printf("\nRENAME all nets: %s -> %s (priority)\n",
313 n_current
->net_name
, name
);
316 s_rename_add(n_current
->net_name
, name
);
320 #if DEBUG /* this shows how to rename nets */
322 ("\nRENAME all nets: %s -> %s (not priority)\n",
323 name
, n_current
->net_name
);
325 /* do the rename anyways, this might cause problems */
326 /* this will rename net which have the same label= */
328 (name
, n_current
->net_name
, TRUE
)) {
330 _("Found duplicate net name, renaming [%s] to [%s]\n"),
331 name
, n_current
->net_name
);
333 s_rename_add(name
, n_current
->net_name
);
334 name
= n_current
->net_name
;
339 fprintf(stderr
, "Net is now called: [%s]\n", name
);
346 n_current
= n_current
->next
;
356 char *s_net_name (TOPLEVEL
* pr_current
, NETLIST
* netlist_head
,
357 NET
* net_head
, char *hierarchy_tag
, int type
)
362 CPINLIST
*pl_current
;
363 char *net_name
= NULL
;
366 int *unnamed_counter
;
367 char *unnamed_string
= NULL
;
370 net_name
= s_net_name_search(pr_current
, net_head
);
377 printf("didn't find named net\n");
380 /* didn't find a name */
381 /* go looking for another net which might have already been named */
382 /* ie you don't want to create a new unnamed net if the net has */
383 /* already been named */
384 nl_current
= netlist_head
;
385 while (nl_current
!= NULL
) {
386 if (nl_current
->cpins
) {
387 pl_current
= nl_current
->cpins
;
388 while (pl_current
!= NULL
) {
389 if (pl_current
->nets
) {
390 n_start
= pl_current
->nets
;
391 if (n_start
->next
&& net_head
->next
) {
392 found
= s_net_find(n_start
->next
, net_head
->next
);
396 s_net_name_search(pr_current
, n_start
);
405 pl_current
= pl_current
->next
;
408 nl_current
= nl_current
->next
;
413 printf("didn't find previously named\n");
416 /* AND we don't want to assign a dangling pin */
417 /* which is signified by having only a head node */
418 /* which is just a place holder */
419 /* and the head node shows up here */
421 if (net_head
->nid
== -1 && net_head
->prev
== NULL
422 && net_head
->next
== NULL
) {
423 string
= g_strdup_printf("unconnected_pin-%d",
424 unnamed_pin_counter
++);
430 cfg
= eda_config_get_context_for_file (NULL
);
434 unnamed_counter
= &unnamed_net_counter
;
435 unnamed_string
= eda_config_get_string (cfg
, "gnetlist", "default-net-name", NULL
);
438 unnamed_counter
= &unnamed_bus_counter
;
439 unnamed_string
= eda_config_get_string (cfg
, "gnetlist", "default-bus-name", NULL
);
442 g_critical (_("Incorrect connectivity type %i in s_name_nets()\n"), type
);
446 /* have we exceeded the number of unnamed nets? */
447 if (*unnamed_counter
< MAX_UNNAMED_NETS
) {
449 if (netlist_mode
== SPICE
) {
450 string
= g_strdup_printf("%d", (*unnamed_counter
)++);
452 temp
= g_strdup_printf ("%s%d", unnamed_string
, (*unnamed_counter
)++);
454 string
= s_hierarchy_create_netname (pr_current
, temp
, hierarchy_tag
);
462 fprintf(stderr
, _("Increase number of unnamed nets (s_net.c)\n"));
466 g_free (unnamed_string
);