From 2886cca8398f4c5a4d68368a19c0e6d0ff97c739 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 12 Jan 2023 16:51:15 +0100 Subject: error: Work around an Android problem. * lib/error.in.h: Renamed from lib/error.h. (_GL_ATTRIBUTE_SPEC_PRINTF_ERROR): New macro. (error): Consider HAVE_ERROR and REPLACE_ERROR. (error_at_line): Consider HAVE_ERROR_AT_LINE and REPLACE_ERROR_AT_LINE. * m4/error_h.m4: New file, partially based on m4/error.m4. * m4/error.m4 (gl_ERROR): Remove the test for error_at_line. * modules/error-h: New file. * modules/error (Files): Remove lib/error.h. (Depends-on): Add error-h. Update conditions. (configure.ac): Require gl_ERROR_H. Update condition. * doc/glibc-headers/error.texi: Mention the 'error-h' module. * doc/glibc-functions/error.texi: Mention the Android problem. * config/srclist.txt: Add comment regarding error.h. --- ChangeLog | 17 +++++++ config/srclist.txt | 2 +- doc/glibc-functions/error.texi | 4 ++ doc/glibc-headers/error.texi | 2 +- lib/error.h | 66 ------------------------ lib/error.in.h | 104 +++++++++++++++++++++++++++++++++++++ m4/error.m4 | 11 +--- m4/error_h.m4 | 113 +++++++++++++++++++++++++++++++++++++++++ modules/error | 11 ++-- modules/error-h | 46 +++++++++++++++++ 10 files changed, 293 insertions(+), 83 deletions(-) delete mode 100644 lib/error.h create mode 100644 lib/error.in.h create mode 100644 m4/error_h.m4 create mode 100644 modules/error-h diff --git a/ChangeLog b/ChangeLog index 4a3480b631..d9d728b7bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2023-01-12 Bruno Haible + + error: Work around an Android problem. + * lib/error.in.h: Renamed from lib/error.h. + (_GL_ATTRIBUTE_SPEC_PRINTF_ERROR): New macro. + (error): Consider HAVE_ERROR and REPLACE_ERROR. + (error_at_line): Consider HAVE_ERROR_AT_LINE and REPLACE_ERROR_AT_LINE. + * m4/error_h.m4: New file, partially based on m4/error.m4. + * m4/error.m4 (gl_ERROR): Remove the test for error_at_line. + * modules/error-h: New file. + * modules/error (Files): Remove lib/error.h. + (Depends-on): Add error-h. Update conditions. + (configure.ac): Require gl_ERROR_H. Update condition. + * doc/glibc-headers/error.texi: Mention the 'error-h' module. + * doc/glibc-functions/error.texi: Mention the Android problem. + * config/srclist.txt: Add comment regarding error.h. + 2023-01-12 Bruno Haible error, verror tests: Add clarification. diff --git a/config/srclist.txt b/config/srclist.txt index bff6a02d8e..1ff4e6ec8d 100644 --- a/config/srclist.txt +++ b/config/srclist.txt @@ -125,7 +125,7 @@ $LIBCSRC time/mktime-internal.h lib # https://sourceware.org/bugzilla/show_bug.cgi?id=321 #$LIBCSRC malloc/obstack.h lib gpl #$LIBCSRC misc/error.c lib gpl -#$LIBCSRC misc/error.h lib gpl +#$LIBCSRC misc/error.h lib gpl (error.in.h in gnulib) #$LIBCSRC misc/getpass.c lib gpl #$LIBCSRC misc/mkstemp.c lib gpl #$LIBCSRC posix/fnmatch.c lib gpl diff --git a/doc/glibc-functions/error.texi b/doc/glibc-functions/error.texi index e0977925b6..c7d63ac42b 100644 --- a/doc/glibc-functions/error.texi +++ b/doc/glibc-functions/error.texi @@ -24,6 +24,10 @@ Portability problems fixed by Gnulib: @item This function is missing on many non-glibc platforms: macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 1.7.9, mingw, MSVC 14, Android 5.1. +@item +This function outputs an extra space if @code{error_print_progname} is set, +on some platforms: +Android 11. @end itemize Portability problems not fixed by Gnulib: diff --git a/doc/glibc-headers/error.texi b/doc/glibc-headers/error.texi index 96a9a14664..4e0ccbffaa 100644 --- a/doc/glibc-headers/error.texi +++ b/doc/glibc-headers/error.texi @@ -18,7 +18,7 @@ Documentation: @uref{https://www.kernel.org/doc/man-pages/online/pages/man3/error.3.html,,man error}. @end itemize -Gnulib module: error +Gnulib module: error-h Portability problems fixed by Gnulib: @itemize diff --git a/lib/error.h b/lib/error.h deleted file mode 100644 index a240526a58..0000000000 --- a/lib/error.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Declaration for error-reporting function - Copyright (C) 1995-1997, 2003, 2006, 2008-2023 Free Software Foundation, - Inc. - This file is part of the GNU C Library. - - This file is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - This file 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . */ - -#ifndef _ERROR_H -#define _ERROR_H 1 - -/* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM. */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Print a message with 'fprintf (stderr, FORMAT, ...)'; - if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). - If STATUS is nonzero, terminate the program with 'exit (STATUS)'. */ - -extern void error (int __status, int __errnum, const char *__format, ...) -#if GNULIB_VFPRINTF_POSIX - _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4)) -#else - _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM, 3, 4)) -#endif - ; - -extern void error_at_line (int __status, int __errnum, const char *__fname, - unsigned int __lineno, const char *__format, ...) -#if GNULIB_VFPRINTF_POSIX - _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 5, 6)) -#else - _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM, 5, 6)) -#endif - ; - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -extern void (*error_print_progname) (void); - -/* This variable is incremented each time 'error' is called. */ -extern unsigned int error_message_count; - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -extern int error_one_per_line; - -#ifdef __cplusplus -} -#endif - -#endif /* error.h */ diff --git a/lib/error.in.h b/lib/error.in.h new file mode 100644 index 0000000000..2ac99c2817 --- /dev/null +++ b/lib/error.in.h @@ -0,0 +1,104 @@ +/* Declarations for error-reporting functions. + Copyright (C) 1995-1997, 2003, 2006, 2008-2023 Free Software Foundation, + Inc. + This file is part of the GNU C Library. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _ERROR_H +#define _ERROR_H 1 + +/* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM. */ +#include + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +#if GNULIB_VFPRINTF_POSIX +# define _GL_ATTRIBUTE_SPEC_PRINTF_ERROR _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD +#else +# define _GL_ATTRIBUTE_SPEC_PRINTF_ERROR _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Print a message with 'fprintf (stderr, FORMAT, ...)'; + if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). + If STATUS is nonzero, terminate the program with 'exit (STATUS)'. */ +#if @REPLACE_ERROR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef error +# define error rpl_error +# endif +_GL_FUNCDECL_RPL (error, void, + (int __status, int __errnum, const char *__format, ...) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4))); +_GL_CXXALIAS_RPL (error, void, + (int __status, int __errnum, const char *__format, ...)); +#else +# if ! @HAVE_ERROR@ +_GL_FUNCDECL_SYS (error, void, + (int __status, int __errnum, const char *__format, ...) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4))); +# endif +_GL_CXXALIAS_SYS (error, void, + (int __status, int __errnum, const char *__format, ...)); +#endif +_GL_CXXALIASWARN (error); + +/* Likewise. If FILENAME is non-NULL, include FILENAME:LINENO: in the + message. */ +#if @REPLACE_ERROR_AT_LINE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef error_at_line +# define error_at_line rpl_error_at_line +# endif +_GL_FUNCDECL_RPL (error_at_line, void, + (int __status, int __errnum, const char *__filename, + unsigned int __lineno, const char *__format, ...) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6))); +_GL_CXXALIAS_RPL (error_at_line, void, + (int __status, int __errnum, const char *__filename, + unsigned int __lineno, const char *__format, ...)); +#else +# if ! @HAVE_ERROR_AT_LINE@ +_GL_FUNCDECL_SYS (error_at_line, void, + (int __status, int __errnum, const char *__filename, + unsigned int __lineno, const char *__format, ...) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6))); +# endif +_GL_CXXALIAS_SYS (error_at_line, void, + (int __status, int __errnum, const char *__filename, + unsigned int __lineno, const char *__format, ...)); +#endif +_GL_CXXALIASWARN (error_at_line); + +/* If NULL, error will flush stdout, then print on stderr the program + name, a colon and a space. Otherwise, error will call this + function without parameters instead. */ +extern void (*error_print_progname) (void); + +/* This variable is incremented each time 'error' is called. */ +extern unsigned int error_message_count; + +/* Sometimes we want to have at most one error per line. This + variable controls whether this mode is selected or not. */ +extern int error_one_per_line; + +#ifdef __cplusplus +} +#endif + +#endif /* error.h */ diff --git a/m4/error.m4 b/m4/error.m4 index 8cc75dffdf..93a7558b5f 100644 --- a/m4/error.m4 +++ b/m4/error.m4 @@ -1,4 +1,4 @@ -#serial 15 +#serial 16 # Copyright (C) 1996-1998, 2001-2004, 2009-2023 Free Software Foundation, Inc. # @@ -8,15 +8,6 @@ AC_DEFUN([gl_ERROR], [ - dnl We don't use AC_FUNC_ERROR_AT_LINE any more, because it is no longer - dnl maintained in Autoconf and because it invokes AC_LIBOBJ. - AC_CACHE_CHECK([for error_at_line], [ac_cv_lib_error_at_line], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[error_at_line (0, 0, "", 0, "an error occurred");]])], - [ac_cv_lib_error_at_line=yes], - [ac_cv_lib_error_at_line=no])]) ]) # Prerequisites of lib/error.c. diff --git a/m4/error_h.m4 b/m4/error_h.m4 new file mode 100644 index 0000000000..bb8f68ff81 --- /dev/null +++ b/m4/error_h.m4 @@ -0,0 +1,113 @@ +# error_h.m4 serial 1 +dnl Copyright (C) 1996-2023 Free Software Foundation, Inc. +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 From Bruno Haible. +dnl Provide a working "error.h". + +AC_DEFUN_ONCE([gl_ERROR_H], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + gl_CHECK_FUNCS_ANDROID([error], [[#include ]]) + if test $ac_cv_func_error = yes; then + HAVE_ERROR=1 + else + HAVE_ERROR=0 + fi + REPLACE_ERROR=0 + + dnl We don't use AC_FUNC_ERROR_AT_LINE any more, because it is no longer + dnl maintained in Autoconf and because it invokes AC_LIBOBJ. + dnl We need to notice a missing declaration, like gl_CHECK_FUNCS_ANDROID does. + AC_CHECK_DECL([error_at_line], , , [[#include ]]) + if test $ac_cv_have_decl_error_at_line = yes; then + AC_CACHE_CHECK([for error_at_line], [ac_cv_lib_error_at_line], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[error_at_line (0, 0, "", 0, "an error occurred");]])], + [ac_cv_lib_error_at_line=yes], + [ac_cv_lib_error_at_line=no])]) + else + ac_cv_lib_error_at_line=no + fi + if test $ac_cv_lib_error_at_line = yes; then + HAVE_ERROR_AT_LINE=1 + else + HAVE_ERROR_AT_LINE=0 + fi + REPLACE_ERROR_AT_LINE=0 + + if test $ac_cv_func_error = yes && test $ac_cv_lib_error_at_line = yes; then + dnl On Android 11, when error_print_progname is set, the output of the + dnl error() function contains an extra space. + AC_CACHE_CHECK([for working error function], + [gl_cv_func_working_error], + [if test $cross_compiling != yes; then + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + static void print_no_progname (void) {} + ]], [[ + error_print_progname = print_no_progname; + error (0, 0, "foo"); + ]]) + ], + [rm -f conftest.out + if test -s conftest$ac_exeext \ + && ./conftest$ac_exeext 2> conftest.out; then + if grep ' ' conftest.out >/dev/null; then + gl_cv_func_working_error=no + else + gl_cv_func_working_error=yes + fi + else + gl_cv_func_working_error=no + fi + rm -f conftest.out + ], + [gl_cv_func_working_error=no]) + else + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include + ]], [[ + error (0, 0, "foo"); + ]]) + ], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_working_error="guessing yes" ;; + # Guess no on Android. + linux*-android*) gl_cv_func_working_error="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_working_error="$gl_cross_guess_normal" ;; + esac + ], + [gl_cv_func_working_error=no]) + fi + ]) + case "$gl_cv_func_working_error" in + *no) + REPLACE_ERROR=1 + REPLACE_ERROR_AT_LINE=1 + ;; + esac + fi + + if test $HAVE_ERROR = 0 || test $REPLACE_ERROR = 1 \ + || test $HAVE_ERROR_AT_LINE = 0 || test $REPLACE_ERROR_AT_LINE = 1; then + dnl Provide a substitute file. + GL_GENERATE_ERROR_H=true + else + GL_GENERATE_ERROR_H=false + fi + + AC_SUBST([HAVE_ERROR]) + AC_SUBST([HAVE_ERROR_AT_LINE]) + AC_SUBST([REPLACE_ERROR]) + AC_SUBST([REPLACE_ERROR_AT_LINE]) +]) diff --git a/modules/error b/modules/error index e8363528aa..5f716865a9 100644 --- a/modules/error +++ b/modules/error @@ -2,20 +2,21 @@ Description: error and error_at_line functions: Error reporting. Files: -lib/error.h lib/error.c m4/error.m4 Depends-on: +error-h stdio getprogname -strerror [test $ac_cv_lib_error_at_line = no] -unistd [test $ac_cv_lib_error_at_line = no] -msvc-nothrow [test $ac_cv_lib_error_at_line = no] +strerror [test $GL_GENERATE_ERROR_H = true] +unistd [test $GL_GENERATE_ERROR_H = true] +msvc-nothrow [test $GL_GENERATE_ERROR_H = true] configure.ac: +AC_REQUIRE([gl_ERROR_H]) gl_ERROR -gl_CONDITIONAL([GL_COND_OBJ_ERROR], [test "$ac_cv_lib_error_at_line" = no]) +gl_CONDITIONAL([GL_COND_OBJ_ERROR], [test $GL_GENERATE_ERROR_H = true]) AM_COND_IF([GL_COND_OBJ_ERROR], [ gl_PREREQ_ERROR ]) diff --git a/modules/error-h b/modules/error-h new file mode 100644 index 0000000000..80bc06194b --- /dev/null +++ b/modules/error-h @@ -0,0 +1,46 @@ +Description: +Functions for error reporting. + +Files: +lib/error.in.h +m4/error_h.m4 + +Depends-on: +gen-header +snippet/c++defs + +configure.ac: +gl_ERROR_H +gl_CONDITIONAL_HEADER([error.h]) +AC_PROG_MKDIR_P + +Makefile.am: +BUILT_SOURCES += $(ERROR_H) + +# We need the following in order to create when the system +# doesn't have one that works. +if GL_GENERATE_ERROR_H +error.h: error.in.h $(top_builddir)/config.status $(CXXDEFS_H) +@NMD@ $(AM_V_GEN)$(MKDIR_P) '%reldir%' + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''HAVE_ERROR''@|$(HAVE_ERROR)|g' \ + -e 's|@''HAVE_ERROR_AT_LINE''@|$(HAVE_ERROR_AT_LINE)|g' \ + -e 's|@''REPLACE_ERROR''@|$(REPLACE_ERROR)|g' \ + -e 's|@''REPLACE_ERROR_AT_LINE''@|$(REPLACE_ERROR_AT_LINE)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + $(srcdir)/error.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +error.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += error.h error.h-t + +Include: +"error.h" + +License: +LGPLv2+ + +Maintainer: +all -- cgit v1.2.1