diff options
-rw-r--r-- | src/dbUtils.c | 2 | ||||
-rw-r--r-- | src/locate.c | 24 |
2 files changed, 25 insertions, 1 deletions
diff --git a/src/dbUtils.c b/src/dbUtils.c index 1ecb9f608..fbade8012 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -295,8 +295,10 @@ static void visitTag(int fd, struct strset *set, for (i = 0; i < tag->numOfItems; i++) { if (tag->items[i]->type == tagType) { strset_add(set, tag->items[i]->value); + return; } } + strset_add(set, ""); } struct list_tags_data { diff --git a/src/locate.c b/src/locate.c index 76e229f4c..7d4a51db9 100644 --- a/src/locate.c +++ b/src/locate.c @@ -126,6 +126,7 @@ static int strstrSearchTag(Song * song, enum tag_type type, char *str) int i; char *duplicate; int ret = 0; + mpd_sint8 visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 }; if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) { char path_max_tmp[MPD_PATH_MAX]; @@ -141,17 +142,27 @@ static int strstrSearchTag(Song * song, enum tag_type type, char *str) return 0; for (i = 0; i < song->tag->numOfItems && !ret; i++) { + visitedTypes[song->tag->items[i]->type] = 1; if (type != LOCATE_TAG_ANY_TYPE && song->tag->items[i]->type != type) { continue; } duplicate = strDupToUpper(song->tag->items[i]->value); - if (strstr(duplicate, str)) + if (*str && strstr(duplicate, str)) ret = 1; free(duplicate); } + /** If the search critieron was not visited during the sweep + * through the song's tag, it means this field is absent from + * the tag or empty. Thus, if the searched string is also + * empty (first char is a \0), then it's a match as well and + * we should return 1. + */ + if (!*str && !visitedTypes[type]) + return 1; + return ret; } @@ -172,6 +183,7 @@ int strstrSearchTags(Song * song, int numItems, LocateTagItem * items) static int tagItemFoundAndMatches(Song * song, enum tag_type type, char *str) { int i; + mpd_sint8 visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 }; if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) { char path_max_tmp[MPD_PATH_MAX]; @@ -185,6 +197,7 @@ static int tagItemFoundAndMatches(Song * song, enum tag_type type, char *str) return 0; for (i = 0; i < song->tag->numOfItems; i++) { + visitedTypes[song->tag->items[i]->type] = 1; if (type != LOCATE_TAG_ANY_TYPE && song->tag->items[i]->type != type) { continue; @@ -194,6 +207,15 @@ static int tagItemFoundAndMatches(Song * song, enum tag_type type, char *str) return 1; } + /** If the search critieron was not visited during the sweep + * through the song's tag, it means this field is absent from + * the tag or empty. Thus, if the searched string is also + * empty (first char is a \0), then it's a match as well and + * we should return 1. + */ + if (!*str && !visitedTypes[type]) + return 1; + return 0; } |