⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glob.c

📁 压缩包中包含LINUX下多个命令的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 1991, 92, 93, 94, 95, 96 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/* Enable GNU extensions in glob.h.  */#ifndef _GNU_SOURCE#define	_GNU_SOURCE	1#endif#include <errno.h>#include <sys/types.h>#include <sys/stat.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.  */#define GLOB_INTERFACE_VERSION 1#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1#include <gnu-versions.h>#if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION#define ELIDE_CODE#endif#endif#ifndef ELIDE_CODE#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 (_AMIGA) && !defined (VMS) && !defined(WIN32)#include <pwd.h>#endif#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)extern int errno;#endif#ifndef	NULL#define	NULL	0#endif#if defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__)# include <dirent.h># define NAMLEN(dirent) strlen((dirent)->d_name)#else# define dirent direct# define NAMLEN(dirent) (dirent)->d_namlen# ifdef HAVE_SYS_NDIR_H#  include <sys/ndir.h># endif# ifdef HAVE_SYS_DIR_H#  include <sys/dir.h># endif# ifdef HAVE_NDIR_H#  include <ndir.h># endif# ifdef HAVE_VMSDIR_H#  include "vmsdir.h"# endif /* HAVE_VMSDIR_H */#endif/* In GNU systems, <dirent.h> defines this macro for us.  */#ifdef _D_NAMLEN#undef NAMLEN#define NAMLEN(d) _D_NAMLEN(d)#endif#if (defined (POSIX) || defined (WIN32)) && !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.  */extern char *getenv ();#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#endif#ifndef __SASC#ifdef WIN32static void *#elsestatic char *#endifmy_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 /* __SASC */#endif /* __GNU_LIBRARY__ */#if	!defined(__alloca) && !defined(__GNU_LIBRARY__)#ifdef	__GNUC__#undef	alloca#define	alloca(n)	__builtin_alloca (n)#else	/* Not GCC.  */#ifdef HAVE_ALLOCA_H#include <alloca.h>#else	/* Not HAVE_ALLOCA_H.  */#ifndef	_AIX#ifdef WIN32#include <malloc.h>#elseextern char *alloca ();#endif /* WIN32 */#endif	/* Not _AIX.  */#endif	/* sparc or HAVE_ALLOCA_H.  */#endif	/* GCC.  */#define	__alloca	alloca#endif#ifndef __GNU_LIBRARY__#define __stat stat#ifdef STAT_MACROS_BROKEN#undef S_ISDIR#endif#ifndef S_ISDIR#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)#endif#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>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;    }  if (flags & GLOB_BRACE)    {      const char *begin = strchr (pattern, '{');      if (begin != NULL)	{	  int firstc;	  size_t restlen;	  const char *p, *end, *next;	  unsigned int depth = 0;	  /* Find the end of the brace expression, by counting braces.	     While we're at it, notice the first comma at top brace level.  */	  end = begin + 1;	  next = NULL;	  while (1)	    {	      switch (*end++)		{		case ',':		  if (depth == 0 && next == NULL)		    next = end;		  continue;		case '{':		  ++depth;		  continue;		case '}':		  if (depth-- == 0)		    break;		  continue;		case '\0':		  return glob (pattern, flags &~ GLOB_BRACE, errfunc, pglob);		}	      break;	    }	  restlen = strlen (end) + 1;	  if (next == NULL)	    next = end;	  /* We have a brace expression.  BEGIN points to the opening {,	     NEXT points past the terminator of the first element, and END	     points past the final }.  We will accumulate result names from	     recursive runs for each brace alternative in the buffer using	     GLOB_APPEND.  */	  if (!(flags & GLOB_APPEND))	    {	      /* This call is to set a new vector, so clear out the		 vector so we can append to it.  */	      pglob->gl_pathc = 0;	      pglob->gl_pathv = NULL;	    }	  firstc = pglob->gl_pathc;	  /* In this loop P points to the beginning of the current element	     and NEXT points past its terminator.  */	  p = begin + 1;	  while (1)	    {	      /* Construct a whole name that is one of the brace		 alternatives in a temporary buffer.  */	      int result;	      size_t bufsz = (begin - pattern) + (next - 1 - p) + restlen;#ifdef __GNUC__	      char onealt[bufsz];#else	      char *onealt = malloc (bufsz);	      if (onealt == NULL)		{		  if (!(flags & GLOB_APPEND))		    globfree (pglob);		  return GLOB_NOSPACE;		}#endif	      memcpy (onealt, pattern, begin - pattern);	      memcpy (&onealt[begin - pattern], p, next - 1 - p);	      memcpy (&onealt[(begin - pattern) + (next - 1 - p)],		      end, restlen);	      result = glob (onealt,			     ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) |			      GLOB_APPEND), errfunc, pglob);#ifndef __GNUC__	      free (onealt);#endif	      /* If we got an error, return it.  */	      if (result && result != GLOB_NOMATCH)		{		  if (!(flags & GLOB_APPEND))		    globfree (pglob);		  return result;		}	      /* Advance past this alternative and process the next.  */	      p = next;	      depth = 0;	    scan:	      switch (*p++)		{		case ',':		  if (depth == 0)		    {		      /* Found the next alternative.  Loop to glob it.  */		      next = p;		      continue;		    }		  goto scan;		case '{':		  ++depth;		  goto scan;		case '}':		  if (depth-- == 0)		    /* End of the brace expression.  Break out of the loop.  */		    break;		  goto scan;		}	    }	  if (pglob->gl_pathc == firstc &&	      !(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))	    return GLOB_NOMATCH;	}    }  /* Find the filename.  */  filename = strrchr (pattern, '/');  if (filename == NULL)    {      filename = pattern;#ifdef _AMIGA      dirname = (char *) "";#else      dirname = (char *) ".";#endif      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;#ifndef VMS  if ((flags & GLOB_TILDE) && dirname[0] == '~')    {      if (dirname[1] == '\0')	{	  /* Look up home directory.  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -