mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-11 23:13:24 -05:00
Add Timo's match patch
This commit is contained in:
parent
9ebe74c9fd
commit
cde5f4c917
@ -28,13 +28,15 @@
|
||||
# Date (date)
|
||||
#
|
||||
# Valid operators include:
|
||||
# is, includes (string)
|
||||
# is, includes (string), matches (string)
|
||||
# >, <, <=, >=, = (int)
|
||||
# after, before (date)
|
||||
#
|
||||
# the "is" operator must exactly match the tag,
|
||||
# while the "includes" operator matches a substring.
|
||||
# Both matches are case-insensitive
|
||||
# the "is" operator must exactly match the tag, while
|
||||
# the "includes" operator matches a substring and
|
||||
# "matches" operator makes trivial wildcard match using
|
||||
# "?" and "*" as wildcards for any character and any
|
||||
# string accordingly. All matches are case-insensitive.
|
||||
#
|
||||
# Valid operands include:
|
||||
# "string value" (string)
|
||||
|
@ -81,6 +81,7 @@ after { yylval.ival=AFTER; return(AFTER); }
|
||||
|
||||
is { yylval.ival=IS; return(IS); }
|
||||
includes { yylval.ival=INCLUDES; return(INCLUDES); }
|
||||
matches { yylval.ival=INCLUDES; return(MATCHES); }
|
||||
= { yylval.ival=EQUALS; return(EQUALS); }
|
||||
|
||||
or |
|
||||
|
@ -72,6 +72,7 @@ int pl_number=2;
|
||||
%token <ival> GREATEREQUAL
|
||||
%token <ival> IS
|
||||
%token <ival> INCLUDES
|
||||
%token <ival> MATCHES
|
||||
|
||||
%token <ival> OR
|
||||
%token <ival> AND
|
||||
@ -168,6 +169,7 @@ strtag: ARTIST
|
||||
|
||||
strbool: IS { $$=$1; }
|
||||
| INCLUDES { $$=$1; }
|
||||
| MATCHES { $$=$1; }
|
||||
| NOT strbool { $$=$2 | 0x80000000; }
|
||||
;
|
||||
|
||||
|
@ -48,6 +48,48 @@ int pl_eval_node(MP3FILE *pmp3, PL_NODE *pnode);
|
||||
|
||||
extern FILE *yyin;
|
||||
|
||||
#define MATCH_WILD_CHR '?'
|
||||
#define MATCH_WILD_STR '*'
|
||||
#define MATCH_CHAR_EQ(m, c, case_sensitive) \
|
||||
(((m) == (c)) || \
|
||||
((! case_sensitive) && \
|
||||
((isalpha((m)) ? toupper((m)) : (m)) == \
|
||||
(isalpha((c)) ? toupper((c)) : (c)))))
|
||||
|
||||
/*
|
||||
* match
|
||||
*
|
||||
* Trivial pattern matcher.
|
||||
* - '*' matches to any (sub)string
|
||||
* - '?' matches to any character
|
||||
* Returs non-zero on match.
|
||||
*/
|
||||
static int match(char *mask, char *str, int case_sensitive)
|
||||
{
|
||||
unsigned char *s, *m;
|
||||
|
||||
m = (unsigned char *)mask;
|
||||
s = (unsigned char *)str;
|
||||
while (*m != '\0') {
|
||||
if ((! MATCH_CHAR_EQ(*m, *s, case_sensitive)) &&
|
||||
(*m != MATCH_WILD_CHR) && (*m != MATCH_WILD_STR)) {
|
||||
return 0;
|
||||
} else if (*m == MATCH_WILD_STR) {
|
||||
m++;
|
||||
while (*s) {
|
||||
if (match((char *)m, (char *)s, case_sensitive))
|
||||
return 1;
|
||||
s++;
|
||||
}
|
||||
return ((!(*m != '\0')) ? 1 : 0);
|
||||
} else {
|
||||
s++;
|
||||
m++;
|
||||
}
|
||||
}
|
||||
return ((!(*s != '\0')) ? 1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* pl_dump
|
||||
*
|
||||
@ -150,6 +192,9 @@ void pl_dump_node(PL_NODE *pnode, int indent) {
|
||||
case INCLUDES:
|
||||
printf("%s",not? "DOES NOT INCLUDE " : "INCLUDES ");
|
||||
break;
|
||||
case MATCHES:
|
||||
printf("%s",not? "DOES NOT MATCH " : "MATCHES ");
|
||||
break;
|
||||
case EQUALS:
|
||||
printf("EQUALS ");
|
||||
break;
|
||||
@ -355,6 +400,10 @@ int pl_eval_node(MP3FILE *pmp3, PL_NODE *pnode) {
|
||||
r_arg=(int)strcasestr(cval,pnode->arg2.cval);
|
||||
retval = not ? !r_arg : r_arg;
|
||||
break;
|
||||
case MATCHES:
|
||||
r_arg = match(pnode->arg2.cval, cval, 0);
|
||||
retval = not ? r_arg : !r_arg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user