libgeda: Remove some exit() calls and assertions.
[geda-gaf/peter-b.git] / libgeda / src / s_slot.c
blob2baab2b2a181cc14bc6af9d719b4f08bdaa167ab
1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
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
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 #ifdef HAVE_LIBDMALLOC
36 #include <dmalloc.h>
37 #endif
39 /*! Basic string splitting delimiters */
40 #define DELIMITERS ",; "
43 /*! \brief Search for slot attribute.
44 * \par Function Description
45 * Search for slot attribute.
47 * The returned value will only come from an attached attribute.
49 * \param [in] object OBJECT list to search.
50 * \param [in] return_found attached slot attribute if found, NULL otherwise.
51 * \return Character string with attribute value, NULL otherwise.
53 * \warning
54 * Caller must g_free returned character string
56 char *s_slot_search_slot (OBJECT *object, OBJECT **return_found)
58 GList *attributes;
59 OBJECT *attrib;
60 char *value = NULL;
62 attributes = o_attrib_return_attribs (object);
63 attrib = o_attrib_find_attrib_by_name (attributes, "slot", 0);
64 g_list_free (attributes);
66 if (attrib != NULL)
67 o_attrib_get_name_value (attrib, NULL, &value);
69 if (return_found)
70 *return_found = attrib;
72 return value;
76 /*! \brief Search for slotdef attribute.
77 * \par Function Description
78 * Search for slotdef attribute.
80 * \param [in] object The OBJECT list to search.
81 * \param [in] slotnumber The slot number to search for.
82 * \return Character string with attribute value, NULL otherwise.
84 * \warning
85 * Caller must g_free returned character string.
87 static char *s_slot_search_slotdef (OBJECT *object, int slotnumber)
89 int counter = 0;
90 char *slotdef;
91 char *search_for;
93 search_for = g_strdup_printf ("%d:", slotnumber);
95 while (1) {
96 slotdef = o_attrib_search_object_attribs_by_name (object, "slotdef",
97 counter++);
98 if (slotdef == NULL ||
99 strncmp (slotdef, search_for, strlen (search_for)) == 0)
100 break;
102 g_free (slotdef);
105 g_free (search_for);
106 return slotdef;
110 /*! \brief Update all slot attributes in an object.
111 * \par Function Description
112 * Update pinnumber attributes in a graphic object.
113 * The interesting case is where the object is an
114 * instantiation of a slotted part. This means that
115 * s_slot_update_object iterates through all pins
116 * found on object and sets the pinnumber= attrib
117 * on each. This doesn't matter for non-slotted
118 * parts, but on slotted parts, this is what sets the
119 * pinnumber= attribute on slots 2, 3, 4....
121 * \param [in] toplevel The TOPLEVEL object.
122 * \param [in,out] object The OBJECT to update.
124 void s_slot_update_object (TOPLEVEL *toplevel, OBJECT *object)
126 OBJECT *o_pin_object;
127 OBJECT *o_pinnum_attrib;
128 GList *attributes;
129 char *string;
130 char *slotdef;
131 char *pinseq;
132 int slot;
133 int slot_string;
134 int pin_counter; /* Internal pin counter private to this fcn. */
135 char* current_pin; /* text from slotdef= to be made into pinnumber= */
136 char* cptr; /* char pointer pointing to pinnumbers in slotdef=#:#,#,# string */
138 /* For this particular graphic object (component instantiation) */
139 /* get the slot number as a string */
140 string = o_attrib_search_object_attribs_by_name (object, "slot", 0);
142 if (string == NULL) {
143 /* Did not find slot= attribute.
144 * This happens if there is no attached slot attribute, and
145 * there is no default slot= attribute inside the symbol.
146 * Assume slot=1.
148 slot = 1;
149 slot_string = 0;
150 } else {
151 slot_string = 1;
152 slot = atoi (string);
153 g_free (string);
156 /* OK, now that we have the slot number, use it to get the */
157 /* corresponding slotdef=#:#,#,# string. */
158 slotdef = s_slot_search_slotdef (object, slot);
160 if (slotdef == NULL) {
161 if (slot_string) /* only an error if there's a slot string */
162 s_log_message (_("Did not find slotdef=#:#,#,#... attribute\n"));
163 return;
166 if (!strstr (slotdef, ":")) {
167 /* Didn't find proper slotdef=#:... put warning into log */
168 s_log_message (_("Improper slotdef syntax: missing \":\".\n"));
169 g_free (slotdef);
170 return;
173 /* skip over slotdef number */
174 /* slotdef is in the form #:#,#,# */
175 /* this code skips first #: */
176 cptr = slotdef;
177 while (*cptr != '\0' && *cptr != ':') {
178 cptr++;
180 cptr++; /* skip colon */
182 if (*cptr == '\0') {
183 s_log_message (_("Did not find proper slotdef=#:#,#,#... attribute\n"));
184 g_free (slotdef);
185 return;
188 /* loop on all pins found in slotdef= attribute */
189 pin_counter = 1; /* internal pin_counter */
190 /* get current pinnumber= from slotdef= attrib */
191 current_pin = strtok (cptr, DELIMITERS);
192 while (current_pin != NULL) {
193 /* get pin on this component with pinseq == pin_counter */
194 pinseq = g_strdup_printf ("%d", pin_counter);
195 o_pin_object = o_complex_find_pin_by_attribute (object, "pinseq", pinseq);
196 g_free (pinseq);
198 if (o_pin_object != NULL) {
199 /* Now rename pinnumber= attrib on this part with value found */
200 /* in slotdef attribute */
201 attributes = o_attrib_return_attribs (o_pin_object);
202 o_pinnum_attrib = o_attrib_find_attrib_by_name (attributes, "pinnumber", 0);
203 g_list_free (attributes);
205 if (o_pinnum_attrib != NULL) {
206 o_text_set_string (toplevel,
207 o_pinnum_attrib,
208 g_strdup_printf ("pinnumber=%s", current_pin));
211 pin_counter++;
212 } else {
213 s_log_message (_("component missing pinseq= attribute\n"));
216 current_pin = strtok (NULL, DELIMITERS);
219 g_free (slotdef);