00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "WOscPatternMatch.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048 #ifndef WOSC_USE_ADDR_WILDCARDS
00049 # define WOSC_USE_ADDR_WILDCARDS 1
00050 #endif
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 bool
00074 WOscPatternMatch::PatternMatch (const char * pattern, const char * test)
00075 {
00076
00077 if (pattern == 0 || pattern[0] == 0) {
00078 #if WOSC_USE_ADDR_WILDCARDS
00079 switch (test[0]) {
00080 case '*': return PatternMatch(pattern, test+1);
00081 case 0: return true;
00082 default: return false;
00083 }
00084 #else
00085 return test[0] == 0;
00086 #endif
00087 }
00088
00089
00090 switch ( test[0] ) {
00091 case 0:
00092 if (pattern[0] == '*')
00093 return PatternMatch (pattern+1,test);
00094 else
00095 return false;
00096 #if WOSC_USE_ADDR_WILDCARDS
00097 case '*':
00098 if (PatternMatch (pattern, test+1)) {
00099 return true;
00100 } else {
00101 return PatternMatch (pattern+1, test);
00102 }
00103 case '?' : return PatternMatch (pattern + 1, test + 1);
00104 #endif
00105 }
00106
00107
00108 switch (pattern[0]) {
00109 case 0 : return test[0] == 0;
00110 case '?' : return PatternMatch (pattern + 1, test + 1);
00111 case '*' :
00112 if (PatternMatch (pattern+1, test)) {
00113 return true;
00114 } else {
00115 return PatternMatch (pattern, test+1);
00116 }
00117 case ']' :
00118 case '}' :
00119
00120
00121
00122 return false;
00123 case '[' :
00124 return MatchBrackets (pattern,test);
00125 case '{' :
00126 return MatchList (pattern,test);
00127 case '\\' :
00128 if (pattern[1] == 0) {
00129 return test[0] == 0;
00130 } else if (pattern[1] == test[0]) {
00131 return PatternMatch (pattern+2,test+1);
00132 } else {
00133 return false;
00134 }
00135 default :
00136 if (pattern[0] == test[0]) {
00137 return PatternMatch (pattern+1,test+1);
00138 } else {
00139 return false;
00140 }
00141 }
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 bool
00165 WOscPatternMatch::MatchBrackets (const char *pattern, const char *test)
00166 {
00167 bool result;
00168 bool negated = false;
00169 const char *p = pattern;
00170
00171 if (pattern[1] == 0) {
00172
00173
00174
00175 return false;
00176 }
00177
00178 if (pattern[1] == '!') {
00179 negated = true;
00180 p++;
00181 }
00182
00183 while (*p != ']') {
00184 if (*p == 0) {
00185
00186
00187
00188 return false;
00189 }
00190 if (p[1] == '-' && p[2] != 0) {
00191 if (test[0] >= p[0] && test[0] <= p[2]) {
00192 result = !negated;
00193 goto advance;
00194 }
00195 }
00196 if (p[0] == test[0]) {
00197 result = !negated;
00198 goto advance;
00199 }
00200 p++;
00201 }
00202
00203 result = negated;
00204
00205 advance:
00206
00207 if (!result)
00208 return false;
00209
00210 while (*p != ']') {
00211 if (*p == 0) {
00212
00213
00214
00215 return false;
00216 }
00217 p++;
00218 }
00219
00220 return PatternMatch (p+1,test+1);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 bool
00243 WOscPatternMatch::MatchList (const char *pattern, const char *test)
00244 {
00245
00246 const char *restOfPattern, *tp = test;
00247
00248
00249 for(restOfPattern = pattern; *restOfPattern != '}'; restOfPattern++) {
00250 if (*restOfPattern == 0) {
00251
00252
00253
00254 return false;
00255 }
00256 }
00257
00258 restOfPattern++;
00259
00260 pattern++;
00261
00262 while (1) {
00263
00264 if (*pattern == ',') {
00265 if (PatternMatch (restOfPattern, tp)) {
00266 return true;
00267 } else {
00268 tp = test;
00269 ++pattern;
00270 }
00271 } else if (*pattern == '}') {
00272 return PatternMatch (restOfPattern, tp);
00273 } else if (*pattern == *tp) {
00274 ++pattern;
00275 ++tp;
00276 } else {
00277 tp = test;
00278 while (*pattern != ',' && *pattern != '}') {
00279 pattern++;
00280 }
00281 if (*pattern == ',') {
00282 pattern++;
00283 }
00284 }
00285 }
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 const char*
00299 WOscPatternMatch::NextSlashOrNull(const char *p)
00300 {
00301 while (*p != '/' && *p != '\0') {
00302 p++;
00303 }
00304 return p;
00305 }