missing NULL terminator in set_config_x
[geda-gaf.git] / gnetlist-legacy / src / s_netattrib.c
blob4c232dca93f1dd13b07506ccedda46e8e2dcd63f
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_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #ifdef HAVE_ASSERT_H
29 #include <assert.h>
30 #endif
31 #ifdef HAVE_STRING_H
32 #include <string.h>
33 #endif
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 ",; "
47 gchar *
48 s_netattrib_pinnum_get_connected_string (const gchar *pinnum)
50 gchar *str = g_strdup_printf (PIN_NET_PREFIX "%s", pinnum);
51 return str;
54 const gchar *
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) {
60 return NULL;
63 return str + prefix_len;
66 void
67 s_netattrib_check_connected_string (const gchar *str)
69 if (s_netattrib_connected_string_get_pinnum (str) == NULL) return;
71 fprintf (stderr,
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;
83 int i = 0;
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];
90 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 */
105 void
106 s_netattrib_create_pins(TOPLEVEL * pr_current, OBJECT * o_current,
107 NETLIST * netlist, char *value,
108 char *hierarchy_tag)
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) {
124 return;
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) {
140 old_cpin =
141 s_cpinlist_search_pin(netlist_tail->cpins, current_pin);
143 if (old_cpin) {
145 g_assert (old_cpin->nets != NULL);
147 if (old_cpin->nets->net_name) {
148 fprintf(stderr,
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,
157 hierarchy_tag);
158 old_cpin->nets->net_name_has_priority = TRUE;
159 connected_to = g_strdup_printf("%s %s",
160 netlist->component_uref,
161 current_pin);
162 old_cpin->nets->connected_to = g_strdup(connected_to);
163 old_cpin->nets->nid = o_current->sid;
164 g_free(connected_to);
165 } else {
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,
179 hierarchy_tag);
181 connected_to = g_strdup_printf("%s %s",
182 netlist->component_uref,
183 current_pin);
184 new_cpin->nets->connected_to = g_strdup(connected_to);
185 new_cpin->nets->nid = o_current->sid;
187 #if DEBUG
188 printf("Finished creating: %s\n", connected_to);
189 printf("netname: %s %s\n", new_cpin->nets->net_name,
190 hierarchy_tag);
191 #endif
193 g_free(connected_to);
196 } else { /* no uref, means this is a special component */
199 current_pin = strtok(NULL, DELIMITERS);
202 g_free(net_name);
206 void
207 s_netattrib_handle (TOPLEVEL * pr_current, OBJECT * o_current,
208 NETLIST * netlist, char *hierarchy_tag)
210 char *value;
211 int counter;
213 /* for now just look inside the component */
214 for (counter = 0; ;) {
215 value = o_attrib_search_inherited_attribs_by_name (o_current,
216 "net", counter);
217 if (value == NULL)
218 break;
220 counter++;
222 s_netattrib_create_pins (pr_current, o_current,
223 netlist, value, hierarchy_tag);
224 g_free (value);
227 /* now look outside the component */
228 for (counter = 0; ;) {
229 value = o_attrib_search_attached_attribs_by_name (o_current,
230 "net", counter);
231 if (value == NULL)
232 break;
234 counter++;
236 s_netattrib_create_pins (pr_current, o_current,
237 netlist, value, hierarchy_tag);
238 g_free (value);
242 char *s_netattrib_net_search (OBJECT * o_current, const gchar *wanted_pin)
244 char *value = NULL;
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;
250 int counter;
252 if (o_current == NULL ||
253 o_current->complex == NULL)
254 return NULL;
256 /* for now just look inside the component */
257 for (counter = 0; ;) {
258 value = o_attrib_search_inherited_attribs_by_name (o_current,
259 "net", counter);
260 if (value == NULL)
261 break;
263 counter++;
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);
269 g_free (value);
270 return NULL;
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);
284 g_free (value);
287 /* now look outside the component */
288 for (counter = 0; ;) {
289 value = o_attrib_search_attached_attribs_by_name (o_current,
290 "net", counter);
291 if (value == NULL)
292 break;
294 counter++;
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);
300 g_free (value);
301 return NULL;
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);
311 return net_name;
313 current_pin = strtok (NULL, DELIMITERS);
316 g_free (value);
319 return return_value;
322 char *s_netattrib_return_netname(TOPLEVEL * pr_current, OBJECT * o_current,
323 char *pinnumber, char *hierarchy_tag)
325 const gchar *current_pin;
326 char *netname;
327 char *temp_netname;
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,
334 current_pin);
336 netname =
337 s_hierarchy_create_netattrib(pr_current, temp_netname,
338 hierarchy_tag);
340 #if DEBUG
341 printf("netname: %s\n", netname);
342 #endif
344 return (netname);