diff --git a/src/strfsong.c b/src/strfsong.c
index 3d5abd5797dfd78e50e9515f72763efabf5ee7cc..48567675d964882e41df3b6b8357da684ff4f2da 100644 (file)
--- a/src/strfsong.c
+++ b/src/strfsong.c
gchar *temp;
gsize n, length = 0;
gboolean found = FALSE;
+ /* "missed" helps handling the case of mere literal text like
+ found==TRUE instead of found==FALSE. */
+ gboolean missed = FALSE;
+
+ s[0] = '\0';
- memset(s, 0, max);
if (song == NULL)
return 0;
/* OR */
if (p[0] == '|') {
++p;
- if(!found) {
- memset(s, 0, max);
+ if(missed && !found) {
+ s[0] = '\0';
length = 0;
+ missed = FALSE;
} else {
p = skip(p);
}
/* AND */
if (p[0] == '&') {
++p;
- if(!found) {
+ if(missed && !found) {
p = skip(p);
} else {
found = FALSE;
+ missed = FALSE;
}
continue;
}
g_strlcat(s, temp, max);
length = strlen(s);
found = TRUE;
+ } else {
+ missed = TRUE;
}
g_free(temp);
continue;
/* EXPRESSION END */
if (p[0] == ']') {
if(last) *last = p+1;
- if(!found && length) {
- memset(s, 0, max);
+ if(missed && !found && length) {
+ s[0] = '\0';
length = 0;
}
return length;
/* pass-through non-escaped portions of the format string */
if (p[0] != '#' && p[0] != '%' && length<max) {
s[length++] = *p;
+ s[length] = '\0';
p++;
continue;
}
/* let the escape character escape itself */
if (p[0] == '#' && p[1] != '\0' && length<max) {
s[length++] = *(p+1);
+ s[length] = '\0';
p+=2;
continue;
}
temp = utf8_to_locale(mpd_song_get_uri(song));
else if (strncmp("%artist%", p, n) == 0)
temp = song_tag_locale(song, MPD_TAG_ARTIST);
+ else if (strncmp("%albumartist", p, n) == 0)
+ temp = song_tag_locale(song, MPD_TAG_ALBUM_ARTIST);
+ else if (strncmp("%composer%", p, n) == 0)
+ temp = song_tag_locale(song, MPD_TAG_COMPOSER);
+ else if (strncmp("%performer%", p, n) == 0)
+ temp = song_tag_locale(song, MPD_TAG_PERFORMER);
else if (strncmp("%title%", p, n) == 0)
temp = song_tag_locale(song, MPD_TAG_TITLE);
else if (strncmp("%album%", p, n) == 0)
if( temp == NULL) {
gsize templen=n;
/* just pass-through any unknown specifiers (including esc) */
- /* drop a null char in so printf stops at the end of this specifier,
- but put the real character back in (pseudo-const) */
if( length+templen > max )
templen = max-length;
- g_strlcat(s, p,max);
+ gchar *ident = g_strndup(p, templen);
+ g_strlcat(s, ident, max);
length+=templen;
+ g_free(ident);
+
+ missed = TRUE;
} else {
gsize templen = strlen(temp);