Filter: handle yyyy-mm-dd dates
[cmus.git] / track_info.c
blobd9fa28d08a7f8c97b7a46f00622727e690ec11ea
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 "debug.h"
27 #include <string.h>
29 static void track_info_free(struct track_info *ti)
31 comments_free(ti->comments);
32 free(ti);
35 struct track_info *track_info_new(const char *filename)
37 struct track_info *ti;
38 int size = strlen(filename) + 1;
40 ti = xmalloc(sizeof(struct track_info) + size);
41 memcpy(ti->filename, filename, size);
42 ti->ref = 1;
43 return ti;
46 void track_info_ref(struct track_info *ti)
48 BUG_ON(ti->ref < 1);
49 ti->ref++;
52 void track_info_unref(struct track_info *ti)
54 BUG_ON(ti->ref < 1);
55 ti->ref--;
56 if (ti->ref == 0)
57 track_info_free(ti);
60 int track_info_has_tag(const struct track_info *ti)
62 return comments_get_val(ti->comments, "artist") ||
63 comments_get_val(ti->comments, "album") ||
64 comments_get_val(ti->comments, "title");
67 int track_info_matches(struct track_info *ti, const char *text, unsigned int flags)
69 const char *artist = comments_get_val(ti->comments, "artist");
70 const char *album = comments_get_val(ti->comments, "album");
71 const char *title = comments_get_val(ti->comments, "title");
72 char **words;
73 int i, matched = 1;
75 words = get_words(text);
76 if (words[0] == NULL)
77 matched = 0;
78 for (i = 0; words[i]; i++) {
79 const char *word = words[i];
81 if ((flags & TI_MATCH_ARTIST && artist) ||
82 (flags & TI_MATCH_ALBUM && album) ||
83 (flags & TI_MATCH_TITLE && title)) {
84 if (flags & TI_MATCH_ARTIST && artist && u_strcasestr(artist, word))
85 continue;
86 if (flags & TI_MATCH_ALBUM && album && u_strcasestr(album, word))
87 continue;
88 if (flags & TI_MATCH_TITLE && title && u_strcasestr(title, word))
89 continue;
90 } else {
91 /* compare with filename (without path) */
92 char *filename = strrchr(ti->filename, '/');
94 if (filename == NULL) {
95 filename = ti->filename;
96 } else {
97 filename++;
99 if (u_strcasestr_filename(filename, word))
100 continue;
102 matched = 0;
103 break;
105 free_str_array(words);
106 return matched;
109 static int xstrcasecmp(const char *a, const char *b)
111 if (a == NULL) {
112 if (b == NULL)
113 return 0;
114 return -1;
115 } else if (b == NULL) {
116 return 1;
118 return u_strcasecmp(a, b);
121 int track_info_cmp(const struct track_info *a, const struct track_info *b, const char * const *keys)
123 int i, res = 0;
125 for (i = 0; keys[i]; i++) {
126 const char *key = keys[i];
127 const char *av, *bv;
129 /* numeric compare for tracknumber and discnumber */
130 if (strcmp(key, "tracknumber") == 0) {
131 res = comments_get_int(a->comments, key) -
132 comments_get_int(b->comments, key);
133 if (res)
134 break;
135 continue;
137 if (strcmp(key, "discnumber") == 0) {
138 res = comments_get_int(a->comments, key) -
139 comments_get_int(b->comments, key);
140 if (res)
141 break;
142 continue;
144 if (strcmp(key, "filename") == 0) {
145 /* NOTE: filenames are not necessarily UTF-8 */
146 res = strcasecmp(a->filename, b->filename);
147 if (res)
148 break;
149 continue;
151 av = comments_get_val(a->comments, key);
152 bv = comments_get_val(b->comments, key);
153 res = xstrcasecmp(av, bv);
154 if (res)
155 break;
157 return res;