📄 glob.c
字号:
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.This library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB. Ifnot, 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 <config.h>#endif#include <errno.h>#include <sys/types.h>/* 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 <stddef.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#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 (DIRENT) || defined (__GNU_LIBRARY__)#include <dirent.h>#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 DIRENT. */#define direct dirent#define D_NAMLEN(d) ((d)->d_namlen)#ifdef SYSNDIR#include <sys/ndir.h>#endif /* SYSNDIR */#ifdef SYSDIR#include <sys/dir.h>#endif /* SYSDIR */#ifdef NDIR#include <ndir.h>#endif /* NDIR */#endif /* POSIX or DIRENT 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 <stdlib.h>#include <string.h>#define ANSI_STRING#else /* No standard headers. */#ifdef HAVE_STRING_H#include <string.h>#define ANSI_STRING#else#include <strings.h>#endif#ifdef HAVE_MEMORY_H#include <memory.h>#endifextern char *malloc (), *realloc ();extern void free ();extern void qsort ();extern void abort (), exit ();#endif /* Standard headers. */#ifndef ANSI_STRING#ifndef bzeroextern void bzero ();#endif#ifndef bcopyextern 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#endifstatic 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 <alloca.h>#else /* Not sparc or HAVE_ALLOCA_H. */#ifndef _AIXextern 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 <fnmatch.h> to take precedence. */#undef FNM_PATHNAME#undef FNM_NOESCAPE#undef FNM_PERIOD#include <fnmatch.h>/* Some system header files erroneously define these. We want our own definitions from <glob.h> 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 <glob.h>__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. */intglob (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 ret = glob (dirname, flags | GLOB_MARK, errfunc, pglob); if (ret == 0) pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK); return ret; } 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -