• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE Support
  • Sitemap
  • Contact Us
 

strigi/src/streams

fnmatch.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1989, 1993, 1994 Guido van Rossum <guido@python.org>
00003  *      The Regents of the University of California.  All rights reserved.
00004  *
00005  * This code is derived from software contributed to Berkeley by
00006  * Guido van Rossum <guido@python.org>.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. All advertising materials mentioning features or use of this software
00017  *    must display the following acknowledgement:
00018  *      This product includes software developed by the University of
00019  *      California, Berkeley and its contributors.
00020  * 4. Neither the name of the University nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036 
00037 #include <ctype.h>
00038 #include "strigi_fnmatch.h"
00039 
00040 /*
00041  * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
00042  * Compares a filename or pathname to a pattern.
00043  */
00044 #include <string.h>
00045 
00046 #define EOS '\0'
00047 
00048 static const char *rangematch(const char *, int, int);
00049 
00050 int fnmatch(const char *pattern, const char *string, int flags)
00051 {
00052     const char *stringstart;
00053     char c, test;
00054 
00055     for (stringstart = string;;) {
00056     switch (c = *pattern++) {
00057     case EOS:
00058         return (*string == EOS ? SUCCESS : FNM_NOMATCH);
00059     case '?':
00060         if (*string == EOS) {
00061         return (FNM_NOMATCH);
00062         }
00063         if (*string == '/' && (flags & FNM_PATHNAME)) {
00064         return (FNM_NOMATCH);
00065         }
00066         if (*string == '.' && (flags & FNM_PERIOD) &&
00067         (string == stringstart ||
00068          ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
00069         return (FNM_NOMATCH);
00070         }
00071         ++string;
00072         break;
00073     case '*':
00074         c = *pattern;
00075         /* Collapse multiple stars. */
00076         while (c == '*') {
00077         c = *++pattern;
00078         }
00079 
00080         if (*string == '.' && (flags & FNM_PERIOD) &&
00081         (string == stringstart ||
00082          ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
00083         return (FNM_NOMATCH);
00084         }
00085 
00086         /* Optimize for pattern with * at end or before /. */
00087         if (c == EOS) {
00088         if (flags & FNM_PATHNAME) {
00089             return (strchr(string, '/') == NULL ? SUCCESS : FNM_NOMATCH);
00090         }
00091         else {
00092             return (SUCCESS);
00093         }
00094         }
00095         else if (c == '/' && flags & FNM_PATHNAME) {
00096             if ((string = strchr(string, '/')) == NULL) {
00097             return (FNM_NOMATCH);
00098         }
00099         break;
00100         }
00101 
00102         /* General case, use recursion. */
00103         while ((test = *string) != EOS) {
00104             if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) {
00105             return (SUCCESS);
00106         }
00107         if (test == '/' && flags & FNM_PATHNAME) {
00108             break;
00109         }
00110         ++string;
00111         }
00112         return (FNM_NOMATCH);
00113     case '[':
00114         if (*string == EOS) {
00115         return (FNM_NOMATCH);
00116         }
00117         if (*string == '/' && flags & FNM_PATHNAME) {
00118         return (FNM_NOMATCH);
00119         }
00120         if (*string == '.' && (flags & FNM_PERIOD) &&
00121         (string == stringstart ||
00122          ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
00123             return (FNM_NOMATCH);
00124         }
00125         if ((pattern = rangematch(pattern, *string, flags)) == NULL) {
00126         return (FNM_NOMATCH);
00127         }
00128         ++string;
00129         break;
00130     case '\\':
00131         if (!(flags & FNM_NOESCAPE)) {
00132         if ((c = *pattern++) == EOS) {
00133             c = '\\';
00134             --pattern;
00135         }
00136         }
00137         /* FALLTHROUGH */
00138     default:
00139         if (flags & FNM_CASE_BLIND) {
00140             if (tolower(c) != tolower(*string)) {
00141             return (FNM_NOMATCH);
00142         }
00143         }
00144         else if (c != *string) {
00145             return (FNM_NOMATCH);
00146         }
00147         string++;
00148         break;
00149     }
00150     /* NOTREACHED */
00151     }
00152 }
00153 
00154 static const char *rangematch(const char *pattern, int test, int flags)
00155 {
00156     int negate, ok;
00157     char c, c2;
00158 
00159     /*
00160      * A bracket expression starting with an unquoted circumflex
00161      * character produces unspecified results (IEEE 1003.2-1992,
00162      * 3.13.2).  This implementation treats it like '!', for
00163      * consistency with the regular expression syntax.
00164      * J.T. Conklin (conklin@ngai.kaleida.com)
00165      */
00166     if ((negate = (*pattern == '!' || *pattern == '^'))) {
00167     ++pattern;
00168     }
00169 
00170     for (ok = 0; (c = *pattern++) != ']';) {
00171         if (c == '\\' && !(flags & FNM_NOESCAPE)) {
00172         c = *pattern++;
00173     }
00174     if (c == EOS) {
00175         return (NULL);
00176     }
00177     if (*pattern == '-' && (c2 = *(pattern + 1)) != EOS && c2 != ']') {
00178         pattern += 2;
00179         if (c2 == '\\' && !(flags & FNM_NOESCAPE)) {
00180         c2 = *pattern++;
00181         }
00182         if (c2 == EOS) {
00183         return (NULL);
00184         }
00185         if ((c <= test && test <= c2)
00186         || ((flags & FNM_CASE_BLIND)
00187             && ((tolower(c) <= tolower(test))
00188             && (tolower(test) <= tolower(c2))))) {
00189         ok = 1;
00190         }
00191     }
00192     else if ((c == test)
00193          || ((flags & FNM_CASE_BLIND)
00194              && (tolower(c) == tolower(test)))) {
00195         ok = 1;
00196     }
00197     }
00198     return (ok == negate ? NULL : pattern);
00199 }
00200 
00201 
00202 /* This function is an Apache addition */
00203 /* return non-zero if pattern has any glob chars in it */
00204 int fnmatch_test(const char *pattern)
00205 {
00206     int nesting;
00207 
00208     nesting = 0;
00209     while (*pattern) {
00210     switch (*pattern) {
00211     case '?':
00212     case '*':
00213         return 1;
00214 
00215     case '\\':
00216         if (*pattern++ == '\0') {
00217         return 0;
00218         }
00219         break;
00220 
00221     case '[':   /* '[' is only a glob if it has a matching ']' */
00222         ++nesting;
00223         break;
00224 
00225     case ']':
00226         if (nesting) {
00227         return 1;
00228         }
00229         break;
00230     }
00231     ++pattern;
00232     }
00233     return 0;
00234 }
00235 
00236 /* Deprecated */
00237 int is_fnmatch(const char *pattern)
00238 {
00239     return fnmatch_test(pattern);
00240 }

strigi/src/streams

Skip menu "strigi/src/streams"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

KDE Support

Skip menu "KDE Support"
  • akonadi
  • Decibel
  • grantlee
  • kdewin
  • phonon
  •     Backend
  • polkit-qt
  • qca
  • qimageblitz
  • soprano
  • strigi
  •     searchclient
  •     streamanalyzer
  •     streams
Generated for KDE Support by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal