Re: fix module qsort_r

2016-10-27 Thread Bruno Haible
Paul Eggert wrote:
> I gave the patch a quick scan just now and it 
> looks fine; please install when you find the time.

Done.

Bruno




Re: fix module qsort_r

2016-10-26 Thread Paul Eggert
Thanks for doing all that. I gave the patch a quick scan just now and it 
looks fine; please install when you find the time.




fix module qsort_r

2016-10-16 Thread Bruno Haible
Hi Paul,

The module 'qsort_r' does not work at all on systems that don't have this 
function.
For example, on AIX 7.1, with a gnulib testdir:

test-qsort_r.c: In function 'main':
test-qsort_r.c:40:3: warning: implicit declaration of function 'qsort_r' 
[-Wimplicit-function-declaration]
   qsort_r (buf, sizeof buf - 1, 1, cmp, );
   ^
gcc -mlong-double-64 -D_ALL_SOURCE -std=gnu11  -g -O2   -o test-qsort_r 
test-qsort_r.o ../gllib/libgnu.a -lm  -lm -lm -lm -lm -lm -lm -lm -lm -lm
ld: 0711-317 ERROR: Undefined symbol: .qsort_r
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
collect2: error: ld returned 8 exit status
make: 1254-004 The error code from the last command is 1.

The problems are:
1) The gl_FUNC_QSORT_R macro finds that
 checking for qsort_r signature... GNU
2) The function does not get declared in gnulib's stdlib.h replacement.
3) It also is not included in libgnu.a (neither qsort.o nor qsort_r.o gets
   included in gl_LIBOBJS).

Ad 1) Yes really it needs an AC_CHECK_FUNC call, because a program such as

#define __EXTENSIONS__ 1
#define _ALL_SOURCE 1
#define _DARWIN_C_SOURCE 1
#define _GNU_SOURCE 1
#include 
#define qsort_t any_nonexistent_name
  void qsort_r (void *, size_t, size_t,
int (*) (void const *, void const *,
 void *),
void *);
  void (*p) (void *, size_t, size_t,
 int (*) (void const *, void const *,
  void *),
 void *) = qsort_r;
int main () { return 0; }

compiles and links perfectly fine.

Ad 2) The idiom in stdlib.h is incomplete. You need to pick the complete one
(e.g. copy from the 'ptsname_r' declaration).

Additionally:
4) The qsort_r function would not be warned about in GNULIB_POSIXCHECK mode.

Here's a proposed fix.


2016-10-16  Bruno Haible  

qsort_r: Fix macrology for platforms that lack the function.
* m4/stdlib_h.m4 (gl_STDLIB_H): Check for qsort_r.
(gl_STDLIB_H_DEFAULTS): Initialize HAVE_QSORT_R.
* modules/stdlib (Makefile.am): Substitute HAVE_QSORT_R.
* lib/stdlib.in.h (qsort_r): Provide declaration if the function does
not exist.
* m4/qsort_r.m4 (gl_FUNC_QSORT_R): Use AC_CHECK_FUNCS to test whether
the function exists.
* modules/qsort_r: Add comments.

diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 70dc88d..db3253b 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -521,6 +521,9 @@ _GL_CXXALIASWARN (putenv);
 #endif
 
 #if @GNULIB_QSORT_R@
+/* Sort an array of NMEMB elements, starting at address BASE, each element
+   occupying SIZE bytes, in ascending order according to the comparison
+   function COMPARE.  */
 # if @REPLACE_QSORT_R@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef qsort_r
@@ -535,12 +538,24 @@ _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t 
nmemb, size_t size,
   void *),
   void *arg));
 # else
+#  if !@HAVE_QSORT_R@
+_GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size,
+  int (*compare) (void const *, void const *,
+  void *),
+  void *arg) _GL_ARG_NONNULL ((1, 4)));
+#  endif
 _GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size,
   int (*compare) (void const *, void const *,
   void *),
   void *arg));
 # endif
 _GL_CXXALIASWARN (qsort_r);
+#elif defined GNULIB_POSIXCHECK
+# undef qsort_r
+# if HAVE_RAW_DECL_QSORT_R
+_GL_WARN_ON_USE (qsort_r, "qsort_r is not portable - "
+ "use gnulib module qsort_r for portability");
+# endif
 #endif
 
 
diff --git a/m4/qsort_r.m4 b/m4/qsort_r.m4
index f3d2927..f1de7d4 100644
--- a/m4/qsort_r.m4
+++ b/m4/qsort_r.m4
@@ -14,35 +14,39 @@ AC_DEFUN([gl_FUNC_QSORT_R],
 
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
 
-  AC_CACHE_CHECK([for qsort_r signature], [gl_cv_qsort_r_signature],
-[AC_LINK_IFELSE(
-   [AC_LANG_PROGRAM([[#include 
-  void qsort_r (void *, size_t, size_t,
-int (*) (void const *, void const *,
- void *),
-void *);
-  void (*p) (void *, size_t, size_t,
- int (*) (void const *, void const *,
-