Bug Summary

File:_build/../libbean/cparam.c
Warning:line 1229, column 15
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cparam.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/_build -fcoverage-compilation-dir=/rootdir/_build -resource-dir /usr/lib/llvm-19/lib/clang/19 -I libbean/libean-2.0.so.0.0.0.p -I libbean -I ../libbean -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gobject-introspection-1.0 -D _FILE_OFFSET_BITS=64 -D HAVE_CONFIG_H -D G_LOG_DOMAIN="libbean" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib/x86_64-linux-gnu" -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-08-03-105933-13762-1 -x c ../libbean/cparam.c
1/* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1997-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
25#include "config.h"
26
27#include <string.h>
28
29#include "cparamspecs.h"
30
31
32/**
33 * CParamSpec: (ref-func c_param_spec_ref_sink) (unref-func c_param_spec_unref) (set-value-func c_value_set_param) (get-value-func c_value_get_param)
34 * @g_type_instance: private `GTypeInstance` portion
35 * @name: name of this parameter: always an interned string
36 * @flags: `CParamFlags` flags for this parameter
37 * @value_type: the `GValue` type for this parameter
38 * @owner_type: `GType` type that uses (introduces) this parameter
39 *
40 * `CParamSpec` encapsulates the metadata required to specify parameters, such as `GObject` properties.
41 *
42 * ## Parameter names
43 *
44 * A property name consists of one or more segments consisting of ASCII letters
45 * and digits, separated by either the `-` or `_` character. The first
46 * character of a property name must be a letter. These are the same rules as
47 * for signal naming (see [func@GObject.signal_new]).
48 *
49 * When creating and looking up a `CParamSpec`, either separator can be
50 * used, but they cannot be mixed. Using `-` is considerably more
51 * efficient, and is the ‘canonical form’. Using `_` is discouraged.
52 */
53
54/* --- defines --- */
55#define PARAM_FLOATING_FLAG0x2 0x2
56#define C_PARAM_USER_MASK(~0U << (8)) (~0U << C_PARAM_USER_SHIFT(8))
57#define PSPEC_APPLIES_TO_VALUE(pspec, value)(((__extension__ ({ const GValue *__val = (const GValue*) ((value
)); GType __t = ((((((CParamSpec*) (void *) ((pspec)))))->
value_type)); gboolean __r; if (!__val) __r = (0); else if (__val
->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds
(__val, __t); __r; }))))
(G_TYPE_CHECK_VALUE_TYPE ((value), C_PARAM_SPEC_VALUE_TYPE (pspec))((__extension__ ({ const GValue *__val = (const GValue*) ((value
)); GType __t = ((((((CParamSpec*) (void *) ((pspec)))))->
value_type)); gboolean __r; if (!__val) __r = (0); else if (__val
->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds
(__val, __t); __r; })))
)
58
59/* --- prototypes --- */
60static void c_param_spec_class_base_init (CParamSpecClass *class);
61static void c_param_spec_class_base_finalize (CParamSpecClass *class);
62static void c_param_spec_class_init (CParamSpecClass *class,
63 gpointer class_data);
64static void c_param_spec_init (CParamSpec *pspec,
65 CParamSpecClass *class);
66static void c_param_spec_finalize (CParamSpec *pspec);
67static void value_param_init (GValue *value);
68static void value_param_free_value (GValue *value);
69static void value_param_copy_value (const GValue *src_value,
70 GValue *dest_value);
71static void value_param_transform_value (const GValue *src_value,
72 GValue *dest_value);
73static gpointer value_param_peek_pointer (const GValue *value);
74static gchar* value_param_collect_value (GValue *value,
75 guint n_collect_values,
76 GTypeCValue *collect_values,
77 guint collect_flags);
78static gchar* value_param_lcopy_value (const GValue *value,
79 guint n_collect_values,
80 GTypeCValue *collect_values,
81 guint collect_flags);
82
83typedef struct
84{
85 GValue default_value;
86 GQuark name_quark;
87} CParamSpecPrivate;
88
89static gint c_param_private_offset;
90
91/* --- functions --- */
92static inline CParamSpecPrivate *
93c_param_spec_get_private (CParamSpec *pspec)
94{
95 return &G_STRUCT_MEMBER (CParamSpecPrivate, pspec, c_param_private_offset)(*(CParamSpecPrivate*) ((gpointer) ((guint8*) ((pspec)) + (glong
) ((c_param_private_offset)))))
;
96}
97
98void
99_c_param_type_init (void)
100{
101 static const GTypeFundamentalInfo finfo = {
102 (G_TYPE_FLAG_CLASSED |
103 G_TYPE_FLAG_INSTANTIATABLE |
104 G_TYPE_FLAG_DERIVABLE |
105 G_TYPE_FLAG_DEEP_DERIVABLE),
106 };
107 static const GTypeValueTable param_value_table = {
108 value_param_init, /* value_init */
109 value_param_free_value, /* value_free */
110 value_param_copy_value, /* value_copy */
111 value_param_peek_pointer, /* value_peek_pointer */
112 "p", /* collect_format */
113 value_param_collect_value, /* collect_value */
114 "p", /* lcopy_format */
115 value_param_lcopy_value, /* lcopy_value */
116 };
117 const GTypeInfo param_spec_info = {
118 sizeof (CParamSpecClass),
119
120 (GBaseInitFunc) c_param_spec_class_base_init,
121 (GBaseFinalizeFunc) c_param_spec_class_base_finalize,
122 (GClassInitFunc) c_param_spec_class_init,
123 (GClassFinalizeFunc) NULL((void*)0),
124 NULL((void*)0), /* class_data */
125
126 sizeof (CParamSpec),
127 0, /* n_preallocs */
128 (GInstanceInitFunc) c_param_spec_init,
129
130 &param_value_table,
131 };
132 GType type;
133
134 /* This should be registered as CParamSpec instead of CParam, for
135 * consistency sake, so that type name can be mapped to struct name,
136 * However, some language bindings, most noticeable the python ones
137 * depends on the "CParam" identifier, see #548689
138 */
139 type = g_type_register_fundamental (C_TYPE_PARAM((GType) ((19) << (2))), g_intern_static_string ("CParam"), &param_spec_info, &finfo, G_TYPE_FLAG_ABSTRACT);
140 g_assert (type == C_TYPE_PARAM)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_76
= 0; if (type == ((GType) ((19) << (2)))) _g_boolean_var_76
= 1; _g_boolean_var_76; }), 1)) ; else g_assertion_message_expr
("libbean", "../libbean/cparam.c", 140, ((const char*) (__func__
)), "type == C_TYPE_PARAM"); } while (0)
;
141 c_param_private_offset = g_type_add_instance_private (type, sizeof (CParamSpecPrivate));
142 g_value_register_transform_func (C_TYPE_PARAM((GType) ((19) << (2))), C_TYPE_PARAM((GType) ((19) << (2))), value_param_transform_value);
143}
144
145static void
146c_param_spec_class_base_init (CParamSpecClass *class)
147{
148}
149
150static void
151c_param_spec_class_base_finalize (CParamSpecClass *class)
152{
153}
154
155static void
156c_param_spec_class_init (CParamSpecClass *class,
157 gpointer class_data)
158{
159 class->value_type = G_TYPE_NONE((GType) ((1) << (2)));
160 class->finalize = c_param_spec_finalize;
161 class->value_set_default = NULL((void*)0);
162 class->value_validate = NULL((void*)0);
163 class->values_cmp = NULL((void*)0);
164
165 g_type_class_adjust_private_offset (class, &c_param_private_offset);
166}
167
168static void
169c_param_spec_init (CParamSpec *pspec,
170 CParamSpecClass *class)
171{
172 pspec->name = NULL((void*)0);
173 pspec->_nick = NULL((void*)0);
174 pspec->_blurb = NULL((void*)0);
175 pspec->flags = 0;
176 pspec->value_type = class->value_type;
177 pspec->owner_type = 0;
178 pspec->qdata = NULL((void*)0);
179 g_datalist_set_flags (&pspec->qdata, PARAM_FLOATING_FLAG0x2);
180 pspec->ref_count = 1;
181 pspec->param_id = 0;
182}
183
184static void
185c_param_spec_finalize (CParamSpec *pspec)
186{
187 CParamSpecPrivate *priv = c_param_spec_get_private (pspec);
188
189 if (priv->default_value.g_type)
190 g_value_reset (&priv->default_value);
191
192 g_datalist_clear (&pspec->qdata);
193
194 if (!(pspec->flags & C_PARAM_STATIC_NICK))
195 g_free (pspec->_nick);
196
197 if (!(pspec->flags & C_PARAM_STATIC_BLURB))
198 g_free (pspec->_blurb);
199
200 g_type_free_instance ((GTypeInstance*) pspec);
201}
202
203/**
204 * c_param_spec_ref: (skip)
205 * @pspec: (transfer none) (not nullable): a valid #CParamSpec
206 *
207 * Increments the reference count of @pspec.
208 *
209 * Returns: (transfer full) (not nullable): the #CParamSpec that was passed into this function
210 */
211CParamSpec*
212c_param_spec_ref (CParamSpec *pspec)
213{
214 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_77
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_77
= 1; _g_boolean_var_77; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return (((void*)0)); } } while (0)
;
215
216 g_atomic_int_inc ((int *)&pspec->ref_count)(__extension__ ({ _Static_assert (sizeof *((int *)&pspec->
ref_count) == sizeof (gint), "Expression evaluates to false")
; (void) (0 ? *((int *)&pspec->ref_count) ^ *((int *)&
pspec->ref_count) : 1); (void) __atomic_fetch_add (((int *
)&pspec->ref_count), 1, 5); }))
;
217
218 return pspec;
219}
220
221/**
222 * c_param_spec_unref: (skip)
223 * @pspec: a valid #CParamSpec
224 *
225 * Decrements the reference count of a @pspec.
226 */
227void
228c_param_spec_unref (CParamSpec *pspec)
229{
230 gboolean is_zero;
231
232 g_return_if_fail (C_IS_PARAM_SPEC (pspec))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_78
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_78
= 1; _g_boolean_var_78; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return; } } while (0)
;
233
234 is_zero = g_atomic_int_dec_and_test ((int *)&pspec->ref_count)(__extension__ ({ _Static_assert (sizeof *((int *)&pspec->
ref_count) == sizeof (gint), "Expression evaluates to false")
; (void) (0 ? *((int *)&pspec->ref_count) ^ *((int *)&
pspec->ref_count) : 1); __atomic_fetch_sub (((int *)&pspec
->ref_count), 1, 5) == 1; }))
;
235
236 if (G_UNLIKELY (is_zero)(__builtin_expect (__extension__ ({ int _g_boolean_var_79 = 0
; if (is_zero) _g_boolean_var_79 = 1; _g_boolean_var_79; }), 0
))
)
237 {
238 C_PARAM_SPEC_GET_CLASS (pspec)((((CParamSpecClass*) (((GTypeInstance*) ((pspec)))->g_class
))))
->finalize (pspec);
239 }
240}
241
242/**
243 * c_param_spec_sink:
244 * @pspec: a valid #CParamSpec
245 *
246 * The initial reference count of a newly created #CParamSpec is 1,
247 * even though no one has explicitly called c_param_spec_ref() on it
248 * yet. So the initial reference count is flagged as "floating", until
249 * someone calls `c_param_spec_ref (pspec); c_param_spec_sink
250 * (pspec);` in sequence on it, taking over the initial
251 * reference count (thus ending up with a @pspec that has a reference
252 * count of 1 still, but is not flagged "floating" anymore).
253 */
254void
255c_param_spec_sink (CParamSpec *pspec)
256{
257 guintptr oldvalue;
258 g_return_if_fail (C_IS_PARAM_SPEC (pspec))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_80
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_80
= 1; _g_boolean_var_80; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return; } } while (0)
;
259
260 oldvalue = g_atomic_pointer_and (&pspec->qdata, ~(gsize)PARAM_FLOATING_FLAG)(__extension__ ({ guintptr *gapa_atomic = (guintptr *) (&
pspec->qdata); _Static_assert (sizeof *(&pspec->qdata
) == sizeof (gpointer), "Expression evaluates to false"); _Static_assert
(sizeof *(&pspec->qdata) == sizeof (guintptr), "Expression evaluates to false"
); (void) (0 ? (gpointer) *(&pspec->qdata) : ((void*)0
)); (void) (0 ? (~(gsize)0x2) ^ (~(gsize)0x2) : 1); (guintptr
) __atomic_fetch_and (gapa_atomic, (~(gsize)0x2), 5); }))
;
261 if (oldvalue & PARAM_FLOATING_FLAG0x2)
262 c_param_spec_unref (pspec);
263}
264
265/**
266 * c_param_spec_ref_sink: (skip)
267 * @pspec: a valid #CParamSpec
268 *
269 * Convenience function to ref and sink a #CParamSpec.
270 *
271 * Since: 2.10
272 * Returns: (transfer full) (not nullable): the #CParamSpec that was passed into this function
273 */
274CParamSpec*
275c_param_spec_ref_sink (CParamSpec *pspec)
276{
277 guintptr oldvalue;
278 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_81
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_81
= 1; _g_boolean_var_81; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return (((void*)0)); } } while (0)
;
279
280 oldvalue = g_atomic_pointer_and (&pspec->qdata, ~(gsize)PARAM_FLOATING_FLAG)(__extension__ ({ guintptr *gapa_atomic = (guintptr *) (&
pspec->qdata); _Static_assert (sizeof *(&pspec->qdata
) == sizeof (gpointer), "Expression evaluates to false"); _Static_assert
(sizeof *(&pspec->qdata) == sizeof (guintptr), "Expression evaluates to false"
); (void) (0 ? (gpointer) *(&pspec->qdata) : ((void*)0
)); (void) (0 ? (~(gsize)0x2) ^ (~(gsize)0x2) : 1); (guintptr
) __atomic_fetch_and (gapa_atomic, (~(gsize)0x2), 5); }))
;
281 if (!(oldvalue & PARAM_FLOATING_FLAG0x2))
282 c_param_spec_ref (pspec);
283
284 return pspec;
285}
286
287/**
288 * c_param_spec_get_name:
289 * @pspec: a valid #CParamSpec
290 *
291 * Get the name of a #CParamSpec.
292 *
293 * The name is always an "interned" string (as per g_intern_string()).
294 * This allows for pointer-value comparisons.
295 *
296 * Returns: the name of @pspec.
297 */
298const gchar *
299c_param_spec_get_name (CParamSpec *pspec)
300{
301 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_82
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_82
= 1; _g_boolean_var_82; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return (((void*)0)); } } while (0)
;
302
303 return pspec->name;
304}
305
306/**
307 * c_param_spec_get_nick:
308 * @pspec: a valid #CParamSpec
309 *
310 * Get the nickname of a #CParamSpec.
311 *
312 * Returns: the nickname of @pspec.
313 */
314const gchar *
315c_param_spec_get_nick (CParamSpec *pspec)
316{
317 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_83
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_83
= 1; _g_boolean_var_83; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return (((void*)0)); } } while (0)
;
318
319 if (pspec->_nick)
320 return pspec->_nick;
321 else
322 {
323 CParamSpec *redirect_target;
324
325 redirect_target = c_param_spec_get_redirect_target (pspec);
326 if (redirect_target && redirect_target->_nick)
327 return redirect_target->_nick;
328 }
329
330 return pspec->name;
331}
332
333/**
334 * c_param_spec_get_blurb:
335 * @pspec: a valid #CParamSpec
336 *
337 * Get the short description of a #CParamSpec.
338 *
339 * Returns: (nullable): the short description of @pspec.
340 */
341const gchar *
342c_param_spec_get_blurb (CParamSpec *pspec)
343{
344 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_84
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_84
= 1; _g_boolean_var_84; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return (((void*)0)); } } while (0)
;
345
346 if (pspec->_blurb)
347 return pspec->_blurb;
348 else
349 {
350 CParamSpec *redirect_target;
351
352 redirect_target = c_param_spec_get_redirect_target (pspec);
353 if (redirect_target && redirect_target->_blurb)
354 return redirect_target->_blurb;
355 }
356
357 return NULL((void*)0);
358}
359
360/* @key must have already been validated with is_valid()
361 * Modifies @key in place. */
362static void
363canonicalize_key (gchar *key)
364{
365 gchar *p;
366
367 for (p = key; *p != 0; p++)
368 {
369 gchar c = *p;
370
371 if (c == '_')
372 *p = '-';
373 }
374}
375
376/* @key must have already been validated with is_valid() */
377static gboolean
378is_canonical (const gchar *key)
379{
380 return (strchr (key, '_') == NULL((void*)0));
381}
382
383/**
384 * c_param_spec_is_valid_name:
385 * @name: the canonical name of the property
386 *
387 * Validate a property name for a #CParamSpec. This can be useful for
388 * dynamically-generated properties which need to be validated at run-time
389 * before actually trying to create them.
390 *
391 * See [canonical parameter names][class@GObject.ParamSpec#parameter-names]
392 * for details of the rules for valid names.
393 *
394 * Returns: %TRUE if @name is a valid property name, %FALSE otherwise.
395 * Since: 2.66
396 */
397gboolean
398c_param_spec_is_valid_name (const gchar *name)
399{
400 const gchar *p;
401
402 /* First character must be a letter. */
403 if ((name[0] < 'A' || name[0] > 'Z') &&
404 (name[0] < 'a' || name[0] > 'z'))
405 return FALSE(0);
406
407 for (p = name; *p != 0; p++)
408 {
409 const gchar c = *p;
410
411 if (c != '-' && c != '_' &&
412 (c < '0' || c > '9') &&
413 (c < 'A' || c > 'Z') &&
414 (c < 'a' || c > 'z'))
415 return FALSE(0);
416 }
417
418 return TRUE(!(0));
419}
420
421/**
422 * c_param_spec_internal: (skip)
423 * @param_type: the #GType for the property; must be derived from %C_TYPE_PARAM
424 * @name: the canonical name of the property
425 * @nick: (nullable): the nickname of the property
426 * @blurb: (nullable): a short description of the property
427 * @flags: a combination of #CParamFlags
428 *
429 * Creates a new #CParamSpec instance.
430 *
431 * See [canonical parameter names][class@GObject.ParamSpec#parameter-names]
432 * for details of the rules for @name. Names which violate these rules lead
433 * to undefined behaviour.
434 *
435 * Beyond the name, #CParamSpecs have two more descriptive strings, the
436 * @nick and @blurb, which may be used as a localized label and description.
437 * For GTK and related libraries these are considered deprecated and may be
438 * omitted, while for other libraries such as GStreamer and its plugins they
439 * are essential. When in doubt, follow the conventions used in the
440 * surrounding code and supporting libraries.
441 *
442 * Returns: (type GObject.ParamSpec): (transfer floating): a newly allocated
443 * #CParamSpec instance, which is initially floating
444 */
445gpointer
446c_param_spec_internal (GType param_type,
447 const gchar *name,
448 const gchar *nick,
449 const gchar *blurb,
450 CParamFlags flags)
451{
452 CParamSpec *pspec;
453 CParamSpecPrivate *priv;
454
455 g_return_val_if_fail (C_TYPE_IS_PARAM (param_type) && param_type != C_TYPE_PARAM, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_85
= 0; if (((g_type_fundamental (param_type)) == ((GType) ((19
) << (2)))) && param_type != ((GType) ((19) <<
(2)))) _g_boolean_var_85 = 1; _g_boolean_var_85; }), 1))) { }
else { g_return_if_fail_warning ("libbean", ((const char*) (
__func__)), "C_TYPE_IS_PARAM (param_type) && param_type != C_TYPE_PARAM"
); return (((void*)0)); } } while (0)
;
456 g_return_val_if_fail (name != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_86
= 0; if (name != ((void*)0)) _g_boolean_var_86 = 1; _g_boolean_var_86
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "name != NULL"); return (((void*)0)
); } } while (0)
;
457 g_return_val_if_fail (c_param_spec_is_valid_name (name), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_87
= 0; if (c_param_spec_is_valid_name (name)) _g_boolean_var_87
= 1; _g_boolean_var_87; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "c_param_spec_is_valid_name (name)"
); return (((void*)0)); } } while (0)
;
458 g_return_val_if_fail (!(flags & C_PARAM_STATIC_NAME) || is_canonical (name), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_88
= 0; if (!(flags & C_PARAM_STATIC_NAME) || is_canonical (
name)) _g_boolean_var_88 = 1; _g_boolean_var_88; }), 1))) { }
else { g_return_if_fail_warning ("libbean", ((const char*) (
__func__)), "!(flags & C_PARAM_STATIC_NAME) || is_canonical (name)"
); return (((void*)0)); } } while (0)
;
459
460 pspec = (gpointer) g_type_create_instance (param_type);
461
462 if (flags & C_PARAM_STATIC_NAME)
463 {
464 /* pspec->name is not freed if (flags & C_PARAM_STATIC_NAME) */
465 pspec->name = (gchar *) g_intern_static_string (name);
466 if (!is_canonical (pspec->name))
467 g_warning ("C_PARAM_STATIC_NAME used with non-canonical pspec name: %s", pspec->name);
468 }
469 else
470 {
471 if (is_canonical (name))
472 pspec->name = (gchar *) g_intern_string (name);
473 else
474 {
475 gchar *tmp = g_strdup (name)g_strdup_inline (name);
476 canonicalize_key (tmp);
477 pspec->name = (gchar *) g_intern_string (tmp);
478 g_free (tmp);
479 }
480 }
481
482 priv = c_param_spec_get_private (pspec);
483 priv->name_quark = g_quark_from_string (pspec->name);
484
485 if (flags & C_PARAM_STATIC_NICK)
486 pspec->_nick = (gchar*) nick;
487 else
488 pspec->_nick = g_strdup (nick)g_strdup_inline (nick);
489
490 if (flags & C_PARAM_STATIC_BLURB)
491 pspec->_blurb = (gchar*) blurb;
492 else
493 pspec->_blurb = g_strdup (blurb)g_strdup_inline (blurb);
494
495 pspec->flags = (flags & C_PARAM_USER_MASK(~0U << (8))) | (flags & C_PARAM_MASK(0x000000ff));
496
497 return pspec;
498}
499
500/**
501 * c_param_spec_get_qdata:
502 * @pspec: a valid #CParamSpec
503 * @quark: a #GQuark, naming the user data pointer
504 *
505 * Gets back user data pointers stored via c_param_spec_set_qdata().
506 *
507 * Returns: (transfer none) (nullable): the user data pointer set, or %NULL
508 */
509gpointer
510c_param_spec_get_qdata (CParamSpec *pspec,
511 GQuark quark)
512{
513 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_89
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_89
= 1; _g_boolean_var_89; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return (((void*)0)); } } while (0)
;
514
515 return quark ? g_datalist_id_get_data (&pspec->qdata, quark) : NULL((void*)0);
516}
517
518/**
519 * c_param_spec_set_qdata:
520 * @pspec: the #CParamSpec to set store a user data pointer
521 * @quark: a #GQuark, naming the user data pointer
522 * @data: (nullable): an opaque user data pointer
523 *
524 * Sets an opaque, named pointer on a #CParamSpec. The name is
525 * specified through a #GQuark (retrieved e.g. via
526 * g_quark_from_static_string()), and the pointer can be gotten back
527 * from the @pspec with c_param_spec_get_qdata(). Setting a
528 * previously set user data pointer, overrides (frees) the old pointer
529 * set, using %NULL as pointer essentially removes the data stored.
530 */
531void
532c_param_spec_set_qdata (CParamSpec *pspec,
533 GQuark quark,
534 gpointer data)
535{
536 g_return_if_fail (C_IS_PARAM_SPEC (pspec))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_90
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_90
= 1; _g_boolean_var_90; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return; } } while (0)
;
537 g_return_if_fail (quark > 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_91
= 0; if (quark > 0) _g_boolean_var_91 = 1; _g_boolean_var_91
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "quark > 0"); return; } } while (
0)
;
538
539 g_datalist_id_set_data (&pspec->qdata, quark, data)g_datalist_id_set_data_full ((&pspec->qdata), (quark),
(data), ((void*)0))
;
540}
541
542/**
543 * c_param_spec_set_qdata_full: (skip)
544 * @pspec: the #CParamSpec to set store a user data pointer
545 * @quark: a #GQuark, naming the user data pointer
546 * @data: (nullable): an opaque user data pointer
547 * @destroy: (nullable): function to invoke with @data as argument, when @data needs to
548 * be freed
549 *
550 * This function works like c_param_spec_set_qdata(), but in addition,
551 * a `void (*destroy) (gpointer)` function may be
552 * specified which is called with @data as argument when the @pspec is
553 * finalized, or the data is being overwritten by a call to
554 * c_param_spec_set_qdata() with the same @quark.
555 */
556void
557c_param_spec_set_qdata_full (CParamSpec *pspec,
558 GQuark quark,
559 gpointer data,
560 GDestroyNotify destroy)
561{
562 g_return_if_fail (C_IS_PARAM_SPEC (pspec))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_92
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_92
= 1; _g_boolean_var_92; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return; } } while (0)
;
563 g_return_if_fail (quark > 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_93
= 0; if (quark > 0) _g_boolean_var_93 = 1; _g_boolean_var_93
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "quark > 0"); return; } } while (
0)
;
564
565 g_datalist_id_set_data_full (&pspec->qdata, quark, data, data ? destroy : (GDestroyNotify) NULL((void*)0));
566}
567
568/**
569 * c_param_spec_steal_qdata:
570 * @pspec: the #CParamSpec to get a stored user data pointer from
571 * @quark: a #GQuark, naming the user data pointer
572 *
573 * Gets back user data pointers stored via c_param_spec_set_qdata()
574 * and removes the @data from @pspec without invoking its destroy()
575 * function (if any was set). Usually, calling this function is only
576 * required to update user data pointers with a destroy notifier.
577 *
578 * Returns: (transfer none) (nullable): the user data pointer set, or %NULL
579 */
580gpointer
581c_param_spec_steal_qdata (CParamSpec *pspec,
582 GQuark quark)
583{
584 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_94
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_94
= 1; _g_boolean_var_94; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return (((void*)0)); } } while (0)
;
585 g_return_val_if_fail (quark > 0, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_95
= 0; if (quark > 0) _g_boolean_var_95 = 1; _g_boolean_var_95
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "quark > 0"); return (((void*)0)
); } } while (0)
;
586
587 return g_datalist_id_remove_no_notify (&pspec->qdata, quark);
588}
589
590/**
591 * c_param_spec_get_redirect_target:
592 * @pspec: a #CParamSpec
593 *
594 * If the paramspec redirects operations to another paramspec,
595 * returns that paramspec. Redirect is used typically for
596 * providing a new implementation of a property in a derived
597 * type while preserving all the properties from the parent
598 * type. Redirection is established by creating a property
599 * of type #CParamSpecOverride. See g_object_class_override_property()
600 * for an example of the use of this capability.
601 *
602 * Since: 2.4
603 *
604 * Returns: (transfer none) (nullable): paramspec to which requests on this
605 * paramspec should be redirected, or %NULL if none.
606 */
607CParamSpec*
608c_param_spec_get_redirect_target (CParamSpec *pspec)
609{
610 GTypeInstance *inst = (GTypeInstance *)pspec;
611
612 if (inst && inst->g_class && inst->g_class->g_type == C_TYPE_PARAM_OVERRIDE(c_param_spec_types[20]))
613 return ((CParamSpecOverride*)pspec)->overridden;
614 else
615 return NULL((void*)0);
616}
617
618/**
619 * c_param_value_set_default:
620 * @pspec: a valid #CParamSpec
621 * @value: a #GValue of correct type for @pspec; since 2.64, you
622 * can also pass an empty #GValue, initialized with %G_VALUE_INIT
623 *
624 * Sets @value to its default value as specified in @pspec.
625 */
626void
627c_param_value_set_default (CParamSpec *pspec,
628 GValue *value)
629{
630 g_return_if_fail (C_IS_PARAM_SPEC (pspec))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_96
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_96
= 1; _g_boolean_var_96; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return; } } while (0)
;
631
632 if (G_VALUE_TYPE (value)(((GValue*) (value))->g_type) == G_TYPE_INVALID((GType) ((0) << (2))))
633 {
634 g_value_init (value, C_PARAM_SPEC_VALUE_TYPE (pspec)(((((CParamSpec*) (void *) ((pspec)))))->value_type));
635 }
636 else
637 {
638 g_return_if_fail (G_IS_VALUE (value))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_97
= 0; if ((((g_type_check_value ((GValue*) (value)))))) _g_boolean_var_97
= 1; _g_boolean_var_97; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "G_IS_VALUE (value)"
); return; } } while (0)
;
639 g_return_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_98
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value)); GType __t = ((((((CParamSpec*) (void *) ((pspec
)))))->value_type)); gboolean __r; if (!__val) __r = (0); else
if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds
(__val, __t); __r; }))))) _g_boolean_var_98 = 1; _g_boolean_var_98
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "PSPEC_APPLIES_TO_VALUE (pspec, value)"
); return; } } while (0)
;
640 g_value_reset (value);
641 }
642
643 C_PARAM_SPEC_GET_CLASS (pspec)((((CParamSpecClass*) (((GTypeInstance*) ((pspec)))->g_class
))))
->value_set_default (pspec, value);
644}
645
646/**
647 * c_param_value_defaults:
648 * @pspec: a valid #CParamSpec
649 * @value: a #GValue of correct type for @pspec
650 *
651 * Checks whether @value contains the default value as specified in @pspec.
652 *
653 * Returns: whether @value contains the canonical default for this @pspec
654 */
655gboolean
656c_param_value_defaults (CParamSpec *pspec,
657 const GValue *value)
658{
659 GValue dflt_value = G_VALUE_INIT{ 0, { { 0 } } };
660 gboolean defaults;
661
662 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_99
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_99
= 1; _g_boolean_var_99; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return ((0)); } } while (0)
;
663 g_return_val_if_fail (G_IS_VALUE (value), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_100
= 0; if ((((g_type_check_value ((GValue*) (value)))))) _g_boolean_var_100
= 1; _g_boolean_var_100; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "G_IS_VALUE (value)"
); return ((0)); } } while (0)
;
664 g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_101
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value)); GType __t = ((((((CParamSpec*) (void *) ((pspec
)))))->value_type)); gboolean __r; if (!__val) __r = (0); else
if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds
(__val, __t); __r; }))))) _g_boolean_var_101 = 1; _g_boolean_var_101
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "PSPEC_APPLIES_TO_VALUE (pspec, value)"
); return ((0)); } } while (0)
;
665
666 g_value_init (&dflt_value, C_PARAM_SPEC_VALUE_TYPE (pspec)(((((CParamSpec*) (void *) ((pspec)))))->value_type));
667 C_PARAM_SPEC_GET_CLASS (pspec)((((CParamSpecClass*) (((GTypeInstance*) ((pspec)))->g_class
))))
->value_set_default (pspec, &dflt_value);
668 defaults = C_PARAM_SPEC_GET_CLASS (pspec)((((CParamSpecClass*) (((GTypeInstance*) ((pspec)))->g_class
))))
->values_cmp (pspec, value, &dflt_value) == 0;
669 g_value_unset (&dflt_value);
670
671 return defaults;
672}
673
674/**
675 * c_param_value_validate:
676 * @pspec: a valid #CParamSpec
677 * @value: a #GValue of correct type for @pspec
678 *
679 * Ensures that the contents of @value comply with the specifications
680 * set out by @pspec. For example, a #CParamSpecInt might require
681 * that integers stored in @value may not be smaller than -42 and not be
682 * greater than +42. If @value contains an integer outside of this range,
683 * it is modified accordingly, so the resulting value will fit into the
684 * range -42 .. +42.
685 *
686 * Returns: whether modifying @value was necessary to ensure validity
687 */
688gboolean
689c_param_value_validate (CParamSpec *pspec,
690 GValue *value)
691{
692 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_102
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_102
= 1; _g_boolean_var_102; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return ((0)); } } while (0)
;
693 g_return_val_if_fail (G_IS_VALUE (value), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_103
= 0; if ((((g_type_check_value ((GValue*) (value)))))) _g_boolean_var_103
= 1; _g_boolean_var_103; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "G_IS_VALUE (value)"
); return ((0)); } } while (0)
;
694 g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_104
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value)); GType __t = ((((((CParamSpec*) (void *) ((pspec
)))))->value_type)); gboolean __r; if (!__val) __r = (0); else
if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds
(__val, __t); __r; }))))) _g_boolean_var_104 = 1; _g_boolean_var_104
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "PSPEC_APPLIES_TO_VALUE (pspec, value)"
); return ((0)); } } while (0)
;
695
696 if (C_PARAM_SPEC_GET_CLASS (pspec)((((CParamSpecClass*) (((GTypeInstance*) ((pspec)))->g_class
))))
->value_validate)
697 {
698 GValue oval = *value;
699
700 if (C_PARAM_SPEC_GET_CLASS (pspec)((((CParamSpecClass*) (((GTypeInstance*) ((pspec)))->g_class
))))
->value_validate (pspec, value) ||
701 memcmp (&oval.data, &value->data, sizeof (oval.data)))
702 return TRUE(!(0));
703 }
704
705 return FALSE(0);
706}
707
708/**
709 * c_param_value_is_valid:
710 * @pspec: a valid #CParamSpec
711 * @value: a #GValue of correct type for @pspec
712 *
713 * Return whether the contents of @value comply with the specifications
714 * set out by @pspec.
715 *
716 * Returns: whether the contents of @value comply with the specifications
717 * set out by @pspec.
718 *
719 * Since: 2.74
720 */
721gboolean
722c_param_value_is_valid (CParamSpec *pspec,
723 const GValue *value)
724{
725 CParamSpecClass *class;
726
727 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_105
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_105
= 1; _g_boolean_var_105; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return ((!(0))); } } while (0)
;
728 g_return_val_if_fail (G_IS_VALUE (value), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_106
= 0; if ((((g_type_check_value ((GValue*) (value)))))) _g_boolean_var_106
= 1; _g_boolean_var_106; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "G_IS_VALUE (value)"
); return ((!(0))); } } while (0)
;
729 g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_107
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value)); GType __t = ((((((CParamSpec*) (void *) ((pspec
)))))->value_type)); gboolean __r; if (!__val) __r = (0); else
if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds
(__val, __t); __r; }))))) _g_boolean_var_107 = 1; _g_boolean_var_107
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "PSPEC_APPLIES_TO_VALUE (pspec, value)"
); return ((!(0))); } } while (0)
;
730
731 class = C_PARAM_SPEC_GET_CLASS (pspec)((((CParamSpecClass*) (((GTypeInstance*) ((pspec)))->g_class
))))
;
732
733 if (class->value_is_valid)
734 return class->value_is_valid (pspec, value);
735 else if (class->value_validate)
736 {
737 GValue val = G_VALUE_INIT{ 0, { { 0 } } };
738 gboolean changed;
739
740 g_value_init (&val, G_VALUE_TYPE (value)(((GValue*) (value))->g_type));
741 g_value_copy (value, &val);
742
743 changed = class->value_validate (pspec, &val);
744
745 g_value_unset (&val);
746
747 return !changed;
748 }
749
750 return TRUE(!(0));
751}
752
753/**
754 * c_param_value_convert:
755 * @pspec: a valid #CParamSpec
756 * @src_value: source #GValue
757 * @dest_value: destination #GValue of correct type for @pspec
758 * @strict_validation: %TRUE requires @dest_value to conform to @pspec
759 * without modifications
760 *
761 * Transforms @src_value into @dest_value if possible, and then
762 * validates @dest_value, in order for it to conform to @pspec. If
763 * @strict_validation is %TRUE this function will only succeed if the
764 * transformed @dest_value complied to @pspec without modifications.
765 *
766 * See also g_value_type_transformable(), g_value_transform() and
767 * c_param_value_validate().
768 *
769 * Returns: %TRUE if transformation and validation were successful,
770 * %FALSE otherwise and @dest_value is left untouched.
771 */
772gboolean
773c_param_value_convert (CParamSpec *pspec,
774 const GValue *src_value,
775 GValue *dest_value,
776 gboolean strict_validation)
777{
778 GValue tmp_value = G_VALUE_INIT{ 0, { { 0 } } };
779
780 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_108
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_108
= 1; _g_boolean_var_108; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return ((0)); } } while (0)
;
781 g_return_val_if_fail (G_IS_VALUE (src_value), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_109
= 0; if ((((g_type_check_value ((GValue*) (src_value)))))) _g_boolean_var_109
= 1; _g_boolean_var_109; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "G_IS_VALUE (src_value)"
); return ((0)); } } while (0)
;
782 g_return_val_if_fail (G_IS_VALUE (dest_value), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_110
= 0; if ((((g_type_check_value ((GValue*) (dest_value)))))) _g_boolean_var_110
= 1; _g_boolean_var_110; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "G_IS_VALUE (dest_value)"
); return ((0)); } } while (0)
;
783 g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, dest_value), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_111
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((dest_value)); GType __t = ((((((CParamSpec*) (void *) ((
pspec)))))->value_type)); gboolean __r; if (!__val) __r = (
0); else if (__val->g_type == __t) __r = (!(0)); else __r =
g_type_check_value_holds (__val, __t); __r; }))))) _g_boolean_var_111
= 1; _g_boolean_var_111; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "PSPEC_APPLIES_TO_VALUE (pspec, dest_value)"
); return ((0)); } } while (0)
;
784
785 /* better leave dest_value untouched when returning FALSE */
786
787 g_value_init (&tmp_value, G_VALUE_TYPE (dest_value)(((GValue*) (dest_value))->g_type));
788 if (g_value_transform (src_value, &tmp_value) &&
789 (!c_param_value_validate (pspec, &tmp_value) || !strict_validation))
790 {
791 g_value_unset (dest_value);
792
793 /* values are relocatable */
794 memcpy (dest_value, &tmp_value, sizeof (tmp_value));
795
796 return TRUE(!(0));
797 }
798 else
799 {
800 g_value_unset (&tmp_value);
801
802 return FALSE(0);
803 }
804}
805
806/**
807 * c_param_values_cmp:
808 * @pspec: a valid #CParamSpec
809 * @value1: a #GValue of correct type for @pspec
810 * @value2: a #GValue of correct type for @pspec
811 *
812 * Compares @value1 with @value2 according to @pspec, and return -1, 0 or +1,
813 * if @value1 is found to be less than, equal to or greater than @value2,
814 * respectively.
815 *
816 * Returns: -1, 0 or +1, for a less than, equal to or greater than result
817 */
818gint
819c_param_values_cmp (CParamSpec *pspec,
820 const GValue *value1,
821 const GValue *value2)
822{
823 gint cmp;
824
825 /* param_values_cmp() effectively does: value1 - value2
826 * so the return values are:
827 * -1) value1 < value2
828 * 0) value1 == value2
829 * 1) value1 > value2
830 */
831 g_return_val_if_fail (C_IS_PARAM_SPEC (pspec), 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_112
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((pspec)), (((GType) ((19) << (2))))))))) _g_boolean_var_112
= 1; _g_boolean_var_112; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (pspec)"
); return (0); } } while (0)
;
832 g_return_val_if_fail (G_IS_VALUE (value1), 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_113
= 0; if ((((g_type_check_value ((GValue*) (value1)))))) _g_boolean_var_113
= 1; _g_boolean_var_113; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "G_IS_VALUE (value1)"
); return (0); } } while (0)
;
833 g_return_val_if_fail (G_IS_VALUE (value2), 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_114
= 0; if ((((g_type_check_value ((GValue*) (value2)))))) _g_boolean_var_114
= 1; _g_boolean_var_114; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "G_IS_VALUE (value2)"
); return (0); } } while (0)
;
834 g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value1), 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_115
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value1)); GType __t = ((((((CParamSpec*) (void *) ((pspec
)))))->value_type)); gboolean __r; if (!__val) __r = (0); else
if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds
(__val, __t); __r; }))))) _g_boolean_var_115 = 1; _g_boolean_var_115
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "PSPEC_APPLIES_TO_VALUE (pspec, value1)"
); return (0); } } while (0)
;
835 g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value2), 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_116
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value2)); GType __t = ((((((CParamSpec*) (void *) ((pspec
)))))->value_type)); gboolean __r; if (!__val) __r = (0); else
if (__val->g_type == __t) __r = (!(0)); else __r = g_type_check_value_holds
(__val, __t); __r; }))))) _g_boolean_var_116 = 1; _g_boolean_var_116
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "PSPEC_APPLIES_TO_VALUE (pspec, value2)"
); return (0); } } while (0)
;
836
837 cmp = C_PARAM_SPEC_GET_CLASS (pspec)((((CParamSpecClass*) (((GTypeInstance*) ((pspec)))->g_class
))))
->values_cmp (pspec, value1, value2);
838
839 return CLAMP (cmp, -1, 1)(((cmp) > (1)) ? (1) : (((cmp) < (-1)) ? (-1) : (cmp)));
840}
841
842static void
843value_param_init (GValue *value)
844{
845 value->data[0].v_pointer = NULL((void*)0);
846}
847
848static void
849value_param_free_value (GValue *value)
850{
851 if (value->data[0].v_pointer)
852 c_param_spec_unref (value->data[0].v_pointer);
853}
854
855static void
856value_param_copy_value (const GValue *src_value,
857 GValue *dest_value)
858{
859 if (src_value->data[0].v_pointer)
860 dest_value->data[0].v_pointer = c_param_spec_ref (src_value->data[0].v_pointer);
861 else
862 dest_value->data[0].v_pointer = NULL((void*)0);
863}
864
865static void
866value_param_transform_value (const GValue *src_value,
867 GValue *dest_value)
868{
869 if (src_value->data[0].v_pointer &&
870 g_type_is_a (C_PARAM_SPEC_TYPE (dest_value->data[0].v_pointer), G_VALUE_TYPE (dest_value))(((((((GTypeClass*) (((GTypeInstance*) (dest_value->data[0
].v_pointer))->g_class))->g_type)))) == ((((GValue*) (dest_value
))->g_type)) || (g_type_is_a) (((((((GTypeClass*) (((GTypeInstance
*) (dest_value->data[0].v_pointer))->g_class))->g_type
)))), ((((GValue*) (dest_value))->g_type))))
)
871 dest_value->data[0].v_pointer = c_param_spec_ref (src_value->data[0].v_pointer);
872 else
873 dest_value->data[0].v_pointer = NULL((void*)0);
874}
875
876static gpointer
877value_param_peek_pointer (const GValue *value)
878{
879 return value->data[0].v_pointer;
880}
881
882static gchar*
883value_param_collect_value (GValue *value,
884 guint n_collect_values,
885 GTypeCValue *collect_values,
886 guint collect_flags)
887{
888 if (collect_values[0].v_pointer)
889 {
890 CParamSpec *param = collect_values[0].v_pointer;
891
892 if (param->g_type_instance.g_class == NULL((void*)0))
893 return g_strconcat ("invalid unclassed param spec pointer for value type '",
894 G_VALUE_TYPE_NAME (value)(g_type_name ((((GValue*) (value))->g_type))),
895 "'",
896 NULL((void*)0));
897 else if (!g_value_type_compatible (C_PARAM_SPEC_TYPE (param)(((((GTypeClass*) (((GTypeInstance*) (param))->g_class))->
g_type)))
, G_VALUE_TYPE (value)(((GValue*) (value))->g_type)))
898 return g_strconcat ("invalid param spec type '",
899 C_PARAM_SPEC_TYPE_NAME (param)(g_type_name ((((((GTypeClass*) (((GTypeInstance*) (param))->
g_class))->g_type)))))
,
900 "' for value type '",
901 G_VALUE_TYPE_NAME (value)(g_type_name ((((GValue*) (value))->g_type))),
902 "'",
903 NULL((void*)0));
904 value->data[0].v_pointer = c_param_spec_ref (param);
905 }
906 else
907 value->data[0].v_pointer = NULL((void*)0);
908
909 return NULL((void*)0);
910}
911
912static gchar*
913value_param_lcopy_value (const GValue *value,
914 guint n_collect_values,
915 GTypeCValue *collect_values,
916 guint collect_flags)
917{
918 CParamSpec **param_p = collect_values[0].v_pointer;
919
920 g_return_val_if_fail (param_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value)))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_117
= 0; if (param_p != ((void*)0)) _g_boolean_var_117 = 1; _g_boolean_var_117
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "param_p != NULL"); return (g_strdup_printf
("value location for '%s' passed as NULL", (g_type_name ((((
GValue*) (value))->g_type))))); } } while (0)
;
921
922 if (!value->data[0].v_pointer)
923 *param_p = NULL((void*)0);
924 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS(1 << 27))
925 *param_p = value->data[0].v_pointer;
926 else
927 *param_p = c_param_spec_ref (value->data[0].v_pointer);
928
929 return NULL((void*)0);
930}
931
932
933/* --- param spec pool --- */
934/**
935 * CParamSpecPool:
936 *
937 * A #CParamSpecPool maintains a collection of #CParamSpecs which can be
938 * quickly accessed by owner and name.
939 *
940 * The implementation of the #GObject property system uses such a pool to
941 * store the #CParamSpecs of the properties all object types.
942 */
943struct _CParamSpecPool
944{
945 GMutex mutex;
946 gboolean type_prefixing;
947 GHashTable *hash_table;
948};
949
950static guint
951param_spec_pool_hash (gconstpointer key_spec)
952{
953 const CParamSpec *key = key_spec;
954 const gchar *p;
955 guint h = (guint) key->owner_type;
956
957 for (p = key->name; *p; p++)
958 h = (h << 5) - h + *p;
959
960 return h;
961}
962
963static gboolean
964param_spec_pool_equals (gconstpointer key_spec_1,
965 gconstpointer key_spec_2)
966{
967 const CParamSpec *key1 = key_spec_1;
968 const CParamSpec *key2 = key_spec_2;
969
970 return (key1->owner_type == key2->owner_type &&
971 (key1->name == key2->name ||
972 strcmp (key1->name, key2->name) == 0));
973}
974
975/**
976 * c_param_spec_pool_new:
977 * @type_prefixing: Whether the pool will support type-prefixed property names.
978 *
979 * Creates a new #CParamSpecPool.
980 *
981 * If @type_prefixing is %TRUE, lookups in the newly created pool will
982 * allow to specify the owner as a colon-separated prefix of the
983 * property name, like "GtkContainer:border-width". This feature is
984 * deprecated, so you should always set @type_prefixing to %FALSE.
985 *
986 * Returns: (transfer full): a newly allocated #CParamSpecPool.
987 */
988CParamSpecPool*
989c_param_spec_pool_new (gboolean type_prefixing)
990{
991 static GMutex init_mutex;
992 CParamSpecPool *pool = g_new (CParamSpecPool, 1)(CParamSpecPool *) (__extension__ ({ gsize __n = (gsize) (1);
gsize __s = sizeof (CParamSpecPool); gpointer __p; if (__s ==
1) __p = g_malloc (__n); else if (__builtin_constant_p (__n)
&& (__s == 0 || __n <= (9223372036854775807L *2UL
+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n
(__n, __s); __p; }))
;
993
994 memcpy (&pool->mutex, &init_mutex, sizeof (init_mutex));
995 pool->type_prefixing = type_prefixing != FALSE(0);
996 pool->hash_table = g_hash_table_new_full (param_spec_pool_hash,
997 param_spec_pool_equals,
998 (GDestroyNotify) c_param_spec_unref,
999 NULL((void*)0));
1000
1001 return pool;
1002}
1003
1004/**
1005 * c_param_spec_pool_free:
1006 * @pool: (transfer full): a #CParamSpecPool
1007 *
1008 * Frees the resources allocated by a #CParamSpecPool.
1009 *
1010 * Since: 2.80
1011 */
1012void
1013c_param_spec_pool_free (CParamSpecPool *pool)
1014{
1015 g_mutex_lock (&pool->mutex);
1016 g_hash_table_unref (pool->hash_table);
1017 g_mutex_unlock (&pool->mutex);
1018 g_mutex_clear (&pool->mutex);
1019 g_free (pool);
1020}
1021
1022/**
1023 * c_param_spec_pool_insert:
1024 * @pool: a #CParamSpecPool.
1025 * @pspec: (transfer none) (not nullable): the #CParamSpec to insert
1026 * @owner_type: a #GType identifying the owner of @pspec
1027 *
1028 * Inserts a #CParamSpec in the pool.
1029 */
1030void
1031c_param_spec_pool_insert (CParamSpecPool *pool,
1032 CParamSpec *pspec,
1033 GType owner_type)
1034{
1035 const gchar *p;
1036
1037 if (pool && pspec && owner_type > 0 && pspec->owner_type == 0)
1038 {
1039 for (p = pspec->name; *p; p++)
1040 {
1041 if (!strchr (G_CSET_A_2_Z"ABCDEFGHIJKLMNOPQRSTUVWXYZ" G_CSET_a_2_z"abcdefghijklmnopqrstuvwxyz" G_CSET_DIGITS"0123456789" "-_", *p))
1042 {
1043 g_critical (G_STRLOC"../libbean/cparam.c" ":" "1043" ": pspec name \"%s\" contains invalid characters", pspec->name);
1044 return;
1045 }
1046 }
1047 g_mutex_lock (&pool->mutex);
1048 pspec->owner_type = owner_type;
1049 c_param_spec_ref (pspec);
1050 g_hash_table_add (pool->hash_table, pspec);
1051 g_mutex_unlock (&pool->mutex);
1052 }
1053 else
1054 {
1055 g_return_if_fail (pool != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_118
= 0; if (pool != ((void*)0)) _g_boolean_var_118 = 1; _g_boolean_var_118
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "pool != NULL"); return; } } while (
0)
;
1056 g_return_if_fail (pspec)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_119
= 0; if (pspec) _g_boolean_var_119 = 1; _g_boolean_var_119; }
), 1))) { } else { g_return_if_fail_warning ("libbean", ((const
char*) (__func__)), "pspec"); return; } } while (0)
;
1057 g_return_if_fail (owner_type > 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_120
= 0; if (owner_type > 0) _g_boolean_var_120 = 1; _g_boolean_var_120
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "owner_type > 0"); return; } } while
(0)
;
1058 g_return_if_fail (pspec->owner_type == 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_121
= 0; if (pspec->owner_type == 0) _g_boolean_var_121 = 1; _g_boolean_var_121
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "pspec->owner_type == 0"); return
; } } while (0)
;
1059 }
1060}
1061
1062/**
1063 * c_param_spec_pool_remove:
1064 * @pool: a #CParamSpecPool
1065 * @pspec: (transfer none) (not nullable): the #CParamSpec to remove
1066 *
1067 * Removes a #CParamSpec from the pool.
1068 */
1069void
1070c_param_spec_pool_remove (CParamSpecPool *pool,
1071 CParamSpec *pspec)
1072{
1073 if (pool && pspec)
1074 {
1075 g_mutex_lock (&pool->mutex);
1076 if (!g_hash_table_remove (pool->hash_table, pspec))
1077 g_critical (G_STRLOC"../libbean/cparam.c" ":" "1077" ": attempt to remove unknown pspec '%s' from pool", pspec->name);
1078 g_mutex_unlock (&pool->mutex);
1079 }
1080 else
1081 {
1082 g_return_if_fail (pool != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_122
= 0; if (pool != ((void*)0)) _g_boolean_var_122 = 1; _g_boolean_var_122
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "pool != NULL"); return; } } while (
0)
;
1083 g_return_if_fail (pspec)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_123
= 0; if (pspec) _g_boolean_var_123 = 1; _g_boolean_var_123; }
), 1))) { } else { g_return_if_fail_warning ("libbean", ((const
char*) (__func__)), "pspec"); return; } } while (0)
;
1084 }
1085}
1086
1087static inline CParamSpec*
1088param_spec_ht_lookup (GHashTable *hash_table,
1089 const gchar *param_name,
1090 GType owner_type,
1091 gboolean walk_ancestors)
1092{
1093 CParamSpec key, *pspec;
1094
1095 key.owner_type = owner_type;
1096 key.name = (gchar*) param_name;
1097 if (walk_ancestors)
1098 do
1099 {
1100 pspec = g_hash_table_lookup (hash_table, &key);
1101 if (pspec)
1102 return pspec;
1103 key.owner_type = g_type_parent (key.owner_type);
1104 }
1105 while (key.owner_type);
1106 else
1107 pspec = g_hash_table_lookup (hash_table, &key);
1108
1109 if (!pspec && !is_canonical (param_name))
1110 {
1111 gchar *canonical;
1112
1113 canonical = g_strdup (key.name)g_strdup_inline (key.name);
1114 canonicalize_key (canonical);
1115
1116 /* try canonicalized form */
1117 key.name = canonical;
1118 key.owner_type = owner_type;
1119
1120 if (walk_ancestors)
1121 do
1122 {
1123 pspec = g_hash_table_lookup (hash_table, &key);
1124 if (pspec)
1125 {
1126 g_free (canonical);
1127 return pspec;
1128 }
1129 key.owner_type = g_type_parent (key.owner_type);
1130 }
1131 while (key.owner_type);
1132 else
1133 pspec = g_hash_table_lookup (hash_table, &key);
1134
1135 g_free (canonical);
1136 }
1137
1138 return pspec;
1139}
1140
1141/**
1142 * c_param_spec_pool_lookup:
1143 * @pool: a #CParamSpecPool
1144 * @param_name: the name to look for
1145 * @owner_type: the owner to look for
1146 * @walk_ancestors: If %TRUE, also try to find a #CParamSpec with @param_name
1147 * owned by an ancestor of @owner_type.
1148 *
1149 * Looks up a #CParamSpec in the pool.
1150 *
1151 * Returns: (transfer none) (nullable): The found #CParamSpec, or %NULL if no
1152 * matching #CParamSpec was found.
1153 */
1154CParamSpec*
1155c_param_spec_pool_lookup (CParamSpecPool *pool,
1156 const gchar *param_name,
1157 GType owner_type,
1158 gboolean walk_ancestors)
1159{
1160 CParamSpec *pspec;
1161
1162 g_return_val_if_fail (pool != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_124
= 0; if (pool != ((void*)0)) _g_boolean_var_124 = 1; _g_boolean_var_124
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "pool != NULL"); return (((void*)0)
); } } while (0)
;
1163 g_return_val_if_fail (param_name != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_125
= 0; if (param_name != ((void*)0)) _g_boolean_var_125 = 1; _g_boolean_var_125
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "param_name != NULL"); return (((void
*)0)); } } while (0)
;
1164
1165 g_mutex_lock (&pool->mutex);
1166
1167 /* try quick and away, i.e. without prefix */
1168 pspec = param_spec_ht_lookup (pool->hash_table, param_name, owner_type, walk_ancestors);
1169 if (pspec)
1170 {
1171 g_mutex_unlock (&pool->mutex);
1172 return pspec;
1173 }
1174
1175 if (pool->type_prefixing)
1176 {
1177 char *delim;
1178
1179 delim = strchr (param_name, ':');
1180
1181 /* strip type prefix */
1182 if (delim && delim[1] == ':')
1183 {
1184 guint l = delim - param_name;
1185 gchar stack_buffer[32], *buffer = l < 32 ? stack_buffer : g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
1186 GType type;
1187
1188 strncpy (buffer, param_name, delim - param_name);
1189 buffer[l] = 0;
1190 type = g_type_from_name (buffer);
1191 if (l >= 32)
1192 g_free (buffer);
1193 if (type) /* type==0 isn't a valid type pefix */
1194 {
1195 /* sanity check, these cases don't make a whole lot of sense */
1196 if ((!walk_ancestors && type != owner_type) || !g_type_is_a (owner_type, type)((owner_type) == (type) || (g_type_is_a) ((owner_type), (type
)))
)
1197 {
1198 g_mutex_unlock (&pool->mutex);
1199
1200 return NULL((void*)0);
1201 }
1202 owner_type = type;
1203 param_name += l + 2;
1204 pspec = param_spec_ht_lookup (pool->hash_table, param_name, owner_type, walk_ancestors);
1205 g_mutex_unlock (&pool->mutex);
1206
1207 return pspec;
1208 }
1209 }
1210 }
1211
1212 /* malformed param_name */
1213
1214 g_mutex_unlock (&pool->mutex);
1215
1216 return NULL((void*)0);
1217}
1218
1219static void
1220pool_list (gpointer key,
1221 gpointer value,
1222 gpointer user_data)
1223{
1224 CParamSpec *pspec = value;
1225 gpointer *data = user_data;
1226 GType owner_type = (GType) data[1];
1227
1228 if (owner_type == pspec->owner_type)
1229 data[0] = g_list_prepend (data[0], pspec);
This statement is never executed
1230}
1231
1232/**
1233 * c_param_spec_pool_list_owned:
1234 * @pool: a #CParamSpecPool
1235 * @owner_type: the owner to look for
1236 *
1237 * Gets an #GList of all #CParamSpecs owned by @owner_type in
1238 * the pool.
1239 *
1240 * Returns: (transfer container) (element-type GObject.ParamSpec): a
1241 * #GList of all #CParamSpecs owned by @owner_type in
1242 * the pool#CParamSpecs.
1243 */
1244GList*
1245c_param_spec_pool_list_owned (CParamSpecPool *pool,
1246 GType owner_type)
1247{
1248 gpointer data[2];
1249
1250 g_return_val_if_fail (pool != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_126
= 0; if (pool != ((void*)0)) _g_boolean_var_126 = 1; _g_boolean_var_126
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "pool != NULL"); return (((void*)0)
); } } while (0)
;
1251 g_return_val_if_fail (owner_type > 0, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_127
= 0; if (owner_type > 0) _g_boolean_var_127 = 1; _g_boolean_var_127
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "owner_type > 0"); return (((void
*)0)); } } while (0)
;
1252
1253 g_mutex_lock (&pool->mutex);
1254 data[0] = NULL((void*)0);
1255 data[1] = GTYPE_TO_POINTER (owner_type)((gpointer) (guintptr) (owner_type));
1256 g_hash_table_foreach (pool->hash_table, pool_list, &data);
1257 g_mutex_unlock (&pool->mutex);
1258
1259 return data[0];
1260}
1261
1262static gint
1263pspec_compare_id (gconstpointer a,
1264 gconstpointer b)
1265{
1266 const CParamSpec *pspec1 = a, *pspec2 = b;
1267
1268 if (pspec1->param_id < pspec2->param_id)
1269 return -1;
1270
1271 if (pspec1->param_id > pspec2->param_id)
1272 return 1;
1273
1274 return strcmp (pspec1->name, pspec2->name);
1275}
1276
1277static inline gboolean
1278should_list_pspec (CParamSpec *pspec,
1279 GType owner_type,
1280 GHashTable *ht)
1281{
1282 CParamSpec *found;
1283
1284 /* Remove paramspecs that are redirected, and also paramspecs
1285 * that have are overridden by non-redirected properties.
1286 * The idea is to get the single paramspec for each name that
1287 * best corresponds to what the application sees.
1288 */
1289 if (c_param_spec_get_redirect_target (pspec))
1290 return FALSE(0);
1291
1292 found = param_spec_ht_lookup (ht, pspec->name, owner_type, TRUE(!(0)));
1293 if (found != pspec)
1294 {
1295 CParamSpec *redirect = c_param_spec_get_redirect_target (found);
1296 if (redirect != pspec)
1297 return FALSE(0);
1298 }
1299
1300 return TRUE(!(0));
1301}
1302
1303static void
1304pool_depth_list (gpointer key,
1305 gpointer value,
1306 gpointer user_data)
1307{
1308 CParamSpec *pspec = value;
1309 gpointer *data = user_data;
1310 GSList **slists = data[0];
1311 GType owner_type = (GType) data[1];
1312 GHashTable *ht = data[2];
1313 int *count = data[3];
1314
1315 if (g_type_is_a (owner_type, pspec->owner_type)((owner_type) == (pspec->owner_type) || (g_type_is_a) ((owner_type
), (pspec->owner_type)))
&&
1316 should_list_pspec (pspec, owner_type, ht))
1317 {
1318 if (G_TYPE_IS_INTERFACE (pspec->owner_type)((g_type_fundamental (pspec->owner_type)) == ((GType) ((2)
<< (2))))
)
1319 {
1320 slists[0] = g_slist_prepend (slists[0], pspec);
1321 *count = *count + 1;
1322 }
1323 else
1324 {
1325 guint d = g_type_depth (pspec->owner_type);
1326
1327 slists[d - 1] = g_slist_prepend (slists[d - 1], pspec);
1328 *count = *count + 1;
1329 }
1330 }
1331}
1332
1333/* We handle interfaces specially since we don't want to
1334 * count interface prerequisites like normal inheritance;
1335 * the property comes from the direct inheritance from
1336 * the prerequisite class, not from the interface that
1337 * prerequires it.
1338 *
1339 * Also 'depth' isn't a meaningful concept for interface
1340 * prerequisites.
1341 */
1342static void
1343pool_depth_list_for_interface (gpointer key,
1344 gpointer value,
1345 gpointer user_data)
1346{
1347 CParamSpec *pspec = value;
1348 gpointer *data = user_data;
1349 GSList **slists = data[0];
1350 GType owner_type = (GType) data[1];
1351 GHashTable *ht = data[2];
1352 int *count = data[3];
1353
1354 if (pspec->owner_type == owner_type &&
1355 should_list_pspec (pspec, owner_type, ht))
1356 {
1357 slists[0] = g_slist_prepend (slists[0], pspec);
1358 *count = *count + 1;
1359 }
1360}
1361
1362/**
1363 * c_param_spec_pool_list:
1364 * @pool: a #CParamSpecPool
1365 * @owner_type: the owner to look for
1366 * @n_pspecs_p: (out): return location for the length of the returned array
1367 *
1368 * Gets an array of all #CParamSpecs owned by @owner_type in
1369 * the pool.
1370 *
1371 * Returns: (array length=n_pspecs_p) (transfer container): a newly
1372 * allocated array containing pointers to all #CParamSpecs
1373 * owned by @owner_type in the pool
1374 */
1375CParamSpec**
1376c_param_spec_pool_list (CParamSpecPool *pool,
1377 GType owner_type,
1378 guint *n_pspecs_p)
1379{
1380 CParamSpec **pspecs, **p;
1381 GSList **slists, *node;
1382 gpointer data[4];
1383 guint d, i;
1384 int n_pspecs = 0;
1385
1386 g_return_val_if_fail (pool != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_128
= 0; if (pool != ((void*)0)) _g_boolean_var_128 = 1; _g_boolean_var_128
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "pool != NULL"); return (((void*)0)
); } } while (0)
;
1387 g_return_val_if_fail (owner_type > 0, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_129
= 0; if (owner_type > 0) _g_boolean_var_129 = 1; _g_boolean_var_129
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "owner_type > 0"); return (((void
*)0)); } } while (0)
;
1388 g_return_val_if_fail (n_pspecs_p != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_130
= 0; if (n_pspecs_p != ((void*)0)) _g_boolean_var_130 = 1; _g_boolean_var_130
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "n_pspecs_p != NULL"); return (((void
*)0)); } } while (0)
;
1389
1390 g_mutex_lock (&pool->mutex);
1391 d = g_type_depth (owner_type);
1392 slists = g_new0 (GSList*, d)(GSList* *) (__extension__ ({ gsize __n = (gsize) (d); gsize __s
= sizeof (GSList*); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
1393 data[0] = slists;
1394 data[1] = GTYPE_TO_POINTER (owner_type)((gpointer) (guintptr) (owner_type));
1395 data[2] = pool->hash_table;
1396 data[3] = &n_pspecs;
1397
1398 g_hash_table_foreach (pool->hash_table,
1399 G_TYPE_IS_INTERFACE (owner_type)((g_type_fundamental (owner_type)) == ((GType) ((2) << (
2))))
?
1400 pool_depth_list_for_interface :
1401 pool_depth_list,
1402 &data);
1403
1404 pspecs = g_new (CParamSpec*, n_pspecs + 1)(CParamSpec* *) (__extension__ ({ gsize __n = (gsize) (n_pspecs
+ 1); gsize __s = sizeof (CParamSpec*); gpointer __p; if (__s
== 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n
) && (__s == 0 || __n <= (9223372036854775807L *2UL
+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n
(__n, __s); __p; }))
;
1405 p = pspecs;
1406 for (i = 0; i < d; i++)
1407 {
1408 slists[i] = g_slist_sort (slists[i], pspec_compare_id);
1409 for (node = slists[i]; node; node = node->next)
1410 *p++ = node->data;
1411 g_slist_free (slists[i]);
1412 }
1413 *p++ = NULL((void*)0);
1414 g_free (slists);
1415 g_mutex_unlock (&pool->mutex);
1416
1417 *n_pspecs_p = n_pspecs;
1418
1419 return pspecs;
1420}
1421
1422/* --- auxiliary functions --- */
1423typedef struct
1424{
1425 /* class portion */
1426 GType value_type;
1427 void (*finalize) (CParamSpec *pspec);
1428 void (*value_set_default) (CParamSpec *pspec,
1429 GValue *value);
1430 gboolean (*value_validate) (CParamSpec *pspec,
1431 GValue *value);
1432 gint (*values_cmp) (CParamSpec *pspec,
1433 const GValue *value1,
1434 const GValue *value2);
1435} ParamSpecClassInfo;
1436
1437static void
1438param_spec_generic_class_init (gpointer g_class,
1439 gpointer class_data)
1440{
1441 CParamSpecClass *class = g_class;
1442 ParamSpecClassInfo *info = class_data;
1443
1444 class->value_type = info->value_type;
1445 if (info->finalize)
1446 class->finalize = info->finalize; /* optional */
1447 class->value_set_default = info->value_set_default;
1448 if (info->value_validate)
1449 class->value_validate = info->value_validate; /* optional */
1450 class->values_cmp = info->values_cmp;
1451 g_free (class_data);
1452}
1453
1454static void
1455default_value_set_default (CParamSpec *pspec,
1456 GValue *value)
1457{
1458 /* value is already zero initialized */
1459}
1460
1461static gint
1462default_values_cmp (CParamSpec *pspec,
1463 const GValue *value1,
1464 const GValue *value2)
1465{
1466 return memcmp (&value1->data, &value2->data, sizeof (value1->data));
1467}
1468
1469/**
1470 * c_param_type_register_static:
1471 * @name: 0-terminated string used as the name of the new #CParamSpec type.
1472 * @pspec_info: The #CParamSpecTypeInfo for this #CParamSpec type.
1473 *
1474 * Registers @name as the name of a new static type derived
1475 * from %C_TYPE_PARAM.
1476 *
1477 * The type system uses the information contained in the #CParamSpecTypeInfo
1478 * structure pointed to by @info to manage the #CParamSpec type and its
1479 * instances.
1480 *
1481 * Returns: The new type identifier.
1482 */
1483GType
1484c_param_type_register_static (const gchar *name,
1485 const CParamSpecTypeInfo *pspec_info)
1486{
1487 GTypeInfo info = {
1488 sizeof (CParamSpecClass), /* class_size */
1489 NULL((void*)0), /* base_init */
1490 NULL((void*)0), /* base_destroy */
1491 param_spec_generic_class_init, /* class_init */
1492 NULL((void*)0), /* class_destroy */
1493 NULL((void*)0), /* class_data */
1494 0, /* instance_size */
1495 16, /* n_preallocs */
1496 NULL((void*)0), /* instance_init */
1497 NULL((void*)0), /* value_table */
1498 };
1499 ParamSpecClassInfo *cinfo;
1500
1501 g_return_val_if_fail (name != NULL, 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_131
= 0; if (name != ((void*)0)) _g_boolean_var_131 = 1; _g_boolean_var_131
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "name != NULL"); return (0); } } while
(0)
;
1502 g_return_val_if_fail (pspec_info != NULL, 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_132
= 0; if (pspec_info != ((void*)0)) _g_boolean_var_132 = 1; _g_boolean_var_132
; }), 1))) { } else { g_return_if_fail_warning ("libbean", ((
const char*) (__func__)), "pspec_info != NULL"); return (0); }
} while (0)
;
1503 g_return_val_if_fail (g_type_from_name (name) == 0, 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_133
= 0; if (g_type_from_name (name) == 0) _g_boolean_var_133 = 1
; _g_boolean_var_133; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "g_type_from_name (name) == 0"
); return (0); } } while (0)
;
1504 g_return_val_if_fail (pspec_info->instance_size >= sizeof (CParamSpec), 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_134
= 0; if (pspec_info->instance_size >= sizeof (CParamSpec
)) _g_boolean_var_134 = 1; _g_boolean_var_134; }), 1))) { } else
{ g_return_if_fail_warning ("libbean", ((const char*) (__func__
)), "pspec_info->instance_size >= sizeof (CParamSpec)")
; return (0); } } while (0)
;
1505 g_return_val_if_fail (g_type_name (pspec_info->value_type) != NULL, 0)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_135
= 0; if (g_type_name (pspec_info->value_type) != ((void*)
0)) _g_boolean_var_135 = 1; _g_boolean_var_135; }), 1))) { } else
{ g_return_if_fail_warning ("libbean", ((const char*) (__func__
)), "g_type_name (pspec_info->value_type) != NULL"); return
(0); } } while (0)
;
1506 /* default: g_return_val_if_fail (pspec_info->value_set_default != NULL, 0); */
1507 /* optional: g_return_val_if_fail (pspec_info->value_validate != NULL, 0); */
1508 /* default: g_return_val_if_fail (pspec_info->values_cmp != NULL, 0); */
1509
1510 info.instance_size = pspec_info->instance_size;
1511 info.n_preallocs = pspec_info->n_preallocs;
1512 info.instance_init = (GInstanceInitFunc) pspec_info->instance_init;
1513 cinfo = g_new (ParamSpecClassInfo, 1)(ParamSpecClassInfo *) (__extension__ ({ gsize __n = (gsize) (
1); gsize __s = sizeof (ParamSpecClassInfo); gpointer __p; if
(__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p
(__n) && (__s == 0 || __n <= (9223372036854775807L
*2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n
(__n, __s); __p; }))
;
1514 cinfo->value_type = pspec_info->value_type;
1515 cinfo->finalize = pspec_info->finalize;
1516 cinfo->value_set_default = pspec_info->value_set_default ? pspec_info->value_set_default : default_value_set_default;
1517 cinfo->value_validate = pspec_info->value_validate;
1518 cinfo->values_cmp = pspec_info->values_cmp ? pspec_info->values_cmp : default_values_cmp;
1519 info.class_data = cinfo;
1520
1521 return g_type_register_static (C_TYPE_PARAM((GType) ((19) << (2))), name, &info, 0);
1522}
1523
1524/**
1525 * c_value_set_param:
1526 * @value: a valid #GValue of type %C_TYPE_PARAM
1527 * @param: (nullable): the #CParamSpec to be set
1528 *
1529 * Set the contents of a %C_TYPE_PARAM #GValue to @param.
1530 */
1531void
1532c_value_set_param (GValue *value,
1533 CParamSpec *param)
1534{
1535 g_return_if_fail (C_VALUE_HOLDS_PARAM (value))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_136
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value)); GType __t = (((GType) ((19) << (2)))); gboolean
__r; if (!__val) __r = (0); else if (__val->g_type == __t
) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t
); __r; }))))) _g_boolean_var_136 = 1; _g_boolean_var_136; })
, 1))) { } else { g_return_if_fail_warning ("libbean", ((const
char*) (__func__)), "C_VALUE_HOLDS_PARAM (value)"); return; }
} while (0)
;
1536 if (param)
1537 g_return_if_fail (C_IS_PARAM_SPEC (param))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_137
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((param)), (((GType) ((19) << (2))))))))) _g_boolean_var_137
= 1; _g_boolean_var_137; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (param)"
); return; } } while (0)
;
1538
1539 if (value->data[0].v_pointer)
1540 c_param_spec_unref (value->data[0].v_pointer);
1541 value->data[0].v_pointer = param;
1542 if (value->data[0].v_pointer)
1543 c_param_spec_ref (value->data[0].v_pointer);
1544}
1545
1546/**
1547 * c_value_set_param_take_ownership: (skip)
1548 * @value: a valid #GValue of type %C_TYPE_PARAM
1549 * @param: (nullable): the #CParamSpec to be set
1550 *
1551 * This is an internal function introduced mainly for C marshallers.
1552 *
1553 * Deprecated: 2.4: Use c_value_take_param() instead.
1554 */
1555void
1556c_value_set_param_take_ownership (GValue *value,
1557 CParamSpec *param)
1558{
1559 c_value_take_param (value, param);
1560}
1561
1562/**
1563 * c_value_take_param: (skip)
1564 * @value: a valid #GValue of type %C_TYPE_PARAM
1565 * @param: (nullable): the #CParamSpec to be set
1566 *
1567 * Sets the contents of a %C_TYPE_PARAM #GValue to @param and takes
1568 * over the ownership of the caller’s reference to @param; the caller
1569 * doesn’t have to unref it any more.
1570 *
1571 * Since: 2.4
1572 */
1573void
1574c_value_take_param (GValue *value,
1575 CParamSpec *param)
1576{
1577 g_return_if_fail (C_VALUE_HOLDS_PARAM (value))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_138
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value)); GType __t = (((GType) ((19) << (2)))); gboolean
__r; if (!__val) __r = (0); else if (__val->g_type == __t
) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t
); __r; }))))) _g_boolean_var_138 = 1; _g_boolean_var_138; })
, 1))) { } else { g_return_if_fail_warning ("libbean", ((const
char*) (__func__)), "C_VALUE_HOLDS_PARAM (value)"); return; }
} while (0)
;
1578 if (param)
1579 g_return_if_fail (C_IS_PARAM_SPEC (param))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_139
= 0; if ((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((param)), (((GType) ((19) << (2))))))))) _g_boolean_var_139
= 1; _g_boolean_var_139; }), 1))) { } else { g_return_if_fail_warning
("libbean", ((const char*) (__func__)), "C_IS_PARAM_SPEC (param)"
); return; } } while (0)
;
1580
1581 if (value->data[0].v_pointer)
1582 c_param_spec_unref (value->data[0].v_pointer);
1583 value->data[0].v_pointer = param; /* we take over the reference count */
1584}
1585
1586/**
1587 * c_value_get_param:
1588 * @value: a valid #GValue whose type is derived from %C_TYPE_PARAM
1589 *
1590 * Get the contents of a %C_TYPE_PARAM #GValue.
1591 *
1592 * Returns: (transfer none): #CParamSpec content of @value
1593 */
1594CParamSpec*
1595c_value_get_param (const GValue *value)
1596{
1597 g_return_val_if_fail (C_VALUE_HOLDS_PARAM (value), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_140
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value)); GType __t = (((GType) ((19) << (2)))); gboolean
__r; if (!__val) __r = (0); else if (__val->g_type == __t
) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t
); __r; }))))) _g_boolean_var_140 = 1; _g_boolean_var_140; })
, 1))) { } else { g_return_if_fail_warning ("libbean", ((const
char*) (__func__)), "C_VALUE_HOLDS_PARAM (value)"); return (
((void*)0)); } } while (0)
;
1598
1599 return value->data[0].v_pointer;
1600}
1601
1602/**
1603 * c_value_dup_param: (skip)
1604 * @value: a valid #GValue whose type is derived from %C_TYPE_PARAM
1605 *
1606 * Get the contents of a %C_TYPE_PARAM #GValue, increasing its
1607 * reference count.
1608 *
1609 * Returns: (transfer full): #CParamSpec content of @value, should be
1610 * unreferenced when no longer needed.
1611 */
1612CParamSpec*
1613c_value_dup_param (const GValue *value)
1614{
1615 g_return_val_if_fail (C_VALUE_HOLDS_PARAM (value), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_141
= 0; if ((((__extension__ ({ const GValue *__val = (const GValue
*) ((value)); GType __t = (((GType) ((19) << (2)))); gboolean
__r; if (!__val) __r = (0); else if (__val->g_type == __t
) __r = (!(0)); else __r = g_type_check_value_holds (__val, __t
); __r; }))))) _g_boolean_var_141 = 1; _g_boolean_var_141; })
, 1))) { } else { g_return_if_fail_warning ("libbean", ((const
char*) (__func__)), "C_VALUE_HOLDS_PARAM (value)"); return (
((void*)0)); } } while (0)
;
1616
1617 return value->data[0].v_pointer ? c_param_spec_ref (value->data[0].v_pointer) : NULL((void*)0);
1618}
1619
1620/**
1621 * c_param_spec_get_default_value:
1622 * @pspec: a #CParamSpec
1623 *
1624 * Gets the default value of @pspec as a pointer to a #GValue.
1625 *
1626 * The #GValue will remain valid for the life of @pspec.
1627 *
1628 * Returns: a pointer to a #GValue which must not be modified
1629 *
1630 * Since: 2.38
1631 **/
1632const GValue *
1633c_param_spec_get_default_value (CParamSpec *pspec)
1634{
1635 CParamSpecPrivate *priv = c_param_spec_get_private (pspec);
1636
1637 /* We use the type field of the GValue as the key for the once because
1638 * it will be zero before it is initialised and non-zero after. We
1639 * have to take care that we don't write a non-zero value to the type
1640 * field before we are completely done, however, because then another
1641 * thread could come along and find the value partially-initialised.
1642 *
1643 * In order to accomplish this we store the default value in a
1644 * stack-allocated GValue. We then set the type field in that value
1645 * to zero and copy the contents into place. We then end by storing
1646 * the type as the last step in order to ensure that we're completely
1647 * done before a g_once_init_enter() could take the fast path in
1648 * another thread.
1649 */
1650 if (g_once_init_enter_pointer (&priv->default_value.g_type)(__extension__ ({ _Static_assert (sizeof *(&priv->default_value
.g_type) == sizeof (gpointer), "Expression evaluates to false"
); (void) (0 ? (gpointer) * (&priv->default_value.g_type
) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *
(&priv->default_value.g_type) == sizeof (gpointer), "Expression evaluates to false"
); __typeof__ (*(&priv->default_value.g_type)) gapg_temp_newval
; __typeof__ ((&priv->default_value.g_type)) gapg_temp_atomic
= (&priv->default_value.g_type); __atomic_load (gapg_temp_atomic
, &gapg_temp_newval, 5); gapg_temp_newval; })) &&
g_once_init_enter_pointer (&priv->default_value.g_type
)); }))
)
1651 {
1652 GValue default_value = G_VALUE_INIT{ 0, { { 0 } } };
1653
1654 g_value_init (&default_value, pspec->value_type);
1655 c_param_value_set_default (pspec, &default_value);
1656
1657 /* store all but the type */
1658 memcpy (priv->default_value.data, default_value.data, sizeof (default_value.data));
1659
1660 g_once_init_leave_pointer (&priv->default_value.g_type, pspec->value_type)(__extension__ ({ _Static_assert (sizeof *(&priv->default_value
.g_type) == sizeof (gpointer), "Expression evaluates to false"
); 0 ? (void) (*(&priv->default_value.g_type) = (pspec
->value_type)) : (void) 0; g_once_init_leave_pointer ((&
priv->default_value.g_type), (gpointer) (guintptr) (pspec->
value_type)); }))
;
1661 }
1662
1663 return &priv->default_value;
1664}
1665
1666/**
1667 * c_param_spec_get_name_quark:
1668 * @pspec: a #CParamSpec
1669 *
1670 * Gets the GQuark for the name.
1671 *
1672 * Returns: the GQuark for @pspec->name.
1673 *
1674 * Since: 2.46
1675 */
1676GQuark
1677c_param_spec_get_name_quark (CParamSpec *pspec)
1678{
1679 CParamSpecPrivate *priv = c_param_spec_get_private (pspec);
1680
1681 /* Return the quark that we've stashed away at creation time.
1682 * This lets us avoid a lock and a hash table lookup when
1683 * dispatching property change notification.
1684 */
1685
1686 return priv->name_quark;
1687}