aboutsummaryrefslogtreecommitdiffstats
path: root/m4/getdelim.m4
blob: 8b6eff47aa22c1fb2cc23389a4f409416df7f974 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# getdelim.m4
# serial 21

dnl Copyright (C) 2005-2007, 2009-2026 Free Software Foundation, Inc.
dnl
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This file is offered as-is, without any warranty.

AC_PREREQ([2.59])

AC_DEFUN([gl_FUNC_GETDELIM],
[
  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
  AC_REQUIRE([AC_CANONICAL_HOST])

  dnl Persuade glibc <stdio.h> to declare getdelim().
  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])

  AC_CHECK_DECLS_ONCE([getdelim])

  gl_CHECK_FUNCS_ANDROID([getdelim], [[#include <stdio.h>]])
  if test $ac_cv_func_getdelim = yes; then
    HAVE_GETDELIM=1
    dnl Found it in some library.  Verify that it works.
    AC_CACHE_CHECK([for working getdelim function],
      [gl_cv_func_working_getdelim],
      [case "$host_os" in
         darwin*)
           dnl On macOS 10.13, valgrind detected an out-of-bounds read during
           dnl the GNU sed test suite:
           dnl   Invalid read of size 16
           dnl      at 0x100EE6A05: _platform_memchr$VARIANT$Base (in /usr/lib/system/libsystem_platform.dylib)
           dnl      by 0x100B7B0BD: getdelim (in /usr/lib/system/libsystem_c.dylib)
           dnl      by 0x10000B0BE: ck_getdelim (utils.c:254)
           gl_cv_func_working_getdelim=no ;;
         *)
           echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data
           touch conftest.empty
           AC_RUN_IFELSE([AC_LANG_SOURCE([[
#    include <stdio.h>
#    include <stdlib.h>
#    include <string.h>
    int main ()
    {
      FILE *in = fopen ("./conftest.data", "r");
      int result = 0;
      if (!in)
        return 1;
      {
        /* Test result for a NULL buffer and a zero size.
           Based on a test program from Karl Heuer.  */
        char *line = NULL;
        size_t siz = 0;
        int len = getdelim (&line, &siz, '\n', in);
        if (!(len == 4 && line && strcmp (line, "foo\n") == 0))
          result |= 2;
        free (line);
      }
      {
        /* Test result for a NULL buffer and a non-zero size.
           This crashes on FreeBSD 8.0.  */
        char *line = NULL;
        size_t siz = (size_t)(~0) / 4;
        if (getdelim (&line, &siz, '\n', in) == -1)
          result |= 4;
        free (line);
      }
      fclose (in);
      {
        /* Test that reading EOF as the first character sets the first byte
           in the buffer to NUL.  This fails on glibc 2.42 and earlier.  */
        in = fopen ("./conftest.empty", "r");
        if (!in)
          return 1;
        char *line = malloc (1);
        line[0] = 'A';
        size_t siz = 1;
        if (getdelim (&line, &siz, '\n', in) != -1 || line[0] != '\0')
          result |= 8;
        free (line);
      }
      fclose (in);
      return result;
    }
    ]])],
             [gl_cv_func_working_getdelim=yes],
             [gl_cv_func_working_getdelim=no],
             [case "$host_os" in
                                    # Guess yes on musl.
                *-musl* | midipix*) gl_cv_func_working_getdelim="guessing yes" ;;
                                    # Guess no on glibc.
                *-gnu* | gnu*)      gl_cv_func_working_getdelim="guessing no" ;;
                *)                  gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;;
              esac
             ])
           ;;
       esac
       rm -f conftest.data conftest.empty
      ])
    case "$gl_cv_func_working_getdelim" in
      *yes) ;;
      *) REPLACE_GETDELIM=1 ;;
    esac
  else
    HAVE_GETDELIM=0
    case "$gl_cv_onwards_func_getdelim" in
      future*) REPLACE_GETDELIM=1 ;;
    esac
  fi

  if test $ac_cv_have_decl_getdelim = no; then
    HAVE_DECL_GETDELIM=0
  fi
])

# Prerequisites of lib/getdelim.c.
AC_DEFUN([gl_PREREQ_GETDELIM],
[
  AC_CHECK_FUNCS([flockfile funlockfile])
  AC_CHECK_DECLS([getc_unlocked])
])