Handle streams separately in tree_add_track()
[cmus.git] / comment.c
blob7f8f0215d78af5164e48fcf53f66454a671fbafb
1 /*
2 * Copyright 2004-2007 Timo Hirvonen
3 */
5 #include "comment.h"
6 #include "xmalloc.h"
7 #include "utils.h"
9 #include <string.h>
11 const char *comments_get_albumartist(const struct keyval *comments)
13 const char *val = keyvals_get_val(comments, "albumartist");
14 if (!val)
15 val = keyvals_get_val(comments, "artist");
16 return val;
19 int comments_get_int(const struct keyval *comments, const char *key)
21 const char *val;
22 long int ival;
24 val = keyvals_get_val(comments, key);
25 if (val == NULL)
26 return -1;
27 if (str_to_int(val, &ival) == -1)
28 return -1;
29 return ival;
32 /* Return date as an integer in the form YYYYMMDD, for sorting purposes.
33 * This function is not year 10000 compliant. */
34 int comments_get_date(const struct keyval *comments, const char *key)
36 const char *val;
37 char *endptr;
38 int year, month, day;
39 long int ival;
41 val = keyvals_get_val(comments, key);
42 if (val == NULL)
43 return -1;
45 year = strtol(val, &endptr, 10);
46 /* Looking for a four-digit number */
47 if (year < 1000 || year > 9999)
48 return -1;
49 ival = year * 10000;
51 if (*endptr == '-' || *endptr == ' ' || *endptr == '/') {
52 month = strtol(endptr+1, &endptr, 10);
53 if (month < 1 || month > 12)
54 return ival;
55 ival += month * 100;
58 if (*endptr == '-' || *endptr == ' ' || *endptr == '/') {
59 day = strtol(endptr+1, &endptr, 10);
60 if (day < 1 || day > 31)
61 return ival;
62 ival += day;
66 return ival;
69 static const char *interesting[] = {
70 "artist", "album", "title", "tracknumber", "discnumber", "genre",
71 "date", "compilation", "albumartist", "artistsort", "albumartistsort",
72 "replaygain_track_gain",
73 "replaygain_track_peak",
74 "replaygain_album_gain",
75 "replaygain_album_peak",
76 "comment",
77 NULL
80 static struct {
81 const char *old;
82 const char *new;
83 } key_map[] = {
84 { "album_artist", "albumartist" },
85 { "album artist", "albumartist" },
86 { "disc", "discnumber" },
87 { "track", "tracknumber" },
88 { NULL, NULL }
91 static const char *fix_key(const char *key)
93 int i;
95 for (i = 0; interesting[i]; i++) {
96 if (!strcasecmp(key, interesting[i]))
97 return interesting[i];
99 for (i = 0; key_map[i].old; i++) {
100 if (!strcasecmp(key, key_map[i].old))
101 return key_map[i].new;
103 return NULL;
106 int comments_add(struct growing_keyvals *c, const char *key, char *val)
108 int i;
110 key = fix_key(key);
111 if (!key) {
112 free(val);
113 return 0;
116 if (!strcmp(key, "tracknumber") || !strcmp(key, "discnumber")) {
117 char *slash = strchr(val, '/');
118 if (slash)
119 *slash = 0;
122 /* don't add duplicates. can't use keyvals_get_val() */
123 for (i = 0; i < c->count; i++) {
124 if (!strcasecmp(key, c->keyvals[i].key) && !strcmp(val, c->keyvals[i].val)) {
125 free(val);
126 return 0;
130 keyvals_add(c, key, val);
131 return 1;
134 int comments_add_const(struct growing_keyvals *c, const char *key, const char *val)
136 return comments_add(c, key, xstrdup(val));