1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3 * Copyright © 2010 Christian Persch
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /*
20 * MT safe
21 */
22
23 #include "config.h"
24
25 #include <string.h>
26 #include <stdlib.h> /* qsort() */
27
28 #include "gvaluetypes.h"
29 #include "gtype-private.h"
30 #include "gvaluecollector.h"
31 #include "gobject.h"
32 #include "gparam.h"
33 #include "gboxed.h"
34 #include "genums.h"
35
36
37 /* --- value functions --- */
38 static void
value_init_long0(GValue * value)39 value_init_long0 (GValue *value)
40 {
41 value->data[0].v_long = 0;
42 }
43
44 static void
value_copy_long0(const GValue * src_value,GValue * dest_value)45 value_copy_long0 (const GValue *src_value,
46 GValue *dest_value)
47 {
48 dest_value->data[0].v_long = src_value->data[0].v_long;
49 }
50
51 static gchar*
value_lcopy_char(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)52 value_lcopy_char (const GValue *value,
53 guint n_collect_values,
54 GTypeCValue *collect_values,
55 guint collect_flags)
56 {
57 gint8 *int8_p = collect_values[0].v_pointer;
58
59 if (!int8_p)
60 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
61
62 *int8_p = value->data[0].v_int;
63
64 return NULL;
65 }
66
67 static gchar*
value_lcopy_boolean(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)68 value_lcopy_boolean (const GValue *value,
69 guint n_collect_values,
70 GTypeCValue *collect_values,
71 guint collect_flags)
72 {
73 gboolean *bool_p = collect_values[0].v_pointer;
74
75 if (!bool_p)
76 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
77
78 *bool_p = value->data[0].v_int;
79
80 return NULL;
81 }
82
83 static gchar*
value_collect_int(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)84 value_collect_int (GValue *value,
85 guint n_collect_values,
86 GTypeCValue *collect_values,
87 guint collect_flags)
88 {
89 value->data[0].v_int = collect_values[0].v_int;
90
91 return NULL;
92 }
93
94 static gchar*
value_lcopy_int(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)95 value_lcopy_int (const GValue *value,
96 guint n_collect_values,
97 GTypeCValue *collect_values,
98 guint collect_flags)
99 {
100 gint *int_p = collect_values[0].v_pointer;
101
102 if (!int_p)
103 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
104
105 *int_p = value->data[0].v_int;
106
107 return NULL;
108 }
109
110 static gchar*
value_collect_long(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)111 value_collect_long (GValue *value,
112 guint n_collect_values,
113 GTypeCValue *collect_values,
114 guint collect_flags)
115 {
116 value->data[0].v_long = collect_values[0].v_long;
117
118 return NULL;
119 }
120
121 static gchar*
value_lcopy_long(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)122 value_lcopy_long (const GValue *value,
123 guint n_collect_values,
124 GTypeCValue *collect_values,
125 guint collect_flags)
126 {
127 glong *long_p = collect_values[0].v_pointer;
128
129 if (!long_p)
130 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
131
132 *long_p = value->data[0].v_long;
133
134 return NULL;
135 }
136
137 static void
value_init_int64(GValue * value)138 value_init_int64 (GValue *value)
139 {
140 value->data[0].v_int64 = 0;
141 }
142
143 static void
value_copy_int64(const GValue * src_value,GValue * dest_value)144 value_copy_int64 (const GValue *src_value,
145 GValue *dest_value)
146 {
147 dest_value->data[0].v_int64 = src_value->data[0].v_int64;
148 }
149
150 static gchar*
value_collect_int64(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)151 value_collect_int64 (GValue *value,
152 guint n_collect_values,
153 GTypeCValue *collect_values,
154 guint collect_flags)
155 {
156 value->data[0].v_int64 = collect_values[0].v_int64;
157
158 return NULL;
159 }
160
161 static gchar*
value_lcopy_int64(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)162 value_lcopy_int64 (const GValue *value,
163 guint n_collect_values,
164 GTypeCValue *collect_values,
165 guint collect_flags)
166 {
167 gint64 *int64_p = collect_values[0].v_pointer;
168
169 if (!int64_p)
170 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
171
172 *int64_p = value->data[0].v_int64;
173
174 return NULL;
175 }
176
177 static void
value_init_float(GValue * value)178 value_init_float (GValue *value)
179 {
180 value->data[0].v_float = 0.0;
181 }
182
183 static void
value_copy_float(const GValue * src_value,GValue * dest_value)184 value_copy_float (const GValue *src_value,
185 GValue *dest_value)
186 {
187 dest_value->data[0].v_float = src_value->data[0].v_float;
188 }
189
190 static gchar*
value_collect_float(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)191 value_collect_float (GValue *value,
192 guint n_collect_values,
193 GTypeCValue *collect_values,
194 guint collect_flags)
195 {
196 value->data[0].v_float = collect_values[0].v_double;
197
198 return NULL;
199 }
200
201 static gchar*
value_lcopy_float(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)202 value_lcopy_float (const GValue *value,
203 guint n_collect_values,
204 GTypeCValue *collect_values,
205 guint collect_flags)
206 {
207 gfloat *float_p = collect_values[0].v_pointer;
208
209 if (!float_p)
210 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
211
212 *float_p = value->data[0].v_float;
213
214 return NULL;
215 }
216
217 static void
value_init_double(GValue * value)218 value_init_double (GValue *value)
219 {
220 value->data[0].v_double = 0.0;
221 }
222
223 static void
value_copy_double(const GValue * src_value,GValue * dest_value)224 value_copy_double (const GValue *src_value,
225 GValue *dest_value)
226 {
227 dest_value->data[0].v_double = src_value->data[0].v_double;
228 }
229
230 static gchar*
value_collect_double(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)231 value_collect_double (GValue *value,
232 guint n_collect_values,
233 GTypeCValue *collect_values,
234 guint collect_flags)
235 {
236 value->data[0].v_double = collect_values[0].v_double;
237
238 return NULL;
239 }
240
241 static gchar*
value_lcopy_double(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)242 value_lcopy_double (const GValue *value,
243 guint n_collect_values,
244 GTypeCValue *collect_values,
245 guint collect_flags)
246 {
247 gdouble *double_p = collect_values[0].v_pointer;
248
249 if (!double_p)
250 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
251
252 *double_p = value->data[0].v_double;
253
254 return NULL;
255 }
256
257 static void
value_init_string(GValue * value)258 value_init_string (GValue *value)
259 {
260 value->data[0].v_pointer = NULL;
261 }
262
263 static void
value_free_string(GValue * value)264 value_free_string (GValue *value)
265 {
266 if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
267 g_free (value->data[0].v_pointer);
268 }
269
270 static void
value_copy_string(const GValue * src_value,GValue * dest_value)271 value_copy_string (const GValue *src_value,
272 GValue *dest_value)
273 {
274 dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
275 }
276
277 static gchar*
value_collect_string(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)278 value_collect_string (GValue *value,
279 guint n_collect_values,
280 GTypeCValue *collect_values,
281 guint collect_flags)
282 {
283 if (!collect_values[0].v_pointer)
284 value->data[0].v_pointer = NULL;
285 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
286 {
287 value->data[0].v_pointer = collect_values[0].v_pointer;
288 value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
289 }
290 else
291 value->data[0].v_pointer = g_strdup (collect_values[0].v_pointer);
292
293 return NULL;
294 }
295
296 static gchar*
value_lcopy_string(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)297 value_lcopy_string (const GValue *value,
298 guint n_collect_values,
299 GTypeCValue *collect_values,
300 guint collect_flags)
301 {
302 gchar **string_p = collect_values[0].v_pointer;
303
304 if (!string_p)
305 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
306
307 if (!value->data[0].v_pointer)
308 *string_p = NULL;
309 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
310 *string_p = value->data[0].v_pointer;
311 else
312 *string_p = g_strdup (value->data[0].v_pointer);
313
314 return NULL;
315 }
316
317 static void
value_init_pointer(GValue * value)318 value_init_pointer (GValue *value)
319 {
320 value->data[0].v_pointer = NULL;
321 }
322
323 static void
value_copy_pointer(const GValue * src_value,GValue * dest_value)324 value_copy_pointer (const GValue *src_value,
325 GValue *dest_value)
326 {
327 dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
328 }
329
330 static gpointer
value_peek_pointer0(const GValue * value)331 value_peek_pointer0 (const GValue *value)
332 {
333 return value->data[0].v_pointer;
334 }
335
336 static gchar*
value_collect_pointer(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)337 value_collect_pointer (GValue *value,
338 guint n_collect_values,
339 GTypeCValue *collect_values,
340 guint collect_flags)
341 {
342 value->data[0].v_pointer = collect_values[0].v_pointer;
343
344 return NULL;
345 }
346
347 static gchar*
value_lcopy_pointer(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)348 value_lcopy_pointer (const GValue *value,
349 guint n_collect_values,
350 GTypeCValue *collect_values,
351 guint collect_flags)
352 {
353 gpointer *pointer_p = collect_values[0].v_pointer;
354
355 if (!pointer_p)
356 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
357
358 *pointer_p = value->data[0].v_pointer;
359
360 return NULL;
361 }
362
363 static void
value_free_variant(GValue * value)364 value_free_variant (GValue *value)
365 {
366 if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) &&
367 value->data[0].v_pointer)
368 g_variant_unref (value->data[0].v_pointer);
369 }
370
371 static void
value_copy_variant(const GValue * src_value,GValue * dest_value)372 value_copy_variant (const GValue *src_value,
373 GValue *dest_value)
374 {
375 if (src_value->data[0].v_pointer)
376 dest_value->data[0].v_pointer = g_variant_ref_sink (src_value->data[0].v_pointer);
377 else
378 dest_value->data[0].v_pointer = NULL;
379 }
380
381 static gchar*
value_collect_variant(GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)382 value_collect_variant (GValue *value,
383 guint n_collect_values,
384 GTypeCValue *collect_values,
385 guint collect_flags)
386 {
387 if (!collect_values[0].v_pointer)
388 value->data[0].v_pointer = NULL;
389 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
390 {
391 value->data[0].v_pointer = collect_values[0].v_pointer;
392 value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
393 }
394 else
395 value->data[0].v_pointer = g_variant_ref_sink (collect_values[0].v_pointer);
396
397 return NULL;
398 }
399
400 static gchar*
value_lcopy_variant(const GValue * value,guint n_collect_values,GTypeCValue * collect_values,guint collect_flags)401 value_lcopy_variant (const GValue *value,
402 guint n_collect_values,
403 GTypeCValue *collect_values,
404 guint collect_flags)
405 {
406 GVariant **variant_p = collect_values[0].v_pointer;
407
408 if (!variant_p)
409 return g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value));
410
411 if (!value->data[0].v_pointer)
412 *variant_p = NULL;
413 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
414 *variant_p = value->data[0].v_pointer;
415 else
416 *variant_p = g_variant_ref_sink (value->data[0].v_pointer);
417
418 return NULL;
419 }
420
421 /* --- type initialization --- */
422 void
_g_value_types_init(void)423 _g_value_types_init (void)
424 {
425 GTypeInfo info = {
426 0, /* class_size */
427 NULL, /* base_init */
428 NULL, /* base_destroy */
429 NULL, /* class_init */
430 NULL, /* class_destroy */
431 NULL, /* class_data */
432 0, /* instance_size */
433 0, /* n_preallocs */
434 NULL, /* instance_init */
435 NULL, /* value_table */
436 };
437 const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
438 GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */;
439
440 /* G_TYPE_CHAR / G_TYPE_UCHAR
441 */
442 {
443 static const GTypeValueTable value_table = {
444 value_init_long0, /* value_init */
445 NULL, /* value_free */
446 value_copy_long0, /* value_copy */
447 NULL, /* value_peek_pointer */
448 "i", /* collect_format */
449 value_collect_int, /* collect_value */
450 "p", /* lcopy_format */
451 value_lcopy_char, /* lcopy_value */
452 };
453 info.value_table = &value_table;
454 type = g_type_register_fundamental (G_TYPE_CHAR, g_intern_static_string ("gchar"), &info, &finfo, 0);
455 g_assert (type == G_TYPE_CHAR);
456 type = g_type_register_fundamental (G_TYPE_UCHAR, g_intern_static_string ("guchar"), &info, &finfo, 0);
457 g_assert (type == G_TYPE_UCHAR);
458 }
459
460 /* G_TYPE_BOOLEAN
461 */
462 {
463 static const GTypeValueTable value_table = {
464 value_init_long0, /* value_init */
465 NULL, /* value_free */
466 value_copy_long0, /* value_copy */
467 NULL, /* value_peek_pointer */
468 "i", /* collect_format */
469 value_collect_int, /* collect_value */
470 "p", /* lcopy_format */
471 value_lcopy_boolean, /* lcopy_value */
472 };
473 info.value_table = &value_table;
474 type = g_type_register_fundamental (G_TYPE_BOOLEAN, g_intern_static_string ("gboolean"), &info, &finfo, 0);
475 g_assert (type == G_TYPE_BOOLEAN);
476 }
477
478 /* G_TYPE_INT / G_TYPE_UINT
479 */
480 {
481 static const GTypeValueTable value_table = {
482 value_init_long0, /* value_init */
483 NULL, /* value_free */
484 value_copy_long0, /* value_copy */
485 NULL, /* value_peek_pointer */
486 "i", /* collect_format */
487 value_collect_int, /* collect_value */
488 "p", /* lcopy_format */
489 value_lcopy_int, /* lcopy_value */
490 };
491 info.value_table = &value_table;
492 type = g_type_register_fundamental (G_TYPE_INT, g_intern_static_string ("gint"), &info, &finfo, 0);
493 g_assert (type == G_TYPE_INT);
494 type = g_type_register_fundamental (G_TYPE_UINT, g_intern_static_string ("guint"), &info, &finfo, 0);
495 g_assert (type == G_TYPE_UINT);
496 }
497
498 /* G_TYPE_LONG / G_TYPE_ULONG
499 */
500 {
501 static const GTypeValueTable value_table = {
502 value_init_long0, /* value_init */
503 NULL, /* value_free */
504 value_copy_long0, /* value_copy */
505 NULL, /* value_peek_pointer */
506 "l", /* collect_format */
507 value_collect_long, /* collect_value */
508 "p", /* lcopy_format */
509 value_lcopy_long, /* lcopy_value */
510 };
511 info.value_table = &value_table;
512 type = g_type_register_fundamental (G_TYPE_LONG, g_intern_static_string ("glong"), &info, &finfo, 0);
513 g_assert (type == G_TYPE_LONG);
514 type = g_type_register_fundamental (G_TYPE_ULONG, g_intern_static_string ("gulong"), &info, &finfo, 0);
515 g_assert (type == G_TYPE_ULONG);
516 }
517
518 /* G_TYPE_INT64 / G_TYPE_UINT64
519 */
520 {
521 static const GTypeValueTable value_table = {
522 value_init_int64, /* value_init */
523 NULL, /* value_free */
524 value_copy_int64, /* value_copy */
525 NULL, /* value_peek_pointer */
526 "q", /* collect_format */
527 value_collect_int64, /* collect_value */
528 "p", /* lcopy_format */
529 value_lcopy_int64, /* lcopy_value */
530 };
531 info.value_table = &value_table;
532 type = g_type_register_fundamental (G_TYPE_INT64, g_intern_static_string ("gint64"), &info, &finfo, 0);
533 g_assert (type == G_TYPE_INT64);
534 type = g_type_register_fundamental (G_TYPE_UINT64, g_intern_static_string ("guint64"), &info, &finfo, 0);
535 g_assert (type == G_TYPE_UINT64);
536 }
537
538 /* G_TYPE_FLOAT
539 */
540 {
541 static const GTypeValueTable value_table = {
542 value_init_float, /* value_init */
543 NULL, /* value_free */
544 value_copy_float, /* value_copy */
545 NULL, /* value_peek_pointer */
546 "d", /* collect_format */
547 value_collect_float, /* collect_value */
548 "p", /* lcopy_format */
549 value_lcopy_float, /* lcopy_value */
550 };
551 info.value_table = &value_table;
552 type = g_type_register_fundamental (G_TYPE_FLOAT, g_intern_static_string ("gfloat"), &info, &finfo, 0);
553 g_assert (type == G_TYPE_FLOAT);
554 }
555
556 /* G_TYPE_DOUBLE
557 */
558 {
559 static const GTypeValueTable value_table = {
560 value_init_double, /* value_init */
561 NULL, /* value_free */
562 value_copy_double, /* value_copy */
563 NULL, /* value_peek_pointer */
564 "d", /* collect_format */
565 value_collect_double, /* collect_value */
566 "p", /* lcopy_format */
567 value_lcopy_double, /* lcopy_value */
568 };
569 info.value_table = &value_table;
570 type = g_type_register_fundamental (G_TYPE_DOUBLE, g_intern_static_string ("gdouble"), &info, &finfo, 0);
571 g_assert (type == G_TYPE_DOUBLE);
572 }
573
574 /* G_TYPE_STRING
575 */
576 {
577 static const GTypeValueTable value_table = {
578 value_init_string, /* value_init */
579 value_free_string, /* value_free */
580 value_copy_string, /* value_copy */
581 value_peek_pointer0, /* value_peek_pointer */
582 "p", /* collect_format */
583 value_collect_string, /* collect_value */
584 "p", /* lcopy_format */
585 value_lcopy_string, /* lcopy_value */
586 };
587 info.value_table = &value_table;
588 type = g_type_register_fundamental (G_TYPE_STRING, g_intern_static_string ("gchararray"), &info, &finfo, 0);
589 g_assert (type == G_TYPE_STRING);
590 }
591
592 /* G_TYPE_POINTER
593 */
594 {
595 static const GTypeValueTable value_table = {
596 value_init_pointer, /* value_init */
597 NULL, /* value_free */
598 value_copy_pointer, /* value_copy */
599 value_peek_pointer0, /* value_peek_pointer */
600 "p", /* collect_format */
601 value_collect_pointer, /* collect_value */
602 "p", /* lcopy_format */
603 value_lcopy_pointer, /* lcopy_value */
604 };
605 info.value_table = &value_table;
606 type = g_type_register_fundamental (G_TYPE_POINTER, g_intern_static_string ("gpointer"), &info, &finfo, 0);
607 g_assert (type == G_TYPE_POINTER);
608 }
609
610 /* G_TYPE_VARIANT
611 */
612 {
613 static const GTypeValueTable value_table = {
614 value_init_pointer, /* value_init */
615 value_free_variant, /* value_free */
616 value_copy_variant, /* value_copy */
617 value_peek_pointer0, /* value_peek_pointer */
618 "p", /* collect_format */
619 value_collect_variant, /* collect_value */
620 "p", /* lcopy_format */
621 value_lcopy_variant, /* lcopy_value */
622 };
623 info.value_table = &value_table;
624 type = g_type_register_fundamental (G_TYPE_VARIANT, g_intern_static_string ("GVariant"), &info, &finfo, 0);
625 g_assert (type == G_TYPE_VARIANT);
626 }
627 }
628
629
630 /* --- GValue functions --- */
631 /**
632 * g_value_set_char:
633 * @value: a valid #GValue of type %G_TYPE_CHAR
634 * @v_char: character value to be set
635 *
636 * Set the contents of a %G_TYPE_CHAR #GValue to @v_char.
637 * Deprecated: 2.32: This function's input type is broken, see g_value_set_schar()
638 */
639 void
g_value_set_char(GValue * value,gchar v_char)640 g_value_set_char (GValue *value,
641 gchar v_char)
642 {
643 g_return_if_fail (G_VALUE_HOLDS_CHAR (value));
644
645 value->data[0].v_int = v_char;
646 }
647
648 /**
649 * g_value_get_char:
650 * @value: a valid #GValue of type %G_TYPE_CHAR
651 *
652 * Do not use this function; it is broken on platforms where the %char
653 * type is unsigned, such as ARM and PowerPC. See g_value_get_schar().
654 *
655 * Get the contents of a %G_TYPE_CHAR #GValue.
656 *
657 * Returns: character contents of @value
658 * Deprecated: 2.32: This function's return type is broken, see g_value_get_schar()
659 */
660 gchar
g_value_get_char(const GValue * value)661 g_value_get_char (const GValue *value)
662 {
663 g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0);
664
665 return value->data[0].v_int;
666 }
667
668 /**
669 * g_value_set_schar:
670 * @value: a valid #GValue of type %G_TYPE_CHAR
671 * @v_char: signed 8 bit integer to be set
672 *
673 * Set the contents of a %G_TYPE_CHAR #GValue to @v_char.
674 *
675 * Since: 2.32
676 */
677 void
g_value_set_schar(GValue * value,gint8 v_char)678 g_value_set_schar (GValue *value,
679 gint8 v_char)
680 {
681 g_return_if_fail (G_VALUE_HOLDS_CHAR (value));
682
683 value->data[0].v_int = v_char;
684 }
685
686 /**
687 * g_value_get_schar:
688 * @value: a valid #GValue of type %G_TYPE_CHAR
689 *
690 * Get the contents of a %G_TYPE_CHAR #GValue.
691 *
692 * Returns: signed 8 bit integer contents of @value
693 * Since: 2.32
694 */
695 gint8
g_value_get_schar(const GValue * value)696 g_value_get_schar (const GValue *value)
697 {
698 g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0);
699
700 return value->data[0].v_int;
701 }
702
703 /**
704 * g_value_set_uchar:
705 * @value: a valid #GValue of type %G_TYPE_UCHAR
706 * @v_uchar: unsigned character value to be set
707 *
708 * Set the contents of a %G_TYPE_UCHAR #GValue to @v_uchar.
709 */
710 void
g_value_set_uchar(GValue * value,guchar v_uchar)711 g_value_set_uchar (GValue *value,
712 guchar v_uchar)
713 {
714 g_return_if_fail (G_VALUE_HOLDS_UCHAR (value));
715
716 value->data[0].v_uint = v_uchar;
717 }
718
719 /**
720 * g_value_get_uchar:
721 * @value: a valid #GValue of type %G_TYPE_UCHAR
722 *
723 * Get the contents of a %G_TYPE_UCHAR #GValue.
724 *
725 * Returns: unsigned character contents of @value
726 */
727 guchar
g_value_get_uchar(const GValue * value)728 g_value_get_uchar (const GValue *value)
729 {
730 g_return_val_if_fail (G_VALUE_HOLDS_UCHAR (value), 0);
731
732 return value->data[0].v_uint;
733 }
734
735 /**
736 * g_value_set_boolean:
737 * @value: a valid #GValue of type %G_TYPE_BOOLEAN
738 * @v_boolean: boolean value to be set
739 *
740 * Set the contents of a %G_TYPE_BOOLEAN #GValue to @v_boolean.
741 */
742 void
g_value_set_boolean(GValue * value,gboolean v_boolean)743 g_value_set_boolean (GValue *value,
744 gboolean v_boolean)
745 {
746 g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (value));
747
748 value->data[0].v_int = v_boolean != FALSE;
749 }
750
751 /**
752 * g_value_get_boolean:
753 * @value: a valid #GValue of type %G_TYPE_BOOLEAN
754 *
755 * Get the contents of a %G_TYPE_BOOLEAN #GValue.
756 *
757 * Returns: boolean contents of @value
758 */
759 gboolean
g_value_get_boolean(const GValue * value)760 g_value_get_boolean (const GValue *value)
761 {
762 g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (value), 0);
763
764 return value->data[0].v_int;
765 }
766
767 /**
768 * g_value_set_int:
769 * @value: a valid #GValue of type %G_TYPE_INT
770 * @v_int: integer value to be set
771 *
772 * Set the contents of a %G_TYPE_INT #GValue to @v_int.
773 */
774 void
g_value_set_int(GValue * value,gint v_int)775 g_value_set_int (GValue *value,
776 gint v_int)
777 {
778 g_return_if_fail (G_VALUE_HOLDS_INT (value));
779
780 value->data[0].v_int = v_int;
781 }
782
783 /**
784 * g_value_get_int:
785 * @value: a valid #GValue of type %G_TYPE_INT
786 *
787 * Get the contents of a %G_TYPE_INT #GValue.
788 *
789 * Returns: integer contents of @value
790 */
791 gint
g_value_get_int(const GValue * value)792 g_value_get_int (const GValue *value)
793 {
794 g_return_val_if_fail (G_VALUE_HOLDS_INT (value), 0);
795
796 return value->data[0].v_int;
797 }
798
799 /**
800 * g_value_set_uint:
801 * @value: a valid #GValue of type %G_TYPE_UINT
802 * @v_uint: unsigned integer value to be set
803 *
804 * Set the contents of a %G_TYPE_UINT #GValue to @v_uint.
805 */
806 void
g_value_set_uint(GValue * value,guint v_uint)807 g_value_set_uint (GValue *value,
808 guint v_uint)
809 {
810 g_return_if_fail (G_VALUE_HOLDS_UINT (value));
811
812 value->data[0].v_uint = v_uint;
813 }
814
815 /**
816 * g_value_get_uint:
817 * @value: a valid #GValue of type %G_TYPE_UINT
818 *
819 * Get the contents of a %G_TYPE_UINT #GValue.
820 *
821 * Returns: unsigned integer contents of @value
822 */
823 guint
g_value_get_uint(const GValue * value)824 g_value_get_uint (const GValue *value)
825 {
826 g_return_val_if_fail (G_VALUE_HOLDS_UINT (value), 0);
827
828 return value->data[0].v_uint;
829 }
830
831 /**
832 * g_value_set_long:
833 * @value: a valid #GValue of type %G_TYPE_LONG
834 * @v_long: long integer value to be set
835 *
836 * Set the contents of a %G_TYPE_LONG #GValue to @v_long.
837 */
838 void
g_value_set_long(GValue * value,glong v_long)839 g_value_set_long (GValue *value,
840 glong v_long)
841 {
842 g_return_if_fail (G_VALUE_HOLDS_LONG (value));
843
844 value->data[0].v_long = v_long;
845 }
846
847 /**
848 * g_value_get_long:
849 * @value: a valid #GValue of type %G_TYPE_LONG
850 *
851 * Get the contents of a %G_TYPE_LONG #GValue.
852 *
853 * Returns: long integer contents of @value
854 */
855 glong
g_value_get_long(const GValue * value)856 g_value_get_long (const GValue *value)
857 {
858 g_return_val_if_fail (G_VALUE_HOLDS_LONG (value), 0);
859
860 return value->data[0].v_long;
861 }
862
863 /**
864 * g_value_set_ulong:
865 * @value: a valid #GValue of type %G_TYPE_ULONG
866 * @v_ulong: unsigned long integer value to be set
867 *
868 * Set the contents of a %G_TYPE_ULONG #GValue to @v_ulong.
869 */
870 void
g_value_set_ulong(GValue * value,gulong v_ulong)871 g_value_set_ulong (GValue *value,
872 gulong v_ulong)
873 {
874 g_return_if_fail (G_VALUE_HOLDS_ULONG (value));
875
876 value->data[0].v_ulong = v_ulong;
877 }
878
879 /**
880 * g_value_get_ulong:
881 * @value: a valid #GValue of type %G_TYPE_ULONG
882 *
883 * Get the contents of a %G_TYPE_ULONG #GValue.
884 *
885 * Returns: unsigned long integer contents of @value
886 */
887 gulong
g_value_get_ulong(const GValue * value)888 g_value_get_ulong (const GValue *value)
889 {
890 g_return_val_if_fail (G_VALUE_HOLDS_ULONG (value), 0);
891
892 return value->data[0].v_ulong;
893 }
894
895 /**
896 * g_value_get_int64:
897 * @value: a valid #GValue of type %G_TYPE_INT64
898 *
899 * Get the contents of a %G_TYPE_INT64 #GValue.
900 *
901 * Returns: 64bit integer contents of @value
902 */
903 void
g_value_set_int64(GValue * value,gint64 v_int64)904 g_value_set_int64 (GValue *value,
905 gint64 v_int64)
906 {
907 g_return_if_fail (G_VALUE_HOLDS_INT64 (value));
908
909 value->data[0].v_int64 = v_int64;
910 }
911
912 /**
913 * g_value_set_int64:
914 * @value: a valid #GValue of type %G_TYPE_INT64
915 * @v_int64: 64bit integer value to be set
916 *
917 * Set the contents of a %G_TYPE_INT64 #GValue to @v_int64.
918 */
919 gint64
g_value_get_int64(const GValue * value)920 g_value_get_int64 (const GValue *value)
921 {
922 g_return_val_if_fail (G_VALUE_HOLDS_INT64 (value), 0);
923
924 return value->data[0].v_int64;
925 }
926
927 /**
928 * g_value_set_uint64:
929 * @value: a valid #GValue of type %G_TYPE_UINT64
930 * @v_uint64: unsigned 64bit integer value to be set
931 *
932 * Set the contents of a %G_TYPE_UINT64 #GValue to @v_uint64.
933 */
934 void
g_value_set_uint64(GValue * value,guint64 v_uint64)935 g_value_set_uint64 (GValue *value,
936 guint64 v_uint64)
937 {
938 g_return_if_fail (G_VALUE_HOLDS_UINT64 (value));
939
940 value->data[0].v_uint64 = v_uint64;
941 }
942
943 /**
944 * g_value_get_uint64:
945 * @value: a valid #GValue of type %G_TYPE_UINT64
946 *
947 * Get the contents of a %G_TYPE_UINT64 #GValue.
948 *
949 * Returns: unsigned 64bit integer contents of @value
950 */
951 guint64
g_value_get_uint64(const GValue * value)952 g_value_get_uint64 (const GValue *value)
953 {
954 g_return_val_if_fail (G_VALUE_HOLDS_UINT64 (value), 0);
955
956 return value->data[0].v_uint64;
957 }
958
959 /**
960 * g_value_set_float:
961 * @value: a valid #GValue of type %G_TYPE_FLOAT
962 * @v_float: float value to be set
963 *
964 * Set the contents of a %G_TYPE_FLOAT #GValue to @v_float.
965 */
966 void
g_value_set_float(GValue * value,gfloat v_float)967 g_value_set_float (GValue *value,
968 gfloat v_float)
969 {
970 g_return_if_fail (G_VALUE_HOLDS_FLOAT (value));
971
972 value->data[0].v_float = v_float;
973 }
974
975 /**
976 * g_value_get_float:
977 * @value: a valid #GValue of type %G_TYPE_FLOAT
978 *
979 * Get the contents of a %G_TYPE_FLOAT #GValue.
980 *
981 * Returns: float contents of @value
982 */
983 gfloat
g_value_get_float(const GValue * value)984 g_value_get_float (const GValue *value)
985 {
986 g_return_val_if_fail (G_VALUE_HOLDS_FLOAT (value), 0);
987
988 return value->data[0].v_float;
989 }
990
991 /**
992 * g_value_set_double:
993 * @value: a valid #GValue of type %G_TYPE_DOUBLE
994 * @v_double: double value to be set
995 *
996 * Set the contents of a %G_TYPE_DOUBLE #GValue to @v_double.
997 */
998 void
g_value_set_double(GValue * value,gdouble v_double)999 g_value_set_double (GValue *value,
1000 gdouble v_double)
1001 {
1002 g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value));
1003
1004 value->data[0].v_double = v_double;
1005 }
1006
1007 /**
1008 * g_value_get_double:
1009 * @value: a valid #GValue of type %G_TYPE_DOUBLE
1010 *
1011 * Get the contents of a %G_TYPE_DOUBLE #GValue.
1012 *
1013 * Returns: double contents of @value
1014 */
1015 gdouble
g_value_get_double(const GValue * value)1016 g_value_get_double (const GValue *value)
1017 {
1018 g_return_val_if_fail (G_VALUE_HOLDS_DOUBLE (value), 0);
1019
1020 return value->data[0].v_double;
1021 }
1022
1023 /**
1024 * g_value_set_string:
1025 * @value: a valid #GValue of type %G_TYPE_STRING
1026 * @v_string: (nullable): caller-owned string to be duplicated for the #GValue
1027 *
1028 * Set the contents of a %G_TYPE_STRING #GValue to @v_string.
1029 */
1030 void
g_value_set_string(GValue * value,const gchar * v_string)1031 g_value_set_string (GValue *value,
1032 const gchar *v_string)
1033 {
1034 gchar *new_val;
1035
1036 g_return_if_fail (G_VALUE_HOLDS_STRING (value));
1037
1038 new_val = g_strdup (v_string);
1039
1040 if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
1041 value->data[1].v_uint = 0;
1042 else
1043 g_free (value->data[0].v_pointer);
1044
1045 value->data[0].v_pointer = new_val;
1046 }
1047
1048 /**
1049 * g_value_set_static_string:
1050 * @value: a valid #GValue of type %G_TYPE_STRING
1051 * @v_string: (nullable): static string to be set
1052 *
1053 * Set the contents of a %G_TYPE_STRING #GValue to @v_string.
1054 * The string is assumed to be static, and is thus not duplicated
1055 * when setting the #GValue.
1056 */
1057 void
g_value_set_static_string(GValue * value,const gchar * v_string)1058 g_value_set_static_string (GValue *value,
1059 const gchar *v_string)
1060 {
1061 g_return_if_fail (G_VALUE_HOLDS_STRING (value));
1062
1063 if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
1064 g_free (value->data[0].v_pointer);
1065 value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
1066 value->data[0].v_pointer = (gchar*) v_string;
1067 }
1068
1069 /**
1070 * g_value_set_string_take_ownership:
1071 * @value: a valid #GValue of type %G_TYPE_STRING
1072 * @v_string: (nullable): duplicated unowned string to be set
1073 *
1074 * This is an internal function introduced mainly for C marshallers.
1075 *
1076 * Deprecated: 2.4: Use g_value_take_string() instead.
1077 */
1078 void
g_value_set_string_take_ownership(GValue * value,gchar * v_string)1079 g_value_set_string_take_ownership (GValue *value,
1080 gchar *v_string)
1081 {
1082 g_value_take_string (value, v_string);
1083 }
1084
1085 /**
1086 * g_value_take_string:
1087 * @value: a valid #GValue of type %G_TYPE_STRING
1088 * @v_string: (nullable): string to take ownership of
1089 *
1090 * Sets the contents of a %G_TYPE_STRING #GValue to @v_string.
1091 *
1092 * Since: 2.4
1093 */
1094 void
g_value_take_string(GValue * value,gchar * v_string)1095 g_value_take_string (GValue *value,
1096 gchar *v_string)
1097 {
1098 g_return_if_fail (G_VALUE_HOLDS_STRING (value));
1099
1100 if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
1101 value->data[1].v_uint = 0;
1102 else
1103 g_free (value->data[0].v_pointer);
1104 value->data[0].v_pointer = v_string;
1105 }
1106
1107 /**
1108 * g_value_get_string:
1109 * @value: a valid #GValue of type %G_TYPE_STRING
1110 *
1111 * Get the contents of a %G_TYPE_STRING #GValue.
1112 *
1113 * Returns: string content of @value
1114 */
1115 const gchar*
g_value_get_string(const GValue * value)1116 g_value_get_string (const GValue *value)
1117 {
1118 g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
1119
1120 return value->data[0].v_pointer;
1121 }
1122
1123 /**
1124 * g_value_dup_string:
1125 * @value: a valid #GValue of type %G_TYPE_STRING
1126 *
1127 * Get a copy the contents of a %G_TYPE_STRING #GValue.
1128 *
1129 * Returns: a newly allocated copy of the string content of @value
1130 */
1131 gchar*
g_value_dup_string(const GValue * value)1132 g_value_dup_string (const GValue *value)
1133 {
1134 g_return_val_if_fail (G_VALUE_HOLDS_STRING (value), NULL);
1135
1136 return g_strdup (value->data[0].v_pointer);
1137 }
1138
1139 /**
1140 * g_value_set_pointer:
1141 * @value: a valid #GValue of %G_TYPE_POINTER
1142 * @v_pointer: pointer value to be set
1143 *
1144 * Set the contents of a pointer #GValue to @v_pointer.
1145 */
1146 void
g_value_set_pointer(GValue * value,gpointer v_pointer)1147 g_value_set_pointer (GValue *value,
1148 gpointer v_pointer)
1149 {
1150 g_return_if_fail (G_VALUE_HOLDS_POINTER (value));
1151
1152 value->data[0].v_pointer = v_pointer;
1153 }
1154
1155 /**
1156 * g_value_get_pointer:
1157 * @value: a valid #GValue of %G_TYPE_POINTER
1158 *
1159 * Get the contents of a pointer #GValue.
1160 *
1161 * Returns: (transfer none): pointer contents of @value
1162 */
1163 gpointer
g_value_get_pointer(const GValue * value)1164 g_value_get_pointer (const GValue *value)
1165 {
1166 g_return_val_if_fail (G_VALUE_HOLDS_POINTER (value), NULL);
1167
1168 return value->data[0].v_pointer;
1169 }
1170
G_DEFINE_POINTER_TYPE(GType,g_gtype)1171 G_DEFINE_POINTER_TYPE (GType, g_gtype)
1172
1173 /**
1174 * g_value_set_gtype:
1175 * @value: a valid #GValue of type %G_TYPE_GTYPE
1176 * @v_gtype: #GType to be set
1177 *
1178 * Set the contents of a %G_TYPE_GTYPE #GValue to @v_gtype.
1179 *
1180 * Since: 2.12
1181 */
1182 void
1183 g_value_set_gtype (GValue *value,
1184 GType v_gtype)
1185 {
1186 g_return_if_fail (G_VALUE_HOLDS_GTYPE (value));
1187
1188 value->data[0].v_pointer = GSIZE_TO_POINTER (v_gtype);
1189
1190 }
1191
1192 /**
1193 * g_value_get_gtype:
1194 * @value: a valid #GValue of type %G_TYPE_GTYPE
1195 *
1196 * Get the contents of a %G_TYPE_GTYPE #GValue.
1197 *
1198 * Since: 2.12
1199 *
1200 * Returns: the #GType stored in @value
1201 */
1202 GType
g_value_get_gtype(const GValue * value)1203 g_value_get_gtype (const GValue *value)
1204 {
1205 g_return_val_if_fail (G_VALUE_HOLDS_GTYPE (value), 0);
1206
1207 return GPOINTER_TO_SIZE (value->data[0].v_pointer);
1208 }
1209
1210 /**
1211 * g_value_set_variant:
1212 * @value: a valid #GValue of type %G_TYPE_VARIANT
1213 * @variant: (nullable): a #GVariant, or %NULL
1214 *
1215 * Set the contents of a variant #GValue to @variant.
1216 * If the variant is floating, it is consumed.
1217 *
1218 * Since: 2.26
1219 */
1220 void
g_value_set_variant(GValue * value,GVariant * variant)1221 g_value_set_variant (GValue *value,
1222 GVariant *variant)
1223 {
1224 GVariant *old_variant;
1225
1226 g_return_if_fail (G_VALUE_HOLDS_VARIANT (value));
1227
1228 old_variant = value->data[0].v_pointer;
1229
1230 if (variant)
1231 value->data[0].v_pointer = g_variant_ref_sink (variant);
1232 else
1233 value->data[0].v_pointer = NULL;
1234
1235 if (old_variant)
1236 g_variant_unref (old_variant);
1237 }
1238
1239 /**
1240 * g_value_take_variant:
1241 * @value: a valid #GValue of type %G_TYPE_VARIANT
1242 * @variant: (nullable) (transfer full): a #GVariant, or %NULL
1243 *
1244 * Set the contents of a variant #GValue to @variant, and takes over
1245 * the ownership of the caller's reference to @variant;
1246 * the caller doesn't have to unref it any more (i.e. the reference
1247 * count of the variant is not increased).
1248 *
1249 * If @variant was floating then its floating reference is converted to
1250 * a hard reference.
1251 *
1252 * If you want the #GValue to hold its own reference to @variant, use
1253 * g_value_set_variant() instead.
1254 *
1255 * This is an internal function introduced mainly for C marshallers.
1256 *
1257 * Since: 2.26
1258 */
1259 void
g_value_take_variant(GValue * value,GVariant * variant)1260 g_value_take_variant (GValue *value,
1261 GVariant *variant)
1262 {
1263 GVariant *old_variant;
1264
1265 g_return_if_fail (G_VALUE_HOLDS_VARIANT (value));
1266
1267 old_variant = value->data[0].v_pointer;
1268
1269 if (variant)
1270 value->data[0].v_pointer = g_variant_take_ref (variant);
1271 else
1272 value->data[0].v_pointer = NULL;
1273
1274 if (old_variant)
1275 g_variant_unref (old_variant);
1276 }
1277
1278 /**
1279 * g_value_get_variant:
1280 * @value: a valid #GValue of type %G_TYPE_VARIANT
1281 *
1282 * Get the contents of a variant #GValue.
1283 *
1284 * Returns: (transfer none) (nullable): variant contents of @value (may be %NULL)
1285 *
1286 * Since: 2.26
1287 */
1288 GVariant*
g_value_get_variant(const GValue * value)1289 g_value_get_variant (const GValue *value)
1290 {
1291 g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL);
1292
1293 return value->data[0].v_pointer;
1294 }
1295
1296 /**
1297 * g_value_dup_variant:
1298 * @value: a valid #GValue of type %G_TYPE_VARIANT
1299 *
1300 * Get the contents of a variant #GValue, increasing its refcount. The returned
1301 * #GVariant is never floating.
1302 *
1303 * Returns: (transfer full) (nullable): variant contents of @value (may be %NULL);
1304 * should be unreffed using g_variant_unref() when no longer needed
1305 *
1306 * Since: 2.26
1307 */
1308 GVariant*
g_value_dup_variant(const GValue * value)1309 g_value_dup_variant (const GValue *value)
1310 {
1311 GVariant *variant;
1312
1313 g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL);
1314
1315 variant = value->data[0].v_pointer;
1316 if (variant)
1317 g_variant_ref_sink (variant);
1318
1319 return variant;
1320 }
1321
1322 /**
1323 * g_strdup_value_contents:
1324 * @value: #GValue which contents are to be described.
1325 *
1326 * Return a newly allocated string, which describes the contents of a
1327 * #GValue. The main purpose of this function is to describe #GValue
1328 * contents for debugging output, the way in which the contents are
1329 * described may change between different GLib versions.
1330 *
1331 * Returns: Newly allocated string.
1332 */
1333 gchar*
g_strdup_value_contents(const GValue * value)1334 g_strdup_value_contents (const GValue *value)
1335 {
1336 const gchar *src;
1337 gchar *contents;
1338
1339 g_return_val_if_fail (G_IS_VALUE (value), NULL);
1340
1341 if (G_VALUE_HOLDS_STRING (value))
1342 {
1343 src = g_value_get_string (value);
1344
1345 if (!src)
1346 contents = g_strdup ("NULL");
1347 else
1348 {
1349 gchar *s = g_strescape (src, NULL);
1350
1351 contents = g_strdup_printf ("\"%s\"", s);
1352 g_free (s);
1353 }
1354 }
1355 else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
1356 {
1357 GValue tmp_value = G_VALUE_INIT;
1358 gchar *s;
1359
1360 g_value_init (&tmp_value, G_TYPE_STRING);
1361 g_value_transform (value, &tmp_value);
1362 s = g_strescape (g_value_get_string (&tmp_value), NULL);
1363 g_value_unset (&tmp_value);
1364 if (G_VALUE_HOLDS_ENUM (value) || G_VALUE_HOLDS_FLAGS (value))
1365 contents = g_strdup_printf ("((%s) %s)",
1366 g_type_name (G_VALUE_TYPE (value)),
1367 s);
1368 else
1369 contents = g_strdup (s ? s : "NULL");
1370 g_free (s);
1371 }
1372 else if (g_value_fits_pointer (value))
1373 {
1374 gpointer p = g_value_peek_pointer (value);
1375
1376 if (!p)
1377 contents = g_strdup ("NULL");
1378 else if (G_VALUE_HOLDS_OBJECT (value))
1379 contents = g_strdup_printf ("((%s*) %p)", G_OBJECT_TYPE_NAME (p), p);
1380 else if (G_VALUE_HOLDS_PARAM (value))
1381 contents = g_strdup_printf ("((%s*) %p)", G_PARAM_SPEC_TYPE_NAME (p), p);
1382 else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
1383 {
1384 GStrv strv = g_value_get_boxed (value);
1385 GString *tmp = g_string_new ("[");
1386
1387 while (*strv != NULL)
1388 {
1389 gchar *escaped = g_strescape (*strv, NULL);
1390
1391 g_string_append_printf (tmp, "\"%s\"", escaped);
1392 g_free (escaped);
1393
1394 if (*++strv != NULL)
1395 g_string_append (tmp, ", ");
1396 }
1397
1398 g_string_append (tmp, "]");
1399 contents = g_string_free (tmp, FALSE);
1400 }
1401 else if (G_VALUE_HOLDS_BOXED (value))
1402 contents = g_strdup_printf ("((%s*) %p)", g_type_name (G_VALUE_TYPE (value)), p);
1403 else if (G_VALUE_HOLDS_POINTER (value))
1404 contents = g_strdup_printf ("((gpointer) %p)", p);
1405 else
1406 contents = g_strdup ("???");
1407 }
1408 else
1409 contents = g_strdup ("???");
1410
1411 return contents;
1412 }
1413
1414 /**
1415 * g_pointer_type_register_static:
1416 * @name: the name of the new pointer type.
1417 *
1418 * Creates a new %G_TYPE_POINTER derived type id for a new
1419 * pointer type with name @name.
1420 *
1421 * Returns: a new %G_TYPE_POINTER derived type id for @name.
1422 */
1423 GType
g_pointer_type_register_static(const gchar * name)1424 g_pointer_type_register_static (const gchar *name)
1425 {
1426 const GTypeInfo type_info = {
1427 0, /* class_size */
1428 NULL, /* base_init */
1429 NULL, /* base_finalize */
1430 NULL, /* class_init */
1431 NULL, /* class_finalize */
1432 NULL, /* class_data */
1433 0, /* instance_size */
1434 0, /* n_preallocs */
1435 NULL, /* instance_init */
1436 NULL /* value_table */
1437 };
1438 GType type;
1439
1440 g_return_val_if_fail (name != NULL, 0);
1441 g_return_val_if_fail (g_type_from_name (name) == 0, 0);
1442
1443 type = g_type_register_static (G_TYPE_POINTER, name, &type_info, 0);
1444
1445 return type;
1446 }
1447