summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglass <glass@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-08 12:50:28 +0000
committerglass <glass@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-08 12:50:28 +0000
commitcd476cd86be581cca4ca56ad1277228ea1dc24ee (patch)
tree5deff144b9c8229910e8ebbe309b326bfe405eff
parentc7652dec6f9c8cbbbe2953a1c435c12a484773f0 (diff)
* configure.in: check qsort_r(3) and whether it is GNU version.
BSD version has different prototype. * util.h: use qsort_r() as ruby_qsort() if it is GNU version. * util.c: define ruby_qsort() if needed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44889 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog9
-rw-r--r--configure.in34
-rw-r--r--include/ruby/util.h4
-rw-r--r--util.c2
4 files changed, 49 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 24c5adf667..b812349c50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sat Feb 8 21:44:07 2014 Masaki Matsushita <glass.saga@gmail.com>
+
+ * configure.in: check qsort_r(3) and whether it is GNU version.
+ BSD version has different prototype.
+
+ * util.h: use qsort_r() as ruby_qsort() if it is GNU version.
+
+ * util.c: define ruby_qsort() if needed.
+
Sat Feb 8 16:34:36 2014 Tanaka Akira <akr@fsij.org>
* lib/resolv.rb (Resolv::DNS::Message::MessageDecoder#get_labels):
diff --git a/configure.in b/configure.in
index 84aec14725..4da41df606 100644
--- a/configure.in
+++ b/configure.in
@@ -1920,6 +1920,7 @@ AC_CHECK_FUNCS(posix_fadvise)
AC_CHECK_FUNCS(posix_memalign)
AC_CHECK_FUNCS(ppoll)
AC_CHECK_FUNCS(pread)
+AC_CHECK_FUNCS(qsort_r)
AC_CHECK_FUNCS(readlink)
AC_CHECK_FUNCS(round)
AC_CHECK_FUNCS(seekdir)
@@ -1980,6 +1981,39 @@ RUBY_CHECK_BUILTIN_FUNC(__builtin_clzll, [__builtin_clzll(0)])
RUBY_CHECK_BUILTIN_FUNC(__builtin_choose_expr, [__builtin_choose_expr(0, 0, 0)])
RUBY_CHECK_BUILTIN_FUNC(__builtin_types_compatible_p, [__builtin_types_compatible_p(int, int)])
+if test "$ac_cv_func_qsort_r" != no; then
+ AC_CACHE_CHECK(that qsort_r is GNU version, rb_cv_gnu_qsort_r,
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <stdlib.h>
+
+int unsorted[] = { 4, 3, 2, 1 };
+int sorted[] = { 1, 2, 3, 4 };
+
+int
+compar(const void *a, const void *b, void *arg)
+{
+ if (*(int *)arg != 42) exit(1);
+ return *(int *)a - *(int *)b;
+}
+
+int
+main(void)
+{
+ int arg = 42;
+ qsort_r(unsorted, 4, sizeof(int), compar, &arg);
+ if (memcmp(sorted, unsorted, 4) != 0) return 1;
+ return 0;
+}
+ ]])],
+ [rb_cv_gnu_qsort_r=yes],
+ [rb_cv_gnu_qsort_r=no])
+ ])
+ if test "$rb_cv_gnu_qsort_r" != no; then
+ AC_DEFINE(HAVE_GNU_QSORT_R, 1)
+ fi
+fi
+
# Some platform need -lrt for clock_gettime, but the other don't.
if test x"$ac_cv_func_clock_gettime" != xyes; then
# glibc 2.17 moves clock_* functions from librt to the main C library.
diff --git a/include/ruby/util.h b/include/ruby/util.h
index 8443af74d9..74cdd0ffd1 100644
--- a/include/ruby/util.h
+++ b/include/ruby/util.h
@@ -55,8 +55,12 @@ unsigned long ruby_scan_oct(const char *, size_t, size_t *);
#define scan_hex(s,l,e) ((int)ruby_scan_hex((s),(l),(e)))
unsigned long ruby_scan_hex(const char *, size_t, size_t *);
+#ifdef HAVE_GNU_QSORT_R
+# define ruby_qsort qsort_r
+#else
void ruby_qsort(void *, const size_t, const size_t,
int (*)(const void *, const void *, void *), void *);
+#endif
void ruby_setenv(const char *, const char *);
void ruby_unsetenv(const char *);
diff --git a/util.c b/util.c
index b0f9030c42..b999aff05c 100644
--- a/util.c
+++ b/util.c
@@ -186,6 +186,7 @@ ruby_strtoul(const char *str, char **endptr, int base)
#endif
+#ifndef HAVE_GNU_QSORT_R
/* mm.c */
#define mmtype long
@@ -452,6 +453,7 @@ ruby_qsort(void* base, const size_t nel, const size_t size, cmpfunc_t *cmp, void
else goto nxt; /* need not to sort both sides */
}
}
+#endif /* HAVE_GNU_QSORT_R */
char *
ruby_strdup(const char *str)