cmus-remote: Read command results
[cmus.git] / track_info.c
blob2b356f706cb17f1adaa0c2dfdfde073b99afe9ec
1 /*
2 * Copyright 2004-2005 Timo Hirvonen
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 * 02111-1307, USA.
20 #include "track_info.h"
21 #include "comment.h"
22 #include "uchar.h"
23 #include "misc.h"
24 #include "xmalloc.h"
25 #include "utils.h"
26 #include "debug.h"
28 #include <string.h>
30 static void track_info_free(struct track_info *ti)
32 comments_free(ti->comments);
33 free(ti);
36 struct track_info *track_info_new(const char *filename)
38 struct track_info *ti;
39 int size = strlen(filename) + 1;
41 ti = xmalloc(sizeof(struct track_info) + size);
42 memcpy(ti->filename, filename, size);
43 ti->ref = 1;
44 return ti;
47 void track_info_ref(struct track_info *ti)
49 BUG_ON(ti->ref < 1);
50 ti->ref++;
53 void track_info_unref(struct track_info *ti)
55 BUG_ON(ti->ref < 1);
56 ti->ref--;
57 if (ti->ref == 0)
58 track_info_free(ti);
61 int track_info_has_tag(const struct track_info *ti)
63 return comments_get_val(ti->comments, "artist") ||
64 comments_get_val(ti->comments, "album") ||
65 comments_get_val(ti->comments, "title");
68 int track_info_matches(struct track_info *ti, const char *text, unsigned int flags)
70 const char *artist = comments_get_val(ti->comments, "artist");
71 const char *album = comments_get_val(ti->comments, "album");
72 const char *title = comments_get_val(ti->comments, "title");
73 char **words;
74 int i, matched = 1;
76 words = get_words(text);
77 if (words[0] == NULL)
78 matched = 0;
79 for (i = 0; words[i]; i++) {
80 const char *word = words[i];
82 if ((flags & TI_MATCH_ARTIST && artist) ||
83 (flags & TI_MATCH_ALBUM && album) ||
84 (flags & TI_MATCH_TITLE && title)) {
85 if (flags & TI_MATCH_ARTIST && artist && u_strcasestr(artist, word))
86 continue;
87 if (flags & TI_MATCH_ALBUM && album && u_strcasestr(album, word))
88 continue;
89 if (flags & TI_MATCH_TITLE && title && u_strcasestr(title, word))
90 continue;
91 } else {
92 /* compare with url or filename without path */
93 char *filename = ti->filename;
95 if (!is_url(filename)) {
96 char *slash = strrchr(ti->filename, '/');
97 if (slash)
98 filename = slash + 1;
100 if (u_strcasestr_filename(filename, word))
101 continue;
103 matched = 0;
104 break;
106 free_str_array(words);
107 return matched;
110 static int xstrcasecmp(const char *a, const char *b)
112 if (a == NULL) {
113 if (b == NULL)
114 return 0;
115 return -1;
116 } else if (b == NULL) {
117 return 1;
119 return u_strcasecmp(a, b);
122 int track_info_cmp(const struct track_info *a, const struct track_info *b, const char * const *keys)
124 int i, res = 0;
126 for (i = 0; keys[i]; i++) {
127 const char *key = keys[i];
128 const char *av, *bv;
130 /* numeric compare for tracknumber and discnumber */
131 if (strcmp(key, "tracknumber") == 0) {
132 res = comments_get_int(a->comments, key) -
133 comments_get_int(b->comments, key);
134 if (res)
135 break;
136 continue;
138 if (strcmp(key, "discnumber") == 0) {
139 res = comments_get_int(a->comments, key) -
140 comments_get_int(b->comments, key);
141 if (res)
142 break;
143 continue;
145 if (strcmp(key, "filename") == 0) {
146 /* NOTE: filenames are not necessarily UTF-8 */
147 res = strcasecmp(a->filename, b->filename);
148 if (res)
149 break;
150 continue;
152 if (strcmp(key, "albumartist") == 0) {
153 av = comments_get_albumartist(a->comments);
154 bv = comments_get_albumartist(b->comments);
155 res = xstrcasecmp(av, bv);
156 if (res)
157 break;
158 continue;
161 av = comments_get_val(a->comments, key);
162 bv = comments_get_val(b->comments, key);
163 res = xstrcasecmp(av, bv);
164 if (res)
165 break;
167 return res;