Commit 32107c10 authored by Paul Eggert's avatar Paul Eggert

glob: merge from glibc with Zanella glob changes

Merge glob from glibc, with changes for glob proposed
by Adhemerval Zanella in the thread starting here:
https://sourceware.org/ml/libc-alpha/2017-08/msg01079.html
plus some fixes for this merge.
* lib/flexmember.h: Change license wording to something that
works unchanged in Glibc, since this code might be used in
Glibc and this will minimize 'diff' output.
* lib/glob_internal.h, lib/glob_pattern_p.c, lib/globfree.c:
New files, ported from glibc.
* lib/glob_pattern_p.c, lib/globfree.c, lib/glob.c [!_LIBC]:
Include <config.h> first.
* lib/glob-libc.h (_Restrict_): Remove.  All uses replaced
with __restrict.
(__size_t): Remove.  All uses replaced by size_t.
(size_t): Define by defining __need_size_t and including <stddef.h>.
This should work even in non-glibc platforms, where any name
pollution is OK.
Use __USE_MISC instead of __USE_BSD || __USE_GNU.
(struct stat64): Don’t worry about __GLOB_GNULIB.
(glob, globfree, glob_pattern_p): Remove macros for
__USE_FILE_OFFSET64 && __GNUC__ < 2 && !defined __GLOB_GNULIB
case.  Remove _GL_ARG_NONNULL as GNU behavior is to accept NULL
but set errno.
* lib/glob.c (_GL_ARG_NONNULL) [!_LIBC]: Remove.  All uses
removed since the glibc behavior works on null pointers.
Do not include stdio.h; old SunOS is irrelevant now.
Do not worry about GLOB_ONLY_P as we now mimic glibc here.
Include glob_internal.h.
(D_INO_TO_RESULT): Depend on (_LIBC || D_INO_IN_DIRENT), not
((POSIX || WINDOWS32) && !__GNU_LIBRARY__).  The latter probably
worked only coincidentally.
(attribute_hidden, __attribute_noinline__, __glibc_unlikely):
Remove macros; now done in glob.in.h.
(size_add_wrapv): Do not use __builtin_add_overflow if __ICC.
(glob): Properly initialize glob structure with
GLOB_BRACE|GLOB_DOOFFS (bug 20707).
Remove old code using SHELL since Bash no longer
uses this.
(glob, prefix_array): Separate MS code better.
(glob, glob_in_dir): Use C99 decls before statements when glibc
does.
(glob_in_dir): Remove old Amiga and VMS code.
(globfree, __glob_pattern_type, __glob_pattern_p): Move to
separate files.
* lib/glob.in.h (attribute_hidden, __attribute_noinline__)
(__glibc_unlikely):
Move here from glob.c.
(__restrict): New macro here, replacing the _Restrict_ in glob.c.
(weak_alias): New macro.
(__size_t): Remove.  All uses replaced by size_t.
* modules/d-ino (License): Now LGPLv2+, for compatibility with glob.
* modules/flexmember (License): Now LGPLv2+, which it should have
been anyway since flexmember.h is not unlimited-license.
* modules/glob (Files): Add +lib/glob_internal.h,
lib/glob_pattern_p.c, lib/globfree.c.
(Depends-on): Remove snippet/arg-nonnull.
parent f320c1eb
2017-08-23 Paul Eggert <eggert@cs.ucla.edu>
glob: merge from glibc with Zanella glob changes
Merge glob from glibc, with changes for glob proposed
by Adhemerval Zanella in the thread starting here:
https://sourceware.org/ml/libc-alpha/2017-08/msg01079.html
plus some fixes for this merge.
* lib/glob_internal.h, lib/glob_pattern_p.c, lib/globfree.c:
New files, ported from glibc.
* lib/glob-libc.h (_Restrict_): Remove. All uses replaced
with __restrict.
(__size_t): Remove. All uses replaced by size_t.
(size_t): Define by defining __need_size_t and including <stddef.h>.
This should work even in non-glibc platforms, where any name
pollution is OK.
Use __USE_MISC instead of __USE_BSD || __USE_GNU.
(struct stat64): Don’t worry about __GLOB_GNULIB.
(glob, globfree, glob_pattern_p): Remove macros for
__USE_FILE_OFFSET64 && __GNUC__ < 2 && !defined __GLOB_GNULIB
case. Remove _GL_ARG_NONNULL as GNU behavior is to accept NULL
but set errno.
* lib/glob.c (_GL_ARG_NONNULL) [!_LIBC]: Remove. All uses
removed since the glibc behavior works on null pointers.
Do not include stdio.h; old SunOS is irrelevant now.
Do not worry about GLOB_ONLY_P as we now mimic glibc here.
Include glob_internal.h.
(D_INO_TO_RESULT): Depend on (_LIBC || D_INO_IN_DIRENT), not
((POSIX || WINDOWS32) && !__GNU_LIBRARY__). The latter probably
worked only coincidentally.
(attribute_hidden, __attribute_noinline__, __glibc_unlikely):
Remove macros; now done in glob.in.h.
(size_add_wrapv): Do not use __builtin_add_overflow if __ICC.
(glob): Properly initialize glob structure with
GLOB_BRACE|GLOB_DOOFFS (bug 20707).
Remove old code using SHELL since Bash no longer
uses this.
(glob, prefix_array): Separate MS code better.
(glob, glob_in_dir): Use C99 decls before statements when glibc
does.
(glob_in_dir): Remove old Amiga and VMS code.
(globfree, __glob_pattern_type, __glob_pattern_p): Move to
separate files.
* lib/glob.in.h (attribute_hidden, __attribute_noinline__)
(__glibc_unlikely):
Move here from glob.c.
(__restrict): New macro here, replacing the _Restrict_ in glob.c.
(weak_alias): New macro.
(__size_t): Remove. All uses replaced by size_t.
* modules/d-ino (License): Now LGPLv2+, for compatibility with glob.
* modules/glob (Files): Add +lib/glob_internal.h,
lib/glob_pattern_p.c, lib/globfree.c.
(Depends-on): Remove snippet/arg-nonnull.
2017-08-22 Paul Eggert <eggert@cs.ucla.edu>
glob: port to clang's Undefined Sanitizer
......@@ -2,18 +2,21 @@
Copyright 2016-2017 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 of the License, or
(at your option) any later version.
This file is part of the GNU C Library.
This program is distributed in the hope that it will be useful,
The GNU C Library 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.
The GNU C Library 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.
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 General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
Written by Paul Eggert. */
......
/* Copyright (C) 1991-1992, 1995-1998, 2000-2001, 2004-2007, 2009-2017 Free
Software Foundation, Inc.
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
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 of the License, or
(at your option) any later version.
The GNU C Library 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 program is distributed in the hope that it will be useful,
The GNU C Library 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.
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 General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLOB_H
#define _GLOB_H 1
......@@ -22,42 +22,10 @@
# include <sys/cdefs.h>
#endif
/* 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
'configure' might #define 'restrict' to those words, so pick a
different name. */
#ifndef _Restrict_
# if 199901L <= __STDC_VERSION__
# define _Restrict_ restrict
# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)
# define _Restrict_ __restrict
# else
# define _Restrict_
# endif
#endif
__BEGIN_DECLS
/* We need 'size_t' for the following definitions. */
#ifndef __size_t
# if defined __GNUC__ && __GNUC__ >= 2
typedef __SIZE_TYPE__ __size_t;
# ifdef __USE_XOPEN
typedef __SIZE_TYPE__ size_t;
# endif
# else
# include <stddef.h>
# ifndef __size_t
# define __size_t size_t
# endif
# endif
#else
/* The GNU CC stddef.h version defines __size_t as empty. We need a real
definition. */
# undef __size_t
# define __size_t size_t
#endif
#define __need_size_t
#include <stddef.h>
/* Bits set in the FLAGS argument to 'glob'. */
#define GLOB_ERR (1 << 0)/* Return on read errors. */
......@@ -69,7 +37,7 @@ typedef __SIZE_TYPE__ size_t;
#define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */
#define GLOB_PERIOD (1 << 7)/* Leading '.' can be matched by metachars. */
#if !defined __USE_POSIX2 || defined __USE_BSD || defined __USE_GNU
#if !defined __USE_POSIX2 || defined __USE_MISC
# define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */
# define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions. */
# define GLOB_BRACE (1 << 10)/* Expand "{a,b}" to "a" "b". */
......@@ -105,9 +73,9 @@ struct stat;
#endif
typedef struct
{
__size_t gl_pathc; /* Count of paths matched by the pattern. */
size_t gl_pathc; /* Count of paths matched by the pattern. */
char **gl_pathv; /* List of matched pathnames. */
__size_t gl_offs; /* Slots to reserve in 'gl_pathv'. */
size_t gl_offs; /* Slots to reserve in 'gl_pathv'. */
int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */
/* If the GLOB_ALTDIRFUNC flag is set, the following functions
......@@ -120,23 +88,23 @@ typedef struct
#endif
void *(*gl_opendir) (const char *);
#ifdef __USE_GNU
int (*gl_lstat) (const char *_Restrict_, struct stat *_Restrict_);
int (*gl_stat) (const char *_Restrict_, struct stat *_Restrict_);
int (*gl_lstat) (const char *__restrict, struct stat *__restrict);
int (*gl_stat) (const char *__restrict, struct stat *__restrict);
#else
int (*gl_lstat) (const char *_Restrict_, void *_Restrict_);
int (*gl_stat) (const char *_Restrict_, void *_Restrict_);
int (*gl_lstat) (const char *__restrict, void *__restrict);
int (*gl_stat) (const char *__restrict, void *__restrict);
#endif
} glob_t;
#if defined __USE_LARGEFILE64 && !defined __GLOB_GNULIB
#ifdef __USE_LARGEFILE64
# ifdef __USE_GNU
struct stat64;
# endif
typedef struct
{
__size_t gl_pathc;
size_t gl_pathc;
char **gl_pathv;
__size_t gl_offs;
size_t gl_offs;
int gl_flags;
/* If the GLOB_ALTDIRFUNC flag is set, the following functions
......@@ -149,20 +117,15 @@ typedef struct
# endif
void *(*gl_opendir) (const char *);
# ifdef __USE_GNU
int (*gl_lstat) (const char *_Restrict_, struct stat64 *_Restrict_);
int (*gl_stat) (const char *_Restrict_, struct stat64 *_Restrict_);
int (*gl_lstat) (const char *__restrict, struct stat64 *__restrict);
int (*gl_stat) (const char *__restrict, struct stat64 *__restrict);
# else
int (*gl_lstat) (const char *_Restrict_, void *_Restrict_);
int (*gl_stat) (const char *_Restrict_, void *_Restrict_);
int (*gl_lstat) (const char *__restrict, void *__restrict);
int (*gl_stat) (const char *__restrict, void *__restrict);
# endif
} glob64_t;
#endif
#if defined __USE_FILE_OFFSET64 && __GNUC__ < 2 && !defined __GLOB_GNULIB
# define glob glob64
# define globfree globfree64
#endif
/* Do glob searching for PATTERN, placing results in PGLOB.
The bits defined above may be set in FLAGS.
If a directory cannot be opened or read and ERRFUNC is not nil,
......@@ -171,29 +134,28 @@ typedef struct
'glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
Otherwise, 'glob' returns zero. */
#if !defined __USE_FILE_OFFSET64 || __GNUC__ < 2 || defined __GLOB_GNULIB
extern int glob (const char *_Restrict_ __pattern, int __flags,
#if !defined __USE_FILE_OFFSET64 || defined __GLOB_GNULIB
extern int glob (const char *__restrict __pattern, int __flags,
int (*__errfunc) (const char *, int),
glob_t *_Restrict_ __pglob) __THROW _GL_ARG_NONNULL ((1, 4));
glob_t *__restrict __pglob) __THROW;
/* Free storage allocated in PGLOB by a previous 'glob' call. */
extern void globfree (glob_t *__pglob) __THROW _GL_ARG_NONNULL ((1));
extern void globfree (glob_t *__pglob) __THROW;
#else
extern int __REDIRECT_NTH (glob, (const char *_Restrict_ __pattern,
extern int __REDIRECT_NTH (glob, (const char *__restrict __pattern,
int __flags,
int (*__errfunc) (const char *, int),
glob_t *_Restrict_ __pglob), glob64);
glob_t *__restrict __pglob), glob64);
extern void __REDIRECT_NTH (globfree, (glob_t *__pglob), globfree64);
#endif
#if defined __USE_LARGEFILE64 && !defined __GLOB_GNULIB
extern int glob64 (const char *_Restrict_ __pattern, int __flags,
#ifdef __USE_LARGEFILE64
extern int glob64 (const char *__restrict __pattern, int __flags,
int (*__errfunc) (const char *, int),
glob64_t *_Restrict_ __pglob)
__THROW _GL_ARG_NONNULL ((1, 4));
glob64_t *__restrict __pglob) __THROW;
extern void globfree64 (glob64_t *__pglob) __THROW _GL_ARG_NONNULL ((1));
extern void globfree64 (glob64_t *__pglob) __THROW;
#endif
......@@ -203,8 +165,7 @@ extern void globfree64 (glob64_t *__pglob) __THROW _GL_ARG_NONNULL ((1));
This function is not part of the interface specified by POSIX.2
but several programs want to use it. */
extern int glob_pattern_p (const char *__pattern, int __quote)
__THROW _GL_ARG_NONNULL ((1));
extern int glob_pattern_p (const char *__pattern, int __quote) __THROW;
#endif
__END_DECLS
......
This diff is collapsed.
......@@ -47,19 +47,40 @@
# define __THROWNL
#endif
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
#define attribute_hidden
/* The definition of _GL_ARG_NONNULL is copied here. */
#ifndef __attribute_noinline__
# if 3 < __GNUC__ + (1 <= __GNUC_MINOR__)
# define __attribute_noinline__ __attribute__ ((__noinline__))
#else
# define __attribute_noinline__ /* Ignore */
# endif
#endif
/* The definition of _GL_WARN_ON_USE is copied here. */
#if __GNUC__ < 3
# define __glibc_unlikely(cond) (cond)
#else
# define __glibc_unlikely(cond) __builtin_expect ((cond), 0)
#endif
#ifndef __size_t
# define __size_t size_t
/* GCC 2.95 and later have "__restrict", and C99 compilers have
"restrict". */
#if ! (defined __restrict || 2 < __GNUC__ + (95 <= __GNUC_MINOR__))
# if 199901L <= __STDC_VERSION__
# define __restrict restrict
# else
# define __restrict
# endif
#endif
#ifndef __USE_GNU
# define __USE_GNU 1
#endif
#ifndef weak_alias
# define weak_alias(name, alias)
#endif
#define glob rpl_glob
#define globfree rpl_globfree
......
/* Shared definition for glob and glob_pattern_p.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library 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.
The GNU C Library 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 the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef GLOB_INTERNAL_H
# define GLOB_INTERNAL_H
static inline int
__glob_pattern_type (const char *pattern, int quote)
{
const char *p;
int ret = 0;
for (p = pattern; *p != '\0'; ++p)
switch (*p)
{
case '?':
case '*':
return 1;
case '\\':
if (quote)
{
if (p[1] != '\0')
++p;
ret |= 2;
}
break;
case '[':
ret |= 4;
break;
case ']':
if (ret & 4)
return 1;
break;
}
return ret;
}
#endif /* GLOB_INTERNAL_H */
/* Return nonzero if PATTERN contains any metacharacters.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library 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.
The GNU C Library 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 the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _LIBC
# include <config.h>
#endif
#include <glob.h>
#include "glob_internal.h"
/* Return nonzero if PATTERN contains any metacharacters.
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
int
__glob_pattern_p (const char *pattern, int quote)
{
return __glob_pattern_type (pattern, quote) == 1;
}
weak_alias (__glob_pattern_p, glob_pattern_p)
/* Frees the dynamically allocated storage from an earlier call to glob.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library 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.
The GNU C Library 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 the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _LIBC
# include <config.h>
#endif
#include <glob.h>
#include <stdlib.h>
/* Free storage allocated in PGLOB by a previous `glob' call. */
void
globfree (glob_t *pglob)
{
if (pglob->gl_pathv != NULL)
{
size_t i;
for (i = 0; i < pglob->gl_pathc; ++i)
free (pglob->gl_pathv[pglob->gl_offs + i]);
free (pglob->gl_pathv);
pglob->gl_pathv = NULL;
}
}
#ifndef globfree
libc_hidden_def (globfree)
#endif
......@@ -14,7 +14,7 @@ Makefile.am:
Include:
License:
LGPL
LGPLv2+
Maintainer:
Jim Meyering
......@@ -15,7 +15,7 @@ Makefile.am:
Include:
License:
unlimited
LGPLv2+
Maintainer:
Paul Eggert, Jim Meyering
......@@ -6,17 +6,20 @@ Files:
lib/glob.in.h
lib/glob-libc.h
lib/glob.c
lib/glob_internal.h
lib/glob_pattern_p.c
lib/globfree.c
m4/glob.m4
Depends-on:
extensions
largefile
snippet/arg-nonnull
snippet/c++defs
snippet/warn-on-use
alloca [test -n "$GLOB_H"]
builtin-expect [test -n "$GLOB_H"]
closedir [test -n "$GLOB_H"]
d-ino [test -n "$GLOB_H"]
d-type [test -n "$GLOB_H"]
dirfd [test -n "$GLOB_H"]
flexmember [test -n "$GLOB_H"]
......@@ -37,6 +40,8 @@ configure.ac:
gl_GLOB
if test -n "$GLOB_H"; then
AC_LIBOBJ([glob])
AC_LIBOBJ([glob_pattern_p])
AC_LIBOBJ([globfree])
gl_PREREQ_GLOB
fi
......@@ -46,12 +51,11 @@ BUILT_SOURCES += $(GLOB_H)
# We need the following in order to create <glob.h> when the system
# doesn't have one that works with the given compiler.
if GL_GENERATE_GLOB_H
glob.h: glob.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
glob.h: glob.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
$(AM_V_GEN)rm -f $@-t $@ && \
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
sed -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_H)|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 && \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment