Back to index

php5  5.3.10
Defines | Typedefs | Functions
glob.c File Reference
#include "php.h"
#include <sys/stat.h>
#include <ctype.h>
#include <sys/param.h>
#include <dirent.h>
#include <pwd.h>
#include <unistd.h>
#include <errno.h>
#include "glob.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Go to the source code of this file.

Defines

#define DOLLAR   '$'
#define DOT   '.'
#define EOS   '\0'
#define LBRACKET   '['
#define NOT   '!'
#define QUESTION   '?'
#define QUOTE   '\\'
#define RANGE   '-'
#define RBRACKET   ']'
#define SEP   DEFAULT_SLASH
#define STAR   '*'
#define TILDE   '~'
#define UNDERSCORE   '_'
#define LBRACE   '{'
#define RBRACE   '}'
#define SLASH   '/'
#define COMMA   ','
#define M_QUOTE   0x8000
#define M_PROTECT   0x4000
#define M_MASK   0xffff
#define M_ASCII   0x00ff
#define CHAR(c)   ((Char)((c)&M_ASCII))
#define META(c)   ((Char)((c)|M_QUOTE))
#define M_ALL   META('*')
#define M_END   META(']')
#define M_NOT   META('!')
#define M_ONE   META('?')
#define M_RNG   META('-')
#define M_SET   META('[')
#define ismeta(c)   (((c)&M_QUOTE) != 0)

Typedefs

typedef u_short Char

Functions

static int compare (const void *, const void *)
static int g_Ctoc (const Char *, char *, u_int)
static int g_lstat (Char *, struct stat *, glob_t *)
static DIRg_opendir (Char *, glob_t *)
static Charg_strchr (Char *, int)
static int g_stat (Char *, struct stat *, glob_t *)
static int glob0 (const Char *, glob_t *)
static int glob1 (Char *, Char *, glob_t *, size_t *)
static int glob2 (Char *, Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *)
static int glob3 (Char *, Char *, Char *, Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *)
static int globextend (const Char *, glob_t *, size_t *)
static const Charglobtilde (const Char *, Char *, size_t, glob_t *)
static int globexp1 (const Char *, glob_t *)
static int globexp2 (const Char *, const Char *, glob_t *, int *)
static int match (Char *, Char *, Char *)
PHPAPI int glob (char *pattern, int flags, errfunc, glob_t *pglob) const
static int globexp1 (Char *pattern, glob_t *pglob) const
static int globexp2 (Char *ptr, Char *pattern, glob_t *pglob, int *rv) const
static const Charglobtilde (Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) const
static int glob0 (Char *pattern, glob_t *pglob) const
static int globextend (Char *path, glob_t *pglob, size_t *limitp) const
PHPAPI void globfree (glob_t *pglob)

Define Documentation

#define CHAR (   c)    ((Char)((c)&M_ASCII))

Definition at line 130 of file glob.c.

#define COMMA   ','

Definition at line 107 of file glob.c.

#define DOLLAR   '$'

Definition at line 91 of file glob.c.

#define DOT   '.'

Definition at line 92 of file glob.c.

#define EOS   '\0'

Definition at line 93 of file glob.c.

#define ismeta (   c)    (((c)&M_QUOTE) != 0)

Definition at line 138 of file glob.c.

#define LBRACE   '{'

Definition at line 104 of file glob.c.

#define LBRACKET   '['

Definition at line 94 of file glob.c.

#define M_ALL   META('*')

Definition at line 132 of file glob.c.

#define M_ASCII   0x00ff

Definition at line 114 of file glob.c.

#define M_END   META(']')

Definition at line 133 of file glob.c.

#define M_MASK   0xffff

Definition at line 113 of file glob.c.

#define M_NOT   META('!')

Definition at line 134 of file glob.c.

#define M_ONE   META('?')

Definition at line 135 of file glob.c.

#define M_PROTECT   0x4000

Definition at line 112 of file glob.c.

#define M_QUOTE   0x8000

Definition at line 111 of file glob.c.

#define M_RNG   META('-')

Definition at line 136 of file glob.c.

#define M_SET   META('[')

Definition at line 137 of file glob.c.

#define META (   c)    ((Char)((c)|M_QUOTE))

Definition at line 131 of file glob.c.

#define NOT   '!'

Definition at line 95 of file glob.c.

#define QUESTION   '?'

Definition at line 96 of file glob.c.

#define QUOTE   '\\'

Definition at line 97 of file glob.c.

#define RANGE   '-'

Definition at line 98 of file glob.c.

#define RBRACE   '}'

Definition at line 105 of file glob.c.

#define RBRACKET   ']'

Definition at line 99 of file glob.c.

#define SEP   DEFAULT_SLASH

Definition at line 100 of file glob.c.

#define SLASH   '/'

Definition at line 106 of file glob.c.

#define STAR   '*'

Definition at line 101 of file glob.c.

#define TILDE   '~'

Definition at line 102 of file glob.c.

#define UNDERSCORE   '_'

Definition at line 103 of file glob.c.


Typedef Documentation

typedef u_short Char

Definition at line 116 of file glob.c.


Function Documentation

static int compare ( const void *  p,
const void *  q 
) [static]

Definition at line 521 of file glob.c.

{
       return(strcmp(*(char **)p, *(char **)q));
}
static int g_Ctoc ( const Char str,
char *  buf,
u_int  len 
) [static]

Definition at line 892 of file glob.c.

{

       while (len--) {
              if ((*buf++ = (char) *str++) == EOS)
                     return (0);
       }
       return (1);
}

Here is the caller graph for this function:

static int g_lstat ( Char fn,
struct stat *  sb,
glob_t pglob 
) [static]

Definition at line 850 of file glob.c.

{
       char buf[MAXPATHLEN];

       if (g_Ctoc(fn, buf, sizeof(buf)))
              return(-1);
       if (pglob->gl_flags & GLOB_ALTDIRFUNC)
              return((*pglob->gl_lstat)(buf, sb));
       return(php_sys_lstat(buf, sb));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static DIR * g_opendir ( Char str,
glob_t pglob 
) [static]

Definition at line 830 of file glob.c.

{
       char buf[MAXPATHLEN];

       if (!*str)
              strlcpy(buf, ".", sizeof buf);
       else {
              if (g_Ctoc(str, buf, sizeof(buf)))
                     return(NULL);
       }

       if (pglob->gl_flags & GLOB_ALTDIRFUNC)
              return((*pglob->gl_opendir)(buf));

       return(opendir(buf));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int g_stat ( Char fn,
struct stat *  sb,
glob_t pglob 
) [static]

Definition at line 865 of file glob.c.

{
       char buf[MAXPATHLEN];

       if (g_Ctoc(fn, buf, sizeof(buf)))
              return(-1);
       if (pglob->gl_flags & GLOB_ALTDIRFUNC)
              return((*pglob->gl_stat)(buf, sb));
       return(php_sys_stat(buf, sb));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Char * g_strchr ( Char str,
int  ch 
) [static]

Definition at line 880 of file glob.c.

{
       do {
              if (*str == ch)
                     return (str);
       } while (*str++);
       return (NULL);
}

Here is the caller graph for this function:

PHPAPI int glob ( char *  pattern,
int  flags,
errfunc  ,
glob_t pglob 
) const

Definition at line 162 of file glob.c.

{
       const u_char *patnext;
       int c;
       Char *bufnext, *bufend, patbuf[MAXPATHLEN];

#ifdef PHP_WIN32
       /* Force skipping escape sequences on windows
        * due to the ambiguity with path backslashes
        */
       flags |= GLOB_NOESCAPE;
#endif

       patnext = (u_char *) pattern;
       if (!(flags & GLOB_APPEND)) {
              pglob->gl_pathc = 0;
              pglob->gl_pathv = NULL;
              if (!(flags & GLOB_DOOFFS))
                     pglob->gl_offs = 0;
       }
       pglob->gl_flags = flags & ~GLOB_MAGCHAR;
       pglob->gl_errfunc = errfunc;
       pglob->gl_matchc = 0;

       bufnext = patbuf;
       bufend = bufnext + MAXPATHLEN - 1;
       if (flags & GLOB_NOESCAPE)
              while (bufnext < bufend && (c = *patnext++) != EOS)
                     *bufnext++ = c;
       else {
              /* Protect the quoted characters. */
              while (bufnext < bufend && (c = *patnext++) != EOS)
                     if (c == QUOTE) {
                            if ((c = *patnext++) == EOS) {
                                   c = QUOTE;
                                   --patnext;
                            }
                            *bufnext++ = c | M_PROTECT;
                     } else
                            *bufnext++ = c;
       }
       *bufnext = EOS;

       if (flags & GLOB_BRACE)
              return globexp1(patbuf, pglob);
       else
              return glob0(patbuf, pglob);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int glob0 ( const Char ,
glob_t  
) [static]

Here is the caller graph for this function:

static int glob0 ( Char pattern,
glob_t pglob 
) const [static]

Definition at line 432 of file glob.c.

{
       const Char *qpatnext;
       int c, err, oldpathc;
       Char *bufnext, patbuf[MAXPATHLEN];
       size_t limit = 0;

       qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
       oldpathc = pglob->gl_pathc;
       bufnext = patbuf;

       /* We don't need to check for buffer overflow any more. */
       while ((c = *qpatnext++) != EOS) {
              switch (c) {
              case LBRACKET:
                     c = *qpatnext;
                     if (c == NOT)
                            ++qpatnext;
                     if (*qpatnext == EOS ||
                            g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
                            *bufnext++ = LBRACKET;
                            if (c == NOT)
                                   --qpatnext;
                            break;
                     }
                     *bufnext++ = M_SET;
                     if (c == NOT)
                            *bufnext++ = M_NOT;
                     c = *qpatnext++;
                     do {
                            *bufnext++ = CHAR(c);
                            if (*qpatnext == RANGE &&
                                   (c = qpatnext[1]) != RBRACKET) {
                                   *bufnext++ = M_RNG;
                                   *bufnext++ = CHAR(c);
                                   qpatnext += 2;
                            }
                     } while ((c = *qpatnext++) != RBRACKET);
                     pglob->gl_flags |= GLOB_MAGCHAR;
                     *bufnext++ = M_END;
                     break;
              case QUESTION:
                     pglob->gl_flags |= GLOB_MAGCHAR;
                     *bufnext++ = M_ONE;
                     break;
              case STAR:
                     pglob->gl_flags |= GLOB_MAGCHAR;
                     /* collapse adjacent stars to one,
                      * to avoid exponential behavior
                      */
                     if (bufnext == patbuf || bufnext[-1] != M_ALL)
                            *bufnext++ = M_ALL;
                     break;
              default:
                     *bufnext++ = CHAR(c);
                     break;
              }
       }
       *bufnext = EOS;
#ifdef DEBUG
       qprintf("glob0:", patbuf);
#endif

       if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0)
              return(err);

       /*
        * If there was no match we are going to append the pattern
        * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
        * and the pattern did not contain any magic characters
        * GLOB_NOMAGIC is there just for compatibility with csh.
        */
       if (pglob->gl_pathc == oldpathc) {
              if ((pglob->gl_flags & GLOB_NOCHECK) ||
                     ((pglob->gl_flags & GLOB_NOMAGIC) &&
                     !(pglob->gl_flags & GLOB_MAGCHAR)))
                     return(globextend(pattern, pglob, &limit));
              else
                     return(GLOB_NOMATCH);
       }
       if (!(pglob->gl_flags & GLOB_NOSORT))
              qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
                     pglob->gl_pathc - oldpathc, sizeof(char *), compare);
       return(0);
}

Here is the call graph for this function:

static int glob1 ( Char pattern,
Char pattern_last,
glob_t pglob,
size_t limitp 
) [static]

Definition at line 527 of file glob.c.

{
       Char pathbuf[MAXPATHLEN];

       /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
       if (*pattern == EOS)
              return(0);
       return(glob2(pathbuf, pathbuf+MAXPATHLEN-1,
              pathbuf, pathbuf+MAXPATHLEN-1,
              pattern, pattern_last, pglob, limitp));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int glob2 ( Char pathbuf,
Char pathbuf_last,
Char pathend,
Char pathend_last,
Char pattern,
Char pattern_last,
glob_t pglob,
size_t limitp 
) [static]

Definition at line 548 of file glob.c.

{
       struct stat sb;
       Char *p, *q;
       int anymeta;

       /*
        * Loop over pattern segments until end of pattern or until
        * segment with meta character found.
        */
       for (anymeta = 0;;) {
              if (*pattern == EOS) {             /* End of pattern? */
                     *pathend = EOS;
                     if (g_lstat(pathbuf, &sb, pglob))
                            return(0);

                     if (((pglob->gl_flags & GLOB_MARK) &&
                            !IS_SLASH(pathend[-1])) && (S_ISDIR(sb.st_mode) ||
                            (S_ISLNK(sb.st_mode) &&
                            (g_stat(pathbuf, &sb, pglob) == 0) &&
                            S_ISDIR(sb.st_mode)))) {
                            if (pathend+1 > pathend_last)
                                   return (1);
                            *pathend++ = SEP;
                            *pathend = EOS;
                     }
                     ++pglob->gl_matchc;
                     return(globextend(pathbuf, pglob, limitp));
              }

              /* Find end of next segment, copy tentatively to pathend. */
              q = pathend;
              p = pattern;
              while (*p != EOS && !IS_SLASH(*p)) {
                     if (ismeta(*p))
                            anymeta = 1;
                     if (q+1 > pathend_last)
                            return (1);
                     *q++ = *p++;
              }

              if (!anymeta) {             /* No expansion, do next segment. */
                     pathend = q;
                     pattern = p;
                     while (IS_SLASH(*pattern)) {
                            if (pathend+1 > pathend_last)
                                   return (1);
                            *pathend++ = *pattern++;
                     }
              } else
                     /* Need expansion, recurse. */
                     return(glob3(pathbuf, pathbuf_last, pathend,
                            pathend_last, pattern, pattern_last,
                            p, pattern_last, pglob, limitp));
       }
       /* NOTREACHED */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int glob3 ( Char pathbuf,
Char pathbuf_last,
Char pathend,
Char pathend_last,
Char pattern,
Char pattern_last,
Char restpattern,
Char restpattern_last,
glob_t pglob,
size_t limitp 
) [static]

Definition at line 612 of file glob.c.

{
       register struct dirent *dp;
       DIR *dirp;
       int err;
       char buf[MAXPATHLEN];

       /*
        * The readdirfunc declaration can't be prototyped, because it is
        * assigned, below, to two functions which are prototyped in glob.h
        * and dirent.h as taking pointers to differently typed opaque
        * structures.
        */
       struct dirent *(*readdirfunc)();

       if (pathend > pathend_last)
              return (1);
       *pathend = EOS;
       errno = 0;

       if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
              /* TODO: don't call for ENOENT or ENOTDIR? */
              if (pglob->gl_errfunc) {
                     if (g_Ctoc(pathbuf, buf, sizeof(buf)))
                            return(GLOB_ABORTED);
                     if (pglob->gl_errfunc(buf, errno) ||
                            pglob->gl_flags & GLOB_ERR)
                            return(GLOB_ABORTED);
              }
              return(0);
       }

       err = 0;

       /* Search directory for matching names. */
       if (pglob->gl_flags & GLOB_ALTDIRFUNC)
              readdirfunc = pglob->gl_readdir;
       else
              readdirfunc = readdir;
       while ((dp = (*readdirfunc)(dirp))) {
              register u_char *sc;
              register Char *dc;

              /* Initial DOT must be matched literally. */
              if (dp->d_name[0] == DOT && *pattern != DOT)
                     continue;
              dc = pathend;
              sc = (u_char *) dp->d_name;
              while (dc < pathend_last && (*dc++ = *sc++) != EOS)
                     ;
              if (dc >= pathend_last) {
                     *dc = EOS;
                     err = 1;
                     break;
              }

              if (!match(pathend, pattern, restpattern)) {
                     *pathend = EOS;
                     continue;
              }
              err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,
                     restpattern, restpattern_last, pglob, limitp);
              if (err)
                     break;
       }

       if (pglob->gl_flags & GLOB_ALTDIRFUNC)
              (*pglob->gl_closedir)(dirp);
       else
              closedir(dirp);
       return(err);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int globexp1 ( const Char ,
glob_t  
) [static]

Here is the caller graph for this function:

static int globexp1 ( Char pattern,
glob_t pglob 
) const [static]

Definition at line 220 of file glob.c.

{
       const Char* ptr = pattern;
       int rv;

       /* Protect a single {}, for find(1), like csh */
       if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
              return glob0(pattern, pglob);

       while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
              if (!globexp2(ptr, pattern, pglob, &rv))
                     return rv;

       return glob0(pattern, pglob);
}

Here is the call graph for this function:

static int globexp2 ( const Char ,
const Char ,
glob_t ,
int  
) [static]

Here is the caller graph for this function:

static int globexp2 ( Char ptr,
Char pattern,
glob_t pglob,
int rv 
) const [static]

Definition at line 245 of file glob.c.

{
       int     i;
       Char   *lm, *ls;
       const Char *pe, *pm, *pl;
       Char    patbuf[MAXPATHLEN];

       /* copy part up to the brace */
       for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
              ;
       *lm = EOS;
       ls = lm;

       /* Find the balanced brace */
       for (i = 0, pe = ++ptr; *pe; pe++)
              if (*pe == LBRACKET) {
                     /* Ignore everything between [] */
                     for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
                            ;
                     if (*pe == EOS) {
                            /*
                             * We could not find a matching RBRACKET.
                             * Ignore and just look for RBRACE
                             */
                            pe = pm;
                     }
              } else if (*pe == LBRACE)
                     i++;
              else if (*pe == RBRACE) {
                     if (i == 0)
                            break;
                     i--;
              }

       /* Non matching braces; just glob the pattern */
       if (i != 0 || *pe == EOS) {
              *rv = glob0(patbuf, pglob);
              return 0;
       }

       for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
              switch (*pm) {
              case LBRACKET:
                     /* Ignore everything between [] */
                     for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
                            ;
                     if (*pm == EOS) {
                            /*
                             * We could not find a matching RBRACKET.
                             * Ignore and just look for RBRACE
                             */
                            pm = pl;
                     }
                     break;

              case LBRACE:
                     i++;
                     break;

              case RBRACE:
                     if (i) {
                            i--;
                            break;
                     }
                     /* FALLTHROUGH */
              case COMMA:
                     if (i && *pm == COMMA)
                            break;
                     else {
                            /* Append the current string */
                            for (lm = ls; (pl < pm); *lm++ = *pl++)
                                   ;

                            /*
                             * Append the rest of the pattern after the
                             * closing brace
                             */
                            for (pl = pe + 1; (*lm++ = *pl++) != EOS; )
                                   ;

                            /* Expand the current pattern */
#ifdef DEBUG
                            qprintf("globexp2:", patbuf);
#endif
                            *rv = globexp1(patbuf, pglob);

                            /* move after the comma, to the next string */
                            pl = pm + 1;
                     }
                     break;

              default:
                     break;
              }
       }
       *rv = 0;
       return 0;
}

Here is the call graph for this function:

static int globextend ( const Char ,
glob_t ,
size_t  
) [static]

Here is the caller graph for this function:

static int globextend ( Char path,
glob_t pglob,
size_t limitp 
) const [static]

Definition at line 706 of file glob.c.

{
       register char **pathv;
       register int i;
       u_int newsize, len;
       char *copy;
       const Char *p;

       newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
       pathv = pglob->gl_pathv ? realloc((char *)pglob->gl_pathv, newsize) :
              malloc(newsize);
       if (pathv == NULL) {
              if (pglob->gl_pathv) {
                     free(pglob->gl_pathv);
                     pglob->gl_pathv = NULL;
              }
              return(GLOB_NOSPACE);
       }

       if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
              /* first time around -- clear initial gl_offs items */
              pathv += pglob->gl_offs;
              for (i = pglob->gl_offs; --i >= 0; )
                     *--pathv = NULL;
       }
       pglob->gl_pathv = pathv;

       for (p = path; *p++;)
              ;
       len = (size_t)(p - path);
       *limitp += len;
       if ((copy = malloc(len)) != NULL) {
              if (g_Ctoc(path, copy, len)) {
                     free(copy);
                     return(GLOB_NOSPACE);
              }
              pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
       }
       pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;

       if ((pglob->gl_flags & GLOB_LIMIT) &&
              newsize + *limitp >= ARG_MAX) {
              errno = 0;
              return(GLOB_NOSPACE);
       }

       return(copy == NULL ? GLOB_NOSPACE : 0);
}

Here is the call graph for this function:

PHPAPI void globfree ( glob_t pglob)

Definition at line 813 of file glob.c.

{
       register int i;
       register char **pp;

       if (pglob->gl_pathv != NULL) {
              pp = pglob->gl_pathv + pglob->gl_offs;
              for (i = pglob->gl_pathc; i--; ++pp)
                     if (*pp)
                            free(*pp);
              free(pglob->gl_pathv);
              pglob->gl_pathv = NULL;
       }
}

Here is the caller graph for this function:

static const Char* globtilde ( const Char ,
Char ,
size_t  ,
glob_t  
) [static]

Here is the caller graph for this function:

static const Char* globtilde ( Char pattern,
Char patbuf,
size_t  patbuf_len,
glob_t pglob 
) const [static]

Definition at line 353 of file glob.c.

{
#ifndef PHP_WIN32
       struct passwd *pwd;
#endif
       char *h;
       const Char *p;
       Char *b, *eb;

       if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
              return pattern;

       /* Copy up to the end of the string or / */
       eb = &patbuf[patbuf_len - 1];
       for (p = pattern + 1, h = (char *) patbuf;
              h < (char *)eb && *p && *p != SLASH; *h++ = (char) *p++)
              ;

       *h = EOS;

#if 0
       if (h == (char *)eb)
              return what;
#endif

       if (((char *) patbuf)[0] == EOS) {
              /*
               * handle a plain ~ or ~/ by expanding $HOME
               * first and then trying the password file
               */
              if ((h = getenv("HOME")) == NULL) {
#ifndef PHP_WIN32
                     if ((pwd = getpwuid(getuid())) == NULL)
                            return pattern;
                     else
                            h = pwd->pw_dir;
#else
                     return pattern;
#endif
              }
       } else {
              /*
               * Expand a ~user
               */
#ifndef PHP_WIN32
              if ((pwd = getpwnam((char*) patbuf)) == NULL)
                     return pattern;
              else
                     h = pwd->pw_dir;
#else
              return pattern;
#endif
       }

       /* Copy the home directory */
       for (b = patbuf; b < eb && *h; *b++ = *h++)
              ;

       /* Append the rest of the pattern */
       while (b < eb && (*b++ = *p++) != EOS)
              ;
       *b = EOS;

       return patbuf;
}
static int match ( Char name,
Char pat,
Char patend 
) [static]

Definition at line 764 of file glob.c.

{
       int ok, negate_range;
       Char c, k;

       while (pat < patend) {
              c = *pat++;
              switch (c & M_MASK) {
              case M_ALL:
                     if (pat == patend)
                            return(1);
                     do
                            if (match(name, pat, patend))
                                   return(1);
                     while (*name++ != EOS)
                            ;
                     return(0);
              case M_ONE:
                     if (*name++ == EOS)
                            return(0);
                     break;
              case M_SET:
                     ok = 0;
                     if ((k = *name++) == EOS)
                            return(0);
                     if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
                            ++pat;
                     while (((c = *pat++) & M_MASK) != M_END)
                            if ((*pat & M_MASK) == M_RNG) {
                                   if (c <= k && k <= pat[1])
                                          ok = 1;
                                   pat += 2;
                            } else if (c == k)
                                   ok = 1;
                     if (ok == negate_range)
                            return(0);
                     break;
              default:
                     if (*name++ != c)
                            return(0);
                     break;
              }
       }
       return(*name == EOS);
}

Here is the call graph for this function: