[BACK]Return to glob.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gen

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/gen/glob.c between version 1.23.4.2 and 1.31.8.2

version 1.23.4.2, 2011/04/24 15:41:10 version 1.31.8.2, 2013/06/23 06:21:05
Line 132  struct glob_limit {
Line 132  struct glob_limit {
 #define M_MASK          0xffff  #define M_MASK          0xffff
 #define M_ASCII         0x00ff  #define M_ASCII         0x00ff
   
 typedef u_short Char;  typedef unsigned short Char;
   
 #else  #else
   
Line 167  static int  glob0(const Char *, glob_t *
Line 167  static int  glob0(const Char *, glob_t *
 static int       glob1(Char *, glob_t *, struct glob_limit *);  static int       glob1(Char *, glob_t *, struct glob_limit *);
 static int       glob2(Char *, Char *, Char *, const Char *, glob_t *,  static int       glob2(Char *, Char *, Char *, const Char *, glob_t *,
     struct glob_limit *);      struct glob_limit *);
 static int       glob3(Char *, Char *, Char *, const Char *, const Char *,  static int       glob3(Char *, Char *, Char *, const Char *, const Char *,
     glob_t *, struct glob_limit *);      const Char *, glob_t *, struct glob_limit *);
 static int       globextend(const Char *, glob_t *, struct glob_limit *);  static int       globextend(const Char *, glob_t *, struct glob_limit *);
 static const Char *globtilde(const Char *, Char *, size_t, glob_t *);  static const Char *globtilde(const Char *, Char *, size_t, glob_t *);
 static int       globexp1(const Char *, glob_t *, struct glob_limit *);  static int       globexp1(const Char *, glob_t *, struct glob_limit *);
Line 180  static void  qprintf(const char *, Char 
Line 180  static void  qprintf(const char *, Char 
 #endif  #endif
   
 int  int
 glob(const char *pattern, int flags, int (*errfunc)(const char *, int),  glob(const char * __restrict pattern, int flags, int (*errfunc)(const char *,
     glob_t *pglob)      int), glob_t * __restrict pglob)
 {  {
         const u_char *patnext;          const unsigned char *patnext;
         int c;          int c;
         Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];          Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
         struct glob_limit limit = { 0, 0, 0, 0 };          struct glob_limit limit = { 0, 0, 0, 0 };
   
         _DIAGASSERT(pattern != NULL);          _DIAGASSERT(pattern != NULL);
   
         patnext = (const u_char *) pattern;          patnext = (const unsigned char *) pattern;
         if (!(flags & GLOB_APPEND)) {          if (!(flags & GLOB_APPEND)) {
                 pglob->gl_pathc = 0;                  pglob->gl_pathc = 0;
                 pglob->gl_pathv = NULL;                  pglob->gl_pathv = NULL;
Line 356  globexp2(const Char *ptr, const Char *pa
Line 356  globexp2(const Char *ptr, const Char *pa
   
                                 /* Expand the current pattern */                                  /* Expand the current pattern */
 #ifdef DEBUG  #ifdef DEBUG
                                 qprintf("globexp2:", patbuf);                                  qprintf("globexp2", patbuf);
 #endif  #endif
                                 *rv = globexp1(patbuf, pglob, limit);                                  *rv = globexp1(patbuf, pglob, limit);
   
Line 523  glob0(const Char *pattern, glob_t *pglob
Line 523  glob0(const Char *pattern, glob_t *pglob
                         break;                          break;
                 case STAR:                  case STAR:
                         pglob->gl_flags |= GLOB_MAGCHAR;                          pglob->gl_flags |= GLOB_MAGCHAR;
                         /* collapse adjacent stars to one,                          /* collapse adjacent stars to one [or three if globstar]
                          * to avoid exponential behavior                           * to avoid exponential behavior
                          */                           */
                         if (bufnext == patbuf || bufnext[-1] != M_ALL)                          if (bufnext == patbuf || bufnext[-1] != M_ALL ||
                               ((pglob->gl_flags & GLOB_STAR) != 0 &&
                               (bufnext - 1 == patbuf || bufnext[-2] != M_ALL ||
                               bufnext - 2 == patbuf || bufnext[-3] != M_ALL)))
                                 *bufnext++ = M_ALL;                                  *bufnext++ = M_ALL;
                         break;                          break;
                 default:                  default:
Line 536  glob0(const Char *pattern, glob_t *pglob
Line 539  glob0(const Char *pattern, glob_t *pglob
         }          }
         *bufnext = EOS;          *bufnext = EOS;
 #ifdef DEBUG  #ifdef DEBUG
         qprintf("glob0:", patbuf);          qprintf("glob0", patbuf);
 #endif  #endif
   
         if ((error = glob1(patbuf, pglob, limit)) != 0)          if ((error = glob1(patbuf, pglob, limit)) != 0)
Line 609  glob2(Char *pathbuf, Char *pathend, Char
Line 612  glob2(Char *pathbuf, Char *pathend, Char
         const Char *p;          const Char *p;
         Char *q;          Char *q;
         int anymeta;          int anymeta;
         Char *pend;  
         ptrdiff_t diff;  
   
         _DIAGASSERT(pathbuf != NULL);          _DIAGASSERT(pathbuf != NULL);
         _DIAGASSERT(pathend != NULL);          _DIAGASSERT(pathend != NULL);
         _DIAGASSERT(pattern != NULL);          _DIAGASSERT(pattern != NULL);
         _DIAGASSERT(pglob != NULL);          _DIAGASSERT(pglob != NULL);
   
   #ifdef DEBUG
           qprintf("glob2", pathbuf);
   #endif
         /*          /*
          * Loop over pattern segments until end of pattern or until           * Loop over pattern segments until end of pattern or until
          * segment with meta character found.           * segment with meta character found.
Line 659  glob2(Char *pathbuf, Char *pathend, Char
Line 663  glob2(Char *pathbuf, Char *pathend, Char
                         *q++ = *p++;                          *q++ = *p++;
                 }                  }
   
                 /*                  if (!anymeta) {
                  * No expansion, or path ends in slash-dot shash-dot-dot,  
                  * do next segment.  
                  */  
                 if (pglob->gl_flags & GLOB_PERIOD) {  
                         for (pend = pathend; pend > pathbuf && pend[-1] == '/';  
                             pend--)  
                                 continue;  
                         diff = pend - pathbuf;  
                 } else {  
                         /* XXX: GCC */  
                         diff = 0;  
                         pend = pathend;  
                 }  
   
                 if ((!anymeta) ||  
                     ((pglob->gl_flags & GLOB_PERIOD) &&  
                      (diff >= 1 && pend[-1] == DOT) &&  
                      (diff >= 2 && (pend[-2] == SLASH || pend[-2] == DOT)) &&  
                      (diff < 3 || pend[-3] == SLASH))) {  
                         pathend = q;                          pathend = q;
                         pattern = p;                          pattern = p;
                         while (*pattern == SEP) {                          while (*pattern == SEP) {
Line 688  glob2(Char *pathbuf, Char *pathend, Char
Line 673  glob2(Char *pathbuf, Char *pathend, Char
                         }                          }
                 } else                  /* Need expansion, recurse. */                  } else                  /* Need expansion, recurse. */
                         return glob3(pathbuf, pathend, pathlim, pattern, p,                          return glob3(pathbuf, pathend, pathlim, pattern, p,
                             pglob, limit);                              pattern, pglob, limit);
         }          }
         /* NOTREACHED */          /* NOTREACHED */
 }  }
   
 static int  static int
 glob3(Char *pathbuf, Char *pathend, Char *pathlim, const Char *pattern,  glob3(Char *pathbuf, Char *pathend, Char *pathlim, const Char *pattern,
     const Char *restpattern, glob_t *pglob, struct glob_limit *limit)      const Char *restpattern, const Char *pglobstar, glob_t *pglob,
       struct glob_limit *limit)
 {  {
         struct dirent *dp;          struct dirent *dp;
         DIR *dirp;          DIR *dirp;
           __gl_stat_t sbuf;
         int error;          int error;
         char buf[MAXPATHLEN];          char buf[MAXPATHLEN];
           int globstar = 0;
           int chase_symlinks = 0;
           const Char *termstar = NULL;
   
         /*          /*
          * The readdirfunc declaration can't be prototyped, because it is           * The readdirfunc declaration can't be prototyped, because it is
Line 719  glob3(Char *pathbuf, Char *pathend, Char
Line 709  glob3(Char *pathbuf, Char *pathend, Char
         *pathend = EOS;          *pathend = EOS;
         errno = 0;          errno = 0;
   
           while (pglobstar < restpattern) {
                   if ((pglobstar[0] & M_MASK) == M_ALL &&
                       (pglobstar[1] & M_MASK) == M_ALL) {
                           globstar = 1;
                           chase_symlinks = (pglobstar[2] & M_MASK) == M_ALL;
                           termstar = pglobstar + (2 + chase_symlinks);
                           break;
                   }
                   pglobstar++;
           }
   
           if (globstar) {
                   error = pglobstar == pattern && termstar == restpattern ?
                       *restpattern == EOS ?
                       glob2(pathbuf, pathend, pathlim, restpattern - 1, pglob,
                       limit) :
                       glob2(pathbuf, pathend, pathlim, restpattern + 1, pglob,
                       limit) :
                       glob3(pathbuf, pathend, pathlim, pattern, restpattern,
                       termstar, pglob, limit);
                   if (error)
                           return error;
                   *pathend = EOS;
           }
   
           if (*pathbuf && (g_lstat(pathbuf, &sbuf, pglob) ||
               !S_ISDIR(sbuf.st_mode)
   #ifdef S_IFLINK
                && ((globstar && !chase_symlinks) || !S_ISLNK(sbuf.st_mode))
   #endif
               ))
                   return 0;
   
         if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {          if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
                 if (pglob->gl_errfunc) {                  if (pglob->gl_errfunc) {
                         if (g_Ctoc(pathbuf, buf, sizeof(buf)))                          if (g_Ctoc(pathbuf, buf, sizeof(buf)))
Line 745  glob3(Char *pathbuf, Char *pathend, Char
Line 768  glob3(Char *pathbuf, Char *pathend, Char
         if (pglob->gl_flags & GLOB_ALTDIRFUNC)          if (pglob->gl_flags & GLOB_ALTDIRFUNC)
                 readdirfunc = pglob->gl_readdir;                  readdirfunc = pglob->gl_readdir;
         else          else
                 readdirfunc = (struct dirent *(*)__P((void *))) readdir;                  readdirfunc = (struct dirent *(*)(void *)) readdir;
         while ((dp = (*readdirfunc)(dirp)) != NULL) {          while ((dp = (*readdirfunc)(dirp)) != NULL) {
                 u_char *sc;                  unsigned char *sc;
                 Char *dc;                  Char *dc;
   
                 if ((pglob->gl_flags & GLOB_LIMIT) &&                  if ((pglob->gl_flags & GLOB_LIMIT) &&
Line 755  glob3(Char *pathbuf, Char *pathend, Char
Line 778  glob3(Char *pathbuf, Char *pathend, Char
                         errno = 0;                          errno = 0;
                         *pathend++ = SEP;                          *pathend++ = SEP;
                         *pathend = EOS;                          *pathend = EOS;
                         return GLOB_NOSPACE;                          error = GLOB_NOSPACE;
                           break;
                 }                  }
   
                 /*                  /*
Line 777  glob3(Char *pathbuf, Char *pathend, Char
Line 801  glob3(Char *pathbuf, Char *pathend, Char
                  * The resulting string contains EOS, so we can                   * The resulting string contains EOS, so we can
                  * use the pathlim character, if it is the nul                   * use the pathlim character, if it is the nul
                  */                   */
                 for (sc = (u_char *) dp->d_name, dc = pathend;                  for (sc = (unsigned char *) dp->d_name, dc = pathend;
                      dc <= pathlim && (*dc++ = *sc++) != EOS;)                       dc <= pathlim && (*dc++ = *sc++) != EOS;)
                         continue;                          continue;
   
Line 800  glob3(Char *pathbuf, Char *pathend, Char
Line 824  glob3(Char *pathbuf, Char *pathend, Char
                         }                          }
                 }                  }
   
                 if (!match(pathend, pattern, restpattern)) {                  if (globstar) {
   #ifdef S_IFLNK
                           if (!chase_symlinks &&
                               (g_lstat(pathbuf, &sbuf, pglob) ||
                               S_ISLNK(sbuf.st_mode)))
                                   continue;
   #endif
   
                           if (!match(pathend, pattern, termstar))
                                   continue;
   
                           if (--dc < pathlim - 2)
                                   *dc++ = SEP;
                           *dc = EOS;
                           error = glob2(pathbuf, dc, pathlim, pglobstar,
                               pglob, limit);
                           if (error)
                                   break;
                         *pathend = EOS;                          *pathend = EOS;
                         continue;                  } else {
                           if (!match(pathend, pattern, restpattern)) {
                                   *pathend = EOS;
                                   continue;
                           }
                           error = glob2(pathbuf, --dc, pathlim, restpattern,
                               pglob, limit);
                           if (error)
                                   break;
                 }                  }
                 error = glob2(pathbuf, --dc, pathlim, restpattern, pglob,  
                     limit);  
                 if (error)  
                         break;  
         }          }
   
         if (pglob->gl_flags & GLOB_ALTDIRFUNC)          if (pglob->gl_flags & GLOB_ALTDIRFUNC)
                 (*pglob->gl_closedir)(dirp);                  (*pglob->gl_closedir)(dirp);
         else          else
Line 909  match(const Char *name, const Char *pat,
Line 953  match(const Char *name, const Char *pat,
                 c = *pat++;                  c = *pat++;
                 switch (c & M_MASK) {                  switch (c & M_MASK) {
                 case M_ALL:                  case M_ALL:
                           while (pat < patend && (*pat & M_MASK) == M_ALL)
                                   pat++;  /* eat consecutive '*' */
                         if (pat == patend)                          if (pat == patend)
                                 return 1;                                  return 1;
                         do                          for (; !match(name, pat, patend); name++)
                             if (match(name, pat, patend))                                  if (*name == EOS)
                                     return 1;                                          return 0;
                         while (*name++ != EOS);                          return 1;
                         return 0;  
                 case M_ONE:                  case M_ONE:
                         if (*name++ == EOS)                          if (*name++ == EOS)
                                 return 0;                                  return 0;
Line 965  globfree(glob_t *pglob)
Line 1010  globfree(glob_t *pglob)
         }          }
 }  }
   
   #ifndef __LIBC12_SOURCE__
   int
   glob_pattern_p(const char *pattern, int quote)
   {
           int range = 0;
   
           for (; *pattern; pattern++)
                   switch (*pattern) {
                   case QUESTION:
                   case STAR:
                           return 1;
   
                   case QUOTE:
                           if (quote && pattern[1] != EOS)
                                 ++pattern;
                           break;
   
                   case LBRACKET:
                           range = 1;
                           break;
   
                   case RBRACKET:
                           if (range)
                                 return 1;
                           break;
                   default:
                           break;
                   }
   
             return 0;
   }
   #endif
   
 static DIR *  static DIR *
 g_opendir(Char *str, glob_t *pglob)  g_opendir(Char *str, glob_t *pglob)
 {  {

Legend:
Removed from v.1.23.4.2  
changed lines
  Added in v.1.31.8.2

CVSweb <webmaster@jp.NetBSD.org>