mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-13 15:56:23 +01:00
Use glibc qsort_r() for g_qsort_with_data()
No point in using an outdated copy that claims to 'work best on a Sun 4/260' when we can just wrap qsort_r...
This commit is contained in:
parent
6cd08472b2
commit
4cda703d8e
40
configure.ac
40
configure.ac
@ -573,6 +573,46 @@ AC_FUNC_VPRINTF
|
|||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2)
|
AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2)
|
||||||
AC_CHECK_FUNCS(atexit on_exit timegm gmtime_r)
|
AC_CHECK_FUNCS(atexit on_exit timegm gmtime_r)
|
||||||
|
# BSD has a qsort_r with wrong argument order
|
||||||
|
AC_MSG_CHECKING([for qsort_r])
|
||||||
|
AC_RUN_IFELSE([[
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmp (const void *a, const void *b, void *c)
|
||||||
|
{
|
||||||
|
const int *ia = a;
|
||||||
|
const int *ib = b;
|
||||||
|
|
||||||
|
if (*ia < *ib)
|
||||||
|
return -1;
|
||||||
|
else if (*ia > *ib)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int arr[3] = { 1, 2, 0 };
|
||||||
|
int d = 3;
|
||||||
|
|
||||||
|
qsort_r (arr, 3, sizeof (int), cmp, &d);
|
||||||
|
|
||||||
|
if (arr[0] == 0 && arr[1] == 1 && arr[2] == 2)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}]],[have_qsort_r=yes],[have_qsort_r=no])
|
||||||
|
|
||||||
|
if test $have_qsort_r = yes ; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(HAVE_QSORT_R, 1, [Define to 1 if you have the 'qsort_r' function])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_CHECK_SIZEOF(char)
|
AC_CHECK_SIZEOF(char)
|
||||||
AC_CHECK_SIZEOF(short)
|
AC_CHECK_SIZEOF(short)
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -42,6 +43,31 @@
|
|||||||
|
|
||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_QSORT_R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_qsort_with_data:
|
||||||
|
* @pbase: start of array to sort
|
||||||
|
* @total_elems: elements in the array
|
||||||
|
* @size: size of each element
|
||||||
|
* @compare_func: function to compare elements
|
||||||
|
* @user_data: data to pass to @compare_func
|
||||||
|
*
|
||||||
|
* This is just like the standard C qsort() function, but
|
||||||
|
* the comparison routine accepts a user data argument.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_qsort_with_data (gconstpointer pbase,
|
||||||
|
gint total_elems,
|
||||||
|
gsize size,
|
||||||
|
GCompareDataFunc compare_func,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
qsort_r (pbase, total_elems, size, compare_func, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
/* Byte-wise swap two items of size SIZE. */
|
/* Byte-wise swap two items of size SIZE. */
|
||||||
#define SWAP(a, b, size) \
|
#define SWAP(a, b, size) \
|
||||||
do \
|
do \
|
||||||
@ -102,18 +128,6 @@ typedef struct
|
|||||||
smaller partition. This *guarantees* no more than log (total_elems)
|
smaller partition. This *guarantees* no more than log (total_elems)
|
||||||
stack size is needed (actually O(1) in this case)! */
|
stack size is needed (actually O(1) in this case)! */
|
||||||
|
|
||||||
/**
|
|
||||||
* g_qsort_with_data:
|
|
||||||
* @pbase: start of array to sort
|
|
||||||
* @total_elems: elements in the array
|
|
||||||
* @size: size of each element
|
|
||||||
* @compare_func: function to compare elements
|
|
||||||
* @user_data: data to pass to @compare_func
|
|
||||||
*
|
|
||||||
* This is just like the standard C qsort() function, but
|
|
||||||
* the comparison routine accepts a user data argument.
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
void
|
void
|
||||||
g_qsort_with_data (gconstpointer pbase,
|
g_qsort_with_data (gconstpointer pbase,
|
||||||
gint total_elems,
|
gint total_elems,
|
||||||
@ -283,3 +297,5 @@ g_qsort_with_data (gconstpointer pbase,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_QSORT_R */
|
||||||
|
@ -161,6 +161,9 @@ mappedfile_LDADD = $(progs_ldadd)
|
|||||||
TEST_PROGS += dataset
|
TEST_PROGS += dataset
|
||||||
dataset_LDADD = $(progs_ldadd)
|
dataset_LDADD = $(progs_ldadd)
|
||||||
|
|
||||||
|
TEST_PROGS += sort
|
||||||
|
sort_LDADD = $(progs_ldadd)
|
||||||
|
|
||||||
if OS_UNIX
|
if OS_UNIX
|
||||||
|
|
||||||
# some testing of gtester funcitonality
|
# some testing of gtester funcitonality
|
||||||
|
60
glib/tests/sort.c
Normal file
60
glib/tests/sort.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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 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, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
int_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
|
||||||
|
{
|
||||||
|
const gint *i1 = p1;
|
||||||
|
const gint *i2 = p2;
|
||||||
|
|
||||||
|
return *i1 - *i2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_sort_basic (void)
|
||||||
|
{
|
||||||
|
gint *data;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
data = g_malloc (10000 * sizeof (int));
|
||||||
|
for (i = 0; i < 10000; i++)
|
||||||
|
{
|
||||||
|
data[i] = g_random_int_range (0, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_qsort_with_data (data, 10000, sizeof (int), int_compare_data, NULL);
|
||||||
|
|
||||||
|
for (i = 1; i < 10000; i++)
|
||||||
|
g_assert_cmpint (data[i -1], <=, data[i]);
|
||||||
|
|
||||||
|
g_free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
g_test_add_func ("/sort/basic", test_sort_basic);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user