[BACK]Return to fnmatch.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/fnmatch.c between version 1.2 and 1.3

version 1.2, 1993/04/10 00:25:35 version 1.3, 1993/06/16 17:16:13
Line 35 
Line 35 
  */   */
   
 #if defined(LIBC_SCCS) && !defined(lint)  #if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)fnmatch.c   5.4 (Berkeley) 2/23/91";  static char sccsid[] = "@(#)fnmatch.c   5.6 (Berkeley) 6/28/92";
 #endif /* LIBC_SCCS and not lint */  #endif /* LIBC_SCCS and not lint */
   
 /*  /*
  * Function fnmatch() as proposed in Posix 1003.2 B.6 (rev. 9).   * Function fnmatch() as proposed in POSIX 1003.2 B.6 (D11.2).
  * Compares a filename or pathname to a pattern.   * Compares a filename or pathname to a pattern.
  */   */
   
 #include <unistd.h>  #include <fnmatch.h>
 #include <string.h>  #include <string.h>
   
 #define EOS     '\0'  #define EOS     '\0'
   
 static char *  static const char *rangematch __P((const char *, int));
 rangematch(pattern, test)  
         register char *pattern, test;  
 {  
         register char c, c2;  
         int negate, ok;  
   
         if (negate = (*pattern == '!'))  
                 ++pattern;  
   
         /*  
          * TO DO: quoting  
          */  
   
         for (ok = 0; (c = *pattern++) != ']';) {  
                 if (c == EOS)  
                         return(NULL);           /* illegal pattern */  
                 if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') {  
                         if (c <= test && test <= c2)  
                                 ok = 1;  
                         pattern += 2;  
                 }  
                 else if (c == test)  
                         ok = 1;  
         }  
         return(ok == negate ? NULL : pattern);  
 }  
   
 fnmatch(pattern, string, flags)  fnmatch(pattern, string, flags)
         register const char *pattern;          register const char *pattern, *string;
         register const char *string;  
         int flags;          int flags;
 {  {
         register char c;          register char c;
         char test, *rangematch();          char test;
   
         for (;;)          for (;;)
                 switch (c = *pattern++) {                  switch (c = *pattern++) {
                 case EOS:                  case EOS:
                         return(!(*string == EOS));                          return (*string == EOS ? 0 : FNM_NOMATCH);
                 case '?':                  case '?':
                         if (((test = *string++) == EOS) ||                          if ((test = *string++) == EOS ||
                             ((test == '/') && (flags & FNM_PATHNAME)))                              test == '/' && flags & FNM_PATHNAME)
                                 return(1);                                  return (FNM_NOMATCH);
                         break;                          break;
                 case '*':                  case '*':
                         c = *pattern;                          c = *pattern;
                         /* collapse multiple stars */                          /* Collapse multiple stars. */
                         while (c == '*')                          while (c == '*')
                                 c = *++pattern;                                  c = *++pattern;
   
                         /* optimize for pattern with * at end or before / */                          /* Optimize for pattern with * at end or before /. */
                         if (c == EOS)                          if (c == EOS)
                                 if (flags & FNM_PATHNAME)                                  if (flags & FNM_PATHNAME)
                                         return(index(string, '/') != NULL);                                          return (index(string, '/') == NULL ?
                                               0 : FNM_NOMATCH);
                                 else                                  else
                                         return(0);                                          return (0);
                         else if ((c == '/') && (flags & FNM_PATHNAME)) {                          else if (c == '/' && flags & FNM_PATHNAME) {
                                 if ((string = index(string, '/')) == NULL)                                  if ((string = index(string, '/')) == NULL)
                                         return(1);                                          return (FNM_NOMATCH);
                                 break;                                  break;
                         }                          }
   
                         /* general case, use recursion */                          /* General case, use recursion. */
                         while ((test = *string) != EOS) {                          while ((test = *string) != EOS) {
                                 if (!fnmatch(pattern, string, flags))                                  if (!fnmatch(pattern, string, flags))
                                         return(0);                                          return (0);
                                 if (test == '/' && flags & FNM_PATHNAME)                                  if (test == '/' && flags & FNM_PATHNAME)
                                         break;                                          break;
                                 ++string;                                  ++string;
                         }                          }
                         return(1);                          return (FNM_NOMATCH);
                 case '[':                  case '[':
                         if ((test = *string++) == EOS ||                          if ((test = *string++) == EOS ||
                             test == '/' && flags & FNM_PATHNAME)                              test == '/' && flags & FNM_PATHNAME)
                                 return(1);                                  return (FNM_NOMATCH);
                         if ((pattern = rangematch(pattern, test)) == NULL)                          if ((pattern = rangematch(pattern, test)) == NULL)
                                 return(1);                                  return (FNM_NOMATCH);
                         break;                          break;
                 case '\\':                  case '\\':
                         if (flags & FNM_QUOTE) {                          if (!(flags & FNM_NOESCAPE)) {
                                 if ((c = *pattern++) == EOS) {                                  if ((c = *pattern++) == EOS) {
                                         c = '\\';                                          c = '\\';
                                         --pattern;                                          --pattern;
                                 }                                  }
                                 if (c != *string++)                                  if (c != *string++)
                                         return(1);                                          return (FNM_NOMATCH);
                                 break;                                  break;
                         }                          }
                         /* FALLTHROUGH */                          /* FALLTHROUGH */
                 default:                  default:
                         if (c != *string++)                          if (c != *string++)
                                 return(1);                                  return (FNM_NOMATCH);
                         break;                          break;
                 }                  }
           /* NOTREACHED */
   }
   
   static const char *
   rangematch(pattern, test)
           register const char *pattern;
           register int test;
   {
           register char c, c2;
           int negate, ok;
   
           if (negate = (*pattern == '!'))
                   ++pattern;
   
           /*
            * XXX
            * TO DO: quoting
            */
           for (ok = 0; (c = *pattern++) != ']';) {
                   if (c == EOS)
                           return (NULL);          /* Illegal pattern. */
                   if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') {
                           if (c <= test && test <= c2)
                                   ok = 1;
                           pattern += 2;
                   }
                   else if (c == test)
                           ok = 1;
           }
           return (ok == negate ? NULL : pattern);
 }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

CVSweb <webmaster@jp.NetBSD.org>