From c7930c993e4624e4e6d9a50cdea448b432a2bf05 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 29 Sep 2008 03:14:33 -0700 Subject: allow searching for albums with an empty tag tfing wrote: > I have quite some files with an empty album tag as they do not come > from a particular album. > > If I want to look for those files and browse them, this happens: > :: nc localhost 6600 > OK MPD 0.12.0 > find album "" > ACK [2@0] {find} too few arguments for "find" > > I'd like to be able to browse those files in a client like gmpc. > So these 2 items would have to be developed: > - list album should report that some files have an empty tag > - it should be possible to search for an empty tag with the find command Patch-by: Marc Pavot ref: http://musicpd.org/mantis/view.php?id=464 --- src/dbUtils.c | 2 ++ src/locate.c | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src') 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; } -- cgit v1.2.3