Migrating docs.
[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  * SECTION:Enums and Flags
21  * @Short_description: Enumeration and flags types
22  * @See_also:#GParamSpecEnum, #GParamSpecFlags, g_param_spec_enum(), g_param_spec_flags(), 
23  * <link linkend="glib-mkenums">glib-mkenums</link>
24  * 
25  * The GLib type system provides fundamental types for enumeration and flags types. (Flags types
26  * are like enumerations, but allow their values to be combined by bitwise or). A registered 
27  * enumeration or flags type associates a name and a nickname with each allowed value, and 
28  * the methods g_enum_get_value_by_name(), g_enum_get_value_by_nick(), g_flags_get_value_by_name()
29  * and g_flags_get_value_by_nick() can look up values by their name or nickname.
30  * When an enumeration or flags type is registered with the GLib type system, it can
31  * be used as value type for object properties, using g_param_spec_enum() or 
32  * g_param_spec_flags().
33  * 
34  * GObject ships with a utility called <link linkend="glib-mkenums">glib-mkenums</link> that can 
35  * construct suitable type registration functions from C enumeration definitions.
36  */
37
38 /*
39  * MT safe
40  */
41
42 #include        <string.h>
43
44 #include        "genums.h"
45
46 #include        "gvalue.h"
47 #include        "gvaluecollector.h"
48
49 #include        "gobjectalias.h"
50
51
52 /* --- prototypes --- */
53 static void     g_enum_class_init               (GEnumClass     *class,
54                                                  gpointer        class_data);
55 static void     g_flags_class_init              (GFlagsClass    *class,
56                                                  gpointer        class_data);
57 static void     value_flags_enum_init           (GValue         *value);
58 static void     value_flags_enum_copy_value     (const GValue   *src_value,
59                                                  GValue         *dest_value);
60 static gchar*   value_flags_enum_collect_value  (GValue         *value,
61                                                  guint           n_collect_values,
62                                                  GTypeCValue    *collect_values,
63                                                  guint           collect_flags);
64 static gchar*   value_flags_enum_lcopy_value    (const GValue   *value,
65                                                  guint           n_collect_values,
66                                                  GTypeCValue    *collect_values,
67                                                  guint           collect_flags);
68
69 /* --- functions --- */
70 void
71 g_enum_types_init (void)
72 {
73   static gboolean initialized = FALSE;
74   static const GTypeValueTable flags_enum_value_table = {
75     value_flags_enum_init,          /* value_init */
76     NULL,                           /* value_free */
77     value_flags_enum_copy_value,    /* value_copy */
78     NULL,                           /* value_peek_pointer */
79     "i",                            /* collect_format */
80     value_flags_enum_collect_value, /* collect_value */
81     "p",                            /* lcopy_format */
82     value_flags_enum_lcopy_value,   /* lcopy_value */
83   };
84   static GTypeInfo info = {
85     0,                          /* class_size */
86     NULL,                       /* base_init */
87     NULL,                       /* base_destroy */
88     NULL,                       /* class_init */
89     NULL,                       /* class_destroy */
90     NULL,                       /* class_data */
91     0,                          /* instance_size */
92     0,                          /* n_preallocs */
93     NULL,                       /* instance_init */
94     &flags_enum_value_table,    /* value_table */
95   };
96   static const GTypeFundamentalInfo finfo = {
97     G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
98   };
99   GType type;
100   
101   g_return_if_fail (initialized == FALSE);
102   initialized = TRUE;
103   
104   /* G_TYPE_ENUM
105    */
106   info.class_size = sizeof (GEnumClass);
107   type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo,
108                                       G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
109   g_assert (type == G_TYPE_ENUM);
110   
111   /* G_TYPE_FLAGS
112    */
113   info.class_size = sizeof (GFlagsClass);
114   type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo,
115                                       G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
116   g_assert (type == G_TYPE_FLAGS);
117 }
118
119 static void
120 value_flags_enum_init (GValue *value)
121 {
122   value->data[0].v_long = 0;
123 }
124
125 static void
126 value_flags_enum_copy_value (const GValue *src_value,
127                              GValue       *dest_value)
128 {
129   dest_value->data[0].v_long = src_value->data[0].v_long;
130 }
131
132 static gchar*
133 value_flags_enum_collect_value (GValue      *value,
134                                 guint        n_collect_values,
135                                 GTypeCValue *collect_values,
136                                 guint        collect_flags)
137 {
138   value->data[0].v_long = collect_values[0].v_int;
139
140   return NULL;
141 }
142
143 static gchar*
144 value_flags_enum_lcopy_value (const GValue *value,
145                               guint         n_collect_values,
146                               GTypeCValue  *collect_values,
147                               guint         collect_flags)
148 {
149   gint *int_p = collect_values[0].v_pointer;
150   
151   if (!int_p)
152     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
153   
154   *int_p = value->data[0].v_long;
155   
156   return NULL;
157 }
158
159 /**
160  * g_enum_register_static:
161  * @name: A nul-terminated string used as the name of the new type.
162  * @const_static_values: An array of #GEnumValue structs for the possible
163  *  enumeration values. The array is terminated by a struct with all 
164  *  members being 0. GObject keeps a reference to the data, so it cannot
165  *  be stack-allocated.
166  * 
167  * Registers a new static enumeration type with the name @name. 
168  * 
169  * It is normally more convenient to let <link linkend="glib-mkenums">glib-mkenums</link> 
170  * generate a my_enum_get_type() function from a usual C enumeration definition
171  * than to write one yourself using g_enum_register_static().
172  * 
173  * Returns: The new type identifier.
174  */
175 GType
176 g_enum_register_static (const gchar      *name,
177                         const GEnumValue *const_static_values)
178 {
179   GTypeInfo enum_type_info = {
180     sizeof (GEnumClass), /* class_size */
181     NULL,                /* base_init */
182     NULL,                /* base_finalize */
183     (GClassInitFunc) g_enum_class_init,
184     NULL,                /* class_finalize */
185     NULL,                /* class_data */
186     0,                   /* instance_size */
187     0,                   /* n_preallocs */
188     NULL,                /* instance_init */
189     NULL,                /* value_table */
190   };
191   GType type;
192   
193   g_return_val_if_fail (name != NULL, 0);
194   g_return_val_if_fail (const_static_values != NULL, 0);
195   
196   enum_type_info.class_data = const_static_values;
197   
198   type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0);
199   
200   return type;
201 }
202
203 /**
204  * g_flags_register_static:
205  * @name: A nul-terminated string used as the name of the new type.
206  * @const_static_values: An array of #GFlagsValue structs for the possible
207  *  flags values. The array is terminated by a struct with all members being 0.
208  *  GObject keeps a reference to the data, so it cannot be stack-allocated.
209  * 
210  * Registers a new static flags type with the name @name. 
211  * 
212  * It is normally more convenient to let <link linkend="glib-mkenums">glib-mkenums</link> 
213  * generate a my_flags_get_type() function from a usual C enumeration definition
214  * than to write one yourself using g_flags_register_static().
215  * 
216  * Returns: The new type identifier.
217  */
218 GType
219 g_flags_register_static (const gchar       *name,
220                          const GFlagsValue *const_static_values)
221 {
222   GTypeInfo flags_type_info = {
223     sizeof (GFlagsClass), /* class_size */
224     NULL,                 /* base_init */
225     NULL,                 /* base_finalize */
226     (GClassInitFunc) g_flags_class_init,
227     NULL,                 /* class_finalize */
228     NULL,                 /* class_data */
229     0,                    /* instance_size */
230     0,                    /* n_preallocs */
231     NULL,                 /* instance_init */
232     NULL,                 /* value_table */
233   };
234   GType type;
235   
236   g_return_val_if_fail (name != NULL, 0);
237   g_return_val_if_fail (const_static_values != NULL, 0);
238   
239   flags_type_info.class_data = const_static_values;
240   
241   type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0);
242   
243   return type;
244 }
245
246 /**
247  * g_enum_complete_type_info:
248  * @g_enum_type: the type identifier of the type being completed
249  * @info: the #GTypeInfo struct to be filled in
250  * @const_values: An array of #GEnumValue structs for the possible
251  *  enumeration values. The array is terminated by a struct with all 
252  *  members being 0.
253  * 
254  * This function is meant to be called from the complete_type_info() function 
255  * of a #GTypePlugin implementation, as in the following example:
256  * 
257  * |[
258  * static void
259  * my_enum_complete_type_info (GTypePlugin     *plugin,
260  *                             GType            g_type,
261  *                             GTypeInfo       *info,
262  *                             GTypeValueTable *value_table)
263  * {
264  *   static const GEnumValue values[] = {
265  *     { MY_ENUM_FOO, "MY_ENUM_FOO", "foo" },
266  *     { MY_ENUM_BAR, "MY_ENUM_BAR", "bar" },
267  *     { 0, NULL, NULL }
268  *   };  
269  *    
270  *   g_enum_complete_type_info (type, info, values);  
271  * }
272  * ]|
273  */
274 void
275 g_enum_complete_type_info (GType             g_enum_type,
276                            GTypeInfo        *info,
277                            const GEnumValue *const_values)
278 {
279   g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
280   g_return_if_fail (info != NULL);
281   g_return_if_fail (const_values != NULL);
282   
283   info->class_size = sizeof (GEnumClass);
284   info->base_init = NULL;
285   info->base_finalize = NULL;
286   info->class_init = (GClassInitFunc) g_enum_class_init;
287   info->class_finalize = NULL;
288   info->class_data = const_values;
289 }
290
291 /**
292  * g_flags_complete_type_info:
293  * @g_flags_type: the type identifier of the type being completed
294  * @info: the #GTypeInfo struct to be filled in
295  * @const_values: An array of #GFlagsValue structs for the possible
296  *  enumeration values. The array is terminated by a struct with all 
297  *  members being 0.
298  * 
299  * This function is meant to be called from the complete_type_info() function 
300  * of a #GTypePlugin implementation, see the example for 
301  * g_enum_complete_type_info() above.
302  */
303 void
304 g_flags_complete_type_info (GType              g_flags_type,
305                             GTypeInfo         *info,
306                             const GFlagsValue *const_values)
307 {
308   g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
309   g_return_if_fail (info != NULL);
310   g_return_if_fail (const_values != NULL);
311   
312   info->class_size = sizeof (GFlagsClass);
313   info->base_init = NULL;
314   info->base_finalize = NULL;
315   info->class_init = (GClassInitFunc) g_flags_class_init;
316   info->class_finalize = NULL;
317   info->class_data = const_values;
318 }
319
320 static void
321 g_enum_class_init (GEnumClass *class,
322                    gpointer    class_data)
323 {
324   g_return_if_fail (G_IS_ENUM_CLASS (class));
325   
326   class->minimum = 0;
327   class->maximum = 0;
328   class->n_values = 0;
329   class->values = class_data;
330   
331   if (class->values)
332     {
333       GEnumValue *values;
334       
335       class->minimum = class->values->value;
336       class->maximum = class->values->value;
337       for (values = class->values; values->value_name; values++)
338         {
339           class->minimum = MIN (class->minimum, values->value);
340           class->maximum = MAX (class->maximum, values->value);
341           class->n_values++;
342         }
343     }
344 }
345
346 static void
347 g_flags_class_init (GFlagsClass *class,
348                     gpointer     class_data)
349 {
350   g_return_if_fail (G_IS_FLAGS_CLASS (class));
351   
352   class->mask = 0;
353   class->n_values = 0;
354   class->values = class_data;
355   
356   if (class->values)
357     {
358       GFlagsValue *values;
359       
360       for (values = class->values; values->value_name; values++)
361         {
362           class->mask |= values->value;
363           class->n_values++;
364         }
365     }
366 }
367
368 /**
369  * g_enum_get_value_by_name:
370  * @enum_class: a #GEnumClass
371  * @name: the name to look up
372  * 
373  * Looks up a #GEnumValue by name.
374  * 
375  * Returns: the #GEnumValue with name @name, or %NULL if the enumeration doesn'
376  *  t have a member with that name
377  */
378 GEnumValue*
379 g_enum_get_value_by_name (GEnumClass  *enum_class,
380                           const gchar *name)
381 {
382   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
383   g_return_val_if_fail (name != NULL, NULL);
384   
385   if (enum_class->n_values)
386     {
387       GEnumValue *enum_value;
388       
389       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
390         if (strcmp (name, enum_value->value_name) == 0)
391           return enum_value;
392     }
393   
394   return NULL;
395 }
396
397 /**
398  * g_flags_get_value_by_name:
399  * @flags_class: a #GFlagsClass
400  * @name: the name to look up
401  * 
402  * Looks up a #GFlagsValue by name.
403  * 
404  * Returns: the #GFlagsValue with name @name, or %NULL if there is no flag with
405  *  that name
406  */
407 GFlagsValue*
408 g_flags_get_value_by_name (GFlagsClass *flags_class,
409                            const gchar *name)
410 {
411   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
412   g_return_val_if_fail (name != NULL, NULL);
413   
414   if (flags_class->n_values)
415     {
416       GFlagsValue *flags_value;
417       
418       for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
419         if (strcmp (name, flags_value->value_name) == 0)
420           return flags_value;
421     }
422   
423   return NULL;
424 }
425
426 /**
427  * g_enum_get_value_by_nick:
428  * @enum_class: a #GEnumClass
429  * @nick: the nickname to look up
430  * 
431  * Looks up a #GEnumValue by nickname.
432  * 
433  * Returns: the #GEnumValue with nickname @nick, or %NULL if the enumeration doesn'
434  *  t have a member with that nickname
435  */
436 GEnumValue*
437 g_enum_get_value_by_nick (GEnumClass  *enum_class,
438                           const gchar *nick)
439 {
440   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
441   g_return_val_if_fail (nick != NULL, NULL);
442   
443   if (enum_class->n_values)
444     {
445       GEnumValue *enum_value;
446       
447       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
448         if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
449           return enum_value;
450     }
451   
452   return NULL;
453 }
454
455 /**
456  * g_flags_get_value_by_nick:
457  * @flags_class: a #GFlagsClass
458  * @nick: the nickname to look up
459  * 
460  * Looks up a #GFlagsValue by nickname.
461  * 
462  * Returns: the #GFlagsValue with nickname @nick, or %NULL if there is no flag
463  *  with that nickname
464  */
465 GFlagsValue*
466 g_flags_get_value_by_nick (GFlagsClass *flags_class,
467                            const gchar *nick)
468 {
469   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
470   g_return_val_if_fail (nick != NULL, NULL);
471   
472   if (flags_class->n_values)
473     {
474       GFlagsValue *flags_value;
475       
476       for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
477         if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
478           return flags_value;
479     }
480   
481   return NULL;
482 }
483
484 /**
485  * g_enum_get_value:
486  * @enum_class: a #GEnumClass
487  * @value: the value to look up
488  * 
489  * Returns the #GEnumValue for a value.
490  * 
491  * Returns: the #GEnumValue for @value, or %NULL if @value is not 
492  *  a member of the enumeration
493  */
494 GEnumValue*
495 g_enum_get_value (GEnumClass *enum_class,
496                   gint        value)
497 {
498   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
499   
500   if (enum_class->n_values)
501     {
502       GEnumValue *enum_value;
503       
504       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
505         if (enum_value->value == value)
506           return enum_value;
507     }
508   
509   return NULL;
510 }
511
512 /**
513  * g_flags_get_first_value:
514  * @flags_class: a #GFlagsClass
515  * @value: the value
516  * 
517  * Returns the first #GFlagsValue which is set in @value.
518  * 
519  * Returns: the first #GFlagsValue which is set in @value, or %NULL if none is set
520  */
521 GFlagsValue*
522 g_flags_get_first_value (GFlagsClass *flags_class,
523                          guint        value)
524 {
525   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
526   
527   if (flags_class->n_values)
528     {
529       GFlagsValue *flags_value;
530
531       if (value == 0)
532         {
533           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
534             if (flags_value->value == 0)
535               return flags_value;
536         }
537       else
538         {
539           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
540             if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value)
541               return flags_value;
542         }      
543     }
544   
545   return NULL;
546 }
547
548 void
549 g_value_set_enum (GValue *value,
550                   gint    v_enum)
551 {
552   g_return_if_fail (G_VALUE_HOLDS_ENUM (value));
553   
554   value->data[0].v_long = v_enum;
555 }
556
557 gint
558 g_value_get_enum (const GValue *value)
559 {
560   g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0);
561   
562   return value->data[0].v_long;
563 }
564
565 void
566 g_value_set_flags (GValue *value,
567                    guint   v_flags)
568 {
569   g_return_if_fail (G_VALUE_HOLDS_FLAGS (value));
570   
571   value->data[0].v_ulong = v_flags;
572 }
573
574 guint
575 g_value_get_flags (const GValue *value)
576 {
577   g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0);
578   
579   return value->data[0].v_ulong;
580 }
581
582 #define __G_ENUMS_C__
583 #include "gobjectaliasdef.c"