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