Use <malloc.h> also with Digital Mars compiler on Win32. (#346808, Serhat
[platform/upstream/glib.git] / gobject / genums.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser 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.
8  *
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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public 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.
18  */
19
20 /*
21  * MT safe
22  */
23
24 #include        <string.h>
25
26 #include        "genums.h"
27
28 #include        "gvalue.h"
29 #include        "gvaluecollector.h"
30
31 #include        "gobjectalias.h"
32
33
34 /* --- prototypes --- */
35 static void     g_enum_class_init               (GEnumClass     *class,
36                                                  gpointer        class_data);
37 static void     g_flags_class_init              (GFlagsClass    *class,
38                                                  gpointer        class_data);
39 static void     value_flags_enum_init           (GValue         *value);
40 static void     value_flags_enum_copy_value     (const GValue   *src_value,
41                                                  GValue         *dest_value);
42 static gchar*   value_flags_enum_collect_value  (GValue         *value,
43                                                  guint           n_collect_values,
44                                                  GTypeCValue    *collect_values,
45                                                  guint           collect_flags);
46 static gchar*   value_flags_enum_lcopy_value    (const GValue   *value,
47                                                  guint           n_collect_values,
48                                                  GTypeCValue    *collect_values,
49                                                  guint           collect_flags);
50
51 /* --- functions --- */
52 void
53 g_enum_types_init (void)
54 {
55   static gboolean initialized = FALSE;
56   static const GTypeValueTable flags_enum_value_table = {
57     value_flags_enum_init,          /* value_init */
58     NULL,                           /* value_free */
59     value_flags_enum_copy_value,    /* value_copy */
60     NULL,                           /* value_peek_pointer */
61     "i",                            /* collect_format */
62     value_flags_enum_collect_value, /* collect_value */
63     "p",                            /* lcopy_format */
64     value_flags_enum_lcopy_value,   /* lcopy_value */
65   };
66   static GTypeInfo info = {
67     0,                          /* class_size */
68     NULL,                       /* base_init */
69     NULL,                       /* base_destroy */
70     NULL,                       /* class_init */
71     NULL,                       /* class_destroy */
72     NULL,                       /* class_data */
73     0,                          /* instance_size */
74     0,                          /* n_preallocs */
75     NULL,                       /* instance_init */
76     &flags_enum_value_table,    /* value_table */
77   };
78   static const GTypeFundamentalInfo finfo = {
79     G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
80   };
81   GType type;
82   
83   g_return_if_fail (initialized == FALSE);
84   initialized = TRUE;
85   
86   /* G_TYPE_ENUM
87    */
88   info.class_size = sizeof (GEnumClass);
89   type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo,
90                                       G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
91   g_assert (type == G_TYPE_ENUM);
92   
93   /* G_TYPE_FLAGS
94    */
95   info.class_size = sizeof (GFlagsClass);
96   type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo,
97                                       G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
98   g_assert (type == G_TYPE_FLAGS);
99 }
100
101 static void
102 value_flags_enum_init (GValue *value)
103 {
104   value->data[0].v_long = 0;
105 }
106
107 static void
108 value_flags_enum_copy_value (const GValue *src_value,
109                              GValue       *dest_value)
110 {
111   dest_value->data[0].v_long = src_value->data[0].v_long;
112 }
113
114 static gchar*
115 value_flags_enum_collect_value (GValue      *value,
116                                 guint        n_collect_values,
117                                 GTypeCValue *collect_values,
118                                 guint        collect_flags)
119 {
120   value->data[0].v_long = collect_values[0].v_int;
121
122   return NULL;
123 }
124
125 static gchar*
126 value_flags_enum_lcopy_value (const GValue *value,
127                               guint         n_collect_values,
128                               GTypeCValue  *collect_values,
129                               guint         collect_flags)
130 {
131   gint *int_p = collect_values[0].v_pointer;
132   
133   if (!int_p)
134     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
135   
136   *int_p = value->data[0].v_long;
137   
138   return NULL;
139 }
140
141 GType
142 g_enum_register_static (const gchar      *name,
143                         const GEnumValue *const_static_values)
144 {
145   GTypeInfo enum_type_info = {
146     sizeof (GEnumClass), /* class_size */
147     NULL,                /* base_init */
148     NULL,                /* base_finalize */
149     (GClassInitFunc) g_enum_class_init,
150     NULL,                /* class_finalize */
151     NULL,                /* class_data */
152     0,                   /* instance_size */
153     0,                   /* n_preallocs */
154     NULL,                /* instance_init */
155     NULL,                /* value_table */
156   };
157   GType type;
158   
159   g_return_val_if_fail (name != NULL, 0);
160   g_return_val_if_fail (const_static_values != NULL, 0);
161   
162   enum_type_info.class_data = const_static_values;
163   
164   type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0);
165   
166   return type;
167 }
168
169 GType
170 g_flags_register_static (const gchar       *name,
171                          const GFlagsValue *const_static_values)
172 {
173   GTypeInfo flags_type_info = {
174     sizeof (GFlagsClass), /* class_size */
175     NULL,                 /* base_init */
176     NULL,                 /* base_finalize */
177     (GClassInitFunc) g_flags_class_init,
178     NULL,                 /* class_finalize */
179     NULL,                 /* class_data */
180     0,                    /* instance_size */
181     0,                    /* n_preallocs */
182     NULL,                 /* instance_init */
183     NULL,                 /* value_table */
184   };
185   GType type;
186   
187   g_return_val_if_fail (name != NULL, 0);
188   g_return_val_if_fail (const_static_values != NULL, 0);
189   
190   flags_type_info.class_data = const_static_values;
191   
192   type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0);
193   
194   return type;
195 }
196
197 void
198 g_enum_complete_type_info (GType             g_enum_type,
199                            GTypeInfo        *info,
200                            const GEnumValue *const_values)
201 {
202   g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
203   g_return_if_fail (info != NULL);
204   g_return_if_fail (const_values != NULL);
205   
206   info->class_size = sizeof (GEnumClass);
207   info->base_init = NULL;
208   info->base_finalize = NULL;
209   info->class_init = (GClassInitFunc) g_enum_class_init;
210   info->class_finalize = NULL;
211   info->class_data = const_values;
212 }
213
214 void
215 g_flags_complete_type_info (GType              g_flags_type,
216                             GTypeInfo         *info,
217                             const GFlagsValue *const_values)
218 {
219   g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
220   g_return_if_fail (info != NULL);
221   g_return_if_fail (const_values != NULL);
222   
223   info->class_size = sizeof (GFlagsClass);
224   info->base_init = NULL;
225   info->base_finalize = NULL;
226   info->class_init = (GClassInitFunc) g_flags_class_init;
227   info->class_finalize = NULL;
228   info->class_data = const_values;
229 }
230
231 static void
232 g_enum_class_init (GEnumClass *class,
233                    gpointer    class_data)
234 {
235   g_return_if_fail (G_IS_ENUM_CLASS (class));
236   
237   class->minimum = 0;
238   class->maximum = 0;
239   class->n_values = 0;
240   class->values = class_data;
241   
242   if (class->values)
243     {
244       GEnumValue *values;
245       
246       class->minimum = class->values->value;
247       class->maximum = class->values->value;
248       for (values = class->values; values->value_name; values++)
249         {
250           class->minimum = MIN (class->minimum, values->value);
251           class->maximum = MAX (class->maximum, values->value);
252           class->n_values++;
253         }
254     }
255 }
256
257 static void
258 g_flags_class_init (GFlagsClass *class,
259                     gpointer     class_data)
260 {
261   g_return_if_fail (G_IS_FLAGS_CLASS (class));
262   
263   class->mask = 0;
264   class->n_values = 0;
265   class->values = class_data;
266   
267   if (class->values)
268     {
269       GFlagsValue *values;
270       
271       for (values = class->values; values->value_name; values++)
272         {
273           class->mask |= values->value;
274           class->n_values++;
275         }
276     }
277 }
278
279 GEnumValue*
280 g_enum_get_value_by_name (GEnumClass  *enum_class,
281                           const gchar *name)
282 {
283   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
284   g_return_val_if_fail (name != NULL, NULL);
285   
286   if (enum_class->n_values)
287     {
288       GEnumValue *enum_value;
289       
290       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
291         if (strcmp (name, enum_value->value_name) == 0)
292           return enum_value;
293     }
294   
295   return NULL;
296 }
297
298 GFlagsValue*
299 g_flags_get_value_by_name (GFlagsClass *flags_class,
300                            const gchar *name)
301 {
302   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
303   g_return_val_if_fail (name != NULL, NULL);
304   
305   if (flags_class->n_values)
306     {
307       GFlagsValue *flags_value;
308       
309       for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
310         if (strcmp (name, flags_value->value_name) == 0)
311           return flags_value;
312     }
313   
314   return NULL;
315 }
316
317 GEnumValue*
318 g_enum_get_value_by_nick (GEnumClass  *enum_class,
319                           const gchar *nick)
320 {
321   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
322   g_return_val_if_fail (nick != NULL, NULL);
323   
324   if (enum_class->n_values)
325     {
326       GEnumValue *enum_value;
327       
328       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
329         if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
330           return enum_value;
331     }
332   
333   return NULL;
334 }
335
336 GFlagsValue*
337 g_flags_get_value_by_nick (GFlagsClass *flags_class,
338                            const gchar *nick)
339 {
340   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
341   g_return_val_if_fail (nick != NULL, NULL);
342   
343   if (flags_class->n_values)
344     {
345       GFlagsValue *flags_value;
346       
347       for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
348         if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
349           return flags_value;
350     }
351   
352   return NULL;
353 }
354
355 GEnumValue*
356 g_enum_get_value (GEnumClass *enum_class,
357                   gint        value)
358 {
359   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
360   
361   if (enum_class->n_values)
362     {
363       GEnumValue *enum_value;
364       
365       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
366         if (enum_value->value == value)
367           return enum_value;
368     }
369   
370   return NULL;
371 }
372
373 GFlagsValue*
374 g_flags_get_first_value (GFlagsClass *flags_class,
375                          guint        value)
376 {
377   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
378   
379   if (flags_class->n_values)
380     {
381       GFlagsValue *flags_value;
382
383       if (value == 0)
384         {
385           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
386             if (flags_value->value == 0)
387               return flags_value;
388         }
389       else
390         {
391           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
392             if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value)
393               return flags_value;
394         }      
395     }
396   
397   return NULL;
398 }
399
400 void
401 g_value_set_enum (GValue *value,
402                   gint    v_enum)
403 {
404   g_return_if_fail (G_VALUE_HOLDS_ENUM (value));
405   
406   value->data[0].v_long = v_enum;
407 }
408
409 gint
410 g_value_get_enum (const GValue *value)
411 {
412   g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0);
413   
414   return value->data[0].v_long;
415 }
416
417 void
418 g_value_set_flags (GValue *value,
419                    guint   v_flags)
420 {
421   g_return_if_fail (G_VALUE_HOLDS_FLAGS (value));
422   
423   value->data[0].v_ulong = v_flags;
424 }
425
426 guint
427 g_value_get_flags (const GValue *value)
428 {
429   g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0);
430   
431   return value->data[0].v_ulong;
432 }
433
434 #define __G_ENUMS_C__
435 #include "gobjectaliasdef.c"