tizen: kdbus: make i explicitly positive in make_single_header_vector
[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  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General
17  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
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 /* --- prototypes --- */
35 static void     g_enum_class_init               (GEnumClass     *class,
36                                                  gpointer        class_data);
37 static void     g_flags_class_init              (GFlagsClass    *class,
38                                                  gpointer        class_data);
39 static void     value_flags_enum_init           (GValue         *value);
40 static void     value_flags_enum_copy_value     (const GValue   *src_value,
41                                                  GValue         *dest_value);
42 static gchar*   value_flags_enum_collect_value  (GValue         *value,
43                                                  guint           n_collect_values,
44                                                  GTypeCValue    *collect_values,
45                                                  guint           collect_flags);
46 static gchar*   value_flags_enum_lcopy_value    (const GValue   *value,
47                                                  guint           n_collect_values,
48                                                  GTypeCValue    *collect_values,
49                                                  guint           collect_flags);
50
51 /* --- functions --- */
52 void
53 _g_enum_types_init (void)
54 {
55   static gboolean initialized = FALSE;
56   static const GTypeValueTable flags_enum_value_table = {
57     value_flags_enum_init,          /* value_init */
58     NULL,                           /* value_free */
59     value_flags_enum_copy_value,    /* value_copy */
60     NULL,                           /* value_peek_pointer */
61     "i",                            /* collect_format */
62     value_flags_enum_collect_value, /* collect_value */
63     "p",                            /* lcopy_format */
64     value_flags_enum_lcopy_value,   /* lcopy_value */
65   };
66   GTypeInfo info = {
67     0,                          /* class_size */
68     NULL,                       /* base_init */
69     NULL,                       /* base_destroy */
70     NULL,                       /* class_init */
71     NULL,                       /* class_destroy */
72     NULL,                       /* class_data */
73     0,                          /* instance_size */
74     0,                          /* n_preallocs */
75     NULL,                       /* instance_init */
76     &flags_enum_value_table,    /* value_table */
77   };
78   static const GTypeFundamentalInfo finfo = {
79     G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
80   };
81   GType type G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;
82   
83   g_return_if_fail (initialized == FALSE);
84   initialized = TRUE;
85   
86   /* G_TYPE_ENUM
87    */
88   info.class_size = sizeof (GEnumClass);
89   type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo,
90                                       G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
91   g_assert (type == G_TYPE_ENUM);
92   
93   /* G_TYPE_FLAGS
94    */
95   info.class_size = sizeof (GFlagsClass);
96   type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo,
97                                       G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
98   g_assert (type == G_TYPE_FLAGS);
99 }
100
101 static void
102 value_flags_enum_init (GValue *value)
103 {
104   value->data[0].v_long = 0;
105 }
106
107 static void
108 value_flags_enum_copy_value (const GValue *src_value,
109                              GValue       *dest_value)
110 {
111   dest_value->data[0].v_long = src_value->data[0].v_long;
112 }
113
114 static gchar*
115 value_flags_enum_collect_value (GValue      *value,
116                                 guint        n_collect_values,
117                                 GTypeCValue *collect_values,
118                                 guint        collect_flags)
119 {
120   if (G_VALUE_HOLDS_ENUM (value))
121     value->data[0].v_long = collect_values[0].v_int;
122   else
123     value->data[0].v_ulong = (guint) collect_values[0].v_int;
124
125   return NULL;
126 }
127
128 static gchar*
129 value_flags_enum_lcopy_value (const GValue *value,
130                               guint         n_collect_values,
131                               GTypeCValue  *collect_values,
132                               guint         collect_flags)
133 {
134   gint *int_p = collect_values[0].v_pointer;
135
136   g_return_val_if_fail (int_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value)));
137
138   *int_p = value->data[0].v_long;
139   
140   return NULL;
141 }
142
143 /**
144  * g_enum_register_static:
145  * @name: A nul-terminated string used as the name of the new type.
146  * @const_static_values: An array of #GEnumValue structs for the possible
147  *  enumeration values. The array is terminated by a struct with all
148  *  members being 0. GObject keeps a reference to the data, so it cannot
149  *  be stack-allocated.
150  *
151  * Registers a new static enumeration type with the name @name.
152  *
153  * It is normally more convenient to let [glib-mkenums][glib-mkenums],
154  * generate a my_enum_get_type() function from a usual C enumeration
155  * definition  than to write one yourself using g_enum_register_static().
156  *
157  * Returns: The new type identifier.
158  */
159 GType
160 g_enum_register_static (const gchar      *name,
161                         const GEnumValue *const_static_values)
162 {
163   GTypeInfo enum_type_info = {
164     sizeof (GEnumClass), /* class_size */
165     NULL,                /* base_init */
166     NULL,                /* base_finalize */
167     (GClassInitFunc) g_enum_class_init,
168     NULL,                /* class_finalize */
169     NULL,                /* class_data */
170     0,                   /* instance_size */
171     0,                   /* n_preallocs */
172     NULL,                /* instance_init */
173     NULL,                /* value_table */
174   };
175   GType type;
176   
177   g_return_val_if_fail (name != NULL, 0);
178   g_return_val_if_fail (const_static_values != NULL, 0);
179   
180   enum_type_info.class_data = const_static_values;
181   
182   type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0);
183   
184   return type;
185 }
186
187 /**
188  * g_flags_register_static:
189  * @name: A nul-terminated string used as the name of the new type.
190  * @const_static_values: An array of #GFlagsValue structs for the possible
191  *  flags values. The array is terminated by a struct with all members being 0.
192  *  GObject keeps a reference to the data, so it cannot be stack-allocated.
193  *
194  * Registers a new static flags type with the name @name.
195  *
196  * It is normally more convenient to let [glib-mkenums][glib-mkenums]
197  * generate a my_flags_get_type() function from a usual C enumeration
198  * definition than to write one yourself using g_flags_register_static().
199  *
200  * Returns: The new type identifier.
201  */
202 GType
203 g_flags_register_static (const gchar       *name,
204                          const GFlagsValue *const_static_values)
205 {
206   GTypeInfo flags_type_info = {
207     sizeof (GFlagsClass), /* class_size */
208     NULL,                 /* base_init */
209     NULL,                 /* base_finalize */
210     (GClassInitFunc) g_flags_class_init,
211     NULL,                 /* class_finalize */
212     NULL,                 /* class_data */
213     0,                    /* instance_size */
214     0,                    /* n_preallocs */
215     NULL,                 /* instance_init */
216     NULL,                 /* value_table */
217   };
218   GType type;
219   
220   g_return_val_if_fail (name != NULL, 0);
221   g_return_val_if_fail (const_static_values != NULL, 0);
222   
223   flags_type_info.class_data = const_static_values;
224   
225   type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0);
226   
227   return type;
228 }
229
230 /**
231  * g_enum_complete_type_info:
232  * @g_enum_type: the type identifier of the type being completed
233  * @info: (out callee-allocates): the #GTypeInfo struct to be filled in
234  * @const_values: An array of #GEnumValue structs for the possible
235  *  enumeration values. The array is terminated by a struct with all
236  *  members being 0.
237  *
238  * This function is meant to be called from the `complete_type_info`
239  * function of a #GTypePlugin implementation, as in the following
240  * example:
241  *
242  * |[<!-- language="C" --> 
243  * static void
244  * my_enum_complete_type_info (GTypePlugin     *plugin,
245  *                             GType            g_type,
246  *                             GTypeInfo       *info,
247  *                             GTypeValueTable *value_table)
248  * {
249  *   static const GEnumValue values[] = {
250  *     { MY_ENUM_FOO, "MY_ENUM_FOO", "foo" },
251  *     { MY_ENUM_BAR, "MY_ENUM_BAR", "bar" },
252  *     { 0, NULL, NULL }
253  *   };
254  *
255  *   g_enum_complete_type_info (type, info, values);
256  * }
257  * ]|
258  */
259 void
260 g_enum_complete_type_info (GType             g_enum_type,
261                            GTypeInfo        *info,
262                            const GEnumValue *const_values)
263 {
264   g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
265   g_return_if_fail (info != NULL);
266   g_return_if_fail (const_values != NULL);
267   
268   info->class_size = sizeof (GEnumClass);
269   info->base_init = NULL;
270   info->base_finalize = NULL;
271   info->class_init = (GClassInitFunc) g_enum_class_init;
272   info->class_finalize = NULL;
273   info->class_data = const_values;
274 }
275
276 /**
277  * g_flags_complete_type_info:
278  * @g_flags_type: the type identifier of the type being completed
279  * @info: (out callee-allocates): the #GTypeInfo struct to be filled in
280  * @const_values: An array of #GFlagsValue structs for the possible
281  *  enumeration values. The array is terminated by a struct with all
282  *  members being 0.
283  *
284  * This function is meant to be called from the complete_type_info()
285  * function of a #GTypePlugin implementation, see the example for
286  * g_enum_complete_type_info() above.
287  */
288 void
289 g_flags_complete_type_info (GType              g_flags_type,
290                             GTypeInfo         *info,
291                             const GFlagsValue *const_values)
292 {
293   g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
294   g_return_if_fail (info != NULL);
295   g_return_if_fail (const_values != NULL);
296   
297   info->class_size = sizeof (GFlagsClass);
298   info->base_init = NULL;
299   info->base_finalize = NULL;
300   info->class_init = (GClassInitFunc) g_flags_class_init;
301   info->class_finalize = NULL;
302   info->class_data = const_values;
303 }
304
305 static void
306 g_enum_class_init (GEnumClass *class,
307                    gpointer    class_data)
308 {
309   g_return_if_fail (G_IS_ENUM_CLASS (class));
310   
311   class->minimum = 0;
312   class->maximum = 0;
313   class->n_values = 0;
314   class->values = class_data;
315   
316   if (class->values)
317     {
318       GEnumValue *values;
319       
320       class->minimum = class->values->value;
321       class->maximum = class->values->value;
322       for (values = class->values; values->value_name; values++)
323         {
324           class->minimum = MIN (class->minimum, values->value);
325           class->maximum = MAX (class->maximum, values->value);
326           class->n_values++;
327         }
328     }
329 }
330
331 static void
332 g_flags_class_init (GFlagsClass *class,
333                     gpointer     class_data)
334 {
335   g_return_if_fail (G_IS_FLAGS_CLASS (class));
336   
337   class->mask = 0;
338   class->n_values = 0;
339   class->values = class_data;
340   
341   if (class->values)
342     {
343       GFlagsValue *values;
344       
345       for (values = class->values; values->value_name; values++)
346         {
347           class->mask |= values->value;
348           class->n_values++;
349         }
350     }
351 }
352
353 /**
354  * g_enum_get_value_by_name:
355  * @enum_class: a #GEnumClass
356  * @name: the name to look up
357  *
358  * Looks up a #GEnumValue by name.
359  *
360  * Returns: (transfer none) (nullable): the #GEnumValue with name @name,
361  *          or %NULL if the enumeration doesn't have a member
362  *          with that name
363  */
364 GEnumValue*
365 g_enum_get_value_by_name (GEnumClass  *enum_class,
366                           const gchar *name)
367 {
368   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
369   g_return_val_if_fail (name != NULL, NULL);
370   
371   if (enum_class->n_values)
372     {
373       GEnumValue *enum_value;
374       
375       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
376         if (strcmp (name, enum_value->value_name) == 0)
377           return enum_value;
378     }
379   
380   return NULL;
381 }
382
383 /**
384  * g_flags_get_value_by_name:
385  * @flags_class: a #GFlagsClass
386  * @name: the name to look up
387  *
388  * Looks up a #GFlagsValue by name.
389  *
390  * Returns: (transfer none) (nullable): the #GFlagsValue with name @name,
391  *          or %NULL if there is no flag with that name
392  */
393 GFlagsValue*
394 g_flags_get_value_by_name (GFlagsClass *flags_class,
395                            const gchar *name)
396 {
397   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
398   g_return_val_if_fail (name != NULL, NULL);
399   
400   if (flags_class->n_values)
401     {
402       GFlagsValue *flags_value;
403       
404       for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
405         if (strcmp (name, flags_value->value_name) == 0)
406           return flags_value;
407     }
408   
409   return NULL;
410 }
411
412 /**
413  * g_enum_get_value_by_nick:
414  * @enum_class: a #GEnumClass
415  * @nick: the nickname to look up
416  *
417  * Looks up a #GEnumValue by nickname.
418  *
419  * Returns: (transfer none) (nullable): the #GEnumValue with nickname @nick,
420  *          or %NULL if the enumeration doesn't have a member
421  *          with that nickname
422  */
423 GEnumValue*
424 g_enum_get_value_by_nick (GEnumClass  *enum_class,
425                           const gchar *nick)
426 {
427   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
428   g_return_val_if_fail (nick != NULL, NULL);
429   
430   if (enum_class->n_values)
431     {
432       GEnumValue *enum_value;
433       
434       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
435         if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
436           return enum_value;
437     }
438   
439   return NULL;
440 }
441
442 /**
443  * g_flags_get_value_by_nick:
444  * @flags_class: a #GFlagsClass
445  * @nick: the nickname to look up
446  *
447  * Looks up a #GFlagsValue by nickname.
448  *
449  * Returns: (transfer none) (nullable): the #GFlagsValue with nickname @nick,
450  *          or %NULL if there is no flag with that nickname
451  */
452 GFlagsValue*
453 g_flags_get_value_by_nick (GFlagsClass *flags_class,
454                            const gchar *nick)
455 {
456   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
457   g_return_val_if_fail (nick != NULL, NULL);
458   
459   if (flags_class->n_values)
460     {
461       GFlagsValue *flags_value;
462       
463       for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
464         if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
465           return flags_value;
466     }
467   
468   return NULL;
469 }
470
471 /**
472  * g_enum_get_value:
473  * @enum_class: a #GEnumClass
474  * @value: the value to look up
475  *
476  * Returns the #GEnumValue for a value.
477  *
478  * Returns: (transfer none) (nullable): the #GEnumValue for @value, or %NULL
479  *          if @value is not a member of the enumeration
480  */
481 GEnumValue*
482 g_enum_get_value (GEnumClass *enum_class,
483                   gint        value)
484 {
485   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
486   
487   if (enum_class->n_values)
488     {
489       GEnumValue *enum_value;
490       
491       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
492         if (enum_value->value == value)
493           return enum_value;
494     }
495   
496   return NULL;
497 }
498
499 /**
500  * g_flags_get_first_value:
501  * @flags_class: a #GFlagsClass
502  * @value: the value
503  *
504  * Returns the first #GFlagsValue which is set in @value.
505  *
506  * Returns: (transfer none) (nullable): the first #GFlagsValue which is set in
507  *          @value, or %NULL if none is set
508  */
509 GFlagsValue*
510 g_flags_get_first_value (GFlagsClass *flags_class,
511                          guint        value)
512 {
513   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
514   
515   if (flags_class->n_values)
516     {
517       GFlagsValue *flags_value;
518
519       if (value == 0)
520         {
521           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
522             if (flags_value->value == 0)
523               return flags_value;
524         }
525       else
526         {
527           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
528             if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value)
529               return flags_value;
530         }      
531     }
532   
533   return NULL;
534 }
535
536 /**
537  * g_enum_to_string:
538  * @g_enum_type: the type identifier of a #GEnumClass type
539  * @value: the value
540  *
541  * Pretty-prints @value in the form of the enum’s name.
542  *
543  * This is intended to be used for debugging purposes. The format of the output
544  * may change in the future.
545  *
546  * Returns: (transfer full): a newly-allocated text string
547  *
548  * Since: 2.54
549  */
550 gchar *
551 g_enum_to_string (GType g_enum_type,
552                   gint  value)
553 {
554   gchar *result;
555   GEnumClass *enum_class;
556   GEnumValue *enum_value;
557
558   g_return_val_if_fail (G_TYPE_IS_ENUM (g_enum_type), NULL);
559
560   enum_class = g_type_class_ref (g_enum_type);
561
562   /* Already warned */
563   if (enum_class == NULL)
564     return g_strdup_printf ("%d", value);
565
566   enum_value = g_enum_get_value (enum_class, value);
567
568   if (enum_value == NULL)
569     result = g_strdup_printf ("%d", value);
570   else
571     result = g_strdup (enum_value->value_name);
572
573   g_type_class_unref (enum_class);
574   return result;
575 }
576
577 /*
578  * g_flags_get_value_string:
579  * @flags_class: a #GFlagsClass
580  * @value: the value
581  *
582  * Pretty-prints @value in the form of the flag names separated by ` | ` and
583  * sorted. Any extra bits will be shown at the end as a hexadecimal number.
584  *
585  * This is intended to be used for debugging purposes. The format of the output
586  * may change in the future.
587  *
588  * Returns: (transfer full): a newly-allocated text string
589  *
590  * Since: 2.54
591  */
592 static gchar *
593 g_flags_get_value_string (GFlagsClass *flags_class,
594                           guint        value)
595 {
596   GString *str;
597   GFlagsValue *flags_value;
598
599   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
600
601   str = g_string_new (NULL);
602
603   while ((str->len == 0 || value != 0) &&
604          (flags_value = g_flags_get_first_value (flags_class, value)) != NULL)
605     {
606       if (str->len > 0)
607         g_string_append (str, " | ");
608
609       g_string_append (str, flags_value->value_name);
610
611       value &= ~flags_value->value;
612     }
613
614   /* Show the extra bits */
615   if (value != 0 || str->len == 0)
616     {
617       if (str->len > 0)
618         g_string_append (str, " | ");
619
620       g_string_append_printf (str, "0x%x", value);
621     }
622
623   return g_string_free (str, FALSE);
624 }
625
626 /**
627  * g_flags_to_string:
628  * @flags_type: the type identifier of a #GFlagsClass type
629  * @value: the value
630  *
631  * Pretty-prints @value in the form of the flag names separated by ` | ` and
632  * sorted. Any extra bits will be shown at the end as a hexadecimal number.
633  *
634  * This is intended to be used for debugging purposes. The format of the output
635  * may change in the future.
636  *
637  * Returns: (transfer full): a newly-allocated text string
638  *
639  * Since: 2.54
640  */
641 gchar *
642 g_flags_to_string (GType flags_type,
643                    guint value)
644 {
645   gchar *result;
646   GFlagsClass *flags_class;
647
648   g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
649
650   flags_class = g_type_class_ref (flags_type);
651
652   /* Already warned */
653   if (flags_class == NULL)
654     return NULL;
655
656   result = g_flags_get_value_string (flags_class, value);
657
658   g_type_class_unref (flags_class);
659   return result;
660 }
661
662
663 /**
664  * g_value_set_enum:
665  * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM
666  * @v_enum: enum value to be set
667  *
668  * Set the contents of a %G_TYPE_ENUM #GValue to @v_enum.
669  */
670 void
671 g_value_set_enum (GValue *value,
672                   gint    v_enum)
673 {
674   g_return_if_fail (G_VALUE_HOLDS_ENUM (value));
675   
676   value->data[0].v_long = v_enum;
677 }
678
679 /**
680  * g_value_get_enum:
681  * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM
682  *
683  * Get the contents of a %G_TYPE_ENUM #GValue.
684  *
685  * Returns: enum contents of @value
686  */
687 gint
688 g_value_get_enum (const GValue *value)
689 {
690   g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0);
691   
692   return value->data[0].v_long;
693 }
694
695 /**
696  * g_value_set_flags:
697  * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS
698  * @v_flags: flags value to be set
699  *
700  * Set the contents of a %G_TYPE_FLAGS #GValue to @v_flags.
701  */
702 void
703 g_value_set_flags (GValue *value,
704                    guint   v_flags)
705 {
706   g_return_if_fail (G_VALUE_HOLDS_FLAGS (value));
707   
708   value->data[0].v_ulong = v_flags;
709 }
710
711 /**
712  * g_value_get_flags:
713  * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS
714  *
715  * Get the contents of a %G_TYPE_FLAGS #GValue.
716  *
717  * Returns: flags contents of @value
718  */
719 guint
720 g_value_get_flags (const GValue *value)
721 {
722   g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0);
723   
724   return value->data[0].v_ulong;
725 }