lib/ms_fnmatch.c

ソースコードを見る。

データ構造

struct  max_n

関数

static int null_match (const smb_ucs2_t *p)
static int ms_fnmatch_core (const smb_ucs2_t *p, const smb_ucs2_t *n, struct max_n *max_n, const smb_ucs2_t *ldot, BOOL is_case_sensitive)
int ms_fnmatch (const char *pattern, const char *string, BOOL translate_pattern, BOOL is_case_sensitive)
int gen_fnmatch (const char *pattern, const char *string)


関数

static int null_match ( const smb_ucs2_t p  )  [static]

ms_fnmatch.c30 行で定義されています。

参照元 ms_fnmatch_core().

00031 {
00032         for (;*p;p++) {
00033                 if (*p != UCS2_CHAR('*') &&
00034                     *p != UCS2_CHAR('<') &&
00035                     *p != UCS2_CHAR('"') &&
00036                     *p != UCS2_CHAR('>')) return -1;
00037         }
00038         return 0;
00039 }

static int ms_fnmatch_core ( const smb_ucs2_t p,
const smb_ucs2_t n,
struct max_n max_n,
const smb_ucs2_t ldot,
BOOL  is_case_sensitive 
) [static]

ms_fnmatch.c57 行で定義されています。

参照先 cnull_match()max_n::postdotmax_n::predottoupper_w().

参照元 ms_fnmatch().

00060 {
00061         smb_ucs2_t c;
00062         int i;
00063 
00064         while ((c = *p++)) {
00065                 switch (c) {
00066                         /* a '*' matches zero or more characters of any type */
00067                 case UCS2_CHAR('*'):
00068                         if (max_n->predot && max_n->predot <= n) {
00069                                 return null_match(p);
00070                         }
00071                         for (i=0; n[i]; i++) {
00072                                 if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) {
00073                                         return 0;
00074                                 }
00075                         }
00076                         if (!max_n->predot || max_n->predot > n) max_n->predot = n;
00077                         return null_match(p);
00078 
00079                         /* a '<' matches zero or more characters of
00080                            any type, but stops matching at the last
00081                            '.' in the string. */
00082                 case UCS2_CHAR('<'):
00083                         if (max_n->predot && max_n->predot <= n) {
00084                                 return null_match(p);
00085                         }
00086                         if (max_n->postdot && max_n->postdot <= n && n <= ldot) {
00087                                 return -1;
00088                         }
00089                         for (i=0; n[i]; i++) {
00090                                 if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) return 0;
00091                                 if (n+i == ldot) {
00092                                         if (ms_fnmatch_core(p, n+i+1, max_n+1, ldot, is_case_sensitive) == 0) return 0;
00093                                         if (!max_n->postdot || max_n->postdot > n) max_n->postdot = n;
00094                                         return -1;
00095                                 }
00096                         }
00097                         if (!max_n->predot || max_n->predot > n) max_n->predot = n;
00098                         return null_match(p);
00099 
00100                         /* a '?' matches any single character */
00101                 case UCS2_CHAR('?'):
00102                         if (! *n) {
00103                                 return -1;
00104                         }
00105                         n++;
00106                         break;
00107 
00108                         /* a '?' matches any single character */
00109                 case UCS2_CHAR('>'):
00110                         if (n[0] == UCS2_CHAR('.')) {
00111                                 if (! n[1] && null_match(p) == 0) {
00112                                         return 0;
00113                                 }
00114                                 break;
00115                         }
00116                         if (! *n) return null_match(p);
00117                         n++;
00118                         break;
00119 
00120                 case UCS2_CHAR('"'):
00121                         if (*n == 0 && null_match(p) == 0) {
00122                                 return 0;
00123                         }
00124                         if (*n != UCS2_CHAR('.')) return -1;
00125                         n++;
00126                         break;
00127 
00128                 default:
00129                         if (c != *n) {
00130                                 if (is_case_sensitive) {
00131                                         return -1;
00132                                 }
00133                                 if (toupper_w(c) != toupper_w(*n)) {
00134                                         return -1;
00135                                 }
00136                         }
00137                         n++;
00138                         break;
00139                 }
00140         }
00141         
00142         if (! *n) {
00143                 return 0;
00144         }
00145         
00146         return -1;
00147 }

int ms_fnmatch ( const char *  pattern,
const char *  string,
BOOL  translate_pattern,
BOOL  is_case_sensitive 
)

ms_fnmatch.c149 行で定義されています。

参照先 ms_fnmatch_core()push_ucs2()StrCaseCmp()strrchr_w().

参照元 gen_fnmatch()mask_match()mask_match_search()reg_match_one().

00151 {
00152         wpstring p, s;
00153         int ret, count, i;
00154         struct max_n *max_n = NULL;
00155 
00156         if (strcmp(string, "..") == 0) {
00157                 string = ".";
00158         }
00159 
00160         if (strpbrk(pattern, "<>*?\"") == NULL) {
00161                 /* this is not just an optmisation - it is essential
00162                    for LANMAN1 correctness */
00163                 if (is_case_sensitive) {
00164                         return strcmp(pattern, string);
00165                 } else {
00166                         return StrCaseCmp(pattern, string);
00167                 }
00168         }
00169 
00170         if (push_ucs2(NULL, p, pattern, sizeof(p), STR_TERMINATE) == (size_t)-1) {
00171                 /* Not quite the right answer, but finding the right one
00172                   under this failure case is expensive, and it's pretty close */
00173                 return -1;
00174         }
00175 
00176         if (push_ucs2(NULL, s, string, sizeof(s), STR_TERMINATE) == (size_t)-1) {
00177                 /* Not quite the right answer, but finding the right one
00178                    under this failure case is expensive, and it's pretty close */
00179                 return -1;
00180         }
00181 
00182         if (translate_pattern) {
00183                 /*
00184                   for older negotiated protocols it is possible to
00185                   translate the pattern to produce a "new style"
00186                   pattern that exactly matches w2k behaviour
00187                 */
00188                 for (i=0;p[i];i++) {
00189                         if (p[i] == UCS2_CHAR('?')) {
00190                                 p[i] = UCS2_CHAR('>');
00191                         } else if (p[i] == UCS2_CHAR('.') && 
00192                                    (p[i+1] == UCS2_CHAR('?') || 
00193                                     p[i+1] == UCS2_CHAR('*') ||
00194                                     p[i+1] == 0)) {
00195                                 p[i] = UCS2_CHAR('"');
00196                         } else if (p[i] == UCS2_CHAR('*') && p[i+1] == UCS2_CHAR('.')) {
00197                                 p[i] = UCS2_CHAR('<');
00198                         }
00199                 }
00200         }
00201 
00202         for (count=i=0;p[i];i++) {
00203                 if (p[i] == UCS2_CHAR('*') || p[i] == UCS2_CHAR('<')) count++;
00204         }
00205 
00206         if (count != 0) {
00207                 max_n = SMB_CALLOC_ARRAY(struct max_n, count);
00208                 if (!max_n) {
00209                         return -1;
00210                 }
00211         }
00212 
00213         ret = ms_fnmatch_core(p, s, max_n, strrchr_w(s, UCS2_CHAR('.')), is_case_sensitive);
00214 
00215         if (max_n) {
00216                 free(max_n);
00217         }
00218 
00219         return ret;
00220 }

int gen_fnmatch ( const char *  pattern,
const char *  string 
)

ms_fnmatch.c224 行で定義されています。

参照先 ms_fnmatch()PROTOCOL_NT1.

参照元 file_find()interpret_interface().

00225 {
00226         return ms_fnmatch(pattern, string, PROTOCOL_NT1, False);
00227 }


Sambaに対してSat Aug 29 21:23:36 2009に生成されました。  doxygen 1.4.7