Bump gEDA version
[geda-gaf.git] / libgeda / src / s_slot.c
blob3a11b8f3b9faf0d27be39a59214d2f7122f87319
1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
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 /*! \file s_slot.c
22 * \brief utility functions for slotted components
25 #include <config.h>
27 #include <stdio.h>
28 #ifdef HAVE_STRING_H
29 #include <string.h>
30 #endif
31 #include <math.h>
33 #include "libgeda_priv.h"
35 /*! Basic string splitting delimiters */
36 #define DELIMITERS ",; "
39 /*! \brief Search for slot attribute.
40 * \par Function Description
41 * Search for slot attribute.
43 * The returned value will only come from an attached attribute.
45 * \param [in] object OBJECT list to search.
46 * \param [in] return_found attached slot attribute if found, NULL otherwise.
47 * \return Character string with attribute value, NULL otherwise.
49 * \warning
50 * Caller must g_free returned character string
52 char *s_slot_search_slot (OBJECT *object, OBJECT **return_found)
54 GList *attributes;
55 OBJECT *attrib;
56 char *value = NULL;
58 attributes = o_attrib_return_attribs (object);
59 attrib = o_attrib_find_attrib_by_name (attributes, "slot", 0);
60 g_list_free (attributes);
62 if (attrib != NULL)
63 o_attrib_get_name_value (attrib, NULL, &value);
65 if (return_found)
66 *return_found = attrib;
68 return value;
72 /*! \brief Search for slotdef attribute.
73 * \par Function Description
74 * Search for slotdef attribute.
76 * \param [in] object The OBJECT list to search.
77 * \param [in] slotnumber The slot number to search for.
78 * \return Character string with attribute value, NULL otherwise.
80 * \warning
81 * Caller must g_free returned character string.
83 static char *s_slot_search_slotdef (OBJECT *object, int slotnumber)
85 int counter = 0;
86 char *slotdef;
87 char *search_for;
89 search_for = g_strdup_printf ("%d:", slotnumber);
91 while (1) {
92 slotdef = o_attrib_search_object_attribs_by_name (object, "slotdef",
93 counter++);
94 if (slotdef == NULL ||
95 strncmp (slotdef, search_for, strlen (search_for)) == 0)
96 break;
98 g_free (slotdef);
101 g_free (search_for);
102 return slotdef;
106 /*! \brief Update all slot attributes in an object.
107 * \par Function Description
108 * Update pinnumber attributes in a graphic object.
109 * The interesting case is where the object is an
110 * instantiation of a slotted part. This means that
111 * s_slot_update_object iterates through all pins
112 * found on object and sets the pinnumber= attrib
113 * on each. This doesn't matter for non-slotted
114 * parts, but on slotted parts, this is what sets the
115 * pinnumber= attribute on slots 2, 3, 4....
117 * \param [in] toplevel The TOPLEVEL object.
118 * \param [in,out] object The OBJECT to update.
120 void s_slot_update_object (TOPLEVEL *toplevel, OBJECT *object)
122 OBJECT *o_pin_object;
123 OBJECT *o_pinnum_attrib;
124 GList *attributes;
125 char *string;
126 char *slotdef;
127 char *pinseq;
128 int slot;
129 int slot_string;
130 int pin_counter; /* Internal pin counter private to this fcn. */
131 char* current_pin; /* text from slotdef= to be made into pinnumber= */
132 char* cptr; /* char pointer pointing to pinnumbers in slotdef=#:#,#,# string */
134 /* For this particular graphic object (component instantiation) */
135 /* get the slot number as a string */
136 string = o_attrib_search_object_attribs_by_name (object, "slot", 0);
138 if (string == NULL) {
139 /* Did not find slot= attribute.
140 * This happens if there is no attached slot attribute, and
141 * there is no default slot= attribute inside the symbol.
142 * Assume slot=1.
144 slot = 1;
145 slot_string = 0;
146 } else {
147 slot_string = 1;
148 slot = atoi (string);
149 g_free (string);
152 /* OK, now that we have the slot number, use it to get the */
153 /* corresponding slotdef=#:#,#,# string. */
154 slotdef = s_slot_search_slotdef (object, slot);
156 if (slotdef == NULL) {
157 if (slot_string) /* only an error if there's a slot string */
158 s_log_message (_("Did not find slotdef=#:#,#,#... attribute\n"));
159 return;
162 if (!strstr (slotdef, ":")) {
163 /* Didn't find proper slotdef=#:... put warning into log */
164 s_log_message (_("Improper slotdef syntax: missing \":\".\n"));
165 g_free (slotdef);
166 return;
169 /* skip over slotdef number */
170 /* slotdef is in the form #:#,#,# */
171 /* this code skips first #: */
172 cptr = slotdef;
173 while (*cptr != '\0' && *cptr != ':') {
174 cptr++;
176 cptr++; /* skip colon */
178 if (*cptr == '\0') {
179 s_log_message (_("Did not find proper slotdef=#:#,#,#... attribute\n"));
180 g_free (slotdef);
181 return;
184 /* loop on all pins found in slotdef= attribute */
185 pin_counter = 1; /* internal pin_counter */
186 /* get current pinnumber= from slotdef= attrib */
187 current_pin = strtok (cptr, DELIMITERS);
188 while (current_pin != NULL) {
189 /* get pin on this component with pinseq == pin_counter */
190 pinseq = g_strdup_printf ("%d", pin_counter);
191 o_pin_object = o_complex_find_pin_by_attribute (object, "pinseq", pinseq);
192 g_free (pinseq);
194 if (o_pin_object != NULL) {
195 /* Now rename pinnumber= attrib on this part with value found */
196 /* in slotdef attribute */
197 attributes = o_attrib_return_attribs (o_pin_object);
198 o_pinnum_attrib = o_attrib_find_attrib_by_name (attributes, "pinnumber", 0);
199 g_list_free (attributes);
201 if (o_pinnum_attrib != NULL) {
202 gchar *buf = g_strdup_printf ("pinnumber=%s", current_pin);
203 o_text_set_string (toplevel, o_pinnum_attrib, buf);
204 g_free (buf);
207 pin_counter++;
208 } else {
209 s_log_message (_("component missing pinseq= attribute\n"));
212 current_pin = strtok (NULL, DELIMITERS);
215 g_free (slotdef);