gnulib: import getline

We use getline in sim today which breaks on older systems that are
not compliant with the latest POSIX standard.  For example, mingw64
for Windows omits getline so we fail to build there.
This commit is contained in:
Mike Frysinger
2021-05-01 18:00:27 -04:00
parent 858c8f2c1b
commit c17253b974
14 changed files with 1012 additions and 225 deletions

View File

@@ -42,6 +42,7 @@
# fnmatch-gnu \
# frexpl \
# getcwd \
# getline \
# gettimeofday \
# gitlog-to-changelog \
# glob \
@@ -691,6 +692,15 @@ EXTRA_libgnu_a_SOURCES += getcwd-lgpl.c
## end gnulib module getcwd-lgpl
## begin gnulib module getdelim
EXTRA_DIST += getdelim.c
EXTRA_libgnu_a_SOURCES += getdelim.c
## end gnulib module getdelim
## begin gnulib module getdtablesize
@@ -700,6 +710,15 @@ EXTRA_libgnu_a_SOURCES += getdtablesize.c
## end gnulib module getdtablesize
## begin gnulib module getline
EXTRA_DIST += getline.c
EXTRA_libgnu_a_SOURCES += getline.c
## end gnulib module getline
## begin gnulib module getlogin_r

View File

@@ -56,6 +56,7 @@
# fnmatch-gnu \
# frexpl \
# getcwd \
# getline \
# gettimeofday \
# gitlog-to-changelog \
# glob \
@@ -217,7 +218,9 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/import/m4/getcwd-abort-bug.m4 \
$(top_srcdir)/import/m4/getcwd-path-max.m4 \
$(top_srcdir)/import/m4/getcwd.m4 \
$(top_srcdir)/import/m4/getdelim.m4 \
$(top_srcdir)/import/m4/getdtablesize.m4 \
$(top_srcdir)/import/m4/getline.m4 \
$(top_srcdir)/import/m4/getlogin.m4 \
$(top_srcdir)/import/m4/getlogin_r.m4 \
$(top_srcdir)/import/m4/getpagesize.m4 \
@@ -1781,10 +1784,10 @@ EXTRA_DIST = m4/gnulib-cache.m4 alloca.c alloca.in.h arpa_inet.in.h \
filenamecat.h flexmember.h float.c float.in.h itold.c \
fnmatch.c fnmatch_loop.c fnmatch.c fnmatch.in.h fpucw.h free.c \
frexp.c frexp.c frexpl.c fstat.c stat-w32.c stat-w32.h \
at-func.c fstatat.c getcwd.c getcwd-lgpl.c getdtablesize.c \
getlogin_r.c getrandom.c gettimeofday.c \
$(top_srcdir)/import/extra/gitlog-to-changelog glob.c \
glob_internal.h glob_pattern_p.c globfree.c glob-libc.h \
at-func.c fstatat.c getcwd.c getcwd-lgpl.c getdelim.c \
getdtablesize.c getline.c getlogin_r.c getrandom.c \
gettimeofday.c $(top_srcdir)/import/extra/gitlog-to-changelog \
glob.c glob_internal.h glob_pattern_p.c globfree.c glob-libc.h \
glob.in.h hard-locale.h inet_ntop.c intprops.h inttypes.in.h \
isblank.c float+.h isnan.c isnand-nolibm.h isnand.c float+.h \
isnan.c isnanl-nolibm.h isnanl.c cdefs.h libc-config.h \
@@ -1864,9 +1867,9 @@ EXTRA_libgnu_a_SOURCES = alloca.c btowc.c canonicalize-lgpl.c \
fchdir.c fcntl.c fdopendir.c float.c itold.c fnmatch.c \
fnmatch_loop.c fnmatch.c free.c frexp.c frexp.c frexpl.c \
fstat.c stat-w32.c at-func.c fstatat.c getcwd.c getcwd-lgpl.c \
getdtablesize.c getlogin_r.c getrandom.c gettimeofday.c glob.c \
glob_pattern_p.c globfree.c inet_ntop.c isblank.c isnan.c \
isnand.c isnan.c isnanl.c lstat.c malloc.c \
getdelim.c getdtablesize.c getline.c getlogin_r.c getrandom.c \
gettimeofday.c glob.c glob_pattern_p.c globfree.c inet_ntop.c \
isblank.c isnan.c isnand.c isnan.c isnanl.c lstat.c malloc.c \
lc-charset-dispatch.c mbrtowc.c mbtowc-lock.c mbsinit.c \
mbsrtowcs-state.c mbsrtowcs.c mbtowc.c memchr.c memmem.c \
memmem.c mempcpy.c memrchr.c mkdir.c mkdtemp.c mkostemp.c \
@@ -2023,7 +2026,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstatat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcwd-lgpl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcwd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdelim.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdtablesize.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getline.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getlogin_r.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getprogname.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getrandom.Po@am__quote@

147
gnulib/import/getdelim.c Normal file
View File

@@ -0,0 +1,147 @@
/* getdelim.c --- Implementation of replacement getdelim function.
Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2021 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>. */
/* Ported from glibc by Simon Josefsson. */
/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
optimizes away the lineptr == NULL || n == NULL || fp == NULL tests below. */
#define _GL_ARG_NONNULL(params)
#include <config.h>
#include <stdio.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#ifndef SSIZE_MAX
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
#endif
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
# define getc_maybe_unlocked(fp) getc(fp)
#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED
# undef flockfile
# undef funlockfile
# define flockfile(x) ((void) 0)
# define funlockfile(x) ((void) 0)
# define getc_maybe_unlocked(fp) getc(fp)
#else
# define getc_maybe_unlocked(fp) getc_unlocked(fp)
#endif
static void
alloc_failed (void)
{
#if defined _WIN32 && ! defined __CYGWIN__
/* Avoid errno problem without using the realloc module; see:
https://lists.gnu.org/r/bug-gnulib/2016-08/msg00025.html */
errno = ENOMEM;
#endif
}
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
NUL-terminate it). *LINEPTR is a pointer returned from malloc (or
NULL), pointing to *N characters of space. It is realloc'ed as
necessary. Returns the number of characters read (not including
the null terminator), or -1 on error or EOF. */
ssize_t
getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
{
ssize_t result;
size_t cur_len = 0;
if (lineptr == NULL || n == NULL || fp == NULL)
{
errno = EINVAL;
return -1;
}
flockfile (fp);
if (*lineptr == NULL || *n == 0)
{
char *new_lineptr;
*n = 120;
new_lineptr = (char *) realloc (*lineptr, *n);
if (new_lineptr == NULL)
{
alloc_failed ();
result = -1;
goto unlock_return;
}
*lineptr = new_lineptr;
}
for (;;)
{
int i;
i = getc_maybe_unlocked (fp);
if (i == EOF)
{
result = -1;
break;
}
/* Make enough space for len+1 (for final NUL) bytes. */
if (cur_len + 1 >= *n)
{
size_t needed_max =
SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
size_t needed = 2 * *n + 1; /* Be generous. */
char *new_lineptr;
if (needed_max < needed)
needed = needed_max;
if (cur_len + 1 >= needed)
{
result = -1;
errno = EOVERFLOW;
goto unlock_return;
}
new_lineptr = (char *) realloc (*lineptr, needed);
if (new_lineptr == NULL)
{
alloc_failed ();
result = -1;
goto unlock_return;
}
*lineptr = new_lineptr;
*n = needed;
}
(*lineptr)[cur_len] = i;
cur_len++;
if (i == delimiter)
break;
}
(*lineptr)[cur_len] = '\0';
result = cur_len ? cur_len : result;
unlock_return:
funlockfile (fp); /* doesn't set errno */
return result;
}

27
gnulib/import/getline.c Normal file
View File

@@ -0,0 +1,27 @@
/* getline.c --- Implementation of replacement getline function.
Copyright (C) 2005-2007, 2009-2021 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>. */
/* Written by Simon Josefsson. */
#include <config.h>
#include <stdio.h>
ssize_t
getline (char **lineptr, size_t *n, FILE *stream)
{
return getdelim (lineptr, n, '\n', stream);
}

View File

@@ -0,0 +1,99 @@
# getdelim.m4 serial 15
dnl Copyright (C) 2005-2007, 2009-2021 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.
AC_PREREQ([2.59])
AC_DEFUN([gl_FUNC_GETDELIM],
[
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
dnl Persuade glibc <stdio.h> to declare getdelim().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
AC_CHECK_DECLS_ONCE([getdelim])
AC_CHECK_FUNCS_ONCE([getdelim])
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],
[echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data
AC_RUN_IFELSE([AC_LANG_SOURCE([[
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
int main ()
{
FILE *in = fopen ("./conftest.data", "r");
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))
{ free (line); fclose (in); return 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)
{ fclose (in); return 3; }
free (line);
}
fclose (in);
return 0;
}
]])],
[gl_cv_func_working_getdelim=yes],
[gl_cv_func_working_getdelim=no],
[dnl We're cross compiling.
dnl Guess it works on glibc2 systems and musl systems.
AC_EGREP_CPP([Lucky GNU user],
[
#include <features.h>
#ifdef __GNU_LIBRARY__
#if (__GLIBC__ >= 2) && !defined __UCLIBC__
Lucky GNU user
#endif
#endif
],
[gl_cv_func_working_getdelim="guessing yes"],
[case "$host_os" in
*-musl*) gl_cv_func_working_getdelim="guessing yes" ;;
*) gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;;
esac
])
])
])
case "$gl_cv_func_working_getdelim" in
*yes) ;;
*) REPLACE_GETDELIM=1 ;;
esac
else
HAVE_GETDELIM=0
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])
])

109
gnulib/import/m4/getline.m4 Normal file
View File

@@ -0,0 +1,109 @@
# getline.m4 serial 30
dnl Copyright (C) 1998-2003, 2005-2007, 2009-2021 Free Software Foundation,
dnl 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.
AC_PREREQ([2.59])
dnl See if there's a working, system-supplied version of the getline function.
dnl We can't just do AC_REPLACE_FUNCS([getline]) because some systems
dnl have a function by that name in -linet that doesn't have anything
dnl to do with the function we need.
AC_DEFUN([gl_FUNC_GETLINE],
[
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
dnl Persuade glibc <stdio.h> to declare getline().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
AC_CHECK_DECLS_ONCE([getline])
gl_getline_needs_run_time_check=no
AC_CHECK_FUNC([getline],
[dnl Found it in some library. Verify that it works.
gl_getline_needs_run_time_check=yes],
[am_cv_func_working_getline=no])
if test $gl_getline_needs_run_time_check = yes; then
AC_CACHE_CHECK([for working getline function],
[am_cv_func_working_getline],
[echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data
AC_RUN_IFELSE([AC_LANG_SOURCE([[
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
int main ()
{
FILE *in = fopen ("./conftest.data", "r");
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 = getline (&line, &siz, in);
if (!(len == 4 && line && strcmp (line, "foo\n") == 0))
{ free (line); fclose (in); return 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 (getline (&line, &siz, in) == -1)
{ fclose (in); return 3; }
free (line);
}
fclose (in);
return 0;
}
]])],
[am_cv_func_working_getline=yes],
[am_cv_func_working_getline=no],
[dnl We're cross compiling.
dnl Guess it works on glibc2 systems and musl systems.
AC_EGREP_CPP([Lucky GNU user],
[
#include <features.h>
#ifdef __GNU_LIBRARY__
#if (__GLIBC__ >= 2) && !defined __UCLIBC__
Lucky GNU user
#endif
#endif
],
[am_cv_func_working_getline="guessing yes"],
[case "$host_os" in
*-musl*) am_cv_func_working_getline="guessing yes" ;;
*) am_cv_func_working_getline="$gl_cross_guess_normal" ;;
esac
])
])
])
fi
if test $ac_cv_have_decl_getline = no; then
HAVE_DECL_GETLINE=0
fi
case "$am_cv_func_working_getline" in
*yes) ;;
*)
dnl Set REPLACE_GETLINE always: Even if we have not found the broken
dnl getline function among $LIBS, it may exist in libinet and the
dnl executable may be linked with -linet.
REPLACE_GETLINE=1
;;
esac
])
# Prerequisites of lib/getline.c.
AC_DEFUN([gl_PREREQ_GETLINE],
[
:
])

View File

@@ -47,6 +47,7 @@
# fnmatch-gnu \
# frexpl \
# getcwd \
# getline \
# gettimeofday \
# gitlog-to-changelog \
# glob \
@@ -89,6 +90,7 @@ gl_MODULES([
fnmatch-gnu
frexpl
getcwd
getline
gettimeofday
gitlog-to-changelog
glob

View File

@@ -101,7 +101,9 @@ AC_DEFUN([gl_EARLY],
# Code from module fstatat:
# Code from module getcwd:
# Code from module getcwd-lgpl:
# Code from module getdelim:
# Code from module getdtablesize:
# Code from module getline:
# Code from module getlogin_r:
# Code from module getprogname:
# Code from module getrandom:
@@ -392,12 +394,24 @@ AC_DEFUN([gl_INIT],
AC_LIBOBJ([getcwd-lgpl])
fi
gl_UNISTD_MODULE_INDICATOR([getcwd])
gl_FUNC_GETDELIM
if test $HAVE_GETDELIM = 0 || test $REPLACE_GETDELIM = 1; then
AC_LIBOBJ([getdelim])
gl_PREREQ_GETDELIM
fi
gl_STDIO_MODULE_INDICATOR([getdelim])
gl_FUNC_GETDTABLESIZE
if test $HAVE_GETDTABLESIZE = 0 || test $REPLACE_GETDTABLESIZE = 1; then
AC_LIBOBJ([getdtablesize])
gl_PREREQ_GETDTABLESIZE
fi
gl_UNISTD_MODULE_INDICATOR([getdtablesize])
gl_FUNC_GETLINE
if test $REPLACE_GETLINE = 1; then
AC_LIBOBJ([getline])
gl_PREREQ_GETLINE
fi
gl_STDIO_MODULE_INDICATOR([getline])
gl_FUNC_GETLOGIN_R
if test $HAVE_GETLOGIN_R = 0 || test $REPLACE_GETLOGIN_R = 1; then
AC_LIBOBJ([getlogin_r])
@@ -990,7 +1004,9 @@ AC_DEFUN([gl_FILE_LIST], [
lib/fstatat.c
lib/getcwd-lgpl.c
lib/getcwd.c
lib/getdelim.c
lib/getdtablesize.c
lib/getline.c
lib/getlogin_r.c
lib/getprogname.c
lib/getprogname.h
@@ -1198,7 +1214,9 @@ AC_DEFUN([gl_FILE_LIST], [
m4/getcwd-abort-bug.m4
m4/getcwd-path-max.m4
m4/getcwd.m4
m4/getdelim.m4
m4/getdtablesize.m4
m4/getline.m4
m4/getlogin.m4
m4/getlogin_r.m4
m4/getpagesize.m4