From 3c53fb8790446df9ee80eb7d3d8051d12e900b8c Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 3 Jan 2025 22:56:56 +0000 Subject: [PATCH] Move the GLib type system into libglib The type system should have never been relegated to libgobject: it's a low level API to register types at run time. Having GType inside libglib allows us to use the type system information everywhere: - generic but type safe storage data types - explicit memory management semantics for all data types - enumeration types for all flags Having the type system inside libglib also allows us to create new and better fundamental types in the future, like sum types, option types, tuples, and generic types. Moved: - gatomicarray - gboxed - genums - gtype - gtypeplugin - gvalue The move is mostly Git surgery, but given the amount of internal API surface, it results in a single commit to avoid breaking bisectability. We need to maintain `gobject/gvaluecollector.h` as a publicly installed header but, to avoid issues in case of excessive inclusions, we make it conflict with `glib/gvaluecollector.h`. See: #2370 See: https://discourse.gnome.org/t/straw-man-moving-the-gtype-api-down-to-libglib-2-0/11169 --- gio/gsocket.c | 2 +- .../gatomicarray-private.h | 7 +- {gobject => glib}/gatomicarray.c | 10 +- {gobject => glib}/gboxed.c | 31 -- {gobject => glib}/gboxed.h | 47 +-- {gobject => glib}/genums.c | 0 {gobject => glib}/genums.h | 44 +-- glib/glib-init.c | 1 + glib/glib-init.h | 1 + glib/glib-object.h | 6 - glib/glib-private.c | 3 + glib/glib-private.h | 3 + {gobject => glib}/glib-types.h | 93 +++--- glib/glib.h | 7 + glib/glib_probes.d | 2 + glib/gtype-private.h | 35 +++ {gobject => glib}/gtype.c | 272 +++++------------ {gobject => glib}/gtype.h | 195 ++++++------ {gobject => glib}/gtypeplugin.c | 2 +- {gobject => glib}/gtypeplugin.h | 16 +- {gobject => glib}/gvalue.c | 24 ++ {gobject => glib}/gvalue.h | 41 ++- glib/gvaluecollector.h | 283 ++++++++++++++++++ {gobject => glib}/gvaluetransform.c | 0 {gobject => glib}/gvaluetypes.c | 8 +- {gobject => glib}/gvaluetypes.h | 96 +++--- glib/meson.build | 19 ++ gobject/gclosure.c | 7 +- gobject/gclosure.h | 13 +- .../{gtype-private.h => gobject-private.h} | 23 +- gobject/gobject.c | 115 ++++++- gobject/gobject.h | 20 +- gobject/gobject_probes.d | 1 - gobject/gparam.c | 2 +- gobject/gparam.h | 9 +- gobject/gparamspecs.c | 2 +- gobject/gparamspecs.h | 5 +- gobject/gsignal.c | 8 +- gobject/gsignal.h | 10 +- gobject/gsourceclosure.h | 19 +- gobject/gtypemodule.c | 1 - gobject/gtypemodule.h | 1 - gobject/gvaluearray.c | 7 + gobject/gvaluearray.h | 3 +- gobject/gvaluecollector.h | 16 +- gobject/meson.build | 19 -- 46 files changed, 922 insertions(+), 607 deletions(-) rename gobject/gatomicarray.h => glib/gatomicarray-private.h (93%) rename {gobject => glib}/gatomicarray.c (96%) rename {gobject => glib}/gboxed.c (95%) rename {gobject => glib}/gboxed.h (77%) rename {gobject => glib}/genums.c (100%) rename {gobject => glib}/genums.h (94%) rename {gobject => glib}/glib-types.h (85%) create mode 100644 glib/gtype-private.h rename {gobject => glib}/gtype.c (97%) rename {gobject => glib}/gtype.h (96%) rename {gobject => glib}/gtypeplugin.c (99%) rename {gobject => glib}/gtypeplugin.h (94%) rename {gobject => glib}/gvalue.c (97%) rename {gobject => glib}/gvalue.h (89%) create mode 100644 glib/gvaluecollector.h rename {gobject => glib}/gvaluetransform.c (100%) rename {gobject => glib}/gvaluetypes.c (99%) rename {gobject => glib}/gvaluetypes.h (87%) rename gobject/{gtype-private.h => gobject-private.h} (77%) diff --git a/gio/gsocket.c b/gio/gsocket.c index 44e935263..7eef7263a 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -59,7 +59,7 @@ #endif #define GOBJECT_COMPILATION -#include "gobject/gtype-private.h" /* For _PRELUDE type define */ +#include "gobject/gobject-private.h" /* For _PRELUDE type define */ #undef GOBJECT_COMPILATION #include "gcancellable.h" #include "gdatagrambased.h" diff --git a/gobject/gatomicarray.h b/glib/gatomicarray-private.h similarity index 93% rename from gobject/gatomicarray.h rename to glib/gatomicarray-private.h index a4fdc0103..b537803fb 100644 --- a/gobject/gatomicarray.h +++ b/glib/gatomicarray-private.h @@ -19,11 +19,8 @@ #ifndef __G_ATOMIC_ARRAY_H__ #define __G_ATOMIC_ARRAY_H__ -#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) -#error "Only can be included directly." -#endif - -#include +#include +#include G_BEGIN_DECLS diff --git a/gobject/gatomicarray.c b/glib/gatomicarray.c similarity index 96% rename from gobject/gatomicarray.c rename to glib/gatomicarray.c index 57807f1d7..dd72f5dc1 100644 --- a/gobject/gatomicarray.c +++ b/glib/gatomicarray.c @@ -19,10 +19,16 @@ #include "config.h" -#include "../glib/gvalgrind.h" +#include "gvalgrind.h" #include -#include "gatomicarray.h" +#include "gatomicarray-private.h" + +#include "gmem.h" +#include "gmessages.h" +#include "gslice.h" +#include "gtestutils.h" +#include "gthread.h" /* A GAtomicArray is a growable, mutable array of data * generally of the form of a header of a specific size and diff --git a/gobject/gboxed.c b/glib/gboxed.c similarity index 95% rename from gobject/gboxed.c rename to glib/gboxed.c index 04cededa0..ac2a16a3c 100644 --- a/gobject/gboxed.c +++ b/glib/gboxed.c @@ -21,16 +21,9 @@ #include -/* for GValueArray */ -#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS -#define GLIB_DISABLE_DEPRECATION_WARNINGS -#endif - #include "gboxed.h" -#include "gclosure.h" #include "gtype-private.h" #include "gvalue.h" -#include "gvaluearray.h" #include "gvaluecollector.h" static inline void /* keep this function in sync with gvalue.c */ @@ -41,27 +34,6 @@ value_meminit (GValue *value, memset (value->data, 0, sizeof (value->data)); } -static GValue * -value_copy (GValue *src_value) -{ - GValue *dest_value = g_new0 (GValue, 1); - - if (G_VALUE_TYPE (src_value)) - { - g_value_init (dest_value, G_VALUE_TYPE (src_value)); - g_value_copy (src_value, dest_value); - } - return dest_value; -} - -static void -value_free (GValue *value) -{ - if (G_VALUE_TYPE (value)) - g_value_unset (value); - g_free (value); -} - static GPollFD * pollfd_copy (GPollFD *src) { @@ -108,9 +80,6 @@ gstring_free (GString *gstring) g_string_free (gstring, TRUE); } -G_DEFINE_BOXED_TYPE (GClosure, g_closure, g_closure_ref, g_closure_unref) -G_DEFINE_BOXED_TYPE (GValue, g_value, value_copy, value_free) -G_DEFINE_BOXED_TYPE (GValueArray, g_value_array, g_value_array_copy, g_value_array_free) G_DEFINE_BOXED_TYPE (GDate, g_date, g_date_copy, g_date_free) /* the naming is a bit odd, but GString is obviously not G_TYPE_STRING */ G_DEFINE_BOXED_TYPE (GString, g_gstring, gstring_copy, gstring_free) diff --git a/gobject/gboxed.h b/glib/gboxed.h similarity index 77% rename from gobject/gboxed.h rename to glib/gboxed.h index d7b3d4e91..c2a56f63d 100644 --- a/gobject/gboxed.h +++ b/glib/gboxed.h @@ -19,14 +19,14 @@ #ifndef __G_BOXED_H__ #define __G_BOXED_H__ -#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) -#error "Only can be included directly." +#if !defined (__GLIB_H_INSIDE__) && !defined(GLIB_COMPILATION) +#error "Only can be included directly." #endif -#include +#include #ifndef __GI_SCANNER__ -#include +#include #endif G_BEGIN_DECLS @@ -68,57 +68,36 @@ typedef void (*GBoxedFreeFunc) (gpointer boxed); /* --- prototypes --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_boxed_copy (GType boxed_type, gconstpointer src_boxed); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_boxed_free (GType boxed_type, gpointer boxed); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_boxed (GValue *value, gconstpointer v_boxed); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_static_boxed (GValue *value, gconstpointer v_boxed); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_take_boxed (GValue *value, gconstpointer v_boxed); -GOBJECT_DEPRECATED_FOR(g_value_take_boxed) +GLIB_DEPRECATED_FOR(g_value_take_boxed) void g_value_set_boxed_take_ownership (GValue *value, gconstpointer v_boxed); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_value_get_boxed (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_value_dup_boxed (const GValue *value); /* --- convenience --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_boxed_type_register_static (const gchar *name, GBoxedCopyFunc boxed_copy, GBoxedFreeFunc boxed_free); -/* --- GObject boxed types --- */ -/** - * G_TYPE_CLOSURE: - * - * The #GType for #GClosure. - */ -#define G_TYPE_CLOSURE (g_closure_get_type ()) - -/** - * G_TYPE_VALUE: - * - * The type ID of the "GValue" type which is a boxed type, - * used to pass around pointers to GValues. - */ -#define G_TYPE_VALUE (g_value_get_type ()) - -GOBJECT_AVAILABLE_IN_ALL -GType g_closure_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL -GType g_value_get_type (void) G_GNUC_CONST; - G_END_DECLS #endif /* __G_BOXED_H__ */ diff --git a/gobject/genums.c b/glib/genums.c similarity index 100% rename from gobject/genums.c rename to glib/genums.c diff --git a/gobject/genums.h b/glib/genums.h similarity index 94% rename from gobject/genums.h rename to glib/genums.h index 0ee8a610d..169493d5a 100644 --- a/gobject/genums.h +++ b/glib/genums.h @@ -19,11 +19,11 @@ #ifndef __G_ENUMS_H__ #define __G_ENUMS_H__ -#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) -#error "Only can be included directly." +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." #endif -#include +#include G_BEGIN_DECLS @@ -217,39 +217,39 @@ struct _GFlagsValue /* --- prototypes --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GEnumValue* g_enum_get_value (GEnumClass *enum_class, gint value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GEnumValue* g_enum_get_value_by_name (GEnumClass *enum_class, const gchar *name); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GEnumValue* g_enum_get_value_by_nick (GEnumClass *enum_class, const gchar *nick); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GFlagsValue* g_flags_get_first_value (GFlagsClass *flags_class, guint value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GFlagsValue* g_flags_get_value_by_name (GFlagsClass *flags_class, const gchar *name); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GFlagsValue* g_flags_get_value_by_nick (GFlagsClass *flags_class, const gchar *nick); -GOBJECT_AVAILABLE_IN_2_54 +GLIB_AVAILABLE_IN_2_54 gchar *g_enum_to_string (GType g_enum_type, gint value); -GOBJECT_AVAILABLE_IN_2_54 +GLIB_AVAILABLE_IN_2_54 gchar *g_flags_to_string (GType flags_type, guint value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_enum (GValue *value, gint v_enum); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gint g_value_get_enum (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_flags (GValue *value, guint v_flags); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL guint g_value_get_flags (const GValue *value); @@ -258,20 +258,20 @@ guint g_value_get_flags (const GValue *value); /* const_static_values is a NULL terminated array of enum/flags * values that is taken over! */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_enum_register_static (const gchar *name, const GEnumValue *const_static_values); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_flags_register_static (const gchar *name, const GFlagsValue *const_static_values); /* functions to complete the type information * for enums/flags implemented by plugins */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_enum_complete_type_info (GType g_enum_type, GTypeInfo *info, const GEnumValue *const_values); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_flags_complete_type_info (GType g_flags_type, GTypeInfo *info, const GFlagsValue *const_values); @@ -292,7 +292,7 @@ void g_flags_complete_type_info (GType g_flags_type, */ #define G_DEFINE_ENUM_VALUE(EnumValue, EnumNick) \ { EnumValue, #EnumValue, EnumNick } \ - GOBJECT_AVAILABLE_MACRO_IN_2_74 + GLIB_AVAILABLE_MACRO_IN_2_74 /** * G_DEFINE_ENUM_TYPE: @@ -331,7 +331,7 @@ type_name ## _get_type (void) { \ } \ return g_define_type__static; \ } \ - GOBJECT_AVAILABLE_MACRO_IN_2_74 + GLIB_AVAILABLE_MACRO_IN_2_74 /** * G_DEFINE_FLAGS_TYPE: @@ -374,7 +374,7 @@ type_name ## _get_type (void) { \ } \ return g_define_type__static; \ } \ - GOBJECT_AVAILABLE_MACRO_IN_2_74 + GLIB_AVAILABLE_MACRO_IN_2_74 G_END_DECLS diff --git a/glib/glib-init.c b/glib/glib-init.c index 3518b90aa..a91c160fd 100644 --- a/glib/glib-init.c +++ b/glib/glib-init.c @@ -420,6 +420,7 @@ glib_init (void) g_debug_init (); g_quark_init (); g_error_init (); + g_type_init_internal (); } #ifdef G_PLATFORM_WIN32 diff --git a/glib/glib-init.h b/glib/glib-init.h index 2ce2f0d46..d77b4807b 100644 --- a/glib/glib-init.h +++ b/glib/glib-init.h @@ -30,6 +30,7 @@ extern GLogLevelFlags g_log_msg_prefix; void glib_init (void); void g_quark_init (void); void g_error_init (void); +void g_type_init_internal (void); #ifdef G_OS_WIN32 #include diff --git a/glib/glib-object.h b/glib/glib-object.h index b00392d8c..83b3f8b30 100644 --- a/glib/glib-object.h +++ b/glib/glib-object.h @@ -23,8 +23,6 @@ #include #include -#include -#include #include #include #include @@ -32,12 +30,8 @@ #include #include #include -#include #include -#include #include -#include -#include #include diff --git a/glib/glib-private.c b/glib/glib-private.c index 15dbc665c..bfcba119b 100644 --- a/glib/glib-private.c +++ b/glib/glib-private.c @@ -25,6 +25,7 @@ #include "glib-init.h" #include "gutilsprivate.h" #include "gdatasetprivate.h" +#include "gtype-private.h" #ifdef USE_INVALID_PARAMETER_HANDLER #include @@ -77,6 +78,8 @@ glib__private__ (void) g_set_prgname_once, g_datalist_id_update_atomic, + + g_type_has_debug_flag, }; return &table; diff --git a/glib/glib-private.h b/glib/glib-private.h index 3417dfaf6..1b6aec96d 100644 --- a/glib/glib-private.h +++ b/glib/glib-private.h @@ -308,6 +308,9 @@ typedef struct { GDataListUpdateAtomicFunc callback, gpointer user_data); + /* See gtype.c */ + gboolean (* g_type_has_debug_flag) (int flag); + /* Add other private functions here, initialize them in glib-private.c */ } GLibPrivateVTable; diff --git a/gobject/glib-types.h b/glib/glib-types.h similarity index 85% rename from gobject/glib-types.h rename to glib/glib-types.h index e31baf144..88fbe0c7d 100644 --- a/gobject/glib-types.h +++ b/glib/glib-types.h @@ -19,12 +19,11 @@ #ifndef __GLIB_TYPES_H__ #define __GLIB_TYPES_H__ -#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) && !defined(GLIB_COMPILATION) -#error "Only can be included directly." +#if !defined (__GLIB_H_INSIDE__) && !defined(GLIB_COMPILATION) +#error "Only can be included directly." #endif #include -#include G_BEGIN_DECLS @@ -178,20 +177,6 @@ typedef gsize GType; */ #define G_TYPE_TIME_ZONE (g_time_zone_get_type ()) -/** - * G_TYPE_IO_CHANNEL: - * - * The #GType for #GIOChannel. - */ -#define G_TYPE_IO_CHANNEL (g_io_channel_get_type ()) - -/** - * G_TYPE_IO_CONDITION: - * - * The #GType for #GIOCondition. - */ -#define G_TYPE_IO_CONDITION (g_io_condition_get_type ()) - /** * G_TYPE_VARIANT_BUILDER: * @@ -372,80 +357,76 @@ typedef gsize GType; */ #define G_TYPE_STRV_BUILDER (g_strv_builder_get_type ()) -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_date_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_strv_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_gstring_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_hash_table_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_array_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_byte_array_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_ptr_array_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_bytes_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_variant_type_get_gtype (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_regex_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_30 +GLIB_AVAILABLE_IN_2_30 GType g_match_info_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_error_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_date_time_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_time_zone_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL -GType g_io_channel_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL -GType g_io_condition_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_variant_builder_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_40 +GLIB_AVAILABLE_IN_2_40 GType g_variant_dict_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_key_file_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_30 +GLIB_AVAILABLE_IN_2_30 GType g_main_loop_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_30 +GLIB_AVAILABLE_IN_2_30 GType g_main_context_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_30 +GLIB_AVAILABLE_IN_2_30 GType g_source_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_36 +GLIB_AVAILABLE_IN_2_36 GType g_pollfd_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_36 +GLIB_AVAILABLE_IN_2_36 GType g_thread_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_36 +GLIB_AVAILABLE_IN_2_36 GType g_checksum_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_36 +GLIB_AVAILABLE_IN_2_36 GType g_markup_parse_context_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_40 +GLIB_AVAILABLE_IN_2_40 GType g_mapped_file_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_44 +GLIB_AVAILABLE_IN_2_44 GType g_option_group_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_66 +GLIB_AVAILABLE_IN_2_66 GType g_uri_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_68 +GLIB_AVAILABLE_IN_2_68 GType g_tree_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_70 +GLIB_AVAILABLE_IN_2_70 GType g_pattern_spec_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_76 +GLIB_AVAILABLE_IN_2_76 GType g_bookmark_file_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_80 +GLIB_AVAILABLE_IN_2_80 GType g_hmac_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_80 +GLIB_AVAILABLE_IN_2_80 GType g_dir_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_80 +GLIB_AVAILABLE_IN_2_80 GType g_rand_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_2_80 +GLIB_AVAILABLE_IN_2_80 GType g_strv_builder_get_type (void) G_GNUC_CONST; -GOBJECT_DEPRECATED_FOR('G_TYPE_VARIANT') +GLIB_DEPRECATED_FOR('G_TYPE_VARIANT') GType g_variant_get_gtype (void) G_GNUC_CONST; G_END_DECLS diff --git a/glib/glib.h b/glib/glib.h index 40e501997..03bfef014 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -93,11 +95,15 @@ #include #include #include +#include +#include #include #include #include #include #include +#include +#include #include #include #include @@ -115,6 +121,7 @@ #include #include +#include #include #undef __GLIB_H_INSIDE__ diff --git a/glib/glib_probes.d b/glib/glib_probes.d index d663b81bf..02bf4a079 100644 --- a/glib/glib_probes.d +++ b/glib/glib_probes.d @@ -58,4 +58,6 @@ provider glib { probe variant__ref_sink(void*, const char*, int, int, int); probe variant__take_ref(void*, const char*, int, int, int); probe variant__from_parent(void*, const char*, int, int, void*); + probe instance__new(void*, unsigned long); + probe type__new(void*, unsigned long, unsigned long); }; diff --git a/glib/gtype-private.h b/glib/gtype-private.h new file mode 100644 index 000000000..588ac06dd --- /dev/null +++ b/glib/gtype-private.h @@ -0,0 +1,35 @@ +/* GLib + * + * SPDX-FileCopyrightText: 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * SPDX-FileCopyrightText: 2025 Emmanuele Bassi + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include "gboxed.h" + +G_BEGIN_DECLS + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +extern GTypeDebugFlags _g_type_debug_flags; +G_GNUC_END_IGNORE_DEPRECATIONS + +gboolean g_type_has_debug_flag (int flag); + +void _g_boxed_type_init (void); /* sync with gboxed.c */ +void _g_enum_types_init (void); /* sync with genums.c */ +void _g_value_c_init (void); /* sync with gvalue.c */ +void _g_value_transforms_init (void); /* sync with gvaluetransform.c */ +void _g_value_types_init (void); /* sync with gvaluetypes.c */ + +/* for gboxed.c */ +gpointer _g_type_boxed_copy (GType type, + gpointer value); +void _g_type_boxed_free (GType type, + gpointer value); +void _g_type_boxed_init (GType type, + GBoxedCopyFunc copy_func, + GBoxedFreeFunc free_func); + +G_END_DECLS diff --git a/gobject/gtype.c b/glib/gtype.c similarity index 97% rename from gobject/gtype.c rename to glib/gtype.c index cbce0acbd..c9f9527e7 100644 --- a/gobject/gtype.c +++ b/glib/gtype.c @@ -23,17 +23,18 @@ #include "config.h" -#include "../glib/gvalgrind.h" +#include "gvalgrind.h" #include #include "gtype.h" #include "gtype-private.h" #include "gtypeplugin.h" #include "gvaluecollector.h" -#include "gatomicarray.h" -#include "gobject_trace.h" +#include "gatomicarray-private.h" +#include "glib_trace.h" #include "glib-private.h" +#include "glib-init.h" #include "gconstructor.h" #ifdef G_OS_WIN32 @@ -487,7 +488,7 @@ type_node_any_new_W (TypeNode *pnode, pnode->children[i] = type; } - TRACE(GOBJECT_TYPE_NEW(name, node->supers[1], type)); + TRACE(GLIB_TYPE_NEW(name, node->supers[1], type)); node->plugin = plugin; node->n_children = 0; @@ -1957,7 +1958,7 @@ g_type_create_instance (GType type) } #endif - TRACE(GOBJECT_OBJECT_NEW(instance, type)); + TRACE(GLIB_INSTANCE_NEW(instance, type)); return instance; } @@ -4486,192 +4487,6 @@ g_type_init (void) g_assert_type_system_initialized (); } -static void -gobject_init (void) -{ - const gchar *env_string; - GTypeInfo info; - TypeNode *node; - GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; - - /* Ensure GLib is initialized first, see - * https://bugzilla.gnome.org/show_bug.cgi?id=756139 - */ - GLIB_PRIVATE_CALL (glib_init) (); - - G_WRITE_LOCK (&type_rw_lock); - - /* setup GObject library wide debugging flags */ - env_string = g_getenv ("GOBJECT_DEBUG"); - if (env_string != NULL) - { - GDebugKey debug_keys[] = { - { "objects", G_TYPE_DEBUG_OBJECTS }, - { "instance-count", G_TYPE_DEBUG_INSTANCE_COUNT }, - { "signals", G_TYPE_DEBUG_SIGNALS }, - }; - - _g_type_debug_flags = g_parse_debug_string (env_string, debug_keys, G_N_ELEMENTS (debug_keys)); - } - - /* quarks */ - static_quark_type_flags = g_quark_from_static_string ("-g-type-private--GTypeFlags"); - static_quark_iface_holder = g_quark_from_static_string ("-g-type-private--IFaceHolder"); - static_quark_dependants_array = g_quark_from_static_string ("-g-type-private--dependants-array"); - - /* type qname hash table */ - static_type_nodes_ht = g_hash_table_new (g_str_hash, g_str_equal); - - /* invalid type G_TYPE_INVALID (0) - */ - static_fundamental_type_nodes[0] = NULL; - - /* void type G_TYPE_NONE - */ - node = type_node_fundamental_new_W (G_TYPE_NONE, g_intern_static_string ("void"), 0); - type = NODE_TYPE (node); - g_assert (type == G_TYPE_NONE); - - /* interface fundamental type G_TYPE_INTERFACE (!classed) - */ - memset (&info, 0, sizeof (info)); - node = type_node_fundamental_new_W (G_TYPE_INTERFACE, g_intern_static_string ("GInterface"), G_TYPE_FLAG_DERIVABLE); - type = NODE_TYPE (node); - type_data_make_W (node, &info, NULL); - g_assert (type == G_TYPE_INTERFACE); - - G_WRITE_UNLOCK (&type_rw_lock); - - _g_value_c_init (); - - /* G_TYPE_TYPE_PLUGIN - */ - g_type_ensure (g_type_plugin_get_type ()); - - /* G_TYPE_* value types - */ - _g_value_types_init (); - - /* G_TYPE_ENUM & G_TYPE_FLAGS - */ - _g_enum_types_init (); - - /* G_TYPE_BOXED - */ - _g_boxed_type_init (); - - /* G_TYPE_PARAM - */ - _g_param_type_init (); - - /* G_TYPE_OBJECT - */ - _g_object_type_init (); - - /* G_TYPE_PARAM_* pspec types - */ - _g_param_spec_types_init (); - - /* Value Transformations - */ - _g_value_transforms_init (); - - /* Signal system - */ - _g_signal_init (); -} - -#ifdef G_PLATFORM_WIN32 - -void gobject_win32_init (void); - -void -gobject_win32_init (void) -{ - /* May be called more than once in static compilation mode */ - static gboolean win32_already_init = FALSE; - if (!win32_already_init) - { - win32_already_init = TRUE; - gobject_init (); - } -} - -#ifndef GLIB_STATIC_COMPILATION - -BOOL WINAPI DllMain (HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved); - -BOOL WINAPI -DllMain (HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - gobject_win32_init (); - break; - - default: - /* do nothing */ - ; - } - - return TRUE; -} - -#elif defined(G_HAS_CONSTRUCTORS) /* && G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION */ -extern void glib_win32_init (void); - -#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA -#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor) -#endif - -G_DEFINE_CONSTRUCTOR(gobject_init_ctor) - -static void -gobject_init_ctor (void) -{ - /* When built dynamically, module initialization is done through DllMain - * function which is called when the dynamic library is loaded by the glib - * module. So, in dynamic configuration glib is always initialized BEFORE - * gobject. - * - * When built statically, initialization mechanism relies on hooking - * functions to the CRT section directly at compilation time. As we don't - * control how each compilation unit will be built and in which order, we - * obtain the same kind of issue as the "static initialization order fiasco". - * In this case, we must ensure explicitly that glib is always well - * initialized BEFORE gobject. - */ - glib_win32_init (); - gobject_win32_init (); -} - -#else /* G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION && !G_HAS_CONSTRUCTORS */ -# error Your platform/compiler is missing constructor support -#endif /* GLIB_STATIC_COMPILATION */ - -#elif defined(G_HAS_CONSTRUCTORS) /* && !G_PLATFORM_WIN32 */ - -#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA -#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor) -#endif - -G_DEFINE_CONSTRUCTOR (gobject_init_ctor) - -static void -gobject_init_ctor (void) -{ - gobject_init (); -} - -#else /* !G_PLATFORM_WIN32 && !G_HAS_CONSTRUCTORS */ -#error Your platform/compiler is missing constructor support -#endif /* G_PLATFORM_WIN32 */ - /** * g_type_class_add_private: * @g_class: (type GObject.TypeClass): class structure for an instantiatable @@ -5082,3 +4897,78 @@ g_type_ensure (GType type) if (G_UNLIKELY (type == (GType)-1)) g_error ("can't happen"); } + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +gboolean +g_type_has_debug_flag (int flag) +{ + return (_g_type_debug_flags & flag) != 0; +} +G_GNUC_END_IGNORE_DEPRECATIONS + +void +g_type_init_internal (void) +{ + GTypeInfo info; + TypeNode *node; + GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; + + G_WRITE_LOCK (&type_rw_lock); + + /* setup debugging flags */ + const char *env_string = g_getenv ("GOBJECT_DEBUG"); + if (env_string != NULL) + { + GDebugKey debug_keys[] = { + { "objects", G_TYPE_DEBUG_OBJECTS }, + { "instance-count", G_TYPE_DEBUG_INSTANCE_COUNT }, + { "signals", G_TYPE_DEBUG_SIGNALS }, + }; + + _g_type_debug_flags = g_parse_debug_string (env_string, debug_keys, G_N_ELEMENTS (debug_keys)); + } + + /* quarks */ + static_quark_type_flags = g_quark_from_static_string ("-g-type-private--GTypeFlags"); + static_quark_iface_holder = g_quark_from_static_string ("-g-type-private--IFaceHolder"); + static_quark_dependants_array = g_quark_from_static_string ("-g-type-private--dependants-array"); + + /* type qname hash table */ + static_type_nodes_ht = g_hash_table_new (g_str_hash, g_str_equal); + + /* invalid type G_TYPE_INVALID (0) */ + static_fundamental_type_nodes[0] = NULL; + + /* void type G_TYPE_NONE */ + node = type_node_fundamental_new_W (G_TYPE_NONE, g_intern_static_string ("void"), 0); + type = NODE_TYPE (node); + g_assert (type == G_TYPE_NONE); + + /* interface fundamental type G_TYPE_INTERFACE (!classed) */ + memset (&info, 0, sizeof (info)); + node = type_node_fundamental_new_W (G_TYPE_INTERFACE, g_intern_static_string ("GInterface"), G_TYPE_FLAG_DERIVABLE); + type = NODE_TYPE (node); + type_data_make_W (node, &info, NULL); + g_assert (type == G_TYPE_INTERFACE); + + G_WRITE_UNLOCK (&type_rw_lock); + + /* GValue initialization */ + _g_value_c_init (); + + /* G_TYPE_TYPE_PLUGIN */ + g_type_ensure (g_type_plugin_get_type ()); + + /* G_TYPE_* fundamental value types */ + _g_value_types_init (); + + /* G_TYPE_ENUM & G_TYPE_FLAGS */ + _g_enum_types_init (); + + /* G_TYPE_BOXED */ + _g_boxed_type_init (); + + /* Value Transformations */ + _g_value_transforms_init (); + +} diff --git a/gobject/gtype.h b/glib/gtype.h similarity index 96% rename from gobject/gtype.h rename to glib/gtype.h index 02a718464..0c8d7923c 100644 --- a/gobject/gtype.h +++ b/glib/gtype.h @@ -16,15 +16,14 @@ * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, see . */ -#ifndef __G_TYPE_H__ -#define __G_TYPE_H__ +#pragma once -#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) -#error "Only can be included directly." +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." #endif -#include -#include +#include +#include G_BEGIN_DECLS @@ -175,18 +174,6 @@ G_BEGIN_DECLS * The fundamental type from which all boxed types are derived. */ #define G_TYPE_BOXED G_TYPE_MAKE_FUNDAMENTAL (18) -/** - * G_TYPE_PARAM: - * - * The fundamental type from which all #GParamSpec types are derived. - */ -#define G_TYPE_PARAM G_TYPE_MAKE_FUNDAMENTAL (19) -/** - * G_TYPE_OBJECT: - * - * The fundamental type for #GObject. - */ -#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20) /** * G_TYPE_VARIANT: * @@ -397,7 +384,7 @@ G_BEGIN_DECLS * * Since: 2.70 */ -#define G_TYPE_IS_FINAL(type) (g_type_test_flags ((type), G_TYPE_FLAG_FINAL)) GOBJECT_AVAILABLE_MACRO_IN_2_70 +#define G_TYPE_IS_FINAL(type) (g_type_test_flags ((type), G_TYPE_FLAG_FINAL)) GLIB_AVAILABLE_MACRO_IN_2_70 /** * G_TYPE_IS_DEPRECATED: @@ -410,7 +397,7 @@ G_BEGIN_DECLS * * Since: 2.76 */ -#define G_TYPE_IS_DEPRECATED(type) (g_type_test_flags ((type), G_TYPE_FLAG_DEPRECATED)) GOBJECT_AVAILABLE_MACRO_IN_2_76 +#define G_TYPE_IS_DEPRECATED(type) (g_type_test_flags ((type), G_TYPE_FLAG_DEPRECATED)) GLIB_AVAILABLE_MACRO_IN_2_76 /* Typedefs @@ -685,7 +672,7 @@ struct _GTypeQuery * `your_type_get_instance_private()` function instead * Returns: (not nullable): a pointer to the private data structure */ -#define G_TYPE_INSTANCE_GET_PRIVATE(instance, g_type, c_type) ((c_type*) g_type_instance_get_private ((GTypeInstance*) (instance), (g_type))) GOBJECT_DEPRECATED_MACRO_IN_2_58_FOR(G_ADD_PRIVATE) +#define G_TYPE_INSTANCE_GET_PRIVATE(instance, g_type, c_type) ((c_type*) g_type_instance_get_private ((GTypeInstance*) (instance), (g_type))) GLIB_DEPRECATED_MACRO_IN_2_58_FOR(G_ADD_PRIVATE) /** * G_TYPE_CLASS_GET_PRIVATE: @@ -728,81 +715,81 @@ typedef enum /*< skip >*/ G_TYPE_DEBUG_SIGNALS = 1 << 1, G_TYPE_DEBUG_INSTANCE_COUNT = 1 << 2, G_TYPE_DEBUG_MASK = 0x07 -} GTypeDebugFlags GOBJECT_DEPRECATED_TYPE_IN_2_36; +} GTypeDebugFlags GLIB_DEPRECATED_TYPE_IN_2_36; /* --- prototypes --- */ G_GNUC_BEGIN_IGNORE_DEPRECATIONS -GOBJECT_DEPRECATED_IN_2_36 +GLIB_DEPRECATED_IN_2_36 void g_type_init (void); -GOBJECT_DEPRECATED_IN_2_36 +GLIB_DEPRECATED_IN_2_36 void g_type_init_with_debug_flags (GTypeDebugFlags debug_flags); G_GNUC_END_IGNORE_DEPRECATIONS -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL const gchar * g_type_name (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GQuark g_type_qname (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_from_name (const gchar *name); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_parent (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL guint g_type_depth (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_next_base (GType leaf_type, GType root_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_type_is_a (GType type, GType is_a_type); /* Hoist exact GType comparisons into the caller */ #define g_type_is_a(a,b) ((a) == (b) || (g_type_is_a) ((a), (b))) -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_class_ref (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_class_peek (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_class_peek_static (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_class_unref (gpointer g_class); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_class_peek_parent (gpointer g_class); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_interface_peek (gpointer instance_class, GType iface_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_interface_peek_parent (gpointer g_iface); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_default_interface_ref (GType g_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_default_interface_peek (GType g_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_default_interface_unref (gpointer g_iface); /* g_free() the returned arrays */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType* g_type_children (GType type, guint *n_children); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType* g_type_interfaces (GType type, guint *n_interfaces); /* per-type _static_ data */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_set_qdata (GType type, GQuark quark, gpointer data); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_get_qdata (GType type, GQuark quark); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_query (GType type, GTypeQuery *query); -GOBJECT_AVAILABLE_IN_2_44 +GLIB_AVAILABLE_IN_2_44 int g_type_get_instance_count (GType type); /* --- type registration --- */ @@ -1082,11 +1069,11 @@ typedef enum /*< skip >*/ */ typedef enum /*< skip >*/ { - G_TYPE_FLAG_NONE GOBJECT_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_TYPE_FLAG_NONE GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, G_TYPE_FLAG_ABSTRACT = (1 << 4), G_TYPE_FLAG_VALUE_ABSTRACT = (1 << 5), - G_TYPE_FLAG_FINAL GOBJECT_AVAILABLE_ENUMERATOR_IN_2_70 = (1 << 6), - G_TYPE_FLAG_DEPRECATED GOBJECT_AVAILABLE_ENUMERATOR_IN_2_76 = (1 << 7) + G_TYPE_FLAG_FINAL GLIB_AVAILABLE_ENUMERATOR_IN_2_70 = (1 << 6), + G_TYPE_FLAG_DEPRECATED GLIB_AVAILABLE_ENUMERATOR_IN_2_76 = (1 << 7) } GTypeFlags; /** * GTypeInfo: @@ -1185,7 +1172,7 @@ struct _GInterfaceInfo * * Since: 2.78 */ -GOBJECT_AVAILABLE_TYPE_IN_2_78 +GLIB_AVAILABLE_TYPE_IN_2_78 typedef void (* GTypeValueInitFunc) (GValue *value); /** @@ -1206,7 +1193,7 @@ typedef void (* GTypeValueInitFunc) (GValue *value); * * Since: 2.78 */ -GOBJECT_AVAILABLE_TYPE_IN_2_78 +GLIB_AVAILABLE_TYPE_IN_2_78 typedef void (* GTypeValueFreeFunc) (GValue *value); /** @@ -1229,7 +1216,7 @@ typedef void (* GTypeValueFreeFunc) (GValue *value); * * Since: 2.78 */ -GOBJECT_AVAILABLE_TYPE_IN_2_78 +GLIB_AVAILABLE_TYPE_IN_2_78 typedef void (* GTypeValueCopyFunc) (const GValue *src_value, GValue *dest_value); @@ -1250,7 +1237,7 @@ typedef void (* GTypeValueCopyFunc) (const GValue *src_value, * * Since: 2.78 */ -GOBJECT_AVAILABLE_TYPE_IN_2_78 +GLIB_AVAILABLE_TYPE_IN_2_78 typedef gpointer (* GTypeValuePeekPointerFunc) (const GValue *value); /** @@ -1337,7 +1324,7 @@ typedef gpointer (* GTypeValuePeekPointerFunc) (const GValue *value); * * Since: 2.78 */ -GOBJECT_AVAILABLE_TYPE_IN_2_78 +GLIB_AVAILABLE_TYPE_IN_2_78 typedef gchar * (* GTypeValueCollectFunc) (GValue *value, guint n_collect_values, GTypeCValue *collect_values, @@ -1399,7 +1386,7 @@ typedef gchar * (* GTypeValueCollectFunc) (GValue *value, * * Since: 2.78 */ -GOBJECT_AVAILABLE_TYPE_IN_2_78 +GLIB_AVAILABLE_TYPE_IN_2_78 typedef gchar * (* GTypeValueLCopyFunc) (const GValue *value, guint n_collect_values, GTypeCValue *collect_values, @@ -1451,12 +1438,12 @@ struct _GTypeValueTable }; G_GNUC_END_IGNORE_DEPRECATIONS -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_register_static (GType parent_type, const gchar *type_name, const GTypeInfo *info, GTypeFlags flags); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_register_static_simple (GType parent_type, const gchar *type_name, guint class_size, @@ -1465,59 +1452,59 @@ GType g_type_register_static_simple (GType parent_type GInstanceInitFunc instance_init, GTypeFlags flags); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_register_dynamic (GType parent_type, const gchar *type_name, GTypePlugin *plugin, GTypeFlags flags); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_register_fundamental (GType type_id, const gchar *type_name, const GTypeInfo *info, const GTypeFundamentalInfo *finfo, GTypeFlags flags); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_add_interface_static (GType instance_type, GType interface_type, const GInterfaceInfo *info); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_add_interface_dynamic (GType instance_type, GType interface_type, GTypePlugin *plugin); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_interface_add_prerequisite (GType interface_type, GType prerequisite_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType*g_type_interface_prerequisites (GType interface_type, guint *n_prerequisites); -GOBJECT_AVAILABLE_IN_2_68 +GLIB_AVAILABLE_IN_2_68 GType g_type_interface_instantiatable_prerequisite (GType interface_type); -GOBJECT_DEPRECATED_IN_2_58 +GLIB_DEPRECATED_IN_2_58 void g_type_class_add_private (gpointer g_class, gsize private_size); -GOBJECT_AVAILABLE_IN_2_38 +GLIB_AVAILABLE_IN_2_38 gint g_type_add_instance_private (GType class_type, gsize private_size); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_instance_get_private (GTypeInstance *instance, GType private_type); -GOBJECT_AVAILABLE_IN_2_38 +GLIB_AVAILABLE_IN_2_38 void g_type_class_adjust_private_offset (gpointer g_class, gint *private_size_or_offset); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_add_class_private (GType class_type, gsize private_size); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_type_class_get_private (GTypeClass *klass, GType private_type); -GOBJECT_AVAILABLE_IN_2_38 +GLIB_AVAILABLE_IN_2_38 gint g_type_class_get_instance_private_offset (gpointer g_class); -GOBJECT_AVAILABLE_IN_2_34 +GLIB_AVAILABLE_IN_2_34 void g_type_ensure (GType type); -GOBJECT_AVAILABLE_IN_2_36 +GLIB_AVAILABLE_IN_2_36 guint g_type_get_type_registration_serial (void); @@ -1931,7 +1918,7 @@ guint g_type_get_type_registration_serial (void); * * Since: 2.70 */ -#define G_DEFINE_FINAL_TYPE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_FINAL, {}) GOBJECT_AVAILABLE_MACRO_IN_2_70 +#define G_DEFINE_FINAL_TYPE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_FINAL, {}) GLIB_AVAILABLE_MACRO_IN_2_70 /** * G_DEFINE_FINAL_TYPE_WITH_CODE: * @TN: the name of the new type, in Camel case @@ -1950,7 +1937,7 @@ guint g_type_get_type_registration_serial (void); * * Since: 2.70 */ -#define G_DEFINE_FINAL_TYPE_WITH_CODE(TN, t_n, T_P, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, G_TYPE_FLAG_FINAL) {_C_;} _G_DEFINE_TYPE_EXTENDED_END() GOBJECT_AVAILABLE_MACRO_IN_2_70 +#define G_DEFINE_FINAL_TYPE_WITH_CODE(TN, t_n, T_P, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, G_TYPE_FLAG_FINAL) {_C_;} _G_DEFINE_TYPE_EXTENDED_END() GLIB_AVAILABLE_MACRO_IN_2_70 /** * G_DEFINE_FINAL_TYPE_WITH_PRIVATE: * @TN: the name of the new type, in Camel case @@ -1966,7 +1953,7 @@ guint g_type_get_type_registration_serial (void); * * Since: 2.70 */ -#define G_DEFINE_FINAL_TYPE_WITH_PRIVATE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_FINAL, G_ADD_PRIVATE (TN)) GOBJECT_AVAILABLE_MACRO_IN_2_70 +#define G_DEFINE_FINAL_TYPE_WITH_PRIVATE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, G_TYPE_FLAG_FINAL, G_ADD_PRIVATE (TN)) GLIB_AVAILABLE_MACRO_IN_2_70 /** * G_DEFINE_TYPE_EXTENDED: * @TN: The name of the new type, in Camel case. @@ -2580,74 +2567,74 @@ type_name##_get_type_once (void) \ { /* custom code follows */ /* --- protected (for fundamental type implementations) --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GTypePlugin* g_type_get_plugin (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GTypePlugin* g_type_interface_get_plugin (GType instance_type, GType interface_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_fundamental_next (void); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_fundamental (GType type_id); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GTypeInstance* g_type_create_instance (GType type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_free_instance (GTypeInstance *instance); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_add_class_cache_func (gpointer cache_data, GTypeClassCacheFunc cache_func); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_remove_class_cache_func (gpointer cache_data, GTypeClassCacheFunc cache_func); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_class_unref_uncached (gpointer g_class); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_add_interface_check (gpointer check_data, GTypeInterfaceCheckFunc check_func); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_remove_interface_check (gpointer check_data, GTypeInterfaceCheckFunc check_func); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GTypeValueTable* g_type_value_table_peek (GType type); /*< private >*/ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_type_check_instance (GTypeInstance *instance) G_GNUC_PURE; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GTypeInstance* g_type_check_instance_cast (GTypeInstance *instance, GType iface_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_type_check_instance_is_a (GTypeInstance *instance, GType iface_type) G_GNUC_PURE; -GOBJECT_AVAILABLE_IN_2_42 +GLIB_AVAILABLE_IN_2_42 gboolean g_type_check_instance_is_fundamentally_a (GTypeInstance *instance, GType fundamental_type) G_GNUC_PURE; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GTypeClass* g_type_check_class_cast (GTypeClass *g_class, GType is_a_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_type_check_class_is_a (GTypeClass *g_class, GType is_a_type) G_GNUC_PURE; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_type_check_is_value_type (GType type) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_type_check_value (const GValue *value) G_GNUC_PURE; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_type_check_value_holds (const GValue *value, GType type) G_GNUC_PURE; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_type_test_flags (GType type, guint flags) G_GNUC_CONST; /* --- debugging functions --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL const gchar * g_type_name_from_instance (GTypeInstance *instance); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL const gchar * g_type_name_from_class (GTypeClass *g_class); @@ -2719,7 +2706,7 @@ const gchar * g_type_name_from_class (GTypeClass *g_class); * * Since: 2.80 */ -#define GPOINTER_TO_TYPE(p) ((GType) (guintptr) (p)) GOBJECT_AVAILABLE_MACRO_IN_2_80 +#define GPOINTER_TO_TYPE(p) ((GType) (guintptr) (p)) GLIB_AVAILABLE_MACRO_IN_2_80 /** * GTYPE_TO_POINTER: * @t: The #GType to convert to a pointer @@ -2729,8 +2716,6 @@ const gchar * g_type_name_from_class (GTypeClass *g_class); * * Since: 2.80 */ -#define GTYPE_TO_POINTER(t) ((gpointer) (guintptr) (t)) GOBJECT_AVAILABLE_MACRO_IN_2_80 +#define GTYPE_TO_POINTER(t) ((gpointer) (guintptr) (t)) GLIB_AVAILABLE_MACRO_IN_2_80 G_END_DECLS - -#endif /* __G_TYPE_H__ */ diff --git a/gobject/gtypeplugin.c b/glib/gtypeplugin.c similarity index 99% rename from gobject/gtypeplugin.c rename to glib/gtypeplugin.c index d9743f588..9c89a05fd 100644 --- a/gobject/gtypeplugin.c +++ b/glib/gtypeplugin.c @@ -20,7 +20,7 @@ #include "config.h" #include "gtypeplugin.h" - +#include "gmessages.h" /** * GTypePlugin: diff --git a/gobject/gtypeplugin.h b/glib/gtypeplugin.h similarity index 94% rename from gobject/gtypeplugin.h rename to glib/gtypeplugin.h index c950dfbd1..3931a4a13 100644 --- a/gobject/gtypeplugin.h +++ b/glib/gtypeplugin.h @@ -19,11 +19,11 @@ #ifndef __G_TYPE_PLUGIN_H__ #define __G_TYPE_PLUGIN_H__ -#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) -#error "Only can be included directly." +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." #endif -#include +#include G_BEGIN_DECLS @@ -108,18 +108,18 @@ struct _GTypePluginClass /* --- prototypes --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_type_plugin_get_type (void) G_GNUC_CONST; -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_plugin_use (GTypePlugin *plugin); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_plugin_unuse (GTypePlugin *plugin); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_plugin_complete_type_info (GTypePlugin *plugin, GType g_type, GTypeInfo *info, GTypeValueTable *value_table); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_type_plugin_complete_interface_info (GTypePlugin *plugin, GType instance_type, GType interface_type, diff --git a/gobject/gvalue.c b/glib/gvalue.c similarity index 97% rename from gobject/gvalue.c rename to glib/gvalue.c index 9d974fac4..ac0b8054b 100644 --- a/gobject/gvalue.c +++ b/glib/gvalue.c @@ -30,6 +30,28 @@ #include "gbsearcharray.h" #include "gtype-private.h" +static GValue * +value_copy (GValue *src_value) +{ + GValue *dest_value = g_new0 (GValue, 1); + + if (G_VALUE_TYPE (src_value)) + { + g_value_init (dest_value, G_VALUE_TYPE (src_value)); + g_value_copy (src_value, dest_value); + } + return dest_value; +} + +static void +value_free (GValue *value) +{ + if (G_VALUE_TYPE (value)) + g_value_unset (value); + g_free (value); +} + +G_DEFINE_BOXED_TYPE (GValue, g_value, value_copy, value_free) /* --- typedefs & structures --- */ typedef struct { @@ -323,6 +345,7 @@ g_value_init_from_instance (GValue *value, { g_return_if_fail (value != NULL && G_VALUE_TYPE(value) == 0); +#if 0 if (G_IS_OBJECT (instance)) { /* Fast-path. @@ -334,6 +357,7 @@ g_value_init_from_instance (GValue *value, value->data[0].v_pointer = g_object_ref (instance); } else +#endif { GType g_type; GTypeValueTable *value_table; diff --git a/gobject/gvalue.h b/glib/gvalue.h similarity index 89% rename from gobject/gvalue.h rename to glib/gvalue.h index 2ac5ca189..a484a9b52 100644 --- a/gobject/gvalue.h +++ b/glib/gvalue.h @@ -21,11 +21,11 @@ #ifndef __G_VALUE_H__ #define __G_VALUE_H__ -#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) #error "Only can be included directly." #endif -#include +#include G_BEGIN_DECLS @@ -82,6 +82,14 @@ G_BEGIN_DECLS */ #define G_VALUE_HOLDS(value,type) (G_TYPE_CHECK_VALUE_TYPE ((value), (type))) +/** + * G_TYPE_VALUE: + * + * The type ID of the "GValue" type which is a boxed type, + * used to pass around pointers to GValues. + */ +#define G_TYPE_VALUE (g_value_get_type ()) + /* --- typedefs & structures --- */ /** @@ -131,42 +139,45 @@ struct _GValue /* --- prototypes --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL +GType g_value_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_ALL GValue* g_value_init (GValue *value, GType g_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_copy (const GValue *src_value, GValue *dest_value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GValue* g_value_reset (GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_unset (GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_instance (GValue *value, gpointer instance); -GOBJECT_AVAILABLE_IN_2_42 +GLIB_AVAILABLE_IN_2_42 void g_value_init_from_instance (GValue *value, gpointer instance); /* --- private --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_value_fits_pointer (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_value_peek_pointer (const GValue *value); /* --- implementation details --- */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_value_type_compatible (GType src_type, GType dest_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_value_type_transformable (GType src_type, GType dest_type); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_value_transform (const GValue *src_value, GValue *dest_value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_register_transform_func (GType src_type, GType dest_type, GValueTransform transform_func); @@ -189,7 +200,7 @@ void g_value_register_transform_func (GType src_type, * * Since: 2.66 */ -#define G_VALUE_INTERNED_STRING (1 << 28) GOBJECT_AVAILABLE_MACRO_IN_2_66 +#define G_VALUE_INTERNED_STRING (1 << 28) GLIB_AVAILABLE_MACRO_IN_2_66 /** * G_VALUE_INIT: diff --git a/glib/gvaluecollector.h b/glib/gvaluecollector.h new file mode 100644 index 000000000..622472e0d --- /dev/null +++ b/glib/gvaluecollector.h @@ -0,0 +1,283 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * gvaluecollector.h: GValue varargs stubs + */ + +#ifndef __GLIB_G_VALUE_COLLECTOR_H__ +#define __GLIB_G_VALUE_COLLECTOR_H__ + +/* Add a guard to avoid including both this file and gobject's copy */ +#define GLIB_GVALUECOLLECTOR_H + +#include + +G_BEGIN_DECLS + +/* we may want to add aggregate types here some day, if requested + * by users. the basic C types are covered already, everything + * smaller than an int is promoted to an integer and floats are + * always promoted to doubles for varargs call constructions. + */ +enum /*< skip >*/ +{ + G_VALUE_COLLECT_INT = 'i', + G_VALUE_COLLECT_LONG = 'l', + G_VALUE_COLLECT_INT64 = 'q', + G_VALUE_COLLECT_DOUBLE = 'd', + G_VALUE_COLLECT_POINTER = 'p' +}; + + +/* vararg union holding actual values collected + */ +/** + * GTypeCValue: + * @v_int: the field for holding integer values + * @v_long: the field for holding long integer values + * @v_int64: the field for holding 64 bit integer values + * @v_double: the field for holding floating point values + * @v_pointer: the field for holding pointers + * + * A union holding one collected value. + */ +union _GTypeCValue +{ + gint v_int; + glong v_long; + gint64 v_int64; + gdouble v_double; + gpointer v_pointer; +}; + +/** + * G_VALUE_COLLECT_INIT: + * @value: a #GValue return location. @value must contain only 0 bytes. + * @_value_type: the #GType to use for @value. + * @var_args: the va_list variable; it may be evaluated multiple times + * @flags: flags which are passed on to the collect_value() function of + * the #GTypeValueTable of @value. + * @__error: a #gchar** variable that will be modified to hold a g_new() + * allocated error messages if something fails + * + * Collects a variable argument value from a `va_list`. + * + * We have to implement the varargs collection as a macro, because on some + * systems `va_list` variables cannot be passed by reference. + * + * Since: 2.24 + */ +#define G_VALUE_COLLECT_INIT(value, _value_type, var_args, flags, __error) \ + G_STMT_START { \ + GTypeValueTable *g_vci_vtab; \ + G_VALUE_COLLECT_INIT2(value, g_vci_vtab, _value_type, var_args, flags, __error); \ +} G_STMT_END + +/** + * G_VALUE_COLLECT_INIT2: + * @value: a #GValue return location. @value must contain only 0 bytes. + * @g_vci_vtab: a #GTypeValueTable pointer that will be set to the value table + * for @_value_type + * @_value_type: the #GType to use for @value. + * @var_args: the va_list variable; it may be evaluated multiple times + * @flags: flags which are passed on to the collect_value() function of + * the #GTypeValueTable of @value. + * @__error: a #gchar** variable that will be modified to hold a g_new() + * allocated error messages if something fails + * + * A variant of G_VALUE_COLLECT_INIT() that provides the #GTypeValueTable + * to the caller. + * + * Since: 2.74 + */ +#define G_VALUE_COLLECT_INIT2(value, g_vci_vtab, _value_type, var_args, flags, __error) \ +G_STMT_START { \ + GValue *g_vci_val = (value); \ + guint g_vci_flags = (flags); \ + const gchar *g_vci_collect_format; \ + GTypeCValue g_vci_cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, }; \ + guint g_vci_n_values = 0; \ + g_vci_vtab = g_type_value_table_peek (_value_type); \ + g_vci_collect_format = g_vci_vtab->collect_format; \ + g_vci_val->g_type = _value_type; /* value_meminit() from gvalue.c */ \ + while (*g_vci_collect_format) \ + { \ + GTypeCValue *g_vci_cvalue = g_vci_cvalues + g_vci_n_values++; \ + \ + switch (*g_vci_collect_format++) \ + { \ + case G_VALUE_COLLECT_INT: \ + g_vci_cvalue->v_int = va_arg ((var_args), gint); \ + break; \ + case G_VALUE_COLLECT_LONG: \ + g_vci_cvalue->v_long = va_arg ((var_args), glong); \ + break; \ + case G_VALUE_COLLECT_INT64: \ + g_vci_cvalue->v_int64 = va_arg ((var_args), gint64); \ + break; \ + case G_VALUE_COLLECT_DOUBLE: \ + g_vci_cvalue->v_double = va_arg ((var_args), gdouble); \ + break; \ + case G_VALUE_COLLECT_POINTER: \ + g_vci_cvalue->v_pointer = va_arg ((var_args), gpointer); \ + break; \ + default: \ + g_assert_not_reached (); \ + } \ + } \ + *(__error) = g_vci_vtab->collect_value (g_vci_val, \ + g_vci_n_values, \ + g_vci_cvalues, \ + g_vci_flags); \ +} G_STMT_END + +/** + * G_VALUE_COLLECT: + * @value: a #GValue return location. @value is supposed to be initialized + * according to the value type to be collected + * @var_args: the va_list variable; it may be evaluated multiple times + * @flags: flags which are passed on to the collect_value() function of + * the #GTypeValueTable of @value. + * @__error: a #gchar** variable that will be modified to hold a g_new() + * allocated error messages if something fails + * + * Collects a variable argument value from a `va_list`. + * + * We have to implement the varargs collection as a macro, because on some systems + * `va_list` variables cannot be passed by reference. + * + * Note: If you are creating the @value argument just before calling this macro, + * you should use the G_VALUE_COLLECT_INIT() variant and pass the uninitialized + * #GValue. That variant is faster than G_VALUE_COLLECT(). + */ +#define G_VALUE_COLLECT(value, var_args, flags, __error) G_STMT_START { \ + GValue *g_vc_value = (value); \ + GType g_vc_value_type = G_VALUE_TYPE (g_vc_value); \ + GTypeValueTable *g_vc_vtable = g_type_value_table_peek (g_vc_value_type); \ + \ + if (g_vc_vtable->value_free) \ + g_vc_vtable->value_free (g_vc_value); \ + memset (g_vc_value->data, 0, sizeof (g_vc_value->data)); \ + \ + G_VALUE_COLLECT_INIT(value, g_vc_value_type, var_args, flags, __error); \ +} G_STMT_END + +/** + * G_VALUE_COLLECT_SKIP: + * @_value_type: the #GType of the value to skip + * @var_args: the va_list variable; it may be evaluated multiple times + * + * Skip an argument of type @_value_type from @var_args. + */ +#define G_VALUE_COLLECT_SKIP(_value_type, var_args) \ +G_STMT_START { \ + GTypeValueTable *g_vcs_vtable = g_type_value_table_peek (_value_type); \ + const gchar *g_vcs_collect_format = g_vcs_vtable->collect_format; \ + \ + while (*g_vcs_collect_format) \ + { \ + switch (*g_vcs_collect_format++) \ + { \ + case G_VALUE_COLLECT_INT: \ + va_arg ((var_args), gint); \ + break; \ + case G_VALUE_COLLECT_LONG: \ + va_arg ((var_args), glong); \ + break; \ + case G_VALUE_COLLECT_INT64: \ + va_arg ((var_args), gint64); \ + break; \ + case G_VALUE_COLLECT_DOUBLE: \ + va_arg ((var_args), gdouble); \ + break; \ + case G_VALUE_COLLECT_POINTER: \ + va_arg ((var_args), gpointer); \ + break; \ + default: \ + g_assert_not_reached (); \ + } \ + } \ +} G_STMT_END + +/** + * G_VALUE_LCOPY: + * @value: a #GValue to store into the @var_args; this must be initialized + * and set + * @var_args: the va_list variable; it may be evaluated multiple times + * @flags: flags which are passed on to the lcopy_value() function of + * the #GTypeValueTable of @value. + * @__error: a #gchar** variable that will be modified to hold a g_new() + * allocated error message if something fails + * + * Stores a value’s value into one or more argument locations from a `va_list`. + * + * This is the inverse of G_VALUE_COLLECT(). + */ +#define G_VALUE_LCOPY(value, var_args, flags, __error) \ +G_STMT_START { \ + const GValue *g_vl_value = (value); \ + guint g_vl_flags = (flags); \ + GType g_vl_value_type = G_VALUE_TYPE (g_vl_value); \ + GTypeValueTable *g_vl_vtable = g_type_value_table_peek (g_vl_value_type); \ + const gchar *g_vl_lcopy_format = g_vl_vtable->lcopy_format; \ + GTypeCValue g_vl_cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, }; \ + guint g_vl_n_values = 0; \ + \ + while (*g_vl_lcopy_format) \ + { \ + GTypeCValue *g_vl_cvalue = g_vl_cvalues + g_vl_n_values++; \ + \ + switch (*g_vl_lcopy_format++) \ + { \ + case G_VALUE_COLLECT_INT: \ + g_vl_cvalue->v_int = va_arg ((var_args), gint); \ + break; \ + case G_VALUE_COLLECT_LONG: \ + g_vl_cvalue->v_long = va_arg ((var_args), glong); \ + break; \ + case G_VALUE_COLLECT_INT64: \ + g_vl_cvalue->v_int64 = va_arg ((var_args), gint64); \ + break; \ + case G_VALUE_COLLECT_DOUBLE: \ + g_vl_cvalue->v_double = va_arg ((var_args), gdouble); \ + break; \ + case G_VALUE_COLLECT_POINTER: \ + g_vl_cvalue->v_pointer = va_arg ((var_args), gpointer); \ + break; \ + default: \ + g_assert_not_reached (); \ + } \ + } \ + *(__error) = g_vl_vtable->lcopy_value (g_vl_value, \ + g_vl_n_values, \ + g_vl_cvalues, \ + g_vl_flags); \ +} G_STMT_END + + +/** + * G_VALUE_COLLECT_FORMAT_MAX_LENGTH: + * + * The maximal number of #GTypeCValues which can be collected for a + * single #GValue. + */ +#define G_VALUE_COLLECT_FORMAT_MAX_LENGTH (8) + +G_END_DECLS + +#endif /* __GLIB_G_VALUE_COLLECTOR_H__ */ diff --git a/gobject/gvaluetransform.c b/glib/gvaluetransform.c similarity index 100% rename from gobject/gvaluetransform.c rename to glib/gvaluetransform.c diff --git a/gobject/gvaluetypes.c b/glib/gvaluetypes.c similarity index 99% rename from gobject/gvaluetypes.c rename to glib/gvaluetypes.c index 0d0e591ea..32c020a3d 100644 --- a/gobject/gvaluetypes.c +++ b/glib/gvaluetypes.c @@ -30,8 +30,6 @@ #include "gvaluetypes.h" #include "gtype-private.h" #include "gvaluecollector.h" -#include "gobject.h" -#include "gparam.h" #include "gboxed.h" #include "genums.h" @@ -1434,10 +1432,6 @@ g_strdup_value_contents (const GValue *value) if (!p) contents = g_strdup ("NULL"); - else if (G_VALUE_HOLDS_OBJECT (value)) - contents = g_strdup_printf ("((%s*) %p)", G_OBJECT_TYPE_NAME (p), p); - else if (G_VALUE_HOLDS_PARAM (value)) - contents = g_strdup_printf ("((%s*) %p)", G_PARAM_SPEC_TYPE_NAME (p), p); else if (G_VALUE_HOLDS (value, G_TYPE_STRV)) { GStrv strv = g_value_get_boxed (value); @@ -1462,7 +1456,7 @@ g_strdup_value_contents (const GValue *value) else if (G_VALUE_HOLDS_POINTER (value)) contents = g_strdup_printf ("((gpointer) %p)", p); else - contents = g_strdup ("???"); + contents = g_strdup_printf ("((%s*) %p)", g_type_name (G_VALUE_TYPE (value)), p); } else contents = g_strdup ("???"); diff --git a/gobject/gvaluetypes.h b/glib/gvaluetypes.h similarity index 87% rename from gobject/gvaluetypes.h rename to glib/gvaluetypes.h index afa659530..173c6d411 100644 --- a/gobject/gvaluetypes.h +++ b/glib/gvaluetypes.h @@ -21,11 +21,13 @@ #ifndef __G_VALUETYPES_H__ #define __G_VALUETYPES_H__ -#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION) -#error "Only can be included directly." +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." #endif -#include +#include +#include +#include G_BEGIN_DECLS @@ -150,7 +152,7 @@ G_BEGIN_DECLS * * Since: 2.66 */ -#define G_VALUE_IS_INTERNED_STRING(value) (G_VALUE_HOLDS_STRING (value) && ((value)->data[1].v_uint & G_VALUE_INTERNED_STRING)) GOBJECT_AVAILABLE_MACRO_IN_2_66 +#define G_VALUE_IS_INTERNED_STRING(value) (G_VALUE_HOLDS_STRING (value) && ((value)->data[1].v_uint & G_VALUE_INTERNED_STRING)) GLIB_AVAILABLE_MACRO_IN_2_66 /** * G_VALUE_HOLDS_POINTER: * @value: a valid #GValue structure @@ -190,118 +192,118 @@ G_BEGIN_DECLS /* --- prototypes --- */ -GOBJECT_DEPRECATED_IN_2_32_FOR(g_value_set_schar) +GLIB_DEPRECATED_IN_2_32_FOR(g_value_set_schar) void g_value_set_char (GValue *value, gchar v_char); -GOBJECT_DEPRECATED_IN_2_32_FOR(g_value_get_schar) +GLIB_DEPRECATED_IN_2_32_FOR(g_value_get_schar) gchar g_value_get_char (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_schar (GValue *value, gint8 v_char); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gint8 g_value_get_schar (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_uchar (GValue *value, guchar v_uchar); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL guchar g_value_get_uchar (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_boolean (GValue *value, gboolean v_boolean); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gboolean g_value_get_boolean (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_int (GValue *value, gint v_int); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gint g_value_get_int (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_uint (GValue *value, guint v_uint); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL guint g_value_get_uint (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_long (GValue *value, glong v_long); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL glong g_value_get_long (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_ulong (GValue *value, gulong v_ulong); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gulong g_value_get_ulong (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_int64 (GValue *value, gint64 v_int64); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gint64 g_value_get_int64 (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_uint64 (GValue *value, guint64 v_uint64); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL guint64 g_value_get_uint64 (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_float (GValue *value, gfloat v_float); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gfloat g_value_get_float (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_double (GValue *value, gdouble v_double); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gdouble g_value_get_double (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_string (GValue *value, const gchar *v_string); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_static_string (GValue *value, const gchar *v_string); -GOBJECT_AVAILABLE_IN_2_66 +GLIB_AVAILABLE_IN_2_66 void g_value_set_interned_string (GValue *value, const gchar *v_string); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL const gchar * g_value_get_string (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gchar* g_value_dup_string (const GValue *value); -GOBJECT_AVAILABLE_IN_2_80 +GLIB_AVAILABLE_IN_2_80 gchar* g_value_steal_string (GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_pointer (GValue *value, gpointer v_pointer); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gpointer g_value_get_pointer (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_gtype_get_type (void); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_gtype (GValue *value, GType v_gtype); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_value_get_gtype (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_set_variant (GValue *value, GVariant *variant); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_take_variant (GValue *value, GVariant *variant); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GVariant* g_value_get_variant (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GVariant* g_value_dup_variant (const GValue *value); /* Convenience for registering new pointer types */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL GType g_pointer_type_register_static (const gchar *name); /* debugging aid, describe value contents as string */ -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL gchar* g_strdup_value_contents (const GValue *value); -GOBJECT_AVAILABLE_IN_ALL +GLIB_AVAILABLE_IN_ALL void g_value_take_string (GValue *value, gchar *v_string); -GOBJECT_DEPRECATED_FOR(g_value_take_string) +GLIB_DEPRECATED_FOR(g_value_take_string) void g_value_set_string_take_ownership (GValue *value, gchar *v_string); diff --git a/glib/meson.build b/glib/meson.build index 2522356ee..5ea4f3cd3 100644 --- a/glib/meson.build +++ b/glib/meson.build @@ -22,6 +22,10 @@ glib_visibility_h = custom_target( install_dir: glib_sub_includedir, ) +# Expose as variable to be used by gobject-introspection +# when it includes GLib as a subproject +glib_types_h = files('glib-types.h') + glib_built_headers = [gversionmacros_h, glib_visibility_h] glib_sources += glib_built_headers glib_c_args_internal = [ @@ -168,6 +172,7 @@ install_headers(glib_deprecated_headers, glib_sub_headers = files( 'glib-autocleanups.h', 'glib-typeof.h', + 'glib-types.h', 'galloca.h', 'garray.h', 'gasyncqueue.h', @@ -176,6 +181,7 @@ glib_sub_headers = files( 'gbase64.h', 'gbitlock.h', 'gbookmarkfile.h', + 'gboxed.h', 'gbytes.h', 'gcharset.h', 'gchecksum.h', @@ -184,6 +190,7 @@ glib_sub_headers = files( 'gdate.h', 'gdatetime.h', 'gdir.h', + 'genums.h', 'genviron.h', 'gerror.h', 'gfileutils.h', @@ -235,11 +242,15 @@ glib_sub_headers = files( 'gtimezone.h', 'gtrashstack.h', 'gtree.h', + 'gtype.h', + 'gtypeplugin.h', 'gtypes.h', 'guuid.h', 'gunicode.h', 'guri.h', 'gutils.h', + 'gvalue.h', + 'gvaluetypes.h', 'gvarianttype.h', 'gvariant.h', 'gversion.h', @@ -266,10 +277,12 @@ glib_sources += files( 'garray.c', 'gasyncqueue.c', 'gatomic.c', + 'gatomicarray.c', 'gbacktrace.c', 'gbase64.c', 'gbitlock.c', 'gbookmarkfile.c', + 'gboxed.c', 'gbytes.c', 'gcharset.c', 'gchecksum.c', @@ -279,6 +292,7 @@ glib_sources += files( 'gdatetime.c', 'gdatetime-private.c', 'gdir.c', + 'genums.c', 'genviron.c', 'gerror.c', 'gfileutils.c', @@ -331,6 +345,8 @@ glib_sources += files( 'gtranslit.c', 'gtrashstack.c', 'gtree.c', + 'gtype.c', + 'gtypeplugin.c', 'guniprop.c', 'gutf8.c', 'gunibreak.c', @@ -339,6 +355,9 @@ glib_sources += files( 'guri.c', 'gutils.c', 'guuid.c', + 'gvalue.c', + 'gvaluetransform.c', + 'gvaluetypes.c', 'gvariant.c', 'gvariant-core.c', 'gvariant-parser.c', diff --git a/gobject/gclosure.c b/gobject/gclosure.c index 2552946e3..f1a918284 100644 --- a/gobject/gclosure.c +++ b/gobject/gclosure.c @@ -26,16 +26,15 @@ #include "../glib/gvalgrind.h" #include - #include #include "gclosure.h" + #include "gboxed.h" -#include "gobject.h" #include "genums.h" +#include "gobject-private.h" #include "gvalue.h" #include "gvaluetypes.h" -#include "gtype-private.h" /** @@ -91,6 +90,8 @@ * automatically removed when the objects they point to go away. */ +G_DEFINE_BOXED_TYPE (GClosure, g_closure, g_closure_ref, g_closure_unref) + #define CLOSURE_MAX_REF_COUNT ((1 << 15) - 1) #define CLOSURE_MAX_N_GUARDS ((1 << 1) - 1) #define CLOSURE_MAX_N_FNOTIFIERS ((1 << 2) - 1) diff --git a/gobject/gclosure.h b/gobject/gclosure.h index 2462bce5e..b6f86cb3b 100644 --- a/gobject/gclosure.h +++ b/gobject/gclosure.h @@ -24,7 +24,8 @@ #error "Only can be included directly." #endif -#include +#include +#include G_BEGIN_DECLS @@ -72,6 +73,13 @@ G_BEGIN_DECLS */ #define G_CALLBACK(f) ((GCallback) (f)) +/** + * G_TYPE_CLOSURE: + * + * The #GType for #GClosure. + */ +#define G_TYPE_CLOSURE (g_closure_get_type ()) + /* -- typedefs --- */ typedef struct _GClosure GClosure; @@ -219,6 +227,9 @@ struct _GCClosure /* --- prototypes --- */ +GOBJECT_AVAILABLE_IN_ALL +GType g_closure_get_type (void) G_GNUC_CONST; + GOBJECT_AVAILABLE_IN_ALL GClosure* g_cclosure_new (GCallback callback_func, gpointer user_data, diff --git a/gobject/gtype-private.h b/gobject/gobject-private.h similarity index 77% rename from gobject/gtype-private.h rename to gobject/gobject-private.h index ae0182dec..26d324d69 100644 --- a/gobject/gtype-private.h +++ b/gobject/gobject-private.h @@ -23,7 +23,8 @@ #error "Only can be included directly." #endif -#include "gboxed.h" +#include "../glib/gtype-private.h" + #include "gclosure.h" #include "gobject.h" @@ -38,7 +39,7 @@ #ifdef G_ENABLE_DEBUG #define GOBJECT_IF_DEBUG(debug_type, code_block) \ G_STMT_START { \ - if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) \ + if (GLIB_PRIVATE_CALL (g_type_has_debug_flag) (G_TYPE_DEBUG_ ## debug_type)) \ { code_block; } \ } G_STMT_END #else /* !G_ENABLE_DEBUG */ @@ -47,10 +48,6 @@ G_STMT_START { \ G_BEGIN_DECLS -G_GNUC_BEGIN_IGNORE_DEPRECATIONS -extern GTypeDebugFlags _g_type_debug_flags; -G_GNUC_END_IGNORE_DEPRECATIONS - typedef struct _GRealClosure GRealClosure; struct _GRealClosure { @@ -64,25 +61,11 @@ struct _GRealClosure #define G_REAL_CLOSURE(_c) \ ((GRealClosure *)G_STRUCT_MEMBER_P ((_c), -G_STRUCT_OFFSET (GRealClosure, closure))) -void _g_value_c_init (void); /* sync with gvalue.c */ -void _g_value_types_init (void); /* sync with gvaluetypes.c */ -void _g_enum_types_init (void); /* sync with genums.c */ void _g_param_type_init (void); /* sync with gparam.c */ -void _g_boxed_type_init (void); /* sync with gboxed.c */ void _g_object_type_init (void); /* sync with gobject.c */ void _g_param_spec_types_init (void); /* sync with gparamspecs.c */ -void _g_value_transforms_init (void); /* sync with gvaluetransform.c */ void _g_signal_init (void); /* sync with gsignal.c */ -/* for gboxed.c */ -gpointer _g_type_boxed_copy (GType type, - gpointer value); -void _g_type_boxed_free (GType type, - gpointer value); -void _g_type_boxed_init (GType type, - GBoxedCopyFunc copy_func, - GBoxedFreeFunc free_func); - gboolean _g_closure_is_void (GClosure *closure, gpointer instance); gboolean _g_closure_supports_invoke_va (GClosure *closure); diff --git a/gobject/gobject.c b/gobject/gobject.c index d7f3d7a91..a6a59e564 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -27,9 +27,9 @@ #include #include "../glib/glib-private.h" +#include "../glib/gtype-private.h" -#include "gobject.h" -#include "gtype-private.h" +#include "gobject-private.h" #include "gvaluecollector.h" #include "gsignal.h" #include "gparamspecs.h" @@ -895,7 +895,7 @@ _g_object_type_init (void) * * See: https://bugzilla.gnome.org/show_bug.cgi?id=769504 */ - if (_g_type_debug_flags & G_TYPE_DEBUG_OBJECTS) \ + if (GLIB_PRIVATE_CALL (g_type_has_debug_flag) (G_TYPE_DEBUG_OBJECTS)) { debug_objects_ht = g_hash_table_new (g_direct_hash, NULL); # ifndef G_HAS_CONSTRUCTORS @@ -2666,6 +2666,8 @@ g_object_new_internal (GObjectClass *class, if (nqueue) g_object_notify_queue_thaw (object, nqueue, FALSE); + TRACE(GOBJECT_OBJECT_NEW(object, class->g_type_class.g_type)); + return object; } @@ -5825,3 +5827,110 @@ g_weak_ref_set (GWeakRef *weak_ref, _weak_ref_set (weak_ref, object, FALSE); } + +static void +gobject_init (void) +{ + /* G_TYPE_PARAM */ + _g_param_type_init (); + + /* G_TYPE_OBJECT */ + _g_object_type_init (); + + /* G_TYPE_PARAM_* pspec types */ + _g_param_spec_types_init (); + + /* Signal system */ + _g_signal_init (); +} + +#ifdef G_PLATFORM_WIN32 + +void gobject_win32_init (void); + +void +gobject_win32_init (void) +{ + /* May be called more than once in static compilation mode */ + static gboolean win32_already_init = FALSE; + if (!win32_already_init) + { + win32_already_init = TRUE; + gobject_init (); + } +} + +#ifndef GLIB_STATIC_COMPILATION + +BOOL WINAPI DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved); + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + gobject_win32_init (); + break; + + default: + /* do nothing */ + ; + } + + return TRUE; +} + +#elif defined(G_HAS_CONSTRUCTORS) /* && G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION */ +extern void glib_win32_init (void); + +#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor) +#endif + +G_DEFINE_CONSTRUCTOR(gobject_init_ctor) + +static void +gobject_init_ctor (void) +{ + /* When built dynamically, module initialization is done through DllMain + * function which is called when the dynamic library is loaded by the glib + * module. So, in dynamic configuration glib is always initialized BEFORE + * gobject. + * + * When built statically, initialization mechanism relies on hooking + * functions to the CRT section directly at compilation time. As we don't + * control how each compilation unit will be built and in which order, we + * obtain the same kind of issue as the "static initialization order fiasco". + * In this case, we must ensure explicitly that glib is always well + * initialized BEFORE gobject. + */ + glib_win32_init (); + gobject_win32_init (); +} + +#else /* G_PLATFORM_WIN32 && GLIB_STATIC_COMPILATION && !G_HAS_CONSTRUCTORS */ +# error Your platform/compiler is missing constructor support +#endif /* GLIB_STATIC_COMPILATION */ + +#elif defined(G_HAS_CONSTRUCTORS) /* && !G_PLATFORM_WIN32 */ + +#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gobject_init_ctor) +#endif + +G_DEFINE_CONSTRUCTOR (gobject_init_ctor) + +static void +gobject_init_ctor (void) +{ + gobject_init (); +} + +#else /* !G_PLATFORM_WIN32 && !G_HAS_CONSTRUCTORS */ +#error Your platform/compiler is missing constructor support +#endif /* G_PLATFORM_WIN32 */ diff --git a/gobject/gobject.h b/gobject/gobject.h index 7d987c4b9..aa0a6fcf4 100644 --- a/gobject/gobject.h +++ b/gobject/gobject.h @@ -23,16 +23,24 @@ #error "Only can be included directly." #endif -#include -#include -#include -#include -#include -#include +#include + +#include +#include +#include +#include G_BEGIN_DECLS /* --- type macros --- */ + +/** + * G_TYPE_OBJECT: + * + * The fundamental type for #GObject. + */ +#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20) + /** * G_TYPE_IS_OBJECT: * @type: Type id to check diff --git a/gobject/gobject_probes.d b/gobject/gobject_probes.d index bddbfae75..b5aee3d02 100644 --- a/gobject/gobject_probes.d +++ b/gobject/gobject_probes.d @@ -1,5 +1,4 @@ provider gobject { - probe type__new(char *, unsigned long, unsigned long); probe object__new(void*, unsigned long); probe object__ref(void*, unsigned long, unsigned int); probe object__unref(void*, unsigned long, unsigned int); diff --git a/gobject/gparam.c b/gobject/gparam.c index 7ad8e76ae..8c9089eaa 100644 --- a/gobject/gparam.c +++ b/gobject/gparam.c @@ -28,7 +28,7 @@ #include "gparam.h" #include "gparamspecs.h" #include "gvaluecollector.h" -#include "gtype-private.h" +#include "gobject-private.h" /** * GParamSpec: (ref-func g_param_spec_ref_sink) (unref-func g_param_spec_unref) (set-value-func g_value_set_param) (get-value-func g_value_get_param) diff --git a/gobject/gparam.h b/gobject/gparam.h index 147ff53a2..0cf94e0b5 100644 --- a/gobject/gparam.h +++ b/gobject/gparam.h @@ -25,11 +25,18 @@ #error "Only can be included directly." #endif -#include +#include +#include G_BEGIN_DECLS /* --- standard type macros --- */ +/** + * G_TYPE_PARAM: + * + * The fundamental type from which all #GParamSpec types are derived. + */ +#define G_TYPE_PARAM G_TYPE_MAKE_FUNDAMENTAL (19) /** * G_TYPE_IS_PARAM: * @type: a #GType ID diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c index 99bcf6085..7c4d5815f 100644 --- a/gobject/gparamspecs.c +++ b/gobject/gparamspecs.c @@ -31,7 +31,7 @@ #endif #include "gparamspecs.h" -#include "gtype-private.h" +#include "gobject-private.h" #include "gvaluecollector.h" #include "gvaluearray.h" diff --git a/gobject/gparamspecs.h b/gobject/gparamspecs.h index eaabc10dc..1da022c17 100644 --- a/gobject/gparamspecs.h +++ b/gobject/gparamspecs.h @@ -25,10 +25,7 @@ #error "Only can be included directly." #endif -#include -#include -#include -#include +#include G_BEGIN_DECLS diff --git a/gobject/gsignal.c b/gobject/gsignal.c index 27484b3a0..6629726b3 100644 --- a/gobject/gsignal.c +++ b/gobject/gsignal.c @@ -29,13 +29,13 @@ #include #include +#define GLIB_COMPILATION +#include "../glib/gvaluecollector.h" + #include "gsignal.h" -#include "gtype-private.h" +#include "gobject-private.h" #include "gbsearcharray.h" -#include "gvaluecollector.h" -#include "gvaluetypes.h" #include "gobject.h" -#include "genums.h" #include "gobject_trace.h" diff --git a/gobject/gsignal.h b/gobject/gsignal.h index b84e66ded..faa03f2e8 100644 --- a/gobject/gsignal.h +++ b/gobject/gsignal.h @@ -23,10 +23,12 @@ #error "Only can be included directly." #endif -#include -#include -#include -#include +#include +#include + +#include +#include +#include G_BEGIN_DECLS diff --git a/gobject/gsourceclosure.h b/gobject/gsourceclosure.h index d60916542..178f057ad 100644 --- a/gobject/gsourceclosure.h +++ b/gobject/gsourceclosure.h @@ -24,10 +24,27 @@ #endif #include -#include G_BEGIN_DECLS +/** + * G_TYPE_IO_CHANNEL: + * + * The #GType for #GIOChannel. + */ +#define G_TYPE_IO_CHANNEL (g_io_channel_get_type ()) +GOBJECT_AVAILABLE_IN_ALL +GType g_io_channel_get_type (void) G_GNUC_CONST; + +/** + * G_TYPE_IO_CONDITION: + * + * The #GType for #GIOCondition. + */ +#define G_TYPE_IO_CONDITION (g_io_condition_get_type ()) +GOBJECT_AVAILABLE_IN_ALL +GType g_io_condition_get_type (void) G_GNUC_CONST; + GOBJECT_AVAILABLE_IN_ALL void g_source_set_closure (GSource *source, GClosure *closure); diff --git a/gobject/gtypemodule.c b/gobject/gtypemodule.c index b7f61c674..0b6844b53 100644 --- a/gobject/gtypemodule.c +++ b/gobject/gtypemodule.c @@ -21,7 +21,6 @@ #include -#include "gtypeplugin.h" #include "gtypemodule.h" diff --git a/gobject/gtypemodule.h b/gobject/gtypemodule.h index fba714bc2..81d952232 100644 --- a/gobject/gtypemodule.h +++ b/gobject/gtypemodule.h @@ -24,7 +24,6 @@ #endif #include -#include G_BEGIN_DECLS diff --git a/gobject/gvaluearray.c b/gobject/gvaluearray.c index 8c6b81d2b..a22c61e24 100644 --- a/gobject/gvaluearray.c +++ b/gobject/gvaluearray.c @@ -26,8 +26,15 @@ #include #include /* qsort() */ +#ifndef GOBJECT_DISABLE_DEPRECATION_WARNINGS +#define GOBJECT_DISABLE_DEPRECATION_WARNINGS +#endif + #include "gvaluearray.h" +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +G_DEFINE_BOXED_TYPE (GValueArray, g_value_array, g_value_array_copy, g_value_array_free) +G_GNUC_END_IGNORE_DEPRECATIONS /** * GValueArray: diff --git a/gobject/gvaluearray.h b/gobject/gvaluearray.h index d6052c0ae..67ae35a14 100644 --- a/gobject/gvaluearray.h +++ b/gobject/gvaluearray.h @@ -25,7 +25,8 @@ #error "Only can be included directly." #endif -#include +#include +#include G_BEGIN_DECLS diff --git a/gobject/gvaluecollector.h b/gobject/gvaluecollector.h index 35608b107..88fa178e3 100644 --- a/gobject/gvaluecollector.h +++ b/gobject/gvaluecollector.h @@ -19,10 +19,18 @@ * gvaluecollector.h: GValue varargs stubs */ -#ifndef __G_VALUE_COLLECTOR_H__ -#define __G_VALUE_COLLECTOR_H__ +#ifndef __GOBJECT_G_VALUE_COLLECTOR_H__ +#define __GOBJECT_G_VALUE_COLLECTOR_H__ -#include +/* Sadly, this file is part of the API but it's not included in + * glib.h or glib-object.h, which means we need to retain a copy inside GObject, + * even if GLib has its own header file, in order to maintain source compatibility. + */ +#ifdef GLIB_GVALUECOLLECTOR_H +#error "You cannot include glib/gvaluecollector.h and gobject/gvaluecollector.h at the same time" +#endif + +#include G_BEGIN_DECLS @@ -277,4 +285,4 @@ G_STMT_START { \ G_END_DECLS -#endif /* __G_VALUE_COLLECTOR_H__ */ +#endif /* __GOBJECT_G_VALUE_COLLECTOR_H__ */ diff --git a/gobject/meson.build b/gobject/meson.build index 748f72bc1..58d385465 100644 --- a/gobject/meson.build +++ b/gobject/meson.build @@ -2,12 +2,9 @@ gobject_includedir = glib_includedir / 'gobject' gobject_install_headers = files( 'gobject-autocleanups.h', - 'glib-types.h', 'gbinding.h', 'gbindinggroup.h', - 'gboxed.h', 'gclosure.h', - 'genums.h', 'gmarshal.h', 'gobject.h', 'gparam.h', @@ -15,13 +12,9 @@ gobject_install_headers = files( 'gsignal.h', 'gsignalgroup.h', 'gsourceclosure.h', - 'gtype.h', 'gtypemodule.h', - 'gtypeplugin.h', - 'gvalue.h', 'gvaluearray.h', 'gvaluecollector.h', - 'gvaluetypes.h', 'gobjectnotifyqueue.c', # sic ) @@ -38,12 +31,9 @@ gobject_sources += gobject_visibility_h install_headers(gobject_install_headers, install_dir : gobject_includedir) gobject_sources += files( - 'gatomicarray.c', 'gbinding.c', 'gbindinggroup.c', - 'gboxed.c', 'gclosure.c', - 'genums.c', 'gmarshal.c', 'gobject.c', 'gparam.c', @@ -51,13 +41,8 @@ gobject_sources += files( 'gsignal.c', 'gsignalgroup.c', 'gsourceclosure.c', - 'gtype.c', 'gtypemodule.c', - 'gtypeplugin.c', - 'gvalue.c', 'gvaluearray.c', - 'gvaluetransform.c', - 'gvaluetypes.c', ) if host_system == 'windows' and glib_build_shared @@ -134,10 +119,6 @@ glib_enumtypes_c = custom_target('glib_enumtypes_c', '--template', files('glib-enumtypes.c.template'), '@INPUT@']) -# Expose as variable to be used by gobject-introspection -# when it includes GLib as a subproject -glib_types_h = files('glib-types.h') - libgobject = library('gobject-2.0', gobject_dtrace_obj, gobject_dtrace_hdr, glib_enumtypes_h, glib_enumtypes_c, sources : gobject_sources,