]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/filematch.c
Remove <gtk/gtk.h> from gtkutil/entry.h
[xonotic/netradiant.git] / libs / filematch.c
1 #include <string.h>
2 #include "filematch.h"
3
4 // LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such...
5
6 int matchpattern( const char *in, const char *pattern, int caseinsensitive ){
7         return matchpattern_with_separator( in, pattern, caseinsensitive, "/\\:", 0 );
8 }
9
10 // wildcard_least_one: if true * matches 1 or more characters
11 //                     if false * matches 0 or more characters
12 int matchpattern_with_separator( const char *in, const char *pattern, int caseinsensitive, const char *separators, int wildcard_least_one ){
13         int c1, c2;
14         while ( *pattern )
15         {
16                 switch ( *pattern )
17                 {
18                 case 0:
19                         return 1; // end of pattern
20                 case '?': // match any single character
21                         if ( *in == 0 || strchr( separators, *in ) ) {
22                                 return 0; // no match
23                         }
24                         in++;
25                         pattern++;
26                         break;
27                 case '*': // match anything until following string
28                         if ( wildcard_least_one ) {
29                                 if ( *in == 0 || strchr( separators, *in ) ) {
30                                         return 0; // no match
31                                 }
32                                 in++;
33                         }
34                         pattern++;
35                         while ( *in )
36                         {
37                                 if ( strchr( separators, *in ) ) {
38                                         break;
39                                 }
40                                 // see if pattern matches at this offset
41                                 if ( matchpattern_with_separator( in, pattern, caseinsensitive, separators, wildcard_least_one ) ) {
42                                         return 1;
43                                 }
44                                 // nope, advance to next offset
45                                 in++;
46                         }
47                         break;
48                 default:
49                         if ( *in != *pattern ) {
50                                 if ( !caseinsensitive ) {
51                                         return 0; // no match
52                                 }
53                                 c1 = *in;
54                                 if ( c1 >= 'A' && c1 <= 'Z' ) {
55                                         c1 += 'a' - 'A';
56                                 }
57                                 c2 = *pattern;
58                                 if ( c2 >= 'A' && c2 <= 'Z' ) {
59                                         c2 += 'a' - 'A';
60                                 }
61                                 if ( c1 != c2 ) {
62                                         return 0; // no match
63                                 }
64                         }
65                         in++;
66                         pattern++;
67                         break;
68                 }
69         }
70         if ( *in ) {
71                 return 0; // reached end of pattern but not end of input
72         }
73         return 1; // success
74 }