summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-10 04:21:39 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-10 04:21:39 +0000
commitef92aa9a454e4b5a36c433384e0106a6c0355308 (patch)
treeffa4521d7e8a80164f88efdccf50245355cbc950 /util.c
parent5679d0c5c2535815865531424504a8c051cdf475 (diff)
util.c: fix ruby_qsort with qsort_s
* util.c (ruby_qsort): __STDC_VERSION__ may not be defined even if it is available. fixed duplicate definitions when qsort_s is available on non-Windows platforms. [ruby-core:88921] [Bug #15091] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64671 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'util.c')
-rw-r--r--util.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/util.c b/util.c
index 3839074..3f74c92 100644
--- a/util.c
+++ b/util.c
@@ -197,27 +197,13 @@ ruby_strtoul(const char *str, char **endptr, int base)
typedef int (cmpfunc_t)(const void*, const void*, void*);
-#if defined HAVE_QSORT_S
-# if defined RUBY_MSVCRT_VERSION
+#if defined HAVE_QSORT_S && defined RUBY_MSVCRT_VERSION
+/* In contrast to its name, Visual Studio qsort_s is incompatible with
+ * C11 in the order of the comparison function's arguments, and same
+ * as BSD qsort_r rather. */
# define qsort_r(base, nel, size, arg, cmp) qsort_s(base, nel, size, cmp, arg)
# define cmp_bsd_qsort cmp_ms_qsort
# define HAVE_BSD_QSORT_R 1
-# elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
-/* C11 qsort_s has the same arguments as ours */
-void
-ruby_qsort(void* base, const size_t nel, const size_t size, cmpfunc_t *cmp, void *d)
-{
- if (!nel || !size) return; /* nothing to sort */
-
- /* get rid of runtime-constraints handler for MT-safeness */
- if (!base || !cmp) return;
- if (nel > RSIZE_MAX || size > RSIZE_MAX) return;
-
- qsort_s(base, nel, size, cmp, d);
-}
-# else
-# error Unknown version qsort_s
-# endif
#endif
#if defined HAVE_BSD_QSORT_R
@@ -241,6 +227,22 @@ ruby_qsort(void* base, const size_t nel, const size_t size, cmpfunc_t *cmp, void
args.arg = d;
qsort_r(base, nel, size, &args, cmp_bsd_qsort);
}
+#elif defined HAVE_QSORT_S
+/* C11 qsort_s has the same arguments as GNU's, but uses
+ * runtime-constraints handler. */
+void
+ruby_qsort(void* base, const size_t nel, const size_t size, cmpfunc_t *cmp, void *d)
+{
+ if (!nel || !size) return; /* nothing to sort */
+
+ /* get rid of runtime-constraints handler for MT-safeness */
+ if (!base || !cmp) return;
+ if (nel > RSIZE_MAX || size > RSIZE_MAX) return;
+
+ qsort_s(base, nel, size, cmp, d);
+}
+# define HAVE_GNU_QSORT_R 1
+# endif
#elif !defined HAVE_GNU_QSORT_R
/* mm.c */