Add Timo's match patch

This commit is contained in:
Ron Pedde 2005-02-28 20:28:44 +00:00
parent 9ebe74c9fd
commit cde5f4c917
4 changed files with 58 additions and 4 deletions

View File

@ -28,13 +28,15 @@
# Date (date) # Date (date)
# #
# Valid operators include: # Valid operators include:
# is, includes (string) # is, includes (string), matches (string)
# >, <, <=, >=, = (int) # >, <, <=, >=, = (int)
# after, before (date) # after, before (date)
# #
# the "is" operator must exactly match the tag, # the "is" operator must exactly match the tag, while
# while the "includes" operator matches a substring. # the "includes" operator matches a substring and
# Both matches are case-insensitive # "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: # Valid operands include:
# "string value" (string) # "string value" (string)

View File

@ -81,6 +81,7 @@ after { yylval.ival=AFTER; return(AFTER); }
is { yylval.ival=IS; return(IS); } is { yylval.ival=IS; return(IS); }
includes { yylval.ival=INCLUDES; return(INCLUDES); } includes { yylval.ival=INCLUDES; return(INCLUDES); }
matches { yylval.ival=INCLUDES; return(MATCHES); }
= { yylval.ival=EQUALS; return(EQUALS); } = { yylval.ival=EQUALS; return(EQUALS); }
or | or |

View File

@ -72,6 +72,7 @@ int pl_number=2;
%token <ival> GREATEREQUAL %token <ival> GREATEREQUAL
%token <ival> IS %token <ival> IS
%token <ival> INCLUDES %token <ival> INCLUDES
%token <ival> MATCHES
%token <ival> OR %token <ival> OR
%token <ival> AND %token <ival> AND
@ -168,6 +169,7 @@ strtag: ARTIST
strbool: IS { $$=$1; } strbool: IS { $$=$1; }
| INCLUDES { $$=$1; } | INCLUDES { $$=$1; }
| MATCHES { $$=$1; }
| NOT strbool { $$=$2 | 0x80000000; } | NOT strbool { $$=$2 | 0x80000000; }
; ;

View File

@ -48,6 +48,48 @@ int pl_eval_node(MP3FILE *pmp3, PL_NODE *pnode);
extern FILE *yyin; 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 * pl_dump
* *
@ -150,6 +192,9 @@ void pl_dump_node(PL_NODE *pnode, int indent) {
case INCLUDES: case INCLUDES:
printf("%s",not? "DOES NOT INCLUDE " : "INCLUDES "); printf("%s",not? "DOES NOT INCLUDE " : "INCLUDES ");
break; break;
case MATCHES:
printf("%s",not? "DOES NOT MATCH " : "MATCHES ");
break;
case EQUALS: case EQUALS:
printf("EQUALS "); printf("EQUALS ");
break; break;
@ -355,6 +400,10 @@ int pl_eval_node(MP3FILE *pmp3, PL_NODE *pnode) {
r_arg=(int)strcasestr(cval,pnode->arg2.cval); r_arg=(int)strcasestr(cval,pnode->arg2.cval);
retval = not ? !r_arg : r_arg; retval = not ? !r_arg : r_arg;
break; break;
case MATCHES:
r_arg = match(pnode->arg2.cval, cval, 0);
retval = not ? r_arg : !r_arg;
break;
} }
} }