In order to add 'posixcheck' support to the 'glob' function, it is necessary to distinguish a module for the <glob.h> header and a module for the glob() and globfree() functions. (Why? Again, because in the 'posixcheck' situation, the module for the header must be present whereas the module for the functions must be absent.)
2018-08-07 Bruno Haible <br...@clisp.org> glob-h: New module. * lib/glob.in.h: Use nearly the usual gnulib idioms for header file replacements. * lib/glob.c: Include <config.h>. * m4/glob_h.m4: New file. * m4/glob.m4 (gl_GLOB): Require gl_GLOB_H. Remove code that is moved to glob_h.m4. Set HAVE_GLOB, REPLACE_GLOB, HAVE_GLOB_PATTERN_P, REPLACE_GLOB_PATTERN_P as appropriate. (gl_PREREQ_GLOB): Don't require AC_C_RESTRICT and AC_USE_SYSTEM_EXTENSIONS, now done through module 'glob-h'. * modules/glob-h: New file. * modules/glob (Files): Remove lib/glob.in.h, lib/glob-libc.h. (Dependencies): Add glob-h. Remove extensions, snippet/*, libc-config, lstat, sys_stat. Change conditions. (configure.ac): Test HAVE_GLOB, REPLACE_GLOB, HAVE_GLOB_PATTERN_P, REPLACE_GLOB_PATTERN_P. Set module indicator. (Makefile.am): Remove code that is moved to glob-h. * doc/posix-headers/glob.texi: Mention the 'glob-h' module. * modules/posixcheck (Depends-on): Add glob-h. diff --git a/doc/posix-headers/glob.texi b/doc/posix-headers/glob.texi index 7c1e09b..2fb24d9 100644 --- a/doc/posix-headers/glob.texi +++ b/doc/posix-headers/glob.texi @@ -3,7 +3,7 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/basedefs/glob.h.html} -Gnulib module: glob +Gnulib module: glob-h Portability problems fixed by Gnulib: @itemize diff --git a/lib/glob.c b/lib/glob.c index c4ba994..17ec19a 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -15,6 +15,10 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ +#ifndef _LIBC +# include <config.h> +#endif + #include <glob.h> #include <errno.h> diff --git a/lib/glob.in.h b/lib/glob.in.h index 656c1eb..6e40ca9 100644 --- a/lib/glob.in.h +++ b/lib/glob.in.h @@ -25,7 +25,7 @@ @PRAGMA_COLUMNS@ /* The include_next requires a split double-inclusion guard. */ -#if !@REPLACE_GLOB@ +#if @HAVE_GLOB_H@ && !@REPLACE_GLOB@ # @INCLUDE_NEXT@ @NEXT_GLOB_H@ #endif @@ -34,6 +34,10 @@ /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + /* GCC 2.95 and later have "__restrict"; C99 compilers have "restrict", and "configure" may have defined "restrict". Other compilers use __restrict, __restrict__, and _Restrict, and @@ -58,7 +62,7 @@ typedef int (*_gl_glob_errfunc_fn) (const char *, int); #endif -#if @REPLACE_GLOB@ +#if !@HAVE_GLOB_H@ || @REPLACE_GLOB@ /* Preparations for including the standard GNU C Library header. */ @@ -76,9 +80,17 @@ typedef int (*_gl_glob_errfunc_fn) (const char *, int); # define __USE_GNU 1 # endif -# define glob rpl_glob -# define globfree rpl_globfree -# define glob_pattern_p rpl_glob_pattern_p +# if @REPLACE_GLOB@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define glob rpl_glob +# define globfree rpl_globfree +# endif +# endif +# if @REPLACE_GLOB_PATTERN_P@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define glob_pattern_p rpl_glob_pattern_p +# endif +# endif # define __glob_pattern_p glob_pattern_p # define __GLOB_GNULIB 1 @@ -88,32 +100,81 @@ typedef int (*_gl_glob_errfunc_fn) (const char *, int); # include "glob-libc.h" -# if defined __cplusplus && defined GNULIB_NAMESPACE -# undef glob -# undef globfree -# undef glob_pattern_p +#endif + + +#if @GNULIB_GLOB@ +# if @REPLACE_GLOB@ +_GL_FUNCDECL_RPL (glob, int, (const char *_Restrict_ __pattern, int __flags, + _gl_glob_errfunc_fn __errfunc, + glob_t *_Restrict_ __pglob) + _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (glob, int, (const char *_Restrict_ __pattern, int __flags, _gl_glob_errfunc_fn __errfunc, glob_t *_Restrict_ __pglob)); -_GL_CXXALIAS_RPL (globfree, void, (glob_t *__pglob)); -_GL_CXXALIAS_RPL (glob_pattern_p, int, (const char *__pattern, int __quote)); -# endif - -#else - +# else +# if !@HAVE_GLOB@ +_GL_FUNCDECL_SYS (glob, int, (const char *_Restrict_ __pattern, int __flags, + _gl_glob_errfunc_fn __errfunc, + glob_t *_Restrict_ __pglob) + _GL_ARG_NONNULL ((1))); +# endif _GL_CXXALIAS_SYS (glob, int, (const char *_Restrict_ __pattern, int __flags, _gl_glob_errfunc_fn __errfunc, glob_t *_Restrict_ __pglob)); -_GL_CXXALIAS_SYS (globfree, void, (glob_t *__pglob)); -_GL_CXXALIAS_SYS (glob_pattern_p, int, (const char *__pattern, int __quote)); - +# endif +_GL_CXXALIASWARN (glob); +#elif defined GNULIB_POSIXCHECK +# undef glob +# if HAVE_RAW_DECL_GLOB +_GL_WARN_ON_USE (glob, + "glob is unportable - " + "use gnulib module glob for portability"); +# endif #endif -#if 0 /* The C function name is rpl_glob in some cases, not glob. */ -_GL_CXXALIASWARN (glob); +#if @GNULIB_GLOB@ +# if @REPLACE_GLOB@ +_GL_FUNCDECL_RPL (globfree, void, (glob_t *__pglob) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (globfree, void, (glob_t *__pglob)); +# else +# if !@HAVE_GLOB@ +_GL_FUNCDECL_SYS (globfree, void, (glob_t *__pglob) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (globfree, void, (glob_t *__pglob)); +# endif _GL_CXXALIASWARN (globfree); +#elif defined GNULIB_POSIXCHECK +# undef globfree +# if HAVE_RAW_DECL_GLOBFREE +_GL_WARN_ON_USE (globfree, + "globfree is unportable - " + "use gnulib module glob for portability"); +# endif +#endif + +#if @GNULIB_GLOB@ +# if @REPLACE_GLOB_PATTERN_P@ +_GL_FUNCDECL_RPL (glob_pattern_p, int, (const char *__pattern, int __quote) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (glob_pattern_p, int, (const char *__pattern, int __quote)); +# else +# if !@HAVE_GLOB_PATTERN_P@ +_GL_FUNCDECL_SYS (glob_pattern_p, int, (const char *__pattern, int __quote) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (glob_pattern_p, int, (const char *__pattern, int __quote)); +# endif _GL_CXXALIASWARN (glob_pattern_p); +#elif defined GNULIB_POSIXCHECK +# undef glob_pattern_p +# if HAVE_RAW_DECL_GLOB_PATTERN_P +_GL_WARN_ON_USE (glob_pattern_p, + "glob_pattern_p is unportable - " + "use gnulib module glob for portability"); +# endif #endif + #endif /* _@GUARD_PREFIX@_GLOB_H */ #endif /* _@GUARD_PREFIX@_GLOB_H */ diff --git a/m4/glob.m4 b/m4/glob.m4 index 37cb917..a9af4e4 100644 --- a/m4/glob.m4 +++ b/m4/glob.m4 @@ -1,4 +1,4 @@ -# glob.m4 serial 18 +# glob.m4 serial 19 dnl Copyright (C) 2005-2007, 2009-2018 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -10,15 +10,13 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_GLOB], [ - dnl <glob.h> is always overridden, because of the C++ GNULIB_NAMESPACE. - gl_CHECK_NEXT_HEADERS([glob.h]) - if test $ac_cv_header_glob_h = yes; then - REPLACE_GLOB=0 + AC_REQUIRE([gl_GLOB_H]) + + AC_CHECK_FUNCS_ONCE([glob glob_pattern_p]) + if test $ac_cv_func_glob = no; then + HAVE_GLOB=0 else - REPLACE_GLOB=1 - fi - if test $REPLACE_GLOB = 0; then AC_CACHE_CHECK([for GNU glob interface version 1 or 2], [gl_cv_gnu_glob_interface_version_1_2], [ AC_COMPILE_IFELSE([AC_LANG_SOURCE( @@ -26,49 +24,55 @@ AC_DEFUN([gl_GLOB], char a[_GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2 ? 1 : -1];]])], [gl_cv_gnu_glob_interface_version_1_2=yes], [gl_cv_gnu_glob_interface_version_1_2=no])]) - if test "$gl_cv_gnu_glob_interface_version_1_2" = "no"; then REPLACE_GLOB=1 fi - fi - - if test $REPLACE_GLOB = 0; then - AC_CACHE_CHECK([whether glob lists broken symlinks], - [gl_cv_glob_lists_symlinks], - [if ln -s conf-doesntexist conf$$-globtest 2>/dev/null; then - gl_cv_glob_lists_symlinks=maybe - else - # If we can't make a symlink, then we cannot test this issue. Be - # pessimistic about this. - gl_cv_glob_lists_symlinks=no - fi - if test $gl_cv_glob_lists_symlinks = maybe; then - AC_RUN_IFELSE([ -AC_LANG_PROGRAM( -[[#include <stddef.h> -#include <glob.h>]], -[[glob_t found; -if (glob ("conf*-globtest", 0, NULL, &found) == GLOB_NOMATCH) return 1;]])], - [gl_cv_glob_lists_symlinks=yes], - [gl_cv_glob_lists_symlinks=no], [gl_cv_glob_lists_symlinks=no]) - fi - rm -f conf$$-globtest - ]) - if test $gl_cv_glob_lists_symlinks = no; then - REPLACE_GLOB=1 + if test $REPLACE_GLOB = 0; then + AC_CACHE_CHECK([whether glob lists broken symlinks], + [gl_cv_glob_lists_symlinks], + [if ln -s conf-doesntexist conf$$-globtest 2>/dev/null; then + gl_cv_glob_lists_symlinks=maybe + else + # If we can't make a symlink, then we cannot test this issue. Be + # pessimistic about this. + gl_cv_glob_lists_symlinks=no + fi + if test $gl_cv_glob_lists_symlinks = maybe; then + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include <stddef.h> + #include <glob.h>]], + [[glob_t found; + if (glob ("conf*-globtest", 0, NULL, &found) == GLOB_NOMATCH) + return 1; + ]])], + [gl_cv_glob_lists_symlinks=yes], + [gl_cv_glob_lists_symlinks=no], + [gl_cv_glob_lists_symlinks=no]) + fi + rm -f conf$$-globtest + ]) + if test $gl_cv_glob_lists_symlinks = no; then + REPLACE_GLOB=1 + fi fi + fi - AC_SUBST([REPLACE_GLOB]) + if test $ac_cv_func_glob_pattern_p = no; then + HAVE_GLOB_PATTERN_P=0 + else + if test $REPLACE_GLOB = 1; then + REPLACE_GLOB_PATTERN_P=1 + fi + fi ]) -# Prerequisites of lib/glob.*. +# Prerequisites of lib/glob.c and lib/globfree.c. AC_DEFUN([gl_PREREQ_GLOB], [ - AC_REQUIRE([gl_CHECK_TYPE_STRUCT_DIRENT_D_TYPE])dnl - AC_REQUIRE([AC_C_RESTRICT])dnl - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])dnl - AC_CHECK_HEADERS_ONCE([unistd.h])dnl - AC_CHECK_FUNCS_ONCE([getlogin_r getpwnam_r])dnl + AC_REQUIRE([gl_CHECK_TYPE_STRUCT_DIRENT_D_TYPE]) + AC_CHECK_HEADERS_ONCE([unistd.h]) + AC_CHECK_FUNCS_ONCE([getlogin_r getpwnam_r]) ]) diff --git a/m4/glob_h.m4 b/m4/glob_h.m4 new file mode 100644 index 0000000..942efe5 --- /dev/null +++ b/m4/glob_h.m4 @@ -0,0 +1,64 @@ +# glob_h.m4 serial 1 +dnl Copyright (C) 2018 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. + +AC_DEFUN([gl_GLOB_H], +[ + AC_REQUIRE([gl_GLOB_H_DEFAULTS]) + m4_ifdef([gl_ANSI_CXX], [AC_REQUIRE([gl_ANSI_CXX])]) + AC_REQUIRE([AC_C_RESTRICT]) + AC_CHECK_HEADERS_ONCE([glob.h]) + gl_CHECK_NEXT_HEADERS([glob.h]) + + if test $ac_cv_header_glob_h = yes; then + HAVE_GLOB_H=1 + else + HAVE_GLOB_H=0 + fi + AC_SUBST([HAVE_GLOB_H]) + + m4_ifdef([gl_POSIXCHECK], + [GLOB_H=glob.h], + [GLOB_H='' + if m4_ifdef([gl_ANSI_CXX], [test "$CXX" != no], [false]); then + dnl Override <glob.h> always, to support the C++ GNULIB_NAMESPACE. + GLOB_H=glob.h + else + if test $ac_cv_header_glob_h != yes; then + dnl Provide a substitute <glob.h> file. + GLOB_H=glob.h + fi + fi + ]) + AC_SUBST([GLOB_H]) + AM_CONDITIONAL([GL_GENERATE_GLOB_H], [test -n "$GLOB_H"]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[#include <glob.h> + ]], + [glob globfree glob_pattern_p]) +]) + +AC_DEFUN([gl_GLOB_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_GLOB_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +AC_DEFUN([gl_GLOB_H_DEFAULTS], +[ + GNULIB_GLOB=0; AC_SUBST([GNULIB_GLOB]) + dnl Assume POSIX and GNU behavior unless another module says otherwise. + HAVE_GLOB=1; AC_SUBST([HAVE_GLOB]) + HAVE_GLOB_PATTERN_P=1; AC_SUBST([HAVE_GLOB_PATTERN_P]) + REPLACE_GLOB=0; AC_SUBST([REPLACE_GLOB]) + REPLACE_GLOB_PATTERN_P=0; AC_SUBST([REPLACE_GLOB_PATTERN_P]) +]) diff --git a/modules/glob b/modules/glob index 94b3fd0..4bf2dd2 100644 --- a/modules/glob +++ b/modules/glob @@ -3,8 +3,6 @@ glob() function: Search for files and directories with paths matching a pattern, with GNU extensions. Files: -lib/glob.in.h -lib/glob-libc.h lib/glob.c lib/glob_internal.h lib/glob_pattern_p.c @@ -12,58 +10,40 @@ lib/globfree.c m4/glob.m4 Depends-on: +glob-h c99 -extensions largefile -snippet/c++defs -alloca [test $REPLACE_GLOB = 1] -builtin-expect [test $REPLACE_GLOB = 1] -closedir [test $REPLACE_GLOB = 1] -d-type [test $REPLACE_GLOB = 1] -flexmember [test $REPLACE_GLOB = 1] -fnmatch [test $REPLACE_GLOB = 1] -getlogin_r [test $REPLACE_GLOB = 1] -libc-config [test $REPLACE_GLOB = 1] -lstat [test $REPLACE_GLOB = 1] -memchr [test $REPLACE_GLOB = 1] -mempcpy [test $REPLACE_GLOB = 1] -opendir [test $REPLACE_GLOB = 1] -readdir [test $REPLACE_GLOB = 1] -scratch_buffer [test $REPLACE_GLOB = 1] -stdbool [test $REPLACE_GLOB = 1] -stdint [test $REPLACE_GLOB = 1] -strdup [test $REPLACE_GLOB = 1] -sys_stat [test $REPLACE_GLOB = 1] -unistd [test $REPLACE_GLOB = 1] -malloc-posix [test $REPLACE_GLOB = 1] +alloca [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +builtin-expect [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +closedir [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +d-type [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +flexmember [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +fnmatch [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +getlogin_r [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +memchr [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +mempcpy [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +opendir [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +readdir [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +scratch_buffer [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +stdbool [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +stdint [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +strdup [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +unistd [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] +malloc-posix [test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1] configure.ac: gl_GLOB -if test $REPLACE_GLOB = 1; then +if test $HAVE_GLOB = 0 || test $REPLACE_GLOB = 1; then AC_LIBOBJ([glob]) - AC_LIBOBJ([glob_pattern_p]) AC_LIBOBJ([globfree]) gl_PREREQ_GLOB fi +if test $HAVE_GLOB_PATTERN_P = 0 || test $REPLACE_GLOB_PATTERN_P = 1; then + AC_LIBOBJ([glob_pattern_p]) +fi +gl_GLOB_MODULE_INDICATOR([glob]) Makefile.am: -BUILT_SOURCES += glob.h - -# We need the following in order to create <glob.h>. -glob.h: glob.in.h $(top_builddir)/config.status $(CXXDEFS_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \ - -e 's|@''REPLACE_GLOB''@|$(REPLACE_GLOB)|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_GLOB_H''@|$(NEXT_GLOB_H)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - < $(srcdir)/glob.in.h; \ - } > $@-t && \ - mv -f $@-t $@ -MOSTLYCLEANFILES += glob.h glob.h-t Include: <glob.h> diff --git a/modules/glob-h b/modules/glob-h new file mode 100644 index 0000000..b490a73 --- /dev/null +++ b/modules/glob-h @@ -0,0 +1,60 @@ +Description: +A <glob.h> that conforms to POSIX. + +Files: +lib/glob.in.h +lib/glob-libc.h +m4/glob_h.m4 + +Depends-on: +extensions +include_next +snippet/arg-nonnull +snippet/c++defs +snippet/warn-on-use +libc-config +lstat +sys_stat + +configure.ac: +gl_GLOB_H + +Makefile.am: +BUILT_SOURCES += $(GLOB_H) + +# We need the following in order to create <glob.h>. +if GL_GENERATE_GLOB_H +glob.h: glob.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \ + -e 's|@''HAVE_GLOB_H''@|$(HAVE_GLOB_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_GLOB_H''@|$(NEXT_GLOB_H)|g' \ + -e 's/@''GNULIB_GLOB''@/$(GNULIB_GLOB)/g' \ + -e 's|@''HAVE_GLOB''@|$(HAVE_GLOB)|g' \ + -e 's|@''HAVE_GLOB_PATTERN_P''@|$(HAVE_GLOB_PATTERN_P)|g' \ + -e 's|@''REPLACE_GLOB''@|$(REPLACE_GLOB)|g' \ + -e 's|@''REPLACE_GLOB_PATTERN_P''@|$(REPLACE_GLOB_PATTERN_P)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/glob.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +glob.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += glob.h glob.h-t + +Include: +<glob.h> + +License: +LGPLv2+ + +Maintainer: +all, glibc diff --git a/modules/posixcheck b/modules/posixcheck index fe40da1..fac9fea 100644 --- a/modules/posixcheck +++ b/modules/posixcheck @@ -12,6 +12,7 @@ ctype dirent fcntl-h fnmatch-h +glob-h iconv-h inttypes-incomplete langinfo