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