summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xs_match.h92
-rw-r--r--xs_version.h2
2 files changed, 58 insertions, 36 deletions
diff --git a/xs_match.h b/xs_match.h
index 9f12c15..dac7e2e 100644
--- a/xs_match.h
+++ b/xs_match.h
@@ -17,50 +17,72 @@ int xs_match(const char *str, const char *spec);
int xs_match(const char *str, const char *spec)
{
- const char *o_str = str;
+ const char *b_str;
+ const char *b_spec = NULL;
+ const char *o_str = str;
-again:
- if (*spec == '*') {
- spec++; /* wildcard */
+retry:
- do {
- if (xs_match(str, spec))
- return 1;
- str++;
- } while (*str);
+ for (;;) {
+ char c = *str++;
+ char p = *spec++;
- return 0;
- }
+ if (c == '\0') {
+ /* end of string; also end of spec? */
+ if (p == '\0' || p == '|')
+ return 1;
+ else
+ break;
+ }
+ else
+ if (p == '?') {
+ /* match anything except the end */
+ if (c == '\0')
+ return 0;
+ }
+ else
+ if (p == '*') {
+ /* end of spec? match */
+ if (*spec == '\0')
+ return 1;
- if (*spec == '?' && *str) {
- spec++; /* any character */
- str++;
- goto again;
+ /* store spec for later */
+ b_spec = spec;
+
+ /* back one char */
+ b_str = --str;
+ }
+ else {
+ if (p == '\\')
+ p = *spec++;
+
+ if (c != p) {
+ /* mismatch; do we have a backtrack? */
+ if (b_spec) {
+ /* continue where we left, one char forward */
+ spec = b_spec;
+ str = ++b_str;
+ }
+ else
+ break;
+ }
+ }
}
- if (*spec == '|')
- return 1; /* alternative separator? positive match */
-
- if (!*spec)
- return 1; /* end of spec? positive match */
-
- if (*spec == '\\')
- spec++; /* escaped char */
+ /* try to find an alternative mark */
+ while (*spec) {
+ char p = *spec++;
- if (*spec == *str) {
- spec++; /* matched 1 char */
- str++;
- goto again;
- }
+ if (p == '\\')
+ p = *spec++;
- /* not matched; are there any alternatives? */
- while (*spec) {
- if (*spec == '|')
- return xs_match(o_str, spec + 1); /* try next alternative */
+ if (p == '|') {
+ /* no backtrack spec, restart str from the beginning */
+ b_spec = NULL;
+ str = o_str;
- if (*spec == '\\')
- spec++; /* escaped char */
- spec++;
+ goto retry;
+ }
}
return 0;
diff --git a/xs_version.h b/xs_version.h
index f6c3412..1873039 100644
--- a/xs_version.h
+++ b/xs_version.h
@@ -1 +1 @@
-/* 06767a70773865042a70680aef50f7ecb077681a */
+/* 263e97c8ac21ff8524e3c890fe4310c696d01056 */