From 5b359484e144b2ff8bdc2dbaee33bb5410d02a41 Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Sun, 8 Aug 2021 23:03:01 -0700 Subject: [PATCH] Allow '*' pattern character to be used mid-string (not just beg or end) Previously, the '*' matching pattern character could only be used as the beginning or ending character of a pattern string; for any other use, it was treated just as any other exact-match character. Now, you can have exact-match characters on both the left and right sides of the '*', so pattern matching like the following is possible: <*@gmail.com> digital*man Multiple '*'s are still not treated special (only the first/left-most '*" is), so, for example, "*blah*" will not likely produce the desired matching effect (use "blah~" instead for this case). --- src/sbbs3/str_util.c | 88 +++++++++++++++++++++++--------------------- src/sbbs3/str_util.h | 2 +- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/sbbs3/str_util.c b/src/sbbs3/str_util.c index dac22f2814..3cf15f5eab 100644 --- a/src/sbbs3/str_util.c +++ b/src/sbbs3/str_util.c @@ -244,64 +244,68 @@ char* strip_char(const char* str, char* dest, char ch) } /****************************************************************************/ -/* Pattern matching string search of 'insearchof' in 'string'. */ -/****************************************************************************/ -BOOL findstr_in_string(const char* insearchof, char* string) -{ +/* Pattern matching string search of 'insearchof' in 'pattern'. */ +/* pattern matching is case-insensitive */ +/* patterns beginning with ';' are comments (never match) */ +/* patterns beginning with '!' are reverse-matched (returns FALSE if match) */ +/* patterns ending in '~' will match string anywhere (sub-string search) */ +/* patterns ending in '^' will match left string fragment only */ +/* patterns including '*' must match both left and right string fragments */ +/* all other patterns are exact-match checking */ +/****************************************************************************/ +BOOL findstr_in_string(const char* search, const char* pattern) +{ + char buf[256]; char* p; - char str[256]; - char search[81]; - int c; - int i; - BOOL found=FALSE; - - if(string==NULL || insearchof==NULL) - return(FALSE); + char* last; + const char* splat; + size_t len; + BOOL found = FALSE; - SAFECOPY(search,insearchof); - strupr(search); - SAFECOPY(str,string); + if(pattern == NULL || search == NULL) + return FALSE; - p=str; -// SKIP_WHITESPACE(p); + SAFECOPY(buf, pattern); + p = buf; - if(*p==';') /* comment */ - return(FALSE); + if(*p == ';') /* comment */ + return FALSE; - if(*p=='!') { /* !match */ - found=TRUE; + if(*p == '!') { /* reverse-match */ + found = TRUE; p++; } truncsp(p); - c=strlen(p); - if(c) { - c--; - strupr(p); - if(p[c]=='~') { - p[c]=0; - if(strstr(search,p)) - found=!found; + len = strlen(p); + if(len > 0) { + last = p + len - 1; + if(*last == '~') { + *last = '\0'; + if(strcasestr(search, p) != NULL) + found = !found; } - else if(p[c]=='^' || p[c]=='*') { - p[c]=0; - if(!strncmp(p,search,c)) - found=!found; + else if(*last == '^') { + if(strnicmp(p, search, len - 1) == 0) + found = !found; } - else if(p[0]=='*') { - i=strlen(search); - if(i<c) - return(found); - if(!strncmp(p+1,search+(i-c),c)) - found=!found; + else if((splat = strchr(p, '*')) != NULL) { + int left = splat - p; + int right = len - (left + 1); + int slen = strlen(search); + if(slen < left + right) + return found; + if(strnicmp(search, p, left) == 0 + && strnicmp(p + left + 1, search + (slen - right), right) == 0) + found = !found; } - else if(!strcmp(p,search)) - found=!found; + else if(stricmp(p, search) == 0) + found = !found; } - return(found); + return found; } static uint32_t encode_ipv4_address(unsigned int byte[]) diff --git a/src/sbbs3/str_util.h b/src/sbbs3/str_util.h index f8dec9b39d..010a6ea9dd 100644 --- a/src/sbbs3/str_util.h +++ b/src/sbbs3/str_util.h @@ -46,7 +46,7 @@ DLLEXPORT char * replace_named_values(const char* src ,char* buf, size_t bufl DLLEXPORT char * condense_whitespace(char* str); DLLEXPORT char exascii_to_ascii_char(uchar ch); DLLEXPORT BOOL findstr(const char *insearch, const char *fname); -DLLEXPORT BOOL findstr_in_string(const char* insearchof, char* string); +DLLEXPORT BOOL findstr_in_string(const char* insearchof, const char* pattern); DLLEXPORT BOOL findstr_in_list(const char* insearchof, str_list_t list); DLLEXPORT str_list_t findstr_list(const char* fname); DLLEXPORT BOOL trashcan(scfg_t* cfg, const char *insearch, const char *name); -- GitLab