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