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