diff options
-rw-r--r-- | .gitlab-ci.yml | 27 | ||||
-rw-r--r-- | docs/reference/glib/glib-sections.txt | 3 | ||||
-rw-r--r-- | gio/gdbusconnection.c | 8 | ||||
-rw-r--r-- | gio/gdbusprivate.c | 2 | ||||
-rw-r--r-- | gio/gtestdbus.c | 2 | ||||
-rw-r--r-- | glib/garray.c | 129 | ||||
-rw-r--r-- | glib/garray.h | 12 | ||||
-rw-r--r-- | glib/gmacros.h | 10 | ||||
-rw-r--r-- | glib/gnode.h | 15 | ||||
-rw-r--r-- | glib/gtypes.h | 14 | ||||
-rw-r--r-- | glib/gunicode.h | 2 | ||||
-rw-r--r-- | glib/guniprop.c | 2 | ||||
-rw-r--r-- | glib/tests/array-test.c | 258 | ||||
-rw-r--r-- | glib/tests/unicode.c | 2 | ||||
-rw-r--r-- | gobject/gvalue.c | 65 |
15 files changed, 498 insertions, 53 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 81fddc25f..9f1643191 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -227,6 +227,33 @@ freebsd-11-x86_64: - "_build/meson-logs" - "_build/${CI_JOB_NAME}-report.xml" +freebsd-12-x86_64: + stage: build + only: + - branches@GNOME/glib + tags: + - freebsd-12 + variables: + CPPFLAGS: -I/usr/local/include + LDFLAGS: -L/usr/local/lib -Wl,--disable-new-dtags + LANG: en_US.UTF-8 + script: + - meson ${MESON_COMMON_OPTIONS} -Db_lundef=false -Diconv=external -Dxattr=false _build + - ninja -C _build + - bash -x ./.gitlab-ci/run-tests.sh + except: + - tags + artifacts: + reports: + junit: "_build/${CI_JOB_NAME}-report.xml" + name: "glib-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}" + when: always + paths: + - "_build/config.h" + - "_build/glib/glibconfig.h" + - "_build/meson-logs" + - "_build/${CI_JOB_NAME}-report.xml" + coverage: image: registry.gitlab.gnome.org/gnome/glib/fedora:v1 stage: coverage diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 888886aba..058000e16 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -2638,11 +2638,14 @@ GPtrArray g_ptr_array_new g_ptr_array_sized_new g_ptr_array_new_with_free_func +g_ptr_array_copy g_ptr_array_new_full g_ptr_array_set_free_func g_ptr_array_ref g_ptr_array_unref g_ptr_array_add +g_ptr_array_extend +g_ptr_array_extend_and_steal g_ptr_array_insert g_ptr_array_remove g_ptr_array_remove_index diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c index 82050204e..26bfc00ac 100644 --- a/gio/gdbusconnection.c +++ b/gio/gdbusconnection.c @@ -128,7 +128,7 @@ * The #GDBusConnection type is used for D-Bus connections to remote * peers such as a message buses. It is a low-level API that offers a * lot of flexibility. For instance, it lets you establish a connection - * over any transport that can by represented as an #GIOStream. + * over any transport that can by represented as a #GIOStream. * * This class is rarely used directly in D-Bus clients. If you are writing * a D-Bus client, it is often easier to use the g_bus_own_name(), @@ -2968,8 +2968,8 @@ g_dbus_connection_new_for_address_sync (const gchar *address, * more details. * * Note that this function should be used with care. Most modern UNIX - * desktops tie the notion of a user session the session bus, and expect - * all of a users applications to quit when their bus connection goes away. + * desktops tie the notion of a user session with the session bus, and expect + * all of a user's applications to quit when their bus connection goes away. * If you are setting @exit_on_close to %FALSE for the shared session * bus connection, you should make sure that your application exits * when the user session ends. @@ -7364,7 +7364,7 @@ bus_get_async_initable_cb (GObject *source_object, * When the operation is finished, @callback will be invoked. You can * then call g_bus_get_finish() to get the result of the operation. * - * This is a asynchronous failable function. See g_bus_get_sync() for + * This is an asynchronous failable function. See g_bus_get_sync() for * the synchronous version. * * Since: 2.26 diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c index 488fe50c4..0421ca56c 100644 --- a/gio/gdbusprivate.c +++ b/gio/gdbusprivate.c @@ -701,7 +701,7 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream, worker); #endif - /* TODO: hmm, hmm... */ + /* The read failed, which could mean the dbus-daemon was sent SIGTERM. */ if (bytes_read == 0) { g_set_error (&error, diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c index 2fc2d51f5..99c9cf8ea 100644 --- a/gio/gtestdbus.c +++ b/gio/gtestdbus.c @@ -801,7 +801,7 @@ g_test_dbus_stop (GTestDBus *self) * Stop the session bus started by g_test_dbus_up(). * * This will wait for the singleton returned by g_bus_get() or g_bus_get_sync() - * is destroyed. This is done to ensure that the next unit test won't get a + * to be destroyed. This is done to ensure that the next unit test won't get a * leaked singleton from this test. */ void diff --git a/glib/garray.c b/glib/garray.c index 84c816da6..2b7957a92 100644 --- a/glib/garray.c +++ b/glib/garray.c @@ -923,6 +923,52 @@ g_ptr_array_new (void) } /** + * g_ptr_array_copy: + * @array: #GPtrArray to duplicate + * @func: (nullable): a copy function used to copy every element in the array + * @user_data: user data passed to the copy function @func, or %NULL + * + * Makes a full (deep) copy of a #GPtrArray. + * + * @func, as a #GCopyFunc, takes two arguments, the data to be copied + * and a @user_data pointer. On common processor architectures, it's safe to + * pass %NULL as @user_data if the copy function takes only one argument. You + * may get compiler warnings from this though if compiling with GCC’s + * `-Wcast-function-type` warning. + * + * If @func is %NULL, then only the pointers (and not what they are + * pointing to) are copied to the new #GPtrArray. + * + * Returns: (transfer full): a deep copy of the initial #GPtrArray. + * + * Since: 2.62 + **/ +GPtrArray * +g_ptr_array_copy (GPtrArray *array, + GCopyFunc func, + gpointer user_data) +{ + gsize i; + GPtrArray *new_array; + + g_return_val_if_fail (array != NULL, NULL); + + new_array = g_ptr_array_sized_new (array->len); + if (func != NULL) + { + for (i = 0; i < array->len; i++) + new_array->pdata[i] = func (array->pdata[i], user_data); + } + else + { + memcpy (new_array->pdata, array->pdata, + array->len * sizeof (*array->pdata)); + } + + return new_array; +} + +/** * g_ptr_array_sized_new: * @reserved_size: number of pointers preallocated * @@ -1493,6 +1539,89 @@ g_ptr_array_add (GPtrArray *array, } /** + * g_ptr_array_extend: + * @array_to_extend: a #GPtrArray. + * @array: (transfer none): a #GPtrArray to add to the end of @array_to_extend. + * @func: (nullable): a copy function used to copy every element in the array + * @user_data: user data passed to the copy function @func, or %NULL + * + * Adds all pointers of @array to the end of the array @array_to_extend. + * The array will grow in size automatically if needed. @array_to_extend is + * modified in-place. + * + * @func, as a #GCopyFunc, takes two arguments, the data to be copied + * and a @user_data pointer. On common processor architectures, it's safe to + * pass %NULL as @user_data if the copy function takes only one argument. You + * may get compiler warnings from this though if compiling with GCC’s + * `-Wcast-function-type` warning. + * + * If @func is %NULL, then only the pointers (and not what they are + * pointing to) are copied to the new #GPtrArray. + * + * Since: 2.62 + **/ +void +g_ptr_array_extend (GPtrArray *array_to_extend, + GPtrArray *array, + GCopyFunc func, + gpointer user_data) +{ + GRealPtrArray *rarray_to_extend = (GRealPtrArray *) array_to_extend; + gsize i; + + g_return_if_fail (array_to_extend != NULL); + g_return_if_fail (array != NULL); + + g_ptr_array_maybe_expand (rarray_to_extend, array->len); + + if (func != NULL) + { + for (i = 0; i < array->len; i++) + rarray_to_extend->pdata[i + rarray_to_extend->len] = + func (array->pdata[i], user_data); + } + else + { + memcpy (rarray_to_extend->pdata + rarray_to_extend->len, array->pdata, + array->len * sizeof (*array->pdata)); + } + + rarray_to_extend->len += array->len; +} + +/** + * g_ptr_array_extend_and_steal: + * @array_to_extend: (transfer none): a #GPtrArray. + * @array: (transfer container): a #GPtrArray to add to the end of + * @array_to_extend. + * + * Adds all the pointers in @array to the end of @array_to_extend, transferring + * ownership of each element from @array to @array_to_extend and modifying + * @array_to_extend in-place. @array is then freed. + * + * As with g_ptr_array_free(), @array will be destroyed if its reference count + * is 1. If its reference count is higher, it will be decremented and the + * length of @array set to zero. + * + * Since: 2.62 + **/ +void +g_ptr_array_extend_and_steal (GPtrArray *array_to_extend, + GPtrArray *array) +{ + gpointer *pdata; + + g_ptr_array_extend (array_to_extend, array, NULL, NULL); + + /* Get rid of @array without triggering the GDestroyNotify attached + * to the elements moved from @array to @array_to_extend. */ + pdata = g_steal_pointer (&array->pdata); + array->len = 0; + g_ptr_array_unref (array); + g_free (pdata); +} + +/** * g_ptr_array_insert: * @array: a #GPtrArray * @index_: the index to place the new element at, or -1 to append diff --git a/glib/garray.h b/glib/garray.h index 6c8c2c363..e97718b74 100644 --- a/glib/garray.h +++ b/glib/garray.h @@ -130,6 +130,10 @@ GLIB_AVAILABLE_IN_ALL GPtrArray* g_ptr_array_new (void); GLIB_AVAILABLE_IN_ALL GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify element_free_func); +GLIB_AVAILABLE_IN_2_62 +GPtrArray *g_ptr_array_copy (GPtrArray *array, + GCopyFunc func, + gpointer user_data); GLIB_AVAILABLE_IN_ALL GPtrArray* g_ptr_array_sized_new (guint reserved_size); GLIB_AVAILABLE_IN_ALL @@ -173,6 +177,14 @@ GPtrArray *g_ptr_array_remove_range (GPtrArray *array, GLIB_AVAILABLE_IN_ALL void g_ptr_array_add (GPtrArray *array, gpointer data); +GLIB_AVAILABLE_IN_2_62 +void g_ptr_array_extend (GPtrArray *array_to_extend, + GPtrArray *array, + GCopyFunc func, + gpointer user_data); +GLIB_AVAILABLE_IN_2_62 +void g_ptr_array_extend_and_steal (GPtrArray *array_to_extend, + GPtrArray *array); GLIB_AVAILABLE_IN_2_40 void g_ptr_array_insert (GPtrArray *array, gint index_, diff --git a/glib/gmacros.h b/glib/gmacros.h index 1c8d64699..c101da6cd 100644 --- a/glib/gmacros.h +++ b/glib/gmacros.h @@ -734,13 +734,21 @@ #ifndef __GI_SCANNER__ /* The static assert macro really confuses the introspection parser */ #define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2 #define G_PASTE(identifier1,identifier2) G_PASTE_ARGS (identifier1, identifier2) +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define G_STATIC_ASSERT(expr) _Static_assert (expr, "Expression evaluates to false") +#define G_STATIC_ASSERT_EXPR(expr) _Static_assert (expr, "Expression evaluates to false") +#elif defined(__cplusplus) && __cplusplus >= 201103L +#define G_STATIC_ASSERT(expr) static_assert (expr, "Expression evaluates to false") +#define G_STATIC_ASSERT_EXPR(expr) static_assert (expr, "Expression evaluates to false") +#else #ifdef __COUNTER__ #define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED #else #define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __LINE__)[(expr) ? 1 : -1] G_GNUC_UNUSED #endif #define G_STATIC_ASSERT_EXPR(expr) ((void) sizeof (char[(expr) ? 1 : -1])) -#endif +#endif /* __STDC_VERSION__ */ +#endif /* !__GI_SCANNER__ */ /* Provide a string identifying the current code position */ #if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__cplusplus) diff --git a/glib/gnode.h b/glib/gnode.h index b7220a44c..693e6154d 100644 --- a/glib/gnode.h +++ b/glib/gnode.h @@ -60,21 +60,6 @@ typedef gboolean (*GNodeTraverseFunc) (GNode *node, typedef void (*GNodeForeachFunc) (GNode *node, gpointer data); -/** - * GCopyFunc: - * @src: (not nullable): A pointer to the data which should be copied - * @data: Additional data - * - * A function of this signature is used to copy the node data - * when doing a deep-copy of a tree. - * - * Returns: (not nullable): A pointer to the copy - * - * Since: 2.4 - */ -typedef gpointer (*GCopyFunc) (gconstpointer src, - gpointer data); - /* N-way tree implementation */ struct _GNode diff --git a/glib/gtypes.h b/glib/gtypes.h index 3eba019be..000c4ca31 100644 --- a/glib/gtypes.h +++ b/glib/gtypes.h @@ -119,6 +119,20 @@ typedef void (*GHFunc) (gpointer key, gpointer user_data); /** + * GCopyFunc: + * @src: (not nullable): A pointer to the data which should be copied + * @data: Additional data + * + * A function of this signature is used to copy the node data + * when doing a deep-copy of a tree. + * + * Returns: (not nullable): A pointer to the copy + * + * Since: 2.4 + */ +typedef gpointer (*GCopyFunc) (gconstpointer src, + gpointer data); +/** * GFreeFunc: * @data: a data pointer * diff --git a/glib/gunicode.h b/glib/gunicode.h index 201af5ce8..c48a8be2e 100644 --- a/glib/gunicode.h +++ b/glib/gunicode.h @@ -561,7 +561,7 @@ typedef enum G_UNICODE_SCRIPT_KHUDAWADI, /* Sind */ G_UNICODE_SCRIPT_LINEAR_A, /* Lina */ G_UNICODE_SCRIPT_MAHAJANI, /* Mahj */ - G_UNICODE_SCRIPT_MANICHAEAN, /* Manu */ + G_UNICODE_SCRIPT_MANICHAEAN, /* Mani */ G_UNICODE_SCRIPT_MENDE_KIKAKUI, /* Mend */ G_UNICODE_SCRIPT_MODI, /* Modi */ G_UNICODE_SCRIPT_MRO, /* Mroo */ diff --git a/glib/guniprop.c b/glib/guniprop.c index 9a79e4316..9f67d9a4e 100644 --- a/glib/guniprop.c +++ b/glib/guniprop.c @@ -1425,7 +1425,7 @@ static const guint32 iso15924_tags[] = PACK ('S','i','n','d'), /* G_UNICODE_SCRIPT_KHUDAWADI */ PACK ('L','i','n','a'), /* G_UNICODE_SCRIPT_LINEAR_A */ PACK ('M','a','h','j'), /* G_UNICODE_SCRIPT_MAHAJANI */ - PACK ('M','a','n','u'), /* G_UNICODE_SCRIPT_MANICHAEAN */ + PACK ('M','a','n','i'), /* G_UNICODE_SCRIPT_MANICHAEAN */ PACK ('M','e','n','d'), /* G_UNICODE_SCRIPT_MENDE_KIKAKUI */ PACK ('M','o','d','i'), /* G_UNICODE_SCRIPT_MODI */ PACK ('M','r','o','o'), /* G_UNICODE_SCRIPT_MRO */ diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c index e0a6109eb..217ef9274 100644 --- a/glib/tests/array-test.c +++ b/glib/tests/array-test.c @@ -23,7 +23,6 @@ */ #undef G_DISABLE_ASSERT -#undef G_LOG_DOMAIN #include <stdio.h> #include <stdlib.h> @@ -746,6 +745,260 @@ pointer_array_free_func (void) g_assert_cmpint (num_free_func_invocations, ==, 0); } +static gpointer +ptr_array_copy_func (gconstpointer src, gpointer userdata) +{ + gsize *dst = g_malloc (sizeof (gsize)); + *dst = *((gsize *) src); + return dst; +} + +/* Test the g_ptr_array_copy() function */ +static void +pointer_array_copy (void) +{ + GPtrArray *ptr_array, *ptr_array2; + gsize i; + const gsize array_size = 100; + gsize *array_test = g_malloc (array_size * sizeof (gsize)); + + g_test_summary ("Check all normal behaviour of stealing elements from one " + "array to append to another, covering different array sizes " + "and element copy functions"); + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + ptr_array = g_ptr_array_copy (NULL, NULL, NULL); + g_test_assert_expected_messages (); + g_assert_cmpuint ((gsize) ptr_array, ==, (gsize) NULL); + } + + /* Initializing array_test */ + for (i = 0; i < array_size; i++) + array_test[i] = i; + + /* Test copy an empty array */ + ptr_array = g_ptr_array_sized_new (0); + ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL); + + g_ptr_array_unref (ptr_array); + g_ptr_array_unref (ptr_array2); + + /* Test simple copy */ + ptr_array = g_ptr_array_sized_new (array_size); + + for (i = 0; i < array_size; i++) + g_ptr_array_add (ptr_array, &array_test[i]); + + ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), ==, + (gsize) g_ptr_array_index (ptr_array2, i)); + + g_ptr_array_free (ptr_array2, TRUE); + + /* Test copy through GCopyFunc */ + ptr_array2 = g_ptr_array_copy (ptr_array, ptr_array_copy_func, NULL); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), !=, + (gsize) g_ptr_array_index (ptr_array2, i)); + + for (i = 0; i < array_size; i++) + free(ptr_array2->pdata[i]); + + g_ptr_array_free (ptr_array2, TRUE); + + /* Final cleanup */ + g_ptr_array_free (ptr_array, TRUE); + g_free (array_test); +} + +/* Test the g_ptr_array_extend() function */ +static void +pointer_array_extend (void) +{ + GPtrArray *ptr_array, *ptr_array2; + gsize i; + const gsize array_size = 100; + gsize *array_test = g_malloc (array_size * sizeof (gsize)); + + if (g_test_undefined ()) + { + /* Testing degenerated cases */ + ptr_array = g_ptr_array_sized_new (0); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_ptr_array_extend (NULL, ptr_array, NULL, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*!= NULL*"); + g_ptr_array_extend (ptr_array, NULL, NULL, NULL); + g_test_assert_expected_messages (); + + g_ptr_array_unref (ptr_array); + } + + /* Initializing array_test */ + for (i = 0; i < array_size; i++) + array_test[i] = i; + + /* Testing extend with array of size zero */ + ptr_array = g_ptr_array_sized_new (0); + ptr_array2 = g_ptr_array_sized_new (0); + + g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL); + + g_assert_cmpuint (ptr_array->len, ==, 0); + g_assert_cmpuint (ptr_array2->len, ==, 0); + + g_ptr_array_unref (ptr_array); + g_ptr_array_unref (ptr_array2); + + /* Testing extend an array of size zero */ + ptr_array = g_ptr_array_sized_new (array_size); + ptr_array2 = g_ptr_array_sized_new (0); + + for (i = 0; i < array_size; i++) + { + g_ptr_array_add (ptr_array, &array_test[i]); + } + + g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i); + + g_ptr_array_unref (ptr_array); + g_ptr_array_unref (ptr_array2); + + /* Testing extend an array of size zero */ + ptr_array = g_ptr_array_sized_new (0); + ptr_array2 = g_ptr_array_sized_new (array_size); + + for (i = 0; i < array_size; i++) + { + g_ptr_array_add (ptr_array2, &array_test[i]); + } + + g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i); + + g_ptr_array_unref (ptr_array); + g_ptr_array_unref (ptr_array2); + + /* Testing simple extend */ + ptr_array = g_ptr_array_sized_new (array_size / 2); + ptr_array2 = g_ptr_array_sized_new (array_size / 2); + + for (i = 0; i < array_size / 2; i++) + { + g_ptr_array_add (ptr_array, &array_test[i]); + g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]); + } + + g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i); + + g_ptr_array_unref (ptr_array); + g_ptr_array_unref (ptr_array2); + + /* Testing extend with GCopyFunc */ + ptr_array = g_ptr_array_sized_new (array_size / 2); + ptr_array2 = g_ptr_array_sized_new (array_size / 2); + + for (i = 0; i < array_size / 2; i++) + { + g_ptr_array_add (ptr_array, &array_test[i]); + g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]); + } + + g_ptr_array_extend (ptr_array, ptr_array2, ptr_array_copy_func, NULL); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i); + + /* Clean-up memory */ + for (i = array_size / 2; i < array_size; i++) + g_free (g_ptr_array_index (ptr_array, i)); + + g_ptr_array_unref (ptr_array); + g_ptr_array_unref (ptr_array2); + g_free (array_test); +} + +/* Test the g_ptr_array_extend_and_steal() function */ +static void +pointer_array_extend_and_steal (void) +{ + GPtrArray *ptr_array, *ptr_array2, *ptr_array3; + gsize i; + const gsize array_size = 100; + gsize *array_test = g_malloc (array_size * sizeof (gsize)); + + /* Initializing array_test */ + for (i = 0; i < array_size; i++) + array_test[i] = i; + + /* Testing simple extend_and_steal() */ + ptr_array = g_ptr_array_sized_new (array_size / 2); + ptr_array2 = g_ptr_array_sized_new (array_size / 2); + + for (i = 0; i < array_size / 2; i++) + { + g_ptr_array_add (ptr_array, &array_test[i]); + g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]); + } + + g_ptr_array_extend_and_steal (ptr_array, ptr_array2); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i); + + g_ptr_array_free (ptr_array, TRUE); + + /* Testing extend_and_steal() with a pending reference to stolen array */ + ptr_array = g_ptr_array_sized_new (array_size / 2); + ptr_array2 = g_ptr_array_sized_new (array_size / 2); + + for (i = 0; i < array_size / 2; i++) + { + g_ptr_array_add (ptr_array, &array_test[i]); + g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]); + } + + ptr_array3 = g_ptr_array_ref (ptr_array2); + + g_ptr_array_extend_and_steal (ptr_array, ptr_array2); + + for (i = 0; i < array_size; i++) + g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i); + + g_assert_cmpuint (ptr_array3->len, ==, 0); + g_assert_null (ptr_array3->pdata); + + g_ptr_array_free (ptr_array, TRUE); + g_ptr_array_free (ptr_array3, TRUE); + + /* Final memory clean-up */ + g_free (array_test); +} + static gint ptr_compare (gconstpointer p1, gconstpointer p2) { @@ -1262,6 +1515,9 @@ main (int argc, char *argv[]) g_test_add_func ("/pointerarray/insert", pointer_array_insert); g_test_add_func ("/pointerarray/ref-count", pointer_array_ref_count); g_test_add_func ("/pointerarray/free-func", pointer_array_free_func); + g_test_add_func ("/pointerarray/array_copy", pointer_array_copy); + g_test_add_func ("/pointerarray/array_extend", pointer_array_extend); + g_test_add_func ("/pointerarray/array_extend_and_steal", pointer_array_extend_and_steal); g_test_add_func ("/pointerarray/sort", pointer_array_sort); g_test_add_func ("/pointerarray/sort-with-data", pointer_array_sort_with_data); g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty); diff --git a/glib/tests/unicode.c b/glib/tests/unicode.c index 50c94edbe..abfe9c9d2 100644 --- a/glib/tests/unicode.c +++ b/glib/tests/unicode.c @@ -1516,7 +1516,7 @@ test_iso15924 (void) { G_UNICODE_SCRIPT_KHUDAWADI, "Sind" }, { G_UNICODE_SCRIPT_LINEAR_A, "Lina" }, { G_UNICODE_SCRIPT_MAHAJANI, "Mahj" }, - { G_UNICODE_SCRIPT_MANICHAEAN, "Manu" }, + { G_UNICODE_SCRIPT_MANICHAEAN, "Mani" }, { G_UNICODE_SCRIPT_MENDE_KIKAKUI, "Mend" }, { G_UNICODE_SCRIPT_MODI, "Modi" }, { G_UNICODE_SCRIPT_MRO, "Mroo" }, diff --git a/gobject/gvalue.c b/gobject/gvalue.c index 8c02e930a..b7a944f4c 100644 --- a/gobject/gvalue.c +++ b/gobject/gvalue.c @@ -162,14 +162,15 @@ GValue* g_value_init (GValue *value, GType g_type) { + GTypeValueTable *value_table; /* g_return_val_if_fail (G_TYPE_IS_VALUE (g_type), NULL); be more elaborate below */ g_return_val_if_fail (value != NULL, NULL); /* g_return_val_if_fail (G_VALUE_TYPE (value) == 0, NULL); be more elaborate below */ - if (G_TYPE_IS_VALUE (g_type) && G_VALUE_TYPE (value) == 0) - { - GTypeValueTable *value_table = g_type_value_table_peek (g_type); + value_table = g_type_value_table_peek (g_type); + if (value_table && G_VALUE_TYPE (value) == 0) + { /* setup and init */ value_meminit (value, g_type); value_table->value_init (value); @@ -181,11 +182,9 @@ g_value_init (GValue *value, g_type_name (G_VALUE_TYPE (value))); else /* !G_TYPE_IS_VALUE (g_type) */ g_warning ("%s: cannot initialize GValue with type '%s', %s", - G_STRLOC, - g_type_name (g_type), - g_type_value_table_peek (g_type) ? - "this type is abstract with regards to GValue use, use a more specific (derived) type" : - "this type has no GTypeValueTable implementation"); + G_STRLOC, + g_type_name (g_type), + value_table ? "this type is abstract with regards to GValue use, use a more specific (derived) type" : "this type has no GTypeValueTable implementation"); return value; } @@ -200,8 +199,8 @@ void g_value_copy (const GValue *src_value, GValue *dest_value) { - g_return_if_fail (G_IS_VALUE (src_value)); - g_return_if_fail (G_IS_VALUE (dest_value)); + g_return_if_fail (src_value); + g_return_if_fail (dest_value); g_return_if_fail (g_value_type_compatible (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value))); if (src_value != dest_value) @@ -209,6 +208,8 @@ g_value_copy (const GValue *src_value, GType dest_type = G_VALUE_TYPE (dest_value); GTypeValueTable *value_table = g_type_value_table_peek (dest_type); + g_return_if_fail (value_table); + /* make sure dest_value's value is free()d */ if (value_table->value_free) value_table->value_free (dest_value); @@ -233,11 +234,12 @@ g_value_reset (GValue *value) { GTypeValueTable *value_table; GType g_type; - - g_return_val_if_fail (G_IS_VALUE (value), NULL); - + + g_return_val_if_fail (value, NULL); g_type = G_VALUE_TYPE (value); + value_table = g_type_value_table_peek (g_type); + g_return_val_if_fail (value_table, NULL); /* make sure value's value is free()d */ if (value_table->value_free) @@ -267,9 +269,10 @@ g_value_unset (GValue *value) if (value->g_type == 0) return; - g_return_if_fail (G_IS_VALUE (value)); + g_return_if_fail (value); value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); + g_return_if_fail (value_table); if (value_table->value_free) value_table->value_free (value); @@ -290,9 +293,10 @@ g_value_fits_pointer (const GValue *value) { GTypeValueTable *value_table; - g_return_val_if_fail (G_IS_VALUE (value), FALSE); + g_return_val_if_fail (value, FALSE); value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); + g_return_val_if_fail (value_table, FALSE); return value_table->value_peek_pointer != NULL; } @@ -312,9 +316,11 @@ g_value_peek_pointer (const GValue *value) { GTypeValueTable *value_table; - g_return_val_if_fail (G_IS_VALUE (value), NULL); + g_return_val_if_fail (value, NULL); value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); + g_return_val_if_fail (value_table, NULL); + if (!value_table->value_peek_pointer) { g_return_val_if_fail (g_value_fits_pointer (value) == TRUE, NULL); @@ -340,17 +346,18 @@ g_value_set_instance (GValue *value, GTypeValueTable *value_table; GTypeCValue cvalue; gchar *error_msg; - - g_return_if_fail (G_IS_VALUE (value)); + + g_return_if_fail (value); + g_type = G_VALUE_TYPE (value); + value_table = g_type_value_table_peek (g_type); + g_return_if_fail (value_table); + if (instance) { g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (instance), G_VALUE_TYPE (value))); } - g_type = G_VALUE_TYPE (value); - value_table = g_type_value_table_peek (g_type); - g_return_if_fail (strcmp (value_table->collect_format, "p") == 0); memset (&cvalue, 0, sizeof (cvalue)); @@ -543,8 +550,8 @@ gboolean g_value_type_transformable (GType src_type, GType dest_type) { - g_return_val_if_fail (G_TYPE_IS_VALUE (src_type), FALSE); - g_return_val_if_fail (G_TYPE_IS_VALUE (dest_type), FALSE); + g_return_val_if_fail (src_type, FALSE); + g_return_val_if_fail (dest_type, FALSE); return (g_value_type_compatible (src_type, dest_type) || transform_func_lookup (src_type, dest_type) != NULL); @@ -564,8 +571,12 @@ gboolean g_value_type_compatible (GType src_type, GType dest_type) { - g_return_val_if_fail (G_TYPE_IS_VALUE (src_type), FALSE); - g_return_val_if_fail (G_TYPE_IS_VALUE (dest_type), FALSE); + g_return_val_if_fail (src_type, FALSE); + g_return_val_if_fail (dest_type, FALSE); + + /* Fast path */ + if (src_type == dest_type) + return TRUE; return (g_type_is_a (src_type, dest_type) && g_type_value_table_peek (dest_type) == g_type_value_table_peek (src_type)); @@ -593,8 +604,8 @@ g_value_transform (const GValue *src_value, { GType dest_type; - g_return_val_if_fail (G_IS_VALUE (src_value), FALSE); - g_return_val_if_fail (G_IS_VALUE (dest_value), FALSE); + g_return_val_if_fail (src_value, FALSE); + g_return_val_if_fail (dest_value, FALSE); dest_type = G_VALUE_TYPE (dest_value); if (g_value_type_compatible (G_VALUE_TYPE (src_value), dest_type)) |