Branch data Line data Source code
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 : 590 : _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 : 590 : 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 : 590 : g_return_if_fail (initialized == FALSE);
84 : 590 : initialized = TRUE;
85 : :
86 : : /* G_TYPE_ENUM
87 : : */
88 : 590 : info.class_size = sizeof (GEnumClass);
89 : 590 : 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 : 590 : g_assert (type == G_TYPE_ENUM);
92 : :
93 : : /* G_TYPE_FLAGS
94 : : */
95 : 590 : info.class_size = sizeof (GFlagsClass);
96 : 590 : 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 : 590 : g_assert (type == G_TYPE_FLAGS);
99 : : }
100 : :
101 : : static void
102 : 2183 : value_flags_enum_init (GValue *value)
103 : : {
104 : 2183 : value->data[0].v_long = 0;
105 : 2183 : }
106 : :
107 : : static void
108 : 0 : value_flags_enum_copy_value (const GValue *src_value,
109 : : GValue *dest_value)
110 : : {
111 : 0 : dest_value->data[0].v_long = src_value->data[0].v_long;
112 : 0 : }
113 : :
114 : : static gchar*
115 : 13817 : value_flags_enum_collect_value (GValue *value,
116 : : guint n_collect_values,
117 : : GTypeCValue *collect_values,
118 : : guint collect_flags)
119 : : {
120 : 13817 : if (G_VALUE_HOLDS_ENUM (value))
121 : 9623 : value->data[0].v_long = collect_values[0].v_int;
122 : : else
123 : 4194 : value->data[0].v_ulong = (guint) collect_values[0].v_int;
124 : :
125 : 13817 : return NULL;
126 : : }
127 : :
128 : : static gchar*
129 : 46 : value_flags_enum_lcopy_value (const GValue *value,
130 : : guint n_collect_values,
131 : : GTypeCValue *collect_values,
132 : : guint collect_flags)
133 : : {
134 : 46 : gint *int_p = collect_values[0].v_pointer;
135 : :
136 : 46 : 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 : 46 : *int_p = (int) value->data[0].v_long;
139 : :
140 : 46 : 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: (array zero-terminated=1): An array of
147 : : * #GEnumValue structs for the possible enumeration values. The array is
148 : : * terminated by a struct with all members being 0. GObject keeps a
149 : : * reference to the data, so it cannot 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 : 1261 : g_enum_register_static (const gchar *name,
161 : : const GEnumValue *const_static_values)
162 : : {
163 : 1261 : 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 : 1261 : g_return_val_if_fail (name != NULL, 0);
178 : 1261 : g_return_val_if_fail (const_static_values != NULL, 0);
179 : :
180 : 1261 : enum_type_info.class_data = const_static_values;
181 : :
182 : 1261 : type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0);
183 : :
184 : 1261 : 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: (array zero-terminated=1): An array of
191 : : * #GFlagsValue structs for the possible flags values. The array is
192 : : * terminated by a struct with all members being 0. GObject keeps a
193 : : * reference to the data, so it cannot be stack-allocated.
194 : : *
195 : : * Registers a new static flags type with the name @name.
196 : : *
197 : : * It is normally more convenient to let [glib-mkenums][glib-mkenums]
198 : : * generate a my_flags_get_type() function from a usual C enumeration
199 : : * definition than to write one yourself using g_flags_register_static().
200 : : *
201 : : * Returns: The new type identifier.
202 : : */
203 : : GType
204 : 726 : g_flags_register_static (const gchar *name,
205 : : const GFlagsValue *const_static_values)
206 : : {
207 : 726 : GTypeInfo flags_type_info = {
208 : : sizeof (GFlagsClass), /* class_size */
209 : : NULL, /* base_init */
210 : : NULL, /* base_finalize */
211 : : (GClassInitFunc) g_flags_class_init,
212 : : NULL, /* class_finalize */
213 : : NULL, /* class_data */
214 : : 0, /* instance_size */
215 : : 0, /* n_preallocs */
216 : : NULL, /* instance_init */
217 : : NULL, /* value_table */
218 : : };
219 : : GType type;
220 : :
221 : 726 : g_return_val_if_fail (name != NULL, 0);
222 : 726 : g_return_val_if_fail (const_static_values != NULL, 0);
223 : :
224 : 726 : flags_type_info.class_data = const_static_values;
225 : :
226 : 726 : type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0);
227 : :
228 : 726 : return type;
229 : : }
230 : :
231 : : /**
232 : : * g_enum_complete_type_info:
233 : : * @g_enum_type: the type identifier of the type being completed
234 : : * @info: (out callee-allocates): the #GTypeInfo struct to be filled in
235 : : * @const_values: (array zero-terminated=1): An array of #GEnumValue
236 : : * structs for the possible enumeration values. The array is terminated
237 : : * by a struct with all members being 0.
238 : : *
239 : : * This function is meant to be called from the `complete_type_info`
240 : : * function of a #GTypePlugin implementation, as in the following
241 : : * example:
242 : : *
243 : : * |[<!-- language="C" -->
244 : : * static void
245 : : * my_enum_complete_type_info (GTypePlugin *plugin,
246 : : * GType g_type,
247 : : * GTypeInfo *info,
248 : : * GTypeValueTable *value_table)
249 : : * {
250 : : * static const GEnumValue values[] = {
251 : : * { MY_ENUM_FOO, "MY_ENUM_FOO", "foo" },
252 : : * { MY_ENUM_BAR, "MY_ENUM_BAR", "bar" },
253 : : * { 0, NULL, NULL }
254 : : * };
255 : : *
256 : : * g_enum_complete_type_info (type, info, values);
257 : : * }
258 : : * ]|
259 : : */
260 : : void
261 : 0 : g_enum_complete_type_info (GType g_enum_type,
262 : : GTypeInfo *info,
263 : : const GEnumValue *const_values)
264 : : {
265 : 0 : g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
266 : 0 : g_return_if_fail (info != NULL);
267 : 0 : g_return_if_fail (const_values != NULL);
268 : :
269 : 0 : info->class_size = sizeof (GEnumClass);
270 : 0 : info->base_init = NULL;
271 : 0 : info->base_finalize = NULL;
272 : 0 : info->class_init = (GClassInitFunc) g_enum_class_init;
273 : 0 : info->class_finalize = NULL;
274 : 0 : info->class_data = const_values;
275 : : }
276 : :
277 : : /**
278 : : * g_flags_complete_type_info:
279 : : * @g_flags_type: the type identifier of the type being completed
280 : : * @info: (out callee-allocates): the #GTypeInfo struct to be filled in
281 : : * @const_values: (array zero-terminated=1): An array of #GFlagsValue
282 : : * structs for the possible enumeration values. The array is terminated
283 : : * by a struct with all members being 0.
284 : : *
285 : : * This function is meant to be called from the complete_type_info()
286 : : * function of a #GTypePlugin implementation, see the example for
287 : : * g_enum_complete_type_info() above.
288 : : */
289 : : void
290 : 0 : g_flags_complete_type_info (GType g_flags_type,
291 : : GTypeInfo *info,
292 : : const GFlagsValue *const_values)
293 : : {
294 : 0 : g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
295 : 0 : g_return_if_fail (info != NULL);
296 : 0 : g_return_if_fail (const_values != NULL);
297 : :
298 : 0 : info->class_size = sizeof (GFlagsClass);
299 : 0 : info->base_init = NULL;
300 : 0 : info->base_finalize = NULL;
301 : 0 : info->class_init = (GClassInitFunc) g_flags_class_init;
302 : 0 : info->class_finalize = NULL;
303 : 0 : info->class_data = const_values;
304 : : }
305 : :
306 : : static void
307 : 1015 : g_enum_class_init (GEnumClass *class,
308 : : gpointer class_data)
309 : : {
310 : 1015 : g_return_if_fail (G_IS_ENUM_CLASS (class));
311 : :
312 : 1015 : class->minimum = 0;
313 : 1015 : class->maximum = 0;
314 : 1015 : class->n_values = 0;
315 : 1015 : class->values = class_data;
316 : :
317 : 1015 : if (class->values)
318 : : {
319 : : GEnumValue *values;
320 : :
321 : 1015 : class->minimum = class->values->value;
322 : 1015 : class->maximum = class->values->value;
323 : 5602 : for (values = class->values; values->value_name; values++)
324 : : {
325 : 4587 : class->minimum = MIN (class->minimum, values->value);
326 : 4587 : class->maximum = MAX (class->maximum, values->value);
327 : 4587 : class->n_values++;
328 : : }
329 : : }
330 : : }
331 : :
332 : : static void
333 : 673 : g_flags_class_init (GFlagsClass *class,
334 : : gpointer class_data)
335 : : {
336 : 673 : g_return_if_fail (G_IS_FLAGS_CLASS (class));
337 : :
338 : 673 : class->mask = 0;
339 : 673 : class->n_values = 0;
340 : 673 : class->values = class_data;
341 : :
342 : 673 : if (class->values)
343 : : {
344 : : GFlagsValue *values;
345 : :
346 : 4770 : for (values = class->values; values->value_name; values++)
347 : : {
348 : 4097 : class->mask |= values->value;
349 : 4097 : class->n_values++;
350 : : }
351 : : }
352 : : }
353 : :
354 : : /* Internal function to compare strings without taking into account
355 : : * character case and more... in order to ease the look ups. */
356 : : static int
357 : 68 : strcmp_ignore_case (const char *str1, const char *str2)
358 : : {
359 : 68 : const char *ptr1 = str1, *ptr2 = str2;
360 : : char c1, c2;
361 : :
362 : : do
363 : : {
364 : : /* Normalize to lower case */
365 : 279 : c1 = g_ascii_tolower (*ptr1++);
366 : 279 : c2 = g_ascii_tolower (*ptr2++);
367 : :
368 : : /* End of either string */
369 : 279 : if (c1 == '\0' || c2 == '\0')
370 : 21 : return c1 - c2;
371 : :
372 : : /* Normalize '-' to '_' */
373 : 258 : c1 = (c1 == '-') ? '_' : c1;
374 : 258 : c2 = (c2 == '-') ? '_' : c2;
375 : : }
376 : 258 : while (c1 == c2);
377 : :
378 : 47 : return c1 - c2;
379 : : }
380 : :
381 : : /**
382 : : * g_enum_get_value_by_name:
383 : : * @enum_class: a #GEnumClass
384 : : * @name: the name to look up
385 : : *
386 : : * Looks up a #GEnumValue by name.
387 : : *
388 : : * Returns: (transfer none) (nullable): the #GEnumValue with name @name,
389 : : * or %NULL if the enumeration doesn't have a member
390 : : * with that name
391 : : */
392 : : GEnumValue*
393 : 3 : g_enum_get_value_by_name (GEnumClass *enum_class,
394 : : const gchar *name)
395 : : {
396 : 3 : g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
397 : 3 : g_return_val_if_fail (name != NULL, NULL);
398 : :
399 : 3 : if (enum_class->n_values)
400 : : {
401 : : GEnumValue *enum_value;
402 : :
403 : 10 : for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
404 : 9 : if (strcmp_ignore_case (name, enum_value->value_name) == 0)
405 : 2 : return enum_value;
406 : : }
407 : :
408 : 1 : return NULL;
409 : : }
410 : :
411 : : /**
412 : : * g_flags_get_value_by_name:
413 : : * @flags_class: a #GFlagsClass
414 : : * @name: the name to look up
415 : : *
416 : : * Looks up a #GFlagsValue by name.
417 : : *
418 : : * Returns: (transfer none) (nullable): the #GFlagsValue with name @name,
419 : : * or %NULL if there is no flag with that name
420 : : */
421 : : GFlagsValue*
422 : 3 : g_flags_get_value_by_name (GFlagsClass *flags_class,
423 : : const gchar *name)
424 : : {
425 : 3 : g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
426 : 3 : g_return_val_if_fail (name != NULL, NULL);
427 : :
428 : 3 : if (flags_class->n_values)
429 : : {
430 : : GFlagsValue *flags_value;
431 : :
432 : 13 : for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
433 : 12 : if (strcmp_ignore_case (name, flags_value->value_name) == 0)
434 : 2 : return flags_value;
435 : : }
436 : :
437 : 1 : return NULL;
438 : : }
439 : :
440 : : /**
441 : : * g_enum_get_value_by_nick:
442 : : * @enum_class: a #GEnumClass
443 : : * @nick: the nickname to look up
444 : : *
445 : : * Looks up a #GEnumValue by nickname.
446 : : *
447 : : * Returns: (transfer none) (nullable): the #GEnumValue with nickname @nick,
448 : : * or %NULL if the enumeration doesn't have a member
449 : : * with that nickname
450 : : */
451 : : GEnumValue*
452 : 12 : g_enum_get_value_by_nick (GEnumClass *enum_class,
453 : : const gchar *nick)
454 : : {
455 : 12 : g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
456 : 12 : g_return_val_if_fail (nick != NULL, NULL);
457 : :
458 : 12 : if (enum_class->n_values)
459 : : {
460 : : GEnumValue *enum_value;
461 : :
462 : 29 : for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
463 : 28 : if (enum_value->value_nick && strcmp_ignore_case (nick, enum_value->value_nick) == 0)
464 : 11 : return enum_value;
465 : : }
466 : :
467 : 1 : return NULL;
468 : : }
469 : :
470 : : /**
471 : : * g_flags_get_value_by_nick:
472 : : * @flags_class: a #GFlagsClass
473 : : * @nick: the nickname to look up
474 : : *
475 : : * Looks up a #GFlagsValue by nickname.
476 : : *
477 : : * Returns: (transfer none) (nullable): the #GFlagsValue with nickname @nick,
478 : : * or %NULL if there is no flag with that nickname
479 : : */
480 : : GFlagsValue*
481 : 7 : g_flags_get_value_by_nick (GFlagsClass *flags_class,
482 : : const gchar *nick)
483 : : {
484 : 7 : g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
485 : 7 : g_return_val_if_fail (nick != NULL, NULL);
486 : :
487 : 7 : if (flags_class->n_values)
488 : : {
489 : : GFlagsValue *flags_value;
490 : :
491 : 20 : for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
492 : 19 : if (flags_value->value_nick && strcmp_ignore_case (nick, flags_value->value_nick) == 0)
493 : 6 : return flags_value;
494 : : }
495 : :
496 : 1 : return NULL;
497 : : }
498 : :
499 : : /**
500 : : * g_enum_get_value:
501 : : * @enum_class: a #GEnumClass
502 : : * @value: the value to look up
503 : : *
504 : : * Returns the #GEnumValue for a value.
505 : : *
506 : : * Returns: (transfer none) (nullable): the #GEnumValue for @value, or %NULL
507 : : * if @value is not a member of the enumeration
508 : : */
509 : : GEnumValue*
510 : 23614 : g_enum_get_value (GEnumClass *enum_class,
511 : : gint value)
512 : : {
513 : 23614 : g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
514 : :
515 : 23614 : if (enum_class->n_values)
516 : : {
517 : : GEnumValue *enum_value;
518 : :
519 : 47256 : for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
520 : 47253 : if (enum_value->value == value)
521 : 23611 : return enum_value;
522 : : }
523 : :
524 : 3 : return NULL;
525 : : }
526 : :
527 : : /**
528 : : * g_flags_get_first_value:
529 : : * @flags_class: a #GFlagsClass
530 : : * @value: the value
531 : : *
532 : : * Returns the first #GFlagsValue which is set in @value.
533 : : *
534 : : * Returns: (transfer none) (nullable): the first #GFlagsValue which is set in
535 : : * @value, or %NULL if none is set
536 : : */
537 : : GFlagsValue*
538 : 69 : g_flags_get_first_value (GFlagsClass *flags_class,
539 : : guint value)
540 : : {
541 : 69 : g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
542 : :
543 : 69 : if (flags_class->n_values)
544 : : {
545 : : GFlagsValue *flags_value;
546 : :
547 : 69 : if (value == 0)
548 : : {
549 : 36 : for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
550 : 35 : if (flags_value->value == 0)
551 : 34 : return flags_value;
552 : : }
553 : : else
554 : : {
555 : 150 : for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
556 : 145 : if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value)
557 : 29 : return flags_value;
558 : : }
559 : : }
560 : :
561 : 6 : return NULL;
562 : : }
563 : :
564 : : /**
565 : : * g_enum_to_string:
566 : : * @g_enum_type: the type identifier of a #GEnumClass type
567 : : * @value: the value
568 : : *
569 : : * Pretty-prints @value in the form of the enum’s name.
570 : : *
571 : : * This is intended to be used for debugging purposes. The format of the output
572 : : * may change in the future.
573 : : *
574 : : * Returns: (transfer full): a newly-allocated text string
575 : : *
576 : : * Since: 2.54
577 : : */
578 : : gchar *
579 : 28 : g_enum_to_string (GType g_enum_type,
580 : : gint value)
581 : : {
582 : : gchar *result;
583 : : GEnumClass *enum_class;
584 : : GEnumValue *enum_value;
585 : :
586 : 28 : g_return_val_if_fail (G_TYPE_IS_ENUM (g_enum_type), NULL);
587 : :
588 : 28 : enum_class = g_type_class_ref (g_enum_type);
589 : :
590 : : /* Already warned */
591 : 28 : if (enum_class == NULL)
592 : 0 : return g_strdup_printf ("%d", value);
593 : :
594 : 28 : enum_value = g_enum_get_value (enum_class, value);
595 : :
596 : 28 : if (enum_value == NULL)
597 : 1 : result = g_strdup_printf ("%d", value);
598 : : else
599 : 54 : result = g_strdup (enum_value->value_name);
600 : :
601 : 28 : g_type_class_unref (enum_class);
602 : 28 : return result;
603 : : }
604 : :
605 : : /*
606 : : * g_flags_get_value_string:
607 : : * @flags_class: a #GFlagsClass
608 : : * @value: the value
609 : : *
610 : : * Pretty-prints @value in the form of the flag names separated by ` | ` and
611 : : * sorted. Any extra bits will be shown at the end as a hexadecimal number.
612 : : *
613 : : * This is intended to be used for debugging purposes. The format of the output
614 : : * may change in the future.
615 : : *
616 : : * Returns: (transfer full): a newly-allocated text string
617 : : *
618 : : * Since: 2.54
619 : : */
620 : : static gchar *
621 : 7 : g_flags_get_value_string (GFlagsClass *flags_class,
622 : : guint value)
623 : : {
624 : : GString *str;
625 : : GFlagsValue *flags_value;
626 : :
627 : 7 : g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
628 : :
629 : 7 : str = g_string_new (NULL);
630 : :
631 : 21 : while ((str->len == 0 || value != 0) &&
632 : 9 : (flags_value = g_flags_get_first_value (flags_class, value)) != NULL)
633 : : {
634 : 5 : if (str->len > 0)
635 : 2 : g_string_append (str, " | ");
636 : :
637 : 5 : g_string_append (str, flags_value->value_name);
638 : :
639 : 5 : value &= ~flags_value->value;
640 : : }
641 : :
642 : : /* Show the extra bits */
643 : 7 : if (value != 0 || str->len == 0)
644 : : {
645 : 4 : if (str->len > 0)
646 : 2 : g_string_append (str, " | ");
647 : :
648 : 4 : g_string_append_printf (str, "0x%x", value);
649 : : }
650 : :
651 : 7 : return g_string_free (str, FALSE);
652 : : }
653 : :
654 : : /**
655 : : * g_flags_to_string:
656 : : * @flags_type: the type identifier of a #GFlagsClass type
657 : : * @value: the value
658 : : *
659 : : * Pretty-prints @value in the form of the flag names separated by ` | ` and
660 : : * sorted. Any extra bits will be shown at the end as a hexadecimal number.
661 : : *
662 : : * This is intended to be used for debugging purposes. The format of the output
663 : : * may change in the future.
664 : : *
665 : : * Returns: (transfer full): a newly-allocated text string
666 : : *
667 : : * Since: 2.54
668 : : */
669 : : gchar *
670 : 7 : g_flags_to_string (GType flags_type,
671 : : guint value)
672 : : {
673 : : gchar *result;
674 : : GFlagsClass *flags_class;
675 : :
676 : 7 : g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
677 : :
678 : 7 : flags_class = g_type_class_ref (flags_type);
679 : :
680 : : /* Already warned */
681 : 7 : if (flags_class == NULL)
682 : 0 : return NULL;
683 : :
684 : 7 : result = g_flags_get_value_string (flags_class, value);
685 : :
686 : 7 : g_type_class_unref (flags_class);
687 : 7 : return result;
688 : : }
689 : :
690 : :
691 : : /**
692 : : * g_value_set_enum:
693 : : * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM
694 : : * @v_enum: enum value to be set
695 : : *
696 : : * Set the contents of a %G_TYPE_ENUM #GValue to @v_enum.
697 : : */
698 : : void
699 : 51 : g_value_set_enum (GValue *value,
700 : : gint v_enum)
701 : : {
702 : 51 : g_return_if_fail (G_VALUE_HOLDS_ENUM (value));
703 : :
704 : 51 : value->data[0].v_long = v_enum;
705 : : }
706 : :
707 : : /**
708 : : * g_value_get_enum:
709 : : * @value: a valid #GValue whose type is derived from %G_TYPE_ENUM
710 : : *
711 : : * Get the contents of a %G_TYPE_ENUM #GValue.
712 : : *
713 : : * Returns: enum contents of @value
714 : : */
715 : : gint
716 : 21884 : g_value_get_enum (const GValue *value)
717 : : {
718 : 21884 : g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0);
719 : :
720 : 21884 : return (int) value->data[0].v_long;
721 : : }
722 : :
723 : : /**
724 : : * g_value_set_flags:
725 : : * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS
726 : : * @v_flags: flags value to be set
727 : : *
728 : : * Set the contents of a %G_TYPE_FLAGS #GValue to @v_flags.
729 : : */
730 : : void
731 : 445 : g_value_set_flags (GValue *value,
732 : : guint v_flags)
733 : : {
734 : 445 : g_return_if_fail (G_VALUE_HOLDS_FLAGS (value));
735 : :
736 : 445 : value->data[0].v_ulong = v_flags;
737 : : }
738 : :
739 : : /**
740 : : * g_value_get_flags:
741 : : * @value: a valid #GValue whose type is derived from %G_TYPE_FLAGS
742 : : *
743 : : * Get the contents of a %G_TYPE_FLAGS #GValue.
744 : : *
745 : : * Returns: flags contents of @value
746 : : */
747 : : guint
748 : 6956 : g_value_get_flags (const GValue *value)
749 : : {
750 : 6956 : g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0);
751 : :
752 : 6956 : return (unsigned int) value->data[0].v_ulong;
753 : : }
|