Not sure it helps its readability (not worse though), at least it
helps performances.

For now the patches uses a big "goto" to preserve code (AFAP), that
could easily be turned into a do {} while.

WDYT?
Index: server/util.c
===================================================================
--- server/util.c	(revision 1827528)
+++ server/util.c	(working copy)
@@ -185,53 +185,47 @@ AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_t
  * Based loosely on sections of wildmat.c by Rich Salz
  * Hmmm... shouldn't this really go component by component?
  */
-AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected)
+static int ap_strcmp_match_rec(const char *str, const char *expected,
+                               apr_size_t xstart, apr_size_t ystart,
+                               int nocase)
 {
-    int x, y;
+    apr_size_t x, y;
 
-    for (x = 0, y = 0; expected[y]; ++y, ++x) {
+again:
+    x = xstart++;
+    for (y = ystart; expected[y]; ++y, ++x) {
         if (expected[y] == '*') {
             while (expected[++y] == '*');
             if (!expected[y])
                 return 0;
-            while (str[x]) {
-                int ret;
-                if ((ret = ap_strcmp_match(&str[x++], &expected[y])) != 1)
-                    return ret;
+            if (str[x]) {
+                return ap_strcmp_match_rec(str, expected, x, y, nocase);
             }
             return -1;
         }
         else if (!str[x])
             return -1;
-        else if ((expected[y] != '?') && (str[x] != expected[y]))
+        else if ((expected[y] != '?') && (str[x] != expected[y]) &&
+                 (!nocase || apr_tolower(str[x]) != apr_tolower(expected[y])))
             return 1;
     }
-    return (str[x] != '\0');
+    if (!str[x])
+        return 0;
+    if (!ystart)
+        return 1;
+
+    /* continue recursion from xstart + 1 */
+    goto again;
 }
 
+AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected)
+{
+    return ap_strcmp_match_rec(str, expected, 0, 0, 0);
+}
+
 AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected)
 {
-    int x, y;
-
-    for (x = 0, y = 0; expected[y]; ++y, ++x) {
-        if (!str[x] && expected[y] != '*')
-            return -1;
-        if (expected[y] == '*') {
-            while (expected[++y] == '*');
-            if (!expected[y])
-                return 0;
-            while (str[x]) {
-                int ret;
-                if ((ret = ap_strcasecmp_match(&str[x++], &expected[y])) != 1)
-                    return ret;
-            }
-            return -1;
-        }
-        else if (expected[y] != '?'
-                 && apr_tolower(str[x]) != apr_tolower(expected[y]))
-            return 1;
-    }
-    return (str[x] != '\0');
+    return ap_strcmp_match_rec(str, expected, 0, 0, 1);
 }
 
 /* We actually compare the canonical root to this root, (but we don't

Reply via email to