Check sscanf() return value in GetValue().
[geda-pcb/whiteaudio.git] / gts / container.c
blobe1dc0fa73d3d7c3294fe3f3829dc1e256f2c2cb1
1 /* GTS - Library for the manipulation of triangulated surfaces
2 * Copyright (C) 1999 Stéphane Popinet
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "gts.h"
22 /* GtsContainee */
24 static void containee_class_init (GtsContaineeClass * klass)
26 klass->remove_container = NULL;
27 klass->add_container = NULL;
28 klass->foreach = NULL;
29 klass->is_contained = NULL;
30 klass->replace = NULL;
33 GtsContaineeClass * gts_containee_class (void)
35 static GtsContaineeClass * klass = NULL;
37 if (klass == NULL) {
38 GtsObjectClassInfo containee_info = {
39 "GtsContainee",
40 sizeof (GtsContainee),
41 sizeof (GtsContaineeClass),
42 (GtsObjectClassInitFunc) containee_class_init,
43 (GtsObjectInitFunc) NULL,
44 (GtsArgSetFunc) NULL,
45 (GtsArgGetFunc) NULL
47 klass = gts_object_class_new (gts_object_class (),
48 &containee_info);
51 return klass;
54 GtsContainee * gts_containee_new (GtsContaineeClass * klass)
56 GtsContainee * object;
58 object = GTS_CONTAINEE (gts_object_new (GTS_OBJECT_CLASS (klass)));
60 return object;
63 gboolean gts_containee_is_contained (GtsContainee * item,
64 GtsContainer * c)
66 g_return_val_if_fail (item != NULL, FALSE);
67 g_return_val_if_fail (c != NULL, FALSE);
69 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->is_contained)
70 return
71 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->is_contained)
72 (item, c);
73 return FALSE;
76 void gts_containee_replace (GtsContainee * item,
77 GtsContainee * with)
79 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->replace)
80 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->replace) (item, with);
81 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->foreach) {
82 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->foreach)
83 (item, (GtsFunc) gts_container_add, with);
84 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->foreach)
85 (item, (GtsFunc) gts_container_remove, item);
89 /* GtsSListContainee */
91 static void slist_containee_destroy (GtsObject * object)
93 GtsSListContainee * item = GTS_SLIST_CONTAINEE (object);
94 GSList * i;
96 i = item->containers;
97 while (i) {
98 GSList * next = i->next;
100 gts_container_remove (i->data, GTS_CONTAINEE (item));
101 i = next;
103 g_assert (item->containers == NULL);
105 (* GTS_OBJECT_CLASS (gts_slist_containee_class ())->parent_class->destroy)
106 (object);
109 static void slist_containee_remove_container (GtsContainee * i,
110 GtsContainer * c)
112 GtsSListContainee * item = GTS_SLIST_CONTAINEE (i);
113 item->containers = g_slist_remove (item->containers, c);
116 static void slist_containee_add_container (GtsContainee * i,
117 GtsContainer * c)
119 GtsSListContainee * item = GTS_SLIST_CONTAINEE (i);
120 if (!g_slist_find (item->containers, c))
121 item->containers = g_slist_prepend (item->containers, c);
124 static void slist_containee_foreach (GtsContainee * c,
125 GtsFunc func,
126 gpointer data)
128 GSList * i = GTS_SLIST_CONTAINEE (c)->containers;
130 while (i) {
131 GSList * next = i->next;
133 (* func) (i->data, data);
134 i = next;
138 static gboolean slist_containee_is_contained (GtsContainee * i,
139 GtsContainer * c)
141 return g_slist_find (GTS_SLIST_CONTAINEE (i)->containers, c) ? TRUE : FALSE;
144 static void slist_containee_class_init (GtsSListContaineeClass * klass)
146 GTS_CONTAINEE_CLASS (klass)->remove_container =
147 slist_containee_remove_container;
148 GTS_CONTAINEE_CLASS (klass)->add_container =
149 slist_containee_add_container;
150 GTS_CONTAINEE_CLASS (klass)->foreach =
151 slist_containee_foreach;
152 GTS_CONTAINEE_CLASS (klass)->is_contained =
153 slist_containee_is_contained;
155 GTS_OBJECT_CLASS (klass)->destroy = slist_containee_destroy;
158 static void slist_containee_init (GtsSListContainee * object)
160 object->containers = NULL;
163 GtsSListContaineeClass * gts_slist_containee_class (void)
165 static GtsSListContaineeClass * klass = NULL;
167 if (klass == NULL) {
168 GtsObjectClassInfo slist_containee_info = {
169 "GtsSListContainee",
170 sizeof (GtsSListContainee),
171 sizeof (GtsSListContaineeClass),
172 (GtsObjectClassInitFunc) slist_containee_class_init,
173 (GtsObjectInitFunc) slist_containee_init,
174 (GtsArgSetFunc) NULL,
175 (GtsArgGetFunc) NULL
177 klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_containee_class ()),
178 &slist_containee_info);
181 return klass;
184 /* GtsContainer */
186 static void remove_container (GtsContainee * item, GtsContainer * c)
188 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->remove_container)
189 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->remove_container)
190 (item, c);
193 static void container_destroy (GtsObject * object)
195 GtsContainer * c = GTS_CONTAINER (object);
197 gts_container_foreach (c, (GtsFunc) remove_container, c);
199 (* GTS_OBJECT_CLASS (gts_container_class ())->parent_class->destroy)
200 (object);
203 static void container_add (GtsContainer * c, GtsContainee * item)
205 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->add_container)
206 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->add_container)
207 (item, c);
210 static void container_remove (GtsContainer * c, GtsContainee * item)
212 if (GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->remove_container)
213 (* GTS_CONTAINEE_CLASS (GTS_OBJECT (item)->klass)->remove_container)
214 (item, c);
217 static void container_clone_add (GtsContainee * item, GtsContainer * clone)
219 gts_container_add (clone, item);
222 static void container_clone (GtsObject * clone, GtsObject * object)
224 gts_object_init (clone, object->klass);
225 gts_container_foreach (GTS_CONTAINER (object),
226 (GtsFunc) container_clone_add, clone);
229 static void container_class_init (GtsContainerClass * klass)
231 klass->add = container_add;
232 klass->remove = container_remove;
233 klass->foreach = NULL;
234 klass->size = NULL;
236 GTS_OBJECT_CLASS (klass)->destroy = container_destroy;
237 GTS_OBJECT_CLASS (klass)->clone = container_clone;
240 GtsContainerClass * gts_container_class (void)
242 static GtsContainerClass * klass = NULL;
244 if (klass == NULL) {
245 GtsObjectClassInfo container_info = {
246 "GtsContainer",
247 sizeof (GtsContainer),
248 sizeof (GtsContainerClass),
249 (GtsObjectClassInitFunc) container_class_init,
250 (GtsObjectInitFunc) NULL,
251 (GtsArgSetFunc) NULL,
252 (GtsArgGetFunc) NULL
254 klass =
255 gts_object_class_new (GTS_OBJECT_CLASS (gts_slist_containee_class ()),
256 &container_info);
259 return klass;
262 GtsContainer * gts_container_new (GtsContainerClass * klass)
264 GtsContainer * object;
266 object = GTS_CONTAINER (gts_object_new (GTS_OBJECT_CLASS (klass)));
268 return object;
271 void gts_container_add (GtsContainer * c,
272 GtsContainee * item)
274 g_return_if_fail (c != NULL);
275 g_return_if_fail (item != NULL);
277 g_assert (GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->add);
278 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->add) (c, item);
281 void gts_container_remove (GtsContainer * c,
282 GtsContainee * item)
284 g_return_if_fail (c != NULL);
285 g_return_if_fail (item != NULL);
287 g_assert (GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->remove);
288 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->remove) (c, item);
291 void gts_container_foreach (GtsContainer * c,
292 GtsFunc func,
293 gpointer data)
295 g_return_if_fail (c != NULL);
296 g_return_if_fail (func != NULL);
298 if (GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->foreach)
299 (* GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->foreach) (c, func, data);
302 guint gts_container_size (GtsContainer * c)
304 g_return_val_if_fail (c != NULL, 0);
306 if (GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->size)
307 return (* GTS_CONTAINER_CLASS (GTS_OBJECT (c)->klass)->size) (c);
308 return 0;
311 /* GtsHashContainer */
313 static void hash_container_destroy (GtsObject * object)
315 GHashTable * items = GTS_HASH_CONTAINER (object)->items;
317 (* GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class->destroy)
318 (object);
320 g_hash_table_destroy (items);
323 static void hash_container_add (GtsContainer * c, GtsContainee * item)
325 g_return_if_fail (GTS_HASH_CONTAINER (c)->frozen == FALSE);
327 g_hash_table_insert (GTS_HASH_CONTAINER (c)->items, item, NULL);
329 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class)->add) (c, item);
332 static void hash_container_remove (GtsContainer * c, GtsContainee * item)
334 g_return_if_fail (GTS_HASH_CONTAINER (c)->frozen == FALSE);
336 g_hash_table_remove (GTS_HASH_CONTAINER (c)->items, item);
338 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_hash_container_class ())->parent_class)->remove) (c, item);
341 static void hash_foreach (GtsContainee * item,
342 gpointer item_data,
343 gpointer * info)
345 (* ((GtsFunc) info[0])) (item, info[1]);
348 static void hash_container_foreach (GtsContainer * c,
349 GtsFunc func,
350 gpointer data)
352 gpointer info[2];
354 info[0] = func;
355 info[1] = data;
356 /* prevent removing or adding items */
357 GTS_HASH_CONTAINER (c)->frozen = TRUE;
358 g_hash_table_foreach (GTS_HASH_CONTAINER (c)->items,
359 (GHFunc) hash_foreach, info);
360 GTS_HASH_CONTAINER (c)->frozen = FALSE;
363 static guint hash_container_size (GtsContainer * c)
365 return g_hash_table_size (GTS_HASH_CONTAINER (c)->items);
368 static void hash_container_class_init (GtsHashContainerClass * klass)
370 GTS_CONTAINER_CLASS (klass)->add = hash_container_add;
371 GTS_CONTAINER_CLASS (klass)->remove = hash_container_remove;
372 GTS_CONTAINER_CLASS (klass)->foreach = hash_container_foreach;
373 GTS_CONTAINER_CLASS (klass)->size = hash_container_size;
375 GTS_OBJECT_CLASS (klass)->destroy = hash_container_destroy;
378 static void hash_container_init (GtsHashContainer * object)
380 object->items = g_hash_table_new (NULL, NULL);
381 object->frozen = FALSE;
384 GtsHashContainerClass * gts_hash_container_class (void)
386 static GtsHashContainerClass * klass = NULL;
388 if (klass == NULL) {
389 GtsObjectClassInfo hash_container_info = {
390 "GtsHashContainer",
391 sizeof (GtsHashContainer),
392 sizeof (GtsHashContainerClass),
393 (GtsObjectClassInitFunc) hash_container_class_init,
394 (GtsObjectInitFunc) hash_container_init,
395 (GtsArgSetFunc) NULL,
396 (GtsArgGetFunc) NULL
398 klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_container_class ()),
399 &hash_container_info);
402 return klass;
405 /* GtsSListContainer */
407 static void slist_container_destroy (GtsObject * object)
409 GSList * items = GTS_SLIST_CONTAINER (object)->items;
411 (* GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class->destroy)
412 (object);
414 g_slist_free (items);
417 static void slist_container_add (GtsContainer * c, GtsContainee * item)
419 g_return_if_fail (GTS_SLIST_CONTAINER (c)->frozen == FALSE);
421 if (!g_slist_find (GTS_SLIST_CONTAINER (c)->items, item))
422 GTS_SLIST_CONTAINER (c)->items =
423 g_slist_prepend (GTS_SLIST_CONTAINER (c)->items, item);
425 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class)->add) (c, item);
428 static void slist_container_remove (GtsContainer * c, GtsContainee * item)
430 g_return_if_fail (GTS_SLIST_CONTAINER (c)->frozen == FALSE);
432 GTS_SLIST_CONTAINER (c)->items =
433 g_slist_remove (GTS_SLIST_CONTAINER (c)->items, item);
435 (* GTS_CONTAINER_CLASS (GTS_OBJECT_CLASS (gts_slist_container_class ())->parent_class)->remove) (c, item);
438 static void slist_container_foreach (GtsContainer * c,
439 GtsFunc func,
440 gpointer data)
442 GSList * i;
444 i = GTS_SLIST_CONTAINER (c)->items;
445 while (i) {
446 GSList * next = i->next;
448 (* func) (i->data, data);
449 i = next;
453 static guint slist_container_size (GtsContainer * c)
455 return g_slist_length (GTS_SLIST_CONTAINER (c)->items);
458 static void slist_container_class_init (GtsSListContainerClass * klass)
460 GTS_CONTAINER_CLASS (klass)->add = slist_container_add;
461 GTS_CONTAINER_CLASS (klass)->remove = slist_container_remove;
462 GTS_CONTAINER_CLASS (klass)->foreach = slist_container_foreach;
463 GTS_CONTAINER_CLASS (klass)->size = slist_container_size;
465 GTS_OBJECT_CLASS (klass)->destroy = slist_container_destroy;
468 static void slist_container_init (GtsSListContainer * object)
470 object->items = NULL;
471 object->frozen = FALSE;
474 GtsSListContainerClass * gts_slist_container_class (void)
476 static GtsSListContainerClass * klass = NULL;
478 if (klass == NULL) {
479 GtsObjectClassInfo slist_container_info = {
480 "GtsSListContainer",
481 sizeof (GtsSListContainer),
482 sizeof (GtsSListContainerClass),
483 (GtsObjectClassInitFunc) slist_container_class_init,
484 (GtsObjectInitFunc) slist_container_init,
485 (GtsArgSetFunc) NULL,
486 (GtsArgGetFunc) NULL
488 klass = gts_object_class_new (GTS_OBJECT_CLASS (gts_container_class ()),
489 &slist_container_info);
492 return klass;