diff options
| -rw-r--r-- | xs_match.h | 92 | ||||
| -rw-r--r-- | xs_version.h | 2 |
2 files changed, 58 insertions, 36 deletions
| @@ -17,50 +17,72 @@ int xs_match(const char *str, const char *spec); | |||
| 17 | 17 | ||
| 18 | int xs_match(const char *str, const char *spec) | 18 | int xs_match(const char *str, const char *spec) |
| 19 | { | 19 | { |
| 20 | const char *o_str = str; | 20 | const char *b_str; |
| 21 | const char *b_spec = NULL; | ||
| 22 | const char *o_str = str; | ||
| 21 | 23 | ||
| 22 | again: | 24 | retry: |
| 23 | if (*spec == '*') { | ||
| 24 | spec++; /* wildcard */ | ||
| 25 | 25 | ||
| 26 | do { | 26 | for (;;) { |
| 27 | if (xs_match(str, spec)) | 27 | char c = *str++; |
| 28 | return 1; | 28 | char p = *spec++; |
| 29 | str++; | ||
| 30 | } while (*str); | ||
| 31 | 29 | ||
| 32 | return 0; | 30 | if (c == '\0') { |
| 33 | } | 31 | /* end of string; also end of spec? */ |
| 32 | if (p == '\0' || p == '|') | ||
| 33 | return 1; | ||
| 34 | else | ||
| 35 | break; | ||
| 36 | } | ||
| 37 | else | ||
| 38 | if (p == '?') { | ||
| 39 | /* match anything except the end */ | ||
| 40 | if (c == '\0') | ||
| 41 | return 0; | ||
| 42 | } | ||
| 43 | else | ||
| 44 | if (p == '*') { | ||
| 45 | /* end of spec? match */ | ||
| 46 | if (*spec == '\0') | ||
| 47 | return 1; | ||
| 34 | 48 | ||
| 35 | if (*spec == '?' && *str) { | 49 | /* store spec for later */ |
| 36 | spec++; /* any character */ | 50 | b_spec = spec; |
| 37 | str++; | 51 | |
| 38 | goto again; | 52 | /* back one char */ |
| 53 | b_str = --str; | ||
| 54 | } | ||
| 55 | else { | ||
| 56 | if (p == '\\') | ||
| 57 | p = *spec++; | ||
| 58 | |||
| 59 | if (c != p) { | ||
| 60 | /* mismatch; do we have a backtrack? */ | ||
| 61 | if (b_spec) { | ||
| 62 | /* continue where we left, one char forward */ | ||
| 63 | spec = b_spec; | ||
| 64 | str = ++b_str; | ||
| 65 | } | ||
| 66 | else | ||
| 67 | break; | ||
| 68 | } | ||
| 69 | } | ||
| 39 | } | 70 | } |
| 40 | 71 | ||
| 41 | if (*spec == '|') | 72 | /* try to find an alternative mark */ |
| 42 | return 1; /* alternative separator? positive match */ | 73 | while (*spec) { |
| 43 | 74 | char p = *spec++; | |
| 44 | if (!*spec) | ||
| 45 | return 1; /* end of spec? positive match */ | ||
| 46 | |||
| 47 | if (*spec == '\\') | ||
| 48 | spec++; /* escaped char */ | ||
| 49 | 75 | ||
| 50 | if (*spec == *str) { | 76 | if (p == '\\') |
| 51 | spec++; /* matched 1 char */ | 77 | p = *spec++; |
| 52 | str++; | ||
| 53 | goto again; | ||
| 54 | } | ||
| 55 | 78 | ||
| 56 | /* not matched; are there any alternatives? */ | 79 | if (p == '|') { |
| 57 | while (*spec) { | 80 | /* no backtrack spec, restart str from the beginning */ |
| 58 | if (*spec == '|') | 81 | b_spec = NULL; |
| 59 | return xs_match(o_str, spec + 1); /* try next alternative */ | 82 | str = o_str; |
| 60 | 83 | ||
| 61 | if (*spec == '\\') | 84 | goto retry; |
| 62 | spec++; /* escaped char */ | 85 | } |
| 63 | spec++; | ||
| 64 | } | 86 | } |
| 65 | 87 | ||
| 66 | return 0; | 88 | 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 */ | ||