Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

fnmatch.c File Reference

Go to the source code of this file.

Functions

char * getenv ()
int internal_function internal_fnmatch (const char *pattern, const char *string, int no_leading_period, int flags)
int fnmatch (pattern, string, flags) const char *pattern

Variables

int errno
const char * string
int flags


Function Documentation

char* getenv  
 

Referenced by add_cvs_excludes(), auth_client(), do_cmd(), get_panic_action(), getpassf(), internal_fnmatch(), open_socket_out(), open_socket_out_wrapped(), and start_socket_client().

int internal_function internal_fnmatch const char *    pattern,
const char *    string,
int    no_leading_period,
int    flags
[static]
 

Definition at line 144 of file fnmatch.c.

References flags, getenv(), and string.

00146 {
00147   register const char *p = pattern, *n = string;
00148   register unsigned char c;
00149 
00150 /* Note that this evaluates C many times.  */
00151 # ifdef _LIBC
00152 #  define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
00153 # else
00154 #  define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
00155 # endif
00156 
00157   while ((c = *p++) != '\0')
00158     {
00159       c = FOLD (c);
00160 
00161       switch (c)
00162         {
00163         case '?':
00164           if (*n == '\0')
00165             return FNM_NOMATCH;
00166           else if (*n == '/' && (flags & FNM_FILE_NAME))
00167             return FNM_NOMATCH;
00168           else if (*n == '.' && no_leading_period
00169                    && (n == string
00170                        || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
00171             return FNM_NOMATCH;
00172           break;
00173 
00174         case '\\':
00175           if (!(flags & FNM_NOESCAPE))
00176             {
00177               c = *p++;
00178               if (c == '\0')
00179                 /* Trailing \ loses.  */
00180                 return FNM_NOMATCH;
00181               c = FOLD (c);
00182             }
00183           if (FOLD ((unsigned char) *n) != c)
00184             return FNM_NOMATCH;
00185           break;
00186 
00187         case '*':
00188           if (*n == '.' && no_leading_period
00189               && (n == string
00190                   || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
00191             return FNM_NOMATCH;
00192 
00193           for (c = *p++; c == '?' || c == '*'; c = *p++)
00194             {
00195               if (*n == '/' && (flags & FNM_FILE_NAME))
00196                 /* A slash does not match a wildcard under FNM_FILE_NAME.  */
00197                 return FNM_NOMATCH;
00198               else if (c == '?')
00199                 {
00200                   /* A ? needs to match one character.  */
00201                   if (*n == '\0')
00202                     /* There isn't another character; no match.  */
00203                     return FNM_NOMATCH;
00204                   else
00205                     /* One character of the string is consumed in matching
00206                        this ? wildcard, so *??? won't match if there are
00207                        less than three characters.  */
00208                     ++n;
00209                 }
00210             }
00211 
00212           if (c == '\0')
00213             /* The wildcard(s) is/are the last element of the pattern.
00214                If the name is a file name and contains another slash
00215                this does mean it cannot match.  */
00216             return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
00217                     ? FNM_NOMATCH : 0);
00218           else
00219             {
00220               const char *endp;
00221 
00222 #if 0
00223               endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
00224 #else
00225 /* replace call to internal glibc function with equivalent */
00226               if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL))
00227                 endp = n + strlen(n);
00228 #endif
00229 
00230               if (c == '[')
00231                 {
00232                   int flags2 = ((flags & FNM_FILE_NAME)
00233                                 ? flags : (flags & ~FNM_PERIOD));
00234 
00235                   for (--p; n < endp; ++n)
00236                     if (internal_fnmatch (p, n,
00237                                           (no_leading_period
00238                                            && (n == string
00239                                                || (n[-1] == '/'
00240                                                    && (flags
00241                                                        & FNM_FILE_NAME)))),
00242                                           flags2)
00243                         == 0)
00244                       return 0;
00245                 }
00246               else if (c == '/' && (flags & FNM_FILE_NAME))
00247                 {
00248                   while (*n != '\0' && *n != '/')
00249                     ++n;
00250                   if (*n == '/'
00251                       && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
00252                                             flags) == 0))
00253                     return 0;
00254                 }
00255               else
00256                 {
00257                   int flags2 = ((flags & FNM_FILE_NAME)
00258                                 ? flags : (flags & ~FNM_PERIOD));
00259 
00260                   if (c == '\\' && !(flags & FNM_NOESCAPE))
00261                     c = *p;
00262                   c = FOLD (c);
00263                   for (--p; n < endp; ++n)
00264                     if (FOLD ((unsigned char) *n) == c
00265                         && (internal_fnmatch (p, n,
00266                                               (no_leading_period
00267                                                && (n == string
00268                                                    || (n[-1] == '/'
00269                                                        && (flags
00270                                                            & FNM_FILE_NAME)))),
00271                                               flags2) == 0))
00272                       return 0;
00273                 }
00274             }
00275 
00276           /* If we come here no match is possible with the wildcard.  */
00277           return FNM_NOMATCH;
00278 
00279         case '[':
00280           {
00281             /* Nonzero if the sense of the character class is inverted.  */
00282             static int posixly_correct;
00283             register int not;
00284             char cold;
00285 
00286             if (posixly_correct == 0)
00287               posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
00288 
00289             if (*n == '\0')
00290               return FNM_NOMATCH;
00291 
00292             if (*n == '.' && no_leading_period && (n == string
00293                                                    || (n[-1] == '/'
00294                                                        && (flags
00295                                                            & FNM_FILE_NAME))))
00296               return FNM_NOMATCH;
00297 
00298             if (*n == '/' && (flags & FNM_FILE_NAME))
00299               /* `/' cannot be matched.  */
00300               return FNM_NOMATCH;
00301 
00302             not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
00303             if (not)
00304               ++p;
00305 
00306             c = *p++;
00307             for (;;)
00308               {
00309                 unsigned char fn = FOLD ((unsigned char) *n);
00310 
00311                 if (!(flags & FNM_NOESCAPE) && c == '\\')
00312                   {
00313                     if (*p == '\0')
00314                       return FNM_NOMATCH;
00315                     c = FOLD ((unsigned char) *p);
00316                     ++p;
00317 
00318                     if (c == fn)
00319                       goto matched;
00320                   }
00321                 else if (c == '[' && *p == ':')
00322                   {
00323                     /* Leave room for the null.  */
00324                     char str[CHAR_CLASS_MAX_LENGTH + 1];
00325                     size_t c1 = 0;
00326 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
00327                     wctype_t wt;
00328 # endif
00329                     const char *startp = p;
00330 
00331                     for (;;)
00332                       {
00333                         if (c1 == CHAR_CLASS_MAX_LENGTH)
00334                           /* The name is too long and therefore the pattern
00335                              is ill-formed.  */
00336                           return FNM_NOMATCH;
00337 
00338                         c = *++p;
00339                         if (c == ':' && p[1] == ']')
00340                           {
00341                             p += 2;
00342                             break;
00343                           }
00344                         if (c < 'a' || c >= 'z')
00345                           {
00346                             /* This cannot possibly be a character class name.
00347                                Match it as a normal range.  */
00348                             p = startp;
00349                             c = '[';
00350                             goto normal_bracket;
00351                           }
00352                         str[c1++] = c;
00353                       }
00354                     str[c1] = '\0';
00355 
00356 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
00357                     wt = IS_CHAR_CLASS (str);
00358                     if (wt == 0)
00359                       /* Invalid character class name.  */
00360                       return FNM_NOMATCH;
00361 
00362                     if (__iswctype (__btowc ((unsigned char) *n), wt))
00363                       goto matched;
00364 # else
00365                     if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
00366                         || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
00367                         || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
00368                         || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
00369                         || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
00370                         || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
00371                         || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
00372                         || (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
00373                         || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
00374                         || (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
00375                         || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
00376                         || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
00377                       goto matched;
00378 # endif
00379                   }
00380                 else if (c == '\0')
00381                   /* [ (unterminated) loses.  */
00382                   return FNM_NOMATCH;
00383                 else
00384                   {
00385                   normal_bracket:
00386                     if (FOLD (c) == fn)
00387                       goto matched;
00388 
00389                     cold = c;
00390                     c = *p++;
00391 
00392                     if (c == '-' && *p != ']')
00393                       {
00394                         /* It is a range.  */
00395                         unsigned char cend = *p++;
00396                         if (!(flags & FNM_NOESCAPE) && cend == '\\')
00397                           cend = *p++;
00398                         if (cend == '\0')
00399                           return FNM_NOMATCH;
00400 
00401                         if (cold <= fn && fn <= FOLD (cend))
00402                           goto matched;
00403 
00404                         c = *p++;
00405                       }
00406                   }
00407 
00408                 if (c == ']')
00409                   break;
00410               }
00411 
00412             if (!not)
00413               return FNM_NOMATCH;
00414             break;
00415 
00416           matched:
00417             /* Skip the rest of the [...] that already matched.  */
00418             while (c != ']')
00419               {
00420                 if (c == '\0')
00421                   /* [... (unterminated) loses.  */
00422                   return FNM_NOMATCH;
00423 
00424                 c = *p++;
00425                 if (!(flags & FNM_NOESCAPE) && c == '\\')
00426                   {
00427                     if (*p == '\0')
00428                       return FNM_NOMATCH;
00429                     /* XXX 1003.2d11 is unclear if this is right.  */
00430                     ++p;
00431                   }
00432                 else if (c == '[' && *p == ':')
00433                   {
00434                     do
00435                       if (*++p == '\0')
00436                         return FNM_NOMATCH;
00437                     while (*p != ':' || p[1] == ']');
00438                     p += 2;
00439                     c = *p;
00440                   }
00441               }
00442             if (not)
00443               return FNM_NOMATCH;
00444           }
00445           break;
00446 
00447         default:
00448           if (c != FOLD ((unsigned char) *n))
00449             return FNM_NOMATCH;
00450         }
00451 
00452       ++n;
00453     }
00454 
00455   if (*n == '\0')
00456     return 0;
00457 
00458   if ((flags & FNM_LEADING_DIR) && *n == '/')
00459     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
00460     return 0;
00461 
00462   return FNM_NOMATCH;
00463 
00464 # undef FOLD
00465 }

int fnmatch pattern   ,
string   ,
flags   
const
 

Referenced by auth_server(), check_one_exclude(), make_exclude(), match_hostname(), and set_compression().


Variable Documentation

int errno
 

Definition at line 135 of file fnmatch.c.

const char* string
 

Definition at line 471 of file fnmatch.c.

Referenced by internal_fnmatch().

int flags
 

Definition at line 472 of file fnmatch.c.

Referenced by internal_fnmatch().


Generated on Tue Apr 16 12:37:38 2002 for rsync by doxygen1.2.15