summaryrefslogtreecommitdiff
path: root/xs_match.h
diff options
context:
space:
mode:
authorGravatar default2023-09-21 11:37:51 +0200
committerGravatar default2023-09-21 11:37:51 +0200
commit8775424f1383ca9a6e97852029d244e4e51abfc4 (patch)
treeaa6f7fe3e772667f30800d02582ab66fe74de38d /xs_match.h
parentMerge pull request 'OAuth Login Page Clean-Up' (#80) from kvibber/snac2:oauth... (diff)
downloadpenes-snac2-8775424f1383ca9a6e97852029d244e4e51abfc4.tar.gz
penes-snac2-8775424f1383ca9a6e97852029d244e4e51abfc4.tar.xz
penes-snac2-8775424f1383ca9a6e97852029d244e4e51abfc4.zip
Backport from xs.
Diffstat (limited to 'xs_match.h')
-rw-r--r--xs_match.h92
1 files changed, 57 insertions, 35 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);
17 17
18int xs_match(const char *str, const char *spec) 18int 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
22again: 24retry:
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;