cleaned up a little
[tridge/junkcode.git] / fnmatch / ms_fnmatch.c
index 772fa91d94feab3c006adf84c29678b2ee8f9828..bd458564db5be26ae13e6588113d8b29d582e3ed 100644 (file)
@@ -77,41 +77,51 @@ static int null_match(const char *p)
        return 0;
 }
 
+
+struct max_n {
+       const char *predot;
+       const char *postdot;
+};
+
 /*
-  the original, recursive function. Needs replacing, but with exactly
-  the same output
+  the test function
 */
-static int fnmatch_test2(const char *p, size_t ofs, const char *n, char **max_n)
+static int fnmatch_core(const char *p, const char *n, struct max_n *max_n, const char *ldot)
 {
        char c;
        int i;
 
-       while ((c = p[ofs++])) {
+       while ((c = *p++)) {
                switch (c) {
                case '*':
-                       if (max_n[ofs] && max_n[ofs] <= n) {
-                               return null_match(p+ofs);
+                       if (max_n->predot && max_n->predot <= n) {
+                               return null_match(p);
                        }
                        for (i=0; n[i]; i++) {
-                               if (fnmatch_test2(p, ofs, n+i, max_n) == 0) {
+                               if (fnmatch_core(p, n+i, max_n+1, ldot) == 0) {
                                        return 0;
                                }
                        }
-                       if (!max_n[ofs] || max_n[ofs] > n) max_n[ofs] = n;
-                       return null_match(p+ofs);
+                       if (!max_n->predot || max_n->predot > n) max_n->predot = n;
+                       return null_match(p);
 
                case '<':
-                       if (max_n[ofs] && max_n[ofs] <= n) {
-                               return null_match(p+ofs);
+                       if (max_n->predot && max_n->predot <= n) {
+                               return null_match(p);
+                       }
+                       if (max_n->postdot && max_n->postdot <= n && n < ldot) {
+                               return -1;
                        }
                        for (i=0; n[i]; i++) {
-                               if (fnmatch_test2(p, ofs, n+i, max_n) == 0) return 0;
-                               if (n[i] == '.' && !strchr(n+i+1,'.')) {
-                                       return fnmatch_test2(p, ofs, n+i+1, max_n);
+                               if (fnmatch_core(p, n+i, max_n+1, ldot) == 0) return 0;
+                               if (n+i == ldot) {
+                                       if (fnmatch_core(p, n+i+1, max_n+1, ldot) == 0) return 0;
+                                       if (!max_n->postdot || max_n->postdot > n) max_n->postdot = n;
+                                       return -1;
                                }
                        }
-                       if (!max_n[ofs] || max_n[ofs] > n) max_n[ofs] = n;
-                       return null_match(p+ofs);
+                       if (!max_n->predot || max_n->predot > n) max_n->predot = n;
+                       return null_match(p);
 
                case '?':
                        if (! *n) {
@@ -122,18 +132,17 @@ static int fnmatch_test2(const char *p, size_t ofs, const char *n, char **max_n)
 
                case '>':
                        if (n[0] == '.') {
-                               if (! n[1] && null_match(p+ofs) == 0) {
+                               if (! n[1] && null_match(p) == 0) {
                                        return 0;
                                }
                                break;
                        }
-                       if (! *n) return null_match(p+ofs);
+                       if (! *n) return null_match(p);
                        n++;
                        break;
 
                case '"':
-                       if (*n == 0 && 
-                           null_match(p+ofs) == 0) {
+                       if (*n == 0 && null_match(p) == 0) {
                                return 0;
                        }
                        if (*n != '.') return -1;
@@ -141,9 +150,7 @@ static int fnmatch_test2(const char *p, size_t ofs, const char *n, char **max_n)
                        break;
 
                default:
-                       if (c != *n && 
-                           toupper(c) != 
-                           toupper(*n)) {
+                       if (c != *n && toupper(c) != toupper(*n)) {
                                return -1;
                        }
                        n++;
@@ -163,14 +170,22 @@ static int fnmatch_test2(const char *p, size_t ofs, const char *n, char **max_n)
 */
 static int fnmatch_test(const char *p, const char *n)
 {
-       int ret;
-       char **max_n;
+       int ret, count, i;
+       struct max_n *max_n = NULL;
 
-       max_n = calloc(sizeof(char *), strlen(p)+1);
+       for (count=i=0;p[i];i++) {
+               if (p[i] == '*' || p[i] == '<') count++;
+       }
 
-       ret = fnmatch_test2(p, 0, n, max_n);
+       if (count) {
+               max_n = calloc(sizeof(struct max_n), count);
+       }
 
-       free(max_n);
+       ret = fnmatch_core(p, n, max_n, strrchr(n, '.'));
+
+       if (max_n) {
+               free(max_n);
+       }
 
        return ret;
 }
@@ -188,7 +203,7 @@ static const char *n_used;
 
 static void sig_alrm(int sig)
 {
-       printf("Too slow!!\np='%s'\ns='%s'\n", p_used, n_used);
+       printf("\nToo slow!!\np='%s'\ns='%s'\n", p_used, n_used);
        exit(0);
 }
 
@@ -242,7 +257,7 @@ int main(void)
                if (t2 > w2) w2 = t2;
 
                if (ret1 != ret2) {
-                       printf("mismatch: ret1=%d ret2=%d pattern='%s' string='%s'\n",
+                       printf("\nmismatch: ret1=%d ret2=%d pattern='%s' string='%s'\n",
                               ret1, ret2, p, n);
                        free(p);
                        free(n);