The property strings are interned already, so this potentially allows for faster
comparisons. The property strings were already not copied, as they were tagged
as static.
This adds support to be able to explicitely stored interned strings into
G_TYPE_STRING GValue.
This is useful for cases where the user:
* *knows* the string to be stored in the GValue is canonical
* Wants to know whther the string stored is canonical
This allows:
* zero-cost GValue copy (the content is guaranteed to be unique and exist
throughout the process life)
* zero-cost string equality checks (if both string GValue are interned, you just
need to check the pointers for equality or not, instead of doing a strcmp).
Fixes#2109
The glib-mkenums program allows generating code to handle enums/flags
with very different purposes. One of its purposes could be generating
per-enum/flag methods to be exposed in a library API, and while doing
that, it would be nice to have a way to specify in which API version
the enum/flag was introduced, so that the same version could be shown
in the generated API methods.
E.g. From the following code:
/**
* QmiWmsMessageProtocol:
* @QMI_WMS_MESSAGE_PROTOCOL_CDMA: CDMA.
* @QMI_WMS_MESSAGE_PROTOCOL_WCDMA: WCDMA.
*
* Type of message protocol.
*
* Since: 1.0
*/
typedef enum { /*< since=1.0 >*/
QMI_WMS_MESSAGE_PROTOCOL_CDMA = 0x00,
QMI_WMS_MESSAGE_PROTOCOL_WCDMA = 0x01
} QmiWmsMessageProtocol;
The template would allow us to generate a method documented like this,
including the Since tag with the value given in the mkenums 'since' tag.
/**
* qmi_wms_message_protocol_get_string:
* @val: a QmiWmsMessageProtocol.
*
* Gets the nickname string for the #QmiWmsMessageProtocol specified at @val.
*
* Returns: (transfer none): a string with the nickname, or %NULL if not found. Do not free the returned value.
* Since: 1.0
*/
const gchar *qmi_wms_message_protocol_get_string (QmiWmsMessageProtocol val);
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
Meson 0.54.0 added a new method meson.override_dependency() that must be
used to ensure dependency consistency. This patch ensures a project that
depends on glib will never link to a mix of system and subproject
libraries. It would happen in such cases:
The system has glib 2.40 installed, and a project does:
dependency('glib-2.0', version: '>=2.60',
fallback: ['glib', 'glib_dep'])
dependency('gobject-2.0')
The first call will configure glib subproject because the system libglib
is too old, but the 2nd call will return system libgobject.
By overriding 'gobject-2.0' dependency while configuring glib subproject
during the first call, meson knows that on the 2nd call it must return
the subproject dependency instead of system dependency.
This also has the nice side effect that with Meson >0.54.0 an
application depending on glib can declare the fallback without knowing
the dependency variable name: dependency('glib-2.0', fallback: 'glib').
The __declspec(dllexport) attribute in itself doesn't imply
'extern' - thus any intended variable declaration with
GLIB_VAR/GOBJECT_VAR would actually be a variable definition. With
C compilers defaulting to -fcommon, this isn't an issue, but
upcoming compilers (GCC 10 and Clang 11) will default to -fno-common,
ending up with duplicate definitions of these variables.
Rename the variables involved so that people get a slightly more
obvious critical warning when they try to ref an object which has
already been finalised.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Making this validation code public allows projects to validate a
GParamSpec name before creating it. While hard-coded GParamSpec don't
need this, we can't afford crashing the main program for dynamically
generated GParamSpec from user-created data.
In such case, we will need to validate the param names and return errors
instead of trying to create a GParamSpec with invalid names.
Includes modifications from Philip Withnall and Emmanuele Bassi to
rearrange the new function addition and split it into one function for
GParamSpecs and one for GSignals.
When calling `g_set_object()` for a type derived from `GObject`, GCC 9.2
was giving the following strict aliasing warning:
```
../../source/malcontent/libmalcontent-ui/user-controls.c:1001:21: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
1001 | if (g_set_object (&self->user, user))
/opt/gnome/install/include/glib-2.0/gobject/gobject.h:744:33: note: in definition of macro ‘g_set_object’
744 | (g_set_object) ((GObject **) (object_ptr), (GObject *) (new_object)) \
| ^~~~~~~~~~
```
This was due to the `(GObject **)` cast.
Pass the pointer through a union to squash this warning. We already do
some size and type checks of the dereferenced type, which should catch
casual errors. The `g_object_ref()` and `g_object_unref()` calls which
subsequently happen inside the `g_set_object()` function also do some
dynamic type checks.
Add a test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
As with `g_variant_new()` (or any varargs function which takes integer
literals of differing widths), callers need to be careful to ensure
their integer literals have the right width.
Tweak the documentation for `g_object_new()`, `g_object_set()` and
`g_object_get()` to clarify this. The documentation for `g_object_get()`
shows that it is not subject to the same caveats, since it operates on
pointers.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #833
While we automatically define cleanup functions for the module, we don't
do it for the module class.
This will allow to manage the ownership of the class when reffing it
without having to cast it to GTypeClass.
The `G_TYPE_IS_INSTANTIATABLE()` check is redundant with a precondition
on the function.
The `g_type_class_peek()` check seems like a pointless restriction: it
should be possible to check for a signal from a class init function.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #650
Use the new g_type_interface_instantiable_prerequisite() to check
compatibility for transform functions.
In particular, this allows interfaces (in my case GDK_TYPE_PAINTABLE) to
be transformed to/from any GObject type (in my case G_TYPE_OBJECT) using
the transform function registered to tranform between any 2 objects
(g_value_object_transform_value() does a type check and uses NULL if the
types don't match).
And this in turn allows be to g_object_bind_property() a gobject-typed
generic property (GtkListItem::item) to a GtkImage::paintable.
Use the newly added g_type_interface_instantiable_prerequisite() to
allow closure return values being interfaces by looking up the
instantiable type for the interface and usings its GValue accessors.
There is (at most) a single GType that is instantiable and a
prerequisite for an interface. This function returns that type.
This type is necessary in particular when dealing with GValues because a
GValue contains an instance of a type.
The format has never previously been specified. It can be anything, but
for sanity’s sake disallow empty strings.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
It provides more useful output on failure, and isn’t compiled out when
building with `G_DISABLE_ASSERT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It provides more useful output on failure, and isn’t compiled out when
building with `G_DISABLE_ASSERT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This will allow subsequent testing of property name canonicalisation.
This test introduces no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
Rather than adding a canonicalised and non-canonicalised version of the
signal to `g_signal_key_bsa`, just add the canonicalised version. Signal
lookups always use the canonicalised key (since the previous commit).
This saves space in `g_signal_key_bsa`, which should speed up lookups;
and it saves significant space in the global `GQuark` table (a 9.6%
reduction in entries in that table, by a rough test using
gnome-software).
We have to be a little more relaxed on the signal name validation than
we are for property name validation, as GTK installs a
`-gtk-private-changed` signal which violates the signal naming rules.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Previously, we’d look up the signal name as passed to (for example)
`g_signal_lookup()`, and rely on the fact that signals are inserted
twice into `g_signal_key_bsa`; once in canonical form and once not.
In preparation for only inserting signals into `g_signal_key_bsa` once,
we now try looking up a signal with the given signal name and, if that
fails, try canonicalising the name and trying again.
This is a performance hit on lookups for non-canonical names, but
shouldn’t affect the performance of lookups for canonical names. If
people want performance, they should use canonical names.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
This eliminates a call from every call site of signal_id_lookup(). It
introduces no functional changes, but allows subsequent refactoring.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Since signal names are the same as property names, reference between the
two. Improve the formatting, and make it clearer that `_` is
discouraged.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
Interned strings are never freed, so we don’t need to take a copy of
them when returning them in a #GValue. This is a minor memory allocation
improvement, with no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Rather than interning a property name string which isn’t canonicalised,
canonicalise it first, and enforce stricter validation on inputs.
The previous code was not incorrect (since the property machinery would
have canonicalised the property names itself, internally), but would
have resulted in non-canonical property names getting into the GQuark
table unnecessarily. With the new code, the interned property names from
property installation time should be consistently reused.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
Inline with the stricter version of the property naming rules from the
documentation, tighten up the validation of property names at
installation time.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It provides more useful output on failure, and isn’t compiled out when
building with `G_DISABLE_ASSERT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The documentation says that parameter names must be alphanumeric (plus
`-` or `_`) and that canonicalisation turns `_` into `-`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
There’s no need to have the property naming documentation in two places,
with one version of it being stricter than the other. Rationalise it to
one place, link to that consistently, and settle on the stricter
version.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #358
We cannot just call
G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, &dflt_value);
without initializing the GValue first. It would call
param_string_set_default(), which would set the pointer value
to a cloned string (which later never gets released, because
the GValue is not known to hold a string).
Fixes: 6ad799ac67
Since we have the type of the GValue we're going to initialize, we can
allow passing an empty (but valid) GValue when retrieving the default
value of a GParamSpec.
This will eliminate additional checks and an unnecessary reset.