From ddbca125a61ae25ffd0acb782d585b9318f4d072 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Sat, 19 Mar 2022 02:15:35 -0400 Subject: [PATCH] tagtree/tagcache add new clause operators begins/ends _oneof new operators @^, @$ begins_oneof and ends_oneof albumartist @^ "L|The L" Led Zeppelin, The look albumartist @$ "girls|Boys" spice girls, beasty boys Change-Id: I26ce3d8155d970a55e003f74e2f9478db76204f1 --- apps/tagcache.c | 27 ++++++++++++++++++++++++++- apps/tagcache.h | 4 +++- apps/tagtree.c | 2 ++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/apps/tagcache.c b/apps/tagcache.c index cf0d73f0fb..5a80885819 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -56,7 +56,7 @@ */ /*#define LOGF_ENABLE*/ -/*#define LOGF_CLAUSES define to enable logf clause matching (LOGF_ENABLE req'd) */ +/*#define LOGF_CLAUSES define to enable logf clause matching (LOGF_ENABLE req'd) */ #include #include @@ -162,6 +162,8 @@ static const char *tag_type_str[] = { [clause_ends_with] = "clause_ends_with", [clause_not_ends_with] = "clause_not_ends_with", [clause_oneof] = "clause_oneof", + [clause_begins_oneof] = "clause_begins_oneof", + [clause_ends_oneof] = "clause_ends_oneof", [clause_logical_or] = "clause_logical_or" }; #define logf_clauses logf @@ -1052,6 +1054,25 @@ inline static bool str_oneof(const char *str, const char *list) return false; } +inline static bool str_begins_ends_oneof(const char *str, const char *list, bool begins) +{ + logf_clauses("%s %s (%s) %s", str, __func__, begins ? "begins" : "ends", list); + const char *sep; + int l, p, len = strlen(str); + + while (*list) + { + sep = strchr(list, '|'); + l = sep ? (intptr_t)sep - (intptr_t)list : (int)strlen(list); + p = begins ? 0 : len - l; + if (l <= len && !strncasecmp(&str[p], list, l)) + return true; + list += sep ? l + 1 : l; + } + + return false; +} + static bool check_against_clause(long numeric, const char *str, const struct tagcache_search_clause *clause) { @@ -1105,6 +1126,10 @@ static bool check_against_clause(long numeric, const char *str, return !str_ends_with(str, clause->str); case clause_oneof: return str_oneof(str, clause->str); + case clause_begins_oneof: + return str_begins_ends_oneof(str, clause->str, true); + case clause_ends_oneof: + return str_begins_ends_oneof(str, clause->str, false); default: logf("Incorrect tag: %d", clause->type); } diff --git a/apps/tagcache.h b/apps/tagcache.h index b7c4aadbb1..1218e42b42 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h @@ -127,7 +127,9 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, enum clause { clause_none, clause_is, clause_is_not, clause_gt, clause_gteq, clause_lt, clause_lteq, clause_contains, clause_not_contains, clause_begins_with, clause_not_begins_with, clause_ends_with, - clause_not_ends_with, clause_oneof, clause_logical_or }; + clause_not_ends_with, clause_oneof, + clause_begins_oneof, clause_ends_oneof, + clause_logical_or }; struct tagcache_stat { bool initialized; /* Is tagcache currently busy? */ diff --git a/apps/tagtree.c b/apps/tagtree.c index 48ef1e28ce..9fb2172e57 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c @@ -418,6 +418,8 @@ static int get_clause(int *condition) CLAUSE('!', '^', clause_not_begins_with), CLAUSE('$', ' ', clause_ends_with), CLAUSE('!', '$', clause_not_ends_with), + CLAUSE('@', '^', clause_begins_oneof), + CLAUSE('@', '$', clause_ends_oneof), CLAUSE('@', ' ', clause_oneof) };