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)
#
# 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)

View File

@ -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 |

View File

@ -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; }
;

View File

@ -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;
}
}