summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml27
-rw-r--r--docs/reference/glib/glib-sections.txt3
-rw-r--r--gio/gdbusconnection.c8
-rw-r--r--gio/gdbusprivate.c2
-rw-r--r--gio/gtestdbus.c2
-rw-r--r--glib/garray.c129
-rw-r--r--glib/garray.h12
-rw-r--r--glib/gmacros.h10
-rw-r--r--glib/gnode.h15
-rw-r--r--glib/gtypes.h14
-rw-r--r--glib/gunicode.h2
-rw-r--r--glib/guniprop.c2
-rw-r--r--glib/tests/array-test.c258
-rw-r--r--glib/tests/unicode.c2
-rw-r--r--gobject/gvalue.c65
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))