# HG changeset patch # User jwe # Date 804105758 0 # Node ID f0dcdcc9a7803e9431e22569ae6c78e449c5aff4 # Parent 3a02b029b6181b8f19d5ab097db0c97e5bfd63bc [project @ 1995-06-25 18:42:38 by jwe] Initial revision diff -r 3a02b029b618 -r f0dcdcc9a780 glob/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glob/Makefile.in Sun Jun 25 18:42:38 1995 +0000 @@ -0,0 +1,66 @@ +# Makefile for standalone distribution of libglob.a (fnmatch, glob). + +# Copyright (C) 1991, 92, 93, 94, 95 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# This 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with this library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# Ultrix 2.2 make doesn't expand the value of VPATH. +VPATH = @srcdir@ +# This must repeat the value, because configure will remove `VPATH = .'. +srcdir = @srcdir@ + +CC = @CC@ +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ + +# Information determined by configure. +DEFS = @DEFS@ + +# How to invoke ar. +AR = @AR@ +ARFLAGS = rv + +# How to invoke ranlib. +RANLIB = @RANLIB@ + +.PHONY: all +all: libglob.a + +libglob.a: glob.o fnmatch.o + $(AR) $(ARFLAGS) $@ glob.o fnmatch.o + $(RANLIB) $@ + +# For some reason, Unix make wants the dependencies on the source files. +# Otherwise it refuses to use an implicit rule! +# And, get this: it doesn't work to use $(srcdir)/foo.c!! +glob.o: $(srcdir)/glob.h $(srcdir)/fnmatch.h glob.c +fnmatch.o: $(srcdir)/fnmatch.h fnmatch.c + +.c.o: + $(CC) -I. -I$(srcdir) -c \ + $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) + +.PHONY: clean realclean glob-clean glob-realclean distclean +clean glob-clean: + -rm -f libglob.a *.o core +distclean glob-realclean: clean + -rm -f TAGS tags Makefile config.status config.h config.log +realcean: distclean + +# For inside the C library. +glob.tar glob.tar.Z: + $(MAKE) -C .. $@ diff -r 3a02b029b618 -r f0dcdcc9a780 glob/configure.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glob/configure.bat Sun Jun 25 18:42:38 1995 +0000 @@ -0,0 +1,26 @@ +@echo off +echo Configuring glob for GO32 +rem This batch file assumes a unix-type "sed" program + +echo # Makefile generated by "configure.bat"> Makefile + +if exist config.sed del config.sed + +echo "s/@srcdir@/./ ">> config.sed +echo "s/@CC@/gcc/ ">> config.sed +echo "s/@CFLAGS@/-O2 -g/ ">> config.sed +echo "s/@CPPFLAGS@/-DHAVE_CONFIG_H -I../ ">> config.sed +echo "s/@AR@/ar/ ">> config.sed +echo "s/@RANLIB@/ranlib/ ">> config.sed +echo "s/@LDFLAGS@// ">> config.sed +echo "s/@DEFS@// ">> config.sed +echo "s/@ALLOCA@// ">> config.sed +echo "s/@LIBS@// ">> config.sed +echo "s/@LIBOBJS@// ">> config.sed +echo "s/^Makefile *:/_Makefile:/ ">> config.sed +echo "s/^config.h *:/_config.h:/ ">> config.sed + +sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed +sed -f config2.sed Makefile.in >> Makefile +del config.sed +del config2.sed diff -r 3a02b029b618 -r f0dcdcc9a780 glob/configure.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glob/configure.in Sun Jun 25 18:42:38 1995 +0000 @@ -0,0 +1,19 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(fnmatch.c) dnl A distinctive file to look for in srcdir. +AC_PREREQ(2.1) dnl Minimum Autoconf version required. +AC_PROG_CC +AC_CHECK_PROG(AR, ar, ar, ar) +AC_PROG_RANLIB +AC_PROG_CPP dnl Later checks need this. +dnl These two want to come early. +AC_AIX +AC_MINIX +AC_ISC_POSIX +AC_CONST +AC_HEADER_STDC +AC_CHECK_HEADERS(memory.h unistd.h string.h) +AC_HEADER_DIRENT +AC_FUNC_CLOSEDIR_VOID +AC_FUNC_ALLOCA +AC_FUNC_STRCOLL +AC_OUTPUT(Makefile) diff -r 3a02b029b618 -r f0dcdcc9a780 glob/fnmatch.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glob/fnmatch.c Sun Jun 25 18:42:38 1995 +0000 @@ -0,0 +1,200 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +#ifndef errno +extern int errno; +#endif + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ +int +fnmatch (pattern, string, flags) + const char *pattern; + const char *string; + int flags; +{ + register const char *p = pattern, *n = string; + register char c; + +/* Note that this evalutes C many times. */ +#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c)) + + while ((c = *p++) != '\0') + { + c = FOLD (c); + + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_FILE_NAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + c = FOLD (c); + } + if (FOLD (*n) != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) + if (((flags & FNM_FILE_NAME) && *n == '/') || + (c == '?' && *n == '\0')) + return FNM_NOMATCH; + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + c1 = FOLD (c1); + for (--p; *n != '\0'; ++n) + if ((c == '[' || FOLD (*n) == c1) && + fnmatch (p, n, flags & ~FNM_PERIOD) == 0) + return 0; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + register int not; + + if (*n == '\0') + return FNM_NOMATCH; + + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + not = (*p == '!' || *p == '^'); + if (not) + ++p; + + c = *p++; + for (;;) + { + register char cstart = c, cend = c; + + if (!(flags & FNM_NOESCAPE) && c == '\\') + cstart = cend = *p++; + + cstart = cend = FOLD (cstart); + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + c = FOLD (c); + + if ((flags & FNM_FILE_NAME) && c == '/') + /* [/] can never match. */ + return FNM_NOMATCH; + + if (c == '-' && *p != ']') + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + cend = FOLD (cend); + + c = *p++; + } + + if (FOLD (*n) >= cstart && FOLD (*n) <= cend) + goto matched; + + if (c == ']') + break; + } + if (!not) + return FNM_NOMATCH; + break; + + matched:; + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != FOLD (*n)) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + if ((flags & FNM_LEADING_DIR) && *n == '/') + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff -r 3a02b029b618 -r f0dcdcc9a780 glob/fnmatch.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glob/fnmatch.h Sun Jun 25 18:42:38 1995 +0000 @@ -0,0 +1,67 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FNMATCH_H + +#define _FNMATCH_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(protos) protos +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(protos) () +/* We can get away without defining `const' here only because in this file + it is used only inside the prototype for `fnmatch', which is elided in + non-ANSI C where `const' is problematical. */ +#endif /* C++ or ANSI C. */ + + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch __P ((const char *__pattern, const char *__string, + int __flags)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff -r 3a02b029b618 -r f0dcdcc9a780 glob/glob.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glob/glob.c Sun Jun 25 18:42:38 1995 +0000 @@ -0,0 +1,671 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +#ifdef STDC_HEADERS +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#ifndef POSIX +#ifdef _POSIX_VERSION +#define POSIX +#endif +#endif +#endif + +#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) +extern int errno; +#endif + +#ifndef NULL +#define NULL 0 +#endif + + +#if defined (POSIX) || defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__) +#include +#ifndef __GNU_LIBRARY__ +#define D_NAMLEN(d) strlen((d)->d_name) +#else /* GNU C library. */ +#define D_NAMLEN(d) ((d)->d_namlen) +#endif /* Not GNU C library. */ +#else /* Not POSIX or HAVE_DIRENT_H. */ +#define direct dirent +#define D_NAMLEN(d) ((d)->d_namlen) +#ifdef HAVE_SYS_NDIR_H +#include +#endif /* HAVE_SYS_NDIR_H */ +#ifdef HAVE_SYS_DIR_H +#include +#endif /* HAVE_SYS_DIR_H */ +#ifdef HAVE_NDIR_H +#include +#endif /* HAVE_NDIR_H */ +#endif /* POSIX or HAVE_DIRENT_H or __GNU_LIBRARY__. */ + +#if defined (POSIX) && !defined (__GNU_LIBRARY__) +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +#define REAL_DIR_ENTRY(dp) 1 +#else +#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* POSIX */ + +#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)) +#include +#include +#define ANSI_STRING +#else /* No standard headers. */ + +#ifdef HAVE_STRING_H +#include +#define ANSI_STRING +#else +#include +#endif +#ifdef HAVE_MEMORY_H +#include +#endif + +extern char *malloc (), *realloc (); +extern void free (); + +extern void qsort (); +extern void abort (), exit (); + +#endif /* Standard headers. */ + +#ifndef ANSI_STRING + +#ifndef bzero +extern void bzero (); +#endif +#ifndef bcopy +extern void bcopy (); +#endif + +#define memcpy(d, s, n) bcopy ((s), (d), (n)) +#define strrchr rindex +/* memset is only used for zero here, but let's be paranoid. */ +#define memset(s, better_be_zero, n) \ + ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) +#endif /* Not ANSI_STRING. */ + +#ifndef HAVE_STRCOLL +#define strcoll strcmp +#endif + + +#ifndef __GNU_LIBRARY__ +#ifdef __GNUC__ +__inline +#endif +static char * +my_realloc (p, n) + char *p; + unsigned int n; +{ + /* These casts are the for sake of the broken Ultrix compiler, + which warns of illegal pointer combinations otherwise. */ + if (p == NULL) + return (char *) malloc (n); + return (char *) realloc (p, n); +} +#define realloc my_realloc +#endif + + +#if !defined(__alloca) && !defined(__GNU_LIBRARY__) + +#ifdef __GNUC__ +#undef alloca +#define alloca(n) __builtin_alloca (n) +#else /* Not GCC. */ +#if defined (sparc) || defined (HAVE_ALLOCA_H) +#include +#else /* Not sparc or HAVE_ALLOCA_H. */ +#ifndef _AIX +extern char *alloca (); +#endif /* Not _AIX. */ +#endif /* sparc or HAVE_ALLOCA_H. */ +#endif /* GCC. */ + +#define __alloca alloca + +#endif + +#ifndef STDC_HEADERS +#undef size_t +#define size_t unsigned int +#endif + +/* Some system header files erroneously define these. + We want our own definitions from to take precedence. */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD +#include + +/* Some system header files erroneously define these. + We want our own definitions from to take precedence. */ +#undef GLOB_ERR +#undef GLOB_MARK +#undef GLOB_NOSORT +#undef GLOB_DOOFFS +#undef GLOB_NOCHECK +#undef GLOB_APPEND +#undef GLOB_NOESCAPE +#undef GLOB_PERIOD +#include + +__ptr_t (*__glob_opendir_hook) __P ((const char *directory)); +const char *(*__glob_readdir_hook) __P ((__ptr_t stream)); +void (*__glob_closedir_hook) __P ((__ptr_t stream)); + +static int glob_pattern_p __P ((const char *pattern, int quote)); +static int glob_in_dir __P ((const char *pattern, const char *directory, + int flags, + int (*errfunc) __P ((const char *, int)), + glob_t *pglob)); +static int prefix_array __P ((const char *prefix, char **array, size_t n)); +static int collated_compare __P ((const __ptr_t, const __ptr_t)); + +/* 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, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `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. */ +int +glob (pattern, flags, errfunc, pglob) + const char *pattern; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + const char *filename; + char *dirname; + size_t dirlen; + int status; + int oldcount; + + if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) + { + errno = EINVAL; + return -1; + } + + /* Find the filename. */ + filename = strrchr (pattern, '/'); + if (filename == NULL) + { + filename = pattern; + dirname = (char *) "."; + dirlen = 0; + } + else if (filename == pattern) + { + /* "/pattern". */ + dirname = (char *) "/"; + dirlen = 1; + ++filename; + } + else + { + dirlen = filename - pattern; + dirname = (char *) __alloca (dirlen + 1); + memcpy (dirname, pattern, dirlen); + dirname[dirlen] = '\0'; + ++filename; + } + + if (filename[0] == '\0' && dirlen > 1) + /* "pattern/". Expand "pattern", appending slashes. */ + { + int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + if (val == 0) + pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK); + return val; + } + + if (!(flags & GLOB_APPEND)) + { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + + oldcount = pglob->gl_pathc; + + if (glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE))) + { + /* The directory name contains metacharacters, so we + have to glob for the directory, and then glob for + the pattern in each directory found. */ + glob_t dirs; + register int i; + + status = glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) | + GLOB_NOSORT), + errfunc, &dirs); + if (status != 0) + return status; + + /* We have successfully globbed the preceding directory name. + For each name we found, call glob_in_dir on it and FILENAME, + appending the results to PGLOB. */ + for (i = 0; i < dirs.gl_pathc; ++i) + { + int oldcount; + +#ifdef SHELL + { + /* Make globbing interruptible in the bash shell. */ + extern int interrupt_state; + + if (interrupt_state) + { + globfree (&dirs); + globfree (&files); + return GLOB_ABEND; + } + } +#endif /* SHELL. */ + + oldcount = pglob->gl_pathc; + status = glob_in_dir (filename, dirs.gl_pathv[i], + (flags | GLOB_APPEND) & ~GLOB_NOCHECK, + errfunc, pglob); + if (status == GLOB_NOMATCH) + /* No matches in this directory. Try the next. */ + continue; + + if (status != 0) + { + globfree (&dirs); + globfree (pglob); + return status; + } + + /* Stick the directory on the front of each name. */ + if (prefix_array (dirs.gl_pathv[i], + &pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount)) + { + globfree (&dirs); + globfree (pglob); + return GLOB_NOSPACE; + } + } + + flags |= GLOB_MAGCHAR; + + if (pglob->gl_pathc == oldcount) + /* No matches. */ + if (flags & GLOB_NOCHECK) + { + size_t len = strlen (pattern) + 1; + char *patcopy = (char *) malloc (len); + if (patcopy == NULL) + return GLOB_NOSPACE; + memcpy (patcopy, pattern, len); + + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? + pglob->gl_offs : 0) + + 1 + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + { + free (patcopy); + return GLOB_NOSPACE; + } + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + pglob->gl_pathv[pglob->gl_pathc++] = patcopy; + pglob->gl_pathv[pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; + } + else + return GLOB_NOMATCH; + } + else + { + status = glob_in_dir (filename, dirname, flags, errfunc, pglob); + if (status != 0) + return status; + + if (dirlen > 0) + { + /* Stick the directory on the front of each name. */ + if (prefix_array (dirname, + &pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount)) + { + globfree (pglob); + return GLOB_NOSPACE; + } + } + } + + if (!(flags & GLOB_NOSORT)) + /* Sort the vector. */ + qsort ((__ptr_t) & pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount, + sizeof (char *), collated_compare); + + return 0; +} + + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +void +globfree (pglob) + register glob_t *pglob; +{ + if (pglob->gl_pathv != NULL) + { + register int i; + for (i = 0; i < pglob->gl_pathc; ++i) + if (pglob->gl_pathv[i] != NULL) + free ((__ptr_t) pglob->gl_pathv[i]); + free ((__ptr_t) pglob->gl_pathv); + } +} + + +/* Do a collated comparison of A and B. */ +static int +collated_compare (a, b) + const __ptr_t a; + const __ptr_t b; +{ + const char *const s1 = *(const char *const * const) a; + const char *const s2 = *(const char *const * const) b; + + if (s1 == s2) + return 0; + if (s1 == NULL) + return 1; + if (s2 == NULL) + return -1; + return strcoll (s1, s2); +} + + +/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's + elements in place. Return nonzero if out of memory, zero if successful. + A slash is inserted between DIRNAME and each elt of ARRAY, + unless DIRNAME is just "/". Each old element of ARRAY is freed. */ +static int +prefix_array (dirname, array, n) + const char *dirname; + char **array; + size_t n; +{ + register size_t i; + size_t dirlen = strlen (dirname); + + if (dirlen == 1 && dirname[0] == '/') + /* DIRNAME is just "/", so normal prepending would get us "//foo". + We want "/foo" instead, so don't prepend any chars from DIRNAME. */ + dirlen = 0; + + for (i = 0; i < n; ++i) + { + size_t eltlen = strlen (array[i]) + 1; + char *new = (char *) malloc (dirlen + 1 + eltlen); + if (new == NULL) + { + while (i > 0) + free ((__ptr_t) array[--i]); + return 1; + } + + memcpy (new, dirname, dirlen); + new[dirlen] = '/'; + memcpy (&new[dirlen + 1], array[i], eltlen); + free ((__ptr_t) array[i]); + array[i] = new; + } + + return 0; +} + + +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ +static int +glob_pattern_p (pattern, quote) + const char *pattern; + int quote; +{ + register const char *p; + int open = 0; + + for (p = pattern; *p != '\0'; ++p) + switch (*p) + { + case '?': + case '*': + return 1; + + case '\\': + if (quote) + ++p; + break; + + case '[': + open = 1; + break; + + case ']': + if (open) + return 1; + break; + } + + return 0; +} + + +/* Like `glob', but PATTERN is a final pathname component, + and matches are searched for in DIRECTORY. + The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. + The GLOB_APPEND flag is assumed to be set (always appends). */ +static int +glob_in_dir (pattern, directory, flags, errfunc, pglob) + const char *pattern; + const char *directory; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + __ptr_t stream; + + struct globlink + { + struct globlink *next; + char *name; + }; + struct globlink *names = NULL; + size_t nfound = 0; + + if (!glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE))) + { + stream = NULL; + flags |= GLOB_NOCHECK; + } + else + { + flags |= GLOB_MAGCHAR; + + stream = (__glob_opendir_hook ? (*__glob_opendir_hook) (directory) + : (__ptr_t) opendir (directory)); + if (stream == NULL) + { + if ((errfunc != NULL && (*errfunc) (directory, errno)) || + (flags & GLOB_ERR)) + return GLOB_ABEND; + } + else + while (1) + { + const char *name; + size_t len; + + if (__glob_readdir_hook) + { + name = (*__glob_readdir_hook) (stream); + if (name == NULL) + break; + len = 0; + } + else + { + struct dirent *d = readdir ((DIR *) stream); + if (d == NULL) + break; + if (! REAL_DIR_ENTRY (d)) + continue; + name = d->d_name; +#ifdef HAVE_D_NAMLEN + len = d->d_namlen; +#else + len = 0; +#endif + } + + if (fnmatch (pattern, name, + (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) | + ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)) == 0) + { + struct globlink *new + = (struct globlink *) __alloca (sizeof (struct globlink)); + if (len == 0) + len = strlen (name); + new->name + = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1); + if (new->name == NULL) + goto memory_error; + memcpy ((__ptr_t) new->name, name, len); + if (flags & GLOB_MARK) + new->name[len++] = '/'; + new->name[len] = '\0'; + new->next = names; + names = new; + ++nfound; + } + } + } + + if (nfound == 0 && (flags & GLOB_NOCHECK)) + { + size_t len = strlen (pattern); + nfound = 1; + names = (struct globlink *) __alloca (sizeof (struct globlink)); + names->next = NULL; + names->name = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1); + if (names->name == NULL) + goto memory_error; + memcpy (names->name, pattern, len); + if (flags & GLOB_MARK) + names->name[len++] = '/'; + names->name[len] = '\0'; + } + + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + + nfound + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + goto memory_error; + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + for (; names != NULL; names = names->next) + pglob->gl_pathv[pglob->gl_pathc++] = names->name; + pglob->gl_pathv[pglob->gl_pathc] = NULL; + + pglob->gl_flags = flags; + + if (stream != NULL) + { + int save = errno; + if (__glob_closedir_hook) + (*__glob_closedir_hook) (stream); + else + (void) closedir ((DIR *) stream); + errno = save; + } + return nfound == 0 ? GLOB_NOMATCH : 0; + + memory_error: + { + int save = errno; + if (__glob_closedir_hook) + (*__glob_closedir_hook) (stream); + else + (void) closedir ((DIR *) stream); + errno = save; + } + while (names != NULL) + { + if (names->name != NULL) + free ((__ptr_t) names->name); + names = names->next; + } + return GLOB_NOSPACE; +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff -r 3a02b029b618 -r f0dcdcc9a780 glob/glob.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glob/glob.h Sun Jun 25 18:42:38 1995 +0000 @@ -0,0 +1,97 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GLOB_H + +#define _GLOB_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#undef __ptr_t +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(protos) protos +#define __ptr_t void * +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(protos) () +#undef const +#define const +#define __ptr_t char * +#endif /* C++ or ANSI C. */ + +/* Bits set in the FLAGS argument to `glob'. */ +#define GLOB_ERR (1 << 0)/* Return on read errors. */ +#define GLOB_MARK (1 << 1)/* Append a slash to each name. */ +#define GLOB_NOSORT (1 << 2)/* Don't sort the names. */ +#define GLOB_DOOFFS (1 << 3)/* Insert PGLOB->gl_offs NULLs. */ +#define GLOB_NOCHECK (1 << 4)/* If nothing matches, return the pattern. */ +#define GLOB_APPEND (1 << 5)/* Append to results of a previous call. */ +#define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */ +#define GLOB_PERIOD (1 << 7)/* Leading `.' can be matched by metachars. */ +#define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ + GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|GLOB_PERIOD) + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_BSD_SOURCE) +#define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */ +#endif + +/* Error returns from `glob'. */ +#define GLOB_NOSPACE 1 /* Ran out of memory. */ +#define GLOB_ABEND 2 /* Read error. */ +#define GLOB_NOMATCH 3 /* No matches found. */ + +/* Structure describing a globbing run. */ +typedef struct + { + int gl_pathc; /* Count of paths matched by the pattern. */ + char **gl_pathv; /* List of matched pathnames. */ + int gl_offs; /* Slots to reserve in `gl_pathv'. */ + int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */ + } glob_t; + +/* 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, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `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. */ +extern int glob __P ((const char *__pattern, int __flags, + int (*__errfunc) __P ((const char *, int)), + glob_t *__pglob)); + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +extern void globfree __P ((glob_t *__pglob)); + + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +/* If they are not NULL, `glob' uses these functions to read directories. */ +extern __ptr_t (*__glob_opendir_hook) __P ((const char *__directory)); +extern const char *(*__glob_readdir_hook) __P ((__ptr_t __stream)); +extern void (*__glob_closedir_hook) __P ((__ptr_t __stream)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* glob.h */