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