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
35 #include <libgeda/libgeda.h>
37 #include "../include/globals.h"
38 #include "../include/prototype.h"
39 #include "../include/gettext.h"
41 /* Used by the connected string functions */
42 #define PIN_NET_PREFIX "__netattrib_power_pin "
44 /* used by the extract functions below */
45 #define DELIMITERS ",; "
48 s_netattrib_pinnum_get_connected_string (const gchar
*pinnum
)
50 gchar
*str
= g_strdup_printf (PIN_NET_PREFIX
"%s", pinnum
);
55 s_netattrib_connected_string_get_pinnum (const gchar
*str
)
57 int prefix_len
= (sizeof PIN_NET_PREFIX
) - 1;
59 if (strncmp (str
, PIN_NET_PREFIX
, prefix_len
) != 0) {
63 return str
+ prefix_len
;
67 s_netattrib_check_connected_string (const gchar
*str
)
69 if (s_netattrib_connected_string_get_pinnum (str
) == NULL
) return;
72 _("ERROR: `%s' is reserved for internal use."), PIN_NET_PREFIX
);
73 exit (1); /*! \bug Use appropriate exit code */
76 /* things to do here : */
77 /* write the net alias function */
79 /* be sure to g_free returned string */
80 char *s_netattrib_extract_netname(char *value
)
82 char *return_value
= NULL
;
85 /* a bit larger than needed ... */
86 return_value
= g_strdup (value
);
88 while (value
[i
] != ':' && value
[i
] != '\0') {
89 return_value
[i
] = value
[i
];
93 if (value
[i
] != ':') {
94 fprintf(stderr
, _("Found malformed net attribute\n"));
95 return (g_strdup ("unknown"));
98 return_value
[i
] = '\0';
100 return (return_value
);
104 /* if this function creates a cpinlist list, it will not have a head node */
106 s_netattrib_create_pins(TOPLEVEL
* pr_current
, OBJECT
* o_current
,
107 NETLIST
* netlist
, char *value
,
110 NETLIST
*netlist_tail
= NULL
;
111 CPINLIST
*cpinlist_tail
= NULL
;
112 CPINLIST
*new_cpin
= NULL
;
113 CPINLIST
*old_cpin
= NULL
;
114 char *connected_to
= NULL
;
115 char *net_name
= NULL
;
116 char *start_of_pinlist
= NULL
;
117 char *char_ptr
= NULL
;
118 char *current_pin
= NULL
;
121 char_ptr
= strchr(value
, ':');
123 if (char_ptr
== NULL
) {
128 net_name
= s_netattrib_extract_netname(value
);
130 /* skip over first : */
131 start_of_pinlist
= char_ptr
+ 1;
132 current_pin
= strtok(start_of_pinlist
, DELIMITERS
);
133 while (current_pin
) {
135 netlist_tail
= s_netlist_return_tail(netlist
);
136 cpinlist_tail
= s_cpinlist_return_tail(netlist_tail
->cpins
);
138 if (netlist
->component_uref
) {
141 s_cpinlist_search_pin(netlist_tail
->cpins
, current_pin
);
145 g_assert (old_cpin
->nets
!= NULL
);
147 if (old_cpin
->nets
->net_name
) {
149 _("Found a cpinlist head with a netname! [%s]\n"),
150 old_cpin
->nets
->net_name
);
151 g_free(old_cpin
->nets
->net_name
);
155 old_cpin
->nets
->net_name
=
156 s_hierarchy_create_netattrib(pr_current
, net_name
,
158 old_cpin
->nets
->net_name_has_priority
= TRUE
;
159 connected_to
= g_strdup_printf("%s %s",
160 netlist
->component_uref
,
162 old_cpin
->nets
->connected_to
= g_strdup(connected_to
);
163 old_cpin
->nets
->nid
= o_current
->sid
;
164 g_free(connected_to
);
168 new_cpin
= s_cpinlist_add(cpinlist_tail
);
170 new_cpin
->pin_number
= g_strdup (current_pin
);
171 new_cpin
->net_name
= NULL
;
173 new_cpin
->plid
= o_current
->sid
;
175 new_cpin
->nets
= s_net_add(NULL
);
176 new_cpin
->nets
->net_name_has_priority
= TRUE
;
177 new_cpin
->nets
->net_name
=
178 s_hierarchy_create_netattrib(pr_current
, net_name
,
181 connected_to
= g_strdup_printf("%s %s",
182 netlist
->component_uref
,
184 new_cpin
->nets
->connected_to
= g_strdup(connected_to
);
185 new_cpin
->nets
->nid
= o_current
->sid
;
188 printf("Finished creating: %s\n", connected_to
);
189 printf("netname: %s %s\n", new_cpin
->nets
->net_name
,
193 g_free(connected_to
);
196 } else { /* no uref, means this is a special component */
199 current_pin
= strtok(NULL
, DELIMITERS
);
207 s_netattrib_handle (TOPLEVEL
* pr_current
, OBJECT
* o_current
,
208 NETLIST
* netlist
, char *hierarchy_tag
)
213 /* for now just look inside the component */
214 for (counter
= 0; ;) {
215 value
= o_attrib_search_inherited_attribs_by_name (o_current
,
222 s_netattrib_create_pins (pr_current
, o_current
,
223 netlist
, value
, hierarchy_tag
);
227 /* now look outside the component */
228 for (counter
= 0; ;) {
229 value
= o_attrib_search_attached_attribs_by_name (o_current
,
236 s_netattrib_create_pins (pr_current
, o_current
,
237 netlist
, value
, hierarchy_tag
);
242 char *s_netattrib_net_search (OBJECT
* o_current
, const gchar
*wanted_pin
)
245 char *char_ptr
= NULL
;
246 char *net_name
= NULL
;
247 char *current_pin
= NULL
;
248 char *start_of_pinlist
= NULL
;
249 char *return_value
= NULL
;
252 if (o_current
== NULL
||
253 o_current
->complex == NULL
)
256 /* for now just look inside the component */
257 for (counter
= 0; ;) {
258 value
= o_attrib_search_inherited_attribs_by_name (o_current
,
265 char_ptr
= strchr (value
, ':');
266 if (char_ptr
== NULL
) {
267 fprintf (stderr
, _("Got an invalid net= attrib [net=%s]\n"
268 "Missing : in net= attrib\n"), value
);
273 net_name
= s_netattrib_extract_netname (value
);
275 start_of_pinlist
= char_ptr
+ 1;
276 current_pin
= strtok (start_of_pinlist
, DELIMITERS
);
277 while (current_pin
&& !return_value
) {
278 if (strcmp (current_pin
, wanted_pin
) == 0) {
279 return_value
= net_name
;
281 current_pin
= strtok (NULL
, DELIMITERS
);
287 /* now look outside the component */
288 for (counter
= 0; ;) {
289 value
= o_attrib_search_attached_attribs_by_name (o_current
,
296 char_ptr
= strchr (value
, ':');
297 if (char_ptr
== NULL
) {
298 fprintf (stderr
, _("Got an invalid net= attrib [net=%s]\n"
299 "Missing : in net= attrib\n"), value
);
304 net_name
= s_netattrib_extract_netname (value
);
306 start_of_pinlist
= char_ptr
+ 1;
307 current_pin
= strtok (start_of_pinlist
, DELIMITERS
);
308 while (current_pin
) {
309 if (strcmp (current_pin
, wanted_pin
) == 0) {
310 g_free (return_value
);
313 current_pin
= strtok (NULL
, DELIMITERS
);
322 char *s_netattrib_return_netname(TOPLEVEL
* pr_current
, OBJECT
* o_current
,
323 char *pinnumber
, char *hierarchy_tag
)
325 const gchar
*current_pin
;
329 current_pin
= s_netattrib_connected_string_get_pinnum (pinnumber
);
330 if (current_pin
== NULL
) return NULL
;
332 /* use hierarchy tag here to make this net uniq */
333 temp_netname
= s_netattrib_net_search(o_current
->parent
,
337 s_hierarchy_create_netattrib(pr_current
, temp_netname
,
341 printf("netname: %s\n", netname
);