|
12 | 12 | #include <string.h> |
13 | 13 | #include <stdlib.h> |
14 | 14 |
|
| 15 | +/** |
| 16 | + * Append all tag entries of a given type into dest buffer. |
| 17 | + * |
| 18 | + * @param dest Pointer to current write position in buffer |
| 19 | + * @param end Pointer to the end of buffer (one past last byte) |
| 20 | + * @param song MPD song object |
| 21 | + * @param tag MPD tag type |
| 22 | + * @return Updated dest pointer after writing; If text added, null-terminated. |
| 23 | + * If no tag of this type fund, returns NULL. |
| 24 | + */ |
| 25 | +static char * |
| 26 | +copy_tags(char *dest, char *end, const struct mpd_song *song, enum mpd_tag_type tag) |
| 27 | +{ |
| 28 | + const char *value = mpd_song_get_tag(song, tag, 0); |
| 29 | + if (value == NULL) |
| 30 | + return NULL; |
| 31 | + |
| 32 | + // Get first tag separately, as it should not have a comma if it is the only entry. |
| 33 | + int written = snprintf(dest, (size_t)(end - dest), "%s", value); |
| 34 | + if (written < 0 || written >= (int)(end - dest)) |
| 35 | + return dest + (end - dest - 1); |
| 36 | + dest += written; |
| 37 | + |
| 38 | + /* mpd_song_get_tag can be called repeatedly with different index |
| 39 | + if tag has multiple entries (e.g. multiple artists) |
| 40 | + It returns nullptr when it runs out. */ |
| 41 | + for (unsigned i = 1; ; ++i) { |
| 42 | + value = mpd_song_get_tag(song, tag, i); |
| 43 | + if (value == NULL) |
| 44 | + break; |
| 45 | + |
| 46 | + // need at least room for ", " + \0 |
| 47 | + if ((size_t)(end - dest) <= 2) |
| 48 | + break; |
| 49 | + *dest++ = ','; |
| 50 | + *dest++ = ' '; |
| 51 | + |
| 52 | + written = snprintf(dest, (size_t)(end - dest), "%s", value); |
| 53 | + if (written < 0 || written >= (int)(end - dest)) |
| 54 | + break; |
| 55 | + dest += written; |
| 56 | + } |
| 57 | + |
| 58 | + return dest; |
| 59 | +} |
| 60 | + |
15 | 61 | static const char * |
16 | 62 | format_mtime(char *buffer, size_t buffer_size, |
17 | 63 | const struct mpd_song *song, const char *format) |
@@ -44,7 +90,9 @@ gcc_pure |
44 | 90 | static const char * |
45 | 91 | song_value(const struct mpd_song *song, const char *name) |
46 | 92 | { |
47 | | - static char buffer[40]; |
| 93 | + /* Arbitrary size. |
| 94 | + Should be large enough to fit multiple artists with long names */ |
| 95 | + static char buffer[256]; |
48 | 96 | const char *value; |
49 | 97 |
|
50 | 98 | if (strcmp(name, "file") == 0) |
@@ -85,7 +133,12 @@ song_value(const struct mpd_song *song, const char *name) |
85 | 133 | if (tag_type == MPD_TAG_UNKNOWN) |
86 | 134 | return NULL; |
87 | 135 |
|
88 | | - value = mpd_song_get_tag(song, tag_type, 0); |
| 136 | + const char *added_text = copy_tags(buffer, buffer + sizeof(buffer), song, tag_type); |
| 137 | + if (added_text != NULL) { |
| 138 | + value = buffer; |
| 139 | + } |
| 140 | + else |
| 141 | + value = NULL; |
89 | 142 | } |
90 | 143 |
|
91 | 144 | if (value != NULL) |
|
0 commit comments