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