aboutsummaryrefslogtreecommitdiffstats
path: root/src/locate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/locate.c')
-rw-r--r--src/locate.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/locate.c b/src/locate.c
new file mode 100644
index 000000000..931a566ad
--- /dev/null
+++ b/src/locate.c
@@ -0,0 +1,193 @@
+#include "locate.h"
+
+#include "utils.h"
+
+#define LOCATE_TAG_FILE_KEY SONG_FILE
+#define LOCATE_TAG_FILE_KEY_OLD "filename"
+#define LOCATE_TAG_ANY_KEY "any"
+
+int getLocateTagItemType(char *str)
+{
+ int i;
+
+ if (0 == strcasecmp(str, LOCATE_TAG_FILE_KEY) ||
+ 0 == strcasecmp(str, LOCATE_TAG_FILE_KEY_OLD))
+ {
+ return LOCATE_TAG_FILE_TYPE;
+ }
+
+ if (0 == strcasecmp(str, LOCATE_TAG_ANY_KEY))
+ {
+ return LOCATE_TAG_ANY_TYPE;
+ }
+
+ for (i = 0; i < TAG_NUM_OF_ITEM_TYPES; i++)
+ {
+ if (0 == strcasecmp(str, mpdTagItemKeys[i]))
+ return i;
+ }
+
+ return -1;
+}
+
+static int initLocateTagItem(LocateTagItem * item, char *typeStr, char *needle)
+{
+ item->tagType = getLocateTagItemType(typeStr);
+
+ if (item->tagType < 0)
+ return -1;
+
+ item->needle = xstrdup(needle);
+
+ return 0;
+}
+
+LocateTagItem *newLocateTagItem(char *typeStr, char *needle)
+{
+ LocateTagItem *ret = xmalloc(sizeof(LocateTagItem));
+
+ if (initLocateTagItem(ret, typeStr, needle) < 0) {
+ free(ret);
+ ret = NULL;
+ }
+
+ return ret;
+}
+
+void freeLocateTagItemArray(int count, LocateTagItem * array)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ free(array[i].needle);
+
+ free(array);
+}
+
+int newLocateTagItemArrayFromArgArray(char *argArray[],
+ int numArgs, LocateTagItem ** arrayRet)
+{
+ int i, j;
+ LocateTagItem *item;
+
+ if (numArgs == 0)
+ return 0;
+
+ if (numArgs % 2 != 0)
+ return -1;
+
+ *arrayRet = xmalloc(sizeof(LocateTagItem) * numArgs / 2);
+
+ for (i = 0, item = *arrayRet; i < numArgs / 2; i++, item++) {
+ if (initLocateTagItem
+ (item, argArray[i * 2], argArray[i * 2 + 1]) < 0)
+ goto fail;
+ }
+
+ return numArgs / 2;
+
+fail:
+ for (j = 0; j < i; j++) {
+ free((*arrayRet)[j].needle);
+ }
+
+ free(*arrayRet);
+ *arrayRet = NULL;
+ return -1;
+}
+
+void freeLocateTagItem(LocateTagItem * item)
+{
+ free(item->needle);
+ free(item);
+}
+
+static int strstrSearchTag(Song * song, int type, char *str)
+{
+ int i;
+ char *dup;
+ int ret = 0;
+
+ if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
+ dup = strDupToUpper(getSongUrl(song));
+ if (strstr(dup, str))
+ ret = 1;
+ free(dup);
+ if (ret == 1 || type == LOCATE_TAG_FILE_TYPE) {
+ return ret;
+ }
+ }
+
+ if (!song->tag)
+ return 0;
+
+ for (i = 0; i < song->tag->numOfItems && !ret; i++) {
+ if (type != LOCATE_TAG_ANY_TYPE &&
+ song->tag->items[i].type != type) {
+ continue;
+ }
+
+ dup = strDupToUpper(song->tag->items[i].value);
+ if (strstr(dup, str))
+ ret = 1;
+ free(dup);
+ }
+
+ return ret;
+}
+
+int strstrSearchTags(Song * song, int numItems, LocateTagItem * items)
+{
+ int i;
+
+ for (i = 0; i < numItems; i++) {
+ if (!strstrSearchTag(song, items[i].tagType,
+ items[i].needle)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int tagItemFoundAndMatches(Song * song, int type, char *str)
+{
+ int i;
+
+ if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
+ if (0 == strcmp(str, getSongUrl(song)))
+ return 1;
+ if (type == LOCATE_TAG_FILE_TYPE)
+ return 0;
+ }
+
+ if (!song->tag)
+ return 0;
+
+ for (i = 0; i < song->tag->numOfItems; i++) {
+ if (type != LOCATE_TAG_ANY_TYPE &&
+ song->tag->items[i].type != type) {
+ continue;
+ }
+
+ if (0 == strcmp(str, song->tag->items[i].value))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int tagItemsFoundAndMatches(Song * song, int numItems, LocateTagItem * items)
+{
+ int i;
+
+ for (i = 0; i < numItems; i++) {
+ if (!tagItemFoundAndMatches(song, items[i].tagType,
+ items[i].needle)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}