[前][次][番号順一覧][スレッド一覧]

ruby-changes:52452

From: nobu <ko1@a...>
Date: Sun, 9 Sep 2018 16:49:09 +0900 (JST)
Subject: [ruby-changes:52452] nobu:r64661 (trunk): util.c: qsort_s in C11

nobu	2018-09-09 16:49:04 +0900 (Sun, 09 Sep 2018)

  New Revision: 64661

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64661

  Log:
    util.c: qsort_s in C11
    
    * configure.ac: macro for C11 to use qsort_s.
    
    * util.c (ruby_qsort): fix for C11 qsort_s.  the comparison function
      for MSVCRT qsort_s is compatible with BSD qsort_r, but not with C11
      qsort_s, in spite of its name.
      note that mingw defines __STDC_VERSION__ but uses qsort_s in MSVCRT,
      so the MSVCRT block needs to preced the C11 block.
      [ruby-core:88899] [Bug #15091]

  Modified files:
    trunk/configure.ac
    trunk/util.c
Index: configure.ac
===================================================================
--- configure.ac	(revision 64660)
+++ configure.ac	(revision 64661)
@@ -1869,7 +1869,7 @@ AC_CHECK_FUNCS(utimes) https://github.com/ruby/ruby/blob/trunk/configure.ac#L1869
 AC_CHECK_FUNCS(wait4)
 AC_CHECK_FUNCS(waitpid)
 
-AS_IF([test "$ac_cv_func_memset_s" = yes],
+AS_CASE(["$ac_cv_func_memset_s:$ac_cvs_func_qsort_s"], [*yes*],
     [RUBY_DEFINE_IF([!defined __STDC_WANT_LIB_EXT1__], [__STDC_WANT_LIB_EXT1__], 1)])
 
 AS_IF([test "$ac_cv_func_getcwd" = yes], [
Index: util.c
===================================================================
--- util.c	(revision 64660)
+++ util.c	(revision 64661)
@@ -195,14 +195,32 @@ ruby_strtoul(const char *str, char **end https://github.com/ruby/ruby/blob/trunk/util.c#L195
 #   define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
 #endif
 
-#if !defined HAVE_BSD_QSORT_R && defined HAVE_QSORT_S
+typedef int (cmpfunc_t)(const void*, const void*, void*);
+
+#if defined HAVE_QSORT_S
+# if defined __MSVCRT__
 # 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
-typedef int (cmpfunc_t)(const void*, const void*, void*);
 
+#if defined HAVE_BSD_QSORT_R
 struct bsd_qsort_r_args {
     cmpfunc_t *cmp;
     void *arg;
@@ -339,7 +357,6 @@ typedef struct { char *LL, *RR; } stack_ https://github.com/ruby/ruby/blob/trunk/util.c#L357
                        ((*cmp)((b),(c),d)<0 ? (b) : ((*cmp)((a),(c),d)<0 ? (c) : (a))) : \
                        ((*cmp)((b),(c),d)>0 ? (b) : ((*cmp)((a),(c),d)<0 ? (a) : (c))))
 
-typedef int (cmpfunc_t)(const void*, const void*, void*);
 void
 ruby_qsort(void* base, const size_t nel, const size_t size, cmpfunc_t *cmp, void *d)
 {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]