fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

filename_match.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: filename_match.cxx 7903 2010-11-28 21:06:39Z matt $"
00003 //
00004 // Pattern matching routines for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 /* Adapted from Rich Salz. */
00029 #include <FL/filename.H>
00030 #include <ctype.h>
00031 
00053 int fl_filename_match(const char *s, const char *p) {
00054   int matched;
00055 
00056   for (;;) {
00057     switch(*p++) {
00058 
00059     case '?' :  // match any single character
00060       if (!*s++) return 0;
00061       break;
00062 
00063     case '*' :  // match 0-n of any characters
00064       if (!*p) return 1; // do trailing * quickly
00065       while (!fl_filename_match(s, p)) if (!*s++) return 0;
00066       return 1;
00067 
00068     case '[': { // match one character in set of form [abc-d] or [^a-b]
00069       if (!*s) return 0;
00070       int reverse = (*p=='^' || *p=='!'); if (reverse) p++;
00071       matched = 0;
00072       char last = 0;
00073       while (*p) {
00074         if (*p=='-' && last) {
00075           if (*s <= *++p && *s >= last ) matched = 1;
00076           last = 0;
00077         } else {
00078           if (*s == *p) matched = 1;
00079         }
00080         last = *p++;
00081         if (*p==']') break;
00082       }
00083       if (matched == reverse) return 0;
00084       s++; p++;}
00085     break;
00086 
00087     case '{' : // {pattern1|pattern2|pattern3}
00088     NEXTCASE:
00089     if (fl_filename_match(s,p)) return 1;
00090     for (matched = 0;;) {
00091       switch (*p++) {
00092       case '\\': if (*p) p++; break;
00093       case '{': matched++; break;
00094       case '}': if (!matched--) return 0; break;
00095       case '|': case ',': if (matched==0) goto NEXTCASE;
00096       case 0: return 0;
00097       }
00098     }
00099     case '|':   // skip rest of |pattern|pattern} when called recursively
00100     case ',':
00101       for (matched = 0; *p && matched >= 0;) {
00102         switch (*p++) {
00103         case '\\': if (*p) p++; break;
00104         case '{': matched++; break;
00105         case '}': matched--; break;
00106         }
00107       }
00108       break;
00109     case '}':
00110       break;
00111 
00112     case 0:     // end of pattern
00113       return !*s;
00114 
00115     case '\\':  // quote next character
00116       if (*p) p++;
00117       /* FALLTHROUGH */
00118     default:
00119       if (tolower(*s) != tolower(*(p-1))) return 0;
00120       s++;
00121       break;
00122     }
00123   }
00124 }
00125 
00126 //
00127 // End of "$Id: filename_match.cxx 7903 2010-11-28 21:06:39Z matt $".
00128 //