1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

lws_strcmp_wildcard

Add helper to do a strcmp() but against the first argument that may
contain zero or more * wildcards
This commit is contained in:
Andy Green 2021-01-16 07:30:25 +00:00
parent 82c858ee2e
commit e2f18957c1
3 changed files with 149 additions and 0 deletions

View file

@ -251,3 +251,15 @@ LWS_VISIBLE LWS_EXTERN int
lws_strexp_expand(lws_strexp_t *exp, const char *in, size_t len,
size_t *pused_in, size_t *pused_out);
/**
* lws_strcmp_wildcard() - strcmp but the first arg can have wildcards
*
* \p wildcard: a string that may contain zero to three *, and may lack a NUL
* \p len: length of the wildcard string
* \p check: string to test to see if it matches wildcard
*
* Exactly like strcmp, but supports patterns like "a*", "a*b", "a*b*" etc
* where a and b are arbitrary substrings
*/
LWS_VISIBLE LWS_EXTERN int
lws_strcmp_wildcard(const char *wildcard, size_t len, const char *check);

View file

@ -1135,6 +1135,82 @@ drain:
return LSTRX_DONE;
}
int
lws_strcmp_wildcard(const char *wildcard, size_t len, const char *check)
{
const char *match[3], *wc[3], *wc_end = wildcard + len;
int sp = 0;
do {
if (wildcard == wc_end) {
/*
* We reached the end of wildcard, but not of check,
* and the last thing in wildcard was not a * or we
* would have completed already... if we can rewind,
* let's try that...
*/
if (sp) {
wildcard = wc[sp - 1];
check = match[--sp];
continue;
}
/* otherwise it's the end of the road for this one */
return 1;
}
if (*wildcard == '*') {
if (++wildcard == wc_end)
/*
* Wildcard ended on a *, so we know we will
* match unconditionally
*/
return 0;
/*
* Now we need to stick wildcard here and see if there
* is any remaining match exists, for eg b of "a*b"
*/
if (sp == LWS_ARRAY_SIZE(match)) {
lwsl_err("%s: exceeds * stack\n", __func__);
return 1; /* we can't deal with it */
}
wc[sp] = wildcard;
/* if we ever pop and come back here, pick up from +1 */
match[sp++] = check + 1;
continue;
}
if (*(check++) == *wildcard) {
if (wildcard == wc_end)
return 0;
/*
* We're still compatible with wildcard... keep going
*/
wildcard++;
continue;
}
if (!sp)
/*
* We're just trying to match literals, and failed...
*/
return 1;
/* we're looking for a post-* match... keep looking... */
} while (*check);
return !!*wildcard;
}
#if LWS_MAX_SMP > 1

View file

@ -660,6 +660,67 @@ int main(int argc, const char **argv)
}
}
if (lws_strcmp_wildcard("allied", 6, "allied")) {
lwsl_user("%s: wc 1 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("a*", 2, "allied")) {
lwsl_user("%s: wc 2 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("all*", 4, "allied")) {
lwsl_user("%s: wc 3 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("all*d", 5, "allied")) {
lwsl_user("%s: wc 4 fail\n", __func__);
fail++;
}
if (!lws_strcmp_wildcard("b*", 2, "allied")) {
lwsl_user("%s: wc 5 fail\n", __func__);
fail++;
}
if (!lws_strcmp_wildcard("b*ed", 4, "allied")) {
lwsl_user("%s: wc 6 fail\n", __func__);
fail++;
}
if (!lws_strcmp_wildcard("allie", 5, "allied")) {
lwsl_user("%s: wc 7 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("allie*", 6, "allied")) {
lwsl_user("%s: wc 8 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("*llie*", 6, "allied")) {
lwsl_user("%s: wc 9 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("*llied", 6, "allied")) {
lwsl_user("%s: wc 10 fail\n", __func__);
fail++;
}
if (!lws_strcmp_wildcard("*llie", 5, "allied")) {
lwsl_user("%s: wc 11 fail\n", __func__);
fail++;
}
if (!lws_strcmp_wildcard("*nope", 5, "allied")) {
lwsl_user("%s: wc 12 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("*li*", 4, "allied")) {
lwsl_user("%s: wc 13 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("*", 1, "allied")) {
lwsl_user("%s: wc 14 fail\n", __func__);
fail++;
}
if (lws_strcmp_wildcard("*abc*d", 6, "xxabyyabcdd")) {
lwsl_user("%s: wc 15 fail\n", __func__);
fail++;
}
lwsl_user("Completed: PASS: %d, FAIL: %d\n", ok, fail);
return !(ok && !fail);