sys_socket tests: Improve tests for macro definitions.
[gnulib.git] / m4 / stpncpy.m4
blob527f1d4212f1b8b0bf348b10e3dc6687213f6973
1 # stpncpy.m4
2 # serial 22
3 dnl Copyright (C) 2002-2003, 2005-2007, 2009-2024 Free Software Foundation,
4 dnl Inc.
5 dnl This file is free software; the Free Software Foundation
6 dnl gives unlimited permission to copy and/or distribute it,
7 dnl with or without modifications, as long as this notice is preserved.
9 AC_DEFUN([gl_FUNC_STPNCPY],
11   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
13   dnl Persuade glibc <string.h> to declare stpncpy().
14   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
16   dnl The stpncpy() declaration in lib/string.in.h uses 'restrict'.
17   AC_REQUIRE([AC_C_RESTRICT])
19   AC_REQUIRE([gl_STRING_H_DEFAULTS])
21   dnl Both glibc and AIX (4.3.3, 5.1) have an stpncpy() function
22   dnl declared in <string.h>. Its side effects are the same as those
23   dnl of strncpy():
24   dnl      stpncpy (dest, src, n)
25   dnl overwrites dest[0..n-1], min(strlen(src),n) bytes coming from src,
26   dnl and the remaining bytes being NULs.  However, the return value is
27   dnl   in glibc:   dest + min(strlen(src),n)
28   dnl   in AIX:     dest + max(0,n-1)
29   dnl Only the glibc return value is useful in practice.
31   AC_CHECK_DECLS_ONCE([stpncpy])
32   gl_CHECK_FUNCS_ANDROID([stpncpy], [[#include <string.h>]])
33   if test $ac_cv_func_stpncpy = yes; then
34     AC_CACHE_CHECK([for working stpncpy], [gl_cv_func_stpncpy], [
35       AC_RUN_IFELSE(
36         [AC_LANG_SOURCE([[
37 #include <stdlib.h>
38 #include <string.h> /* for strcpy */
39 /* The stpncpy prototype is missing in <string.h> on AIX 4.  */
40 #if !HAVE_DECL_STPNCPY
41 extern
42 # ifdef __cplusplus
43 "C"
44 # endif
45 char *stpncpy (char *dest, const char *src, size_t n);
46 #endif
47 int main ()
49   int result = 0;
50   const char *src = "Hello";
51   char dest[10];
52   /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+1 here.  */
53   {
54     strcpy (dest, "\377\377\377\377\377\377");
55     if (stpncpy (dest, src, 2) != dest + 2)
56       result |= 1;
57   }
58   /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+4 here.  */
59   {
60     strcpy (dest, "\377\377\377\377\377\377");
61     if (stpncpy (dest, src, 5) != dest + 5)
62       result |= 2;
63   }
64   /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+6 here.  */
65   {
66     strcpy (dest, "\377\377\377\377\377\377");
67     if (stpncpy (dest, src, 7) != dest + 5)
68       result |= 4;
69   }
70   return result;
72 ]])],
73         [gl_cv_func_stpncpy=yes],
74         [gl_cv_func_stpncpy=no],
75         [dnl Guess yes on glibc systems and musl systems.
76          AC_EGREP_CPP([Thanks for using GNU], [
77 #include <features.h>
78 #ifdef __GNU_LIBRARY__
79   Thanks for using GNU
80 #endif
81 ],         [gl_cv_func_stpncpy="guessing yes"],
82            [case "$host_os" in
83               *-musl* | midipix*) gl_cv_func_stpncpy="guessing yes" ;;
84               *)                  gl_cv_func_stpncpy="$gl_cross_guess_normal" ;;
85             esac
86            ])
87         ])
88     ])
89     case "$gl_cv_func_stpncpy" in
90       *yes)
91         AC_DEFINE([HAVE_STPNCPY], [1],
92           [Define if you have the stpncpy() function and it works.])
93         ;;
94       *)
95         REPLACE_STPNCPY=1
96         ;;
97     esac
98   else
99     HAVE_STPNCPY=0
100     case "$gl_cv_onwards_func_stpncpy" in
101       future*) REPLACE_STPNCPY=1 ;;
102     esac
103   fi
106 # Prerequisites of lib/stpncpy.c.
107 AC_DEFUN([gl_PREREQ_STPNCPY], [
108   :