diff --git a/src/strfsong.c b/src/strfsong.c
index 39e0c52a0fa9a37541904dd273e5d9445f76ebc7..b64c350ba6dace76d83b8c70f0dd49d591b1eefc 100644 (file)
--- a/src/strfsong.c
+++ b/src/strfsong.c
/* ncmpc (Ncurses MPD Client)
/* ncmpc (Ncurses MPD Client)
- * (c) 2004-2009 The Music Player Daemon Project
+ * (c) 2004-2017 The Music Player Daemon Project
* Project homepage: http://musicpd.org
* Project homepage: http://musicpd.org
-
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
-
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
#include "strfsong.h"
#include "charset.h"
#include "strfsong.h"
#include "charset.h"
-#include "utils.h"
+#include "time_format.h"
#include <mpd/client.h>
#include <mpd/client.h>
const char *first)
{
const char *p = mpd_song_get_tag(song, tag, 1);
const char *first)
{
const char *p = mpd_song_get_tag(song, tag, 1);
- char *buffer, *prev;
-
if (p == NULL)
return NULL;
if (p == NULL)
return NULL;
- buffer = concat_tag_values(first, p);
+ char *buffer = concat_tag_values(first, p);
for (unsigned i = 2; (p = mpd_song_get_tag(song, tag, i)) != NULL;
++i) {
for (unsigned i = 2; (p = mpd_song_get_tag(song, tag, i)) != NULL;
++i) {
- prev = buffer;
+ char *prev = buffer;
buffer = concat_tag_values(buffer, p);
g_free(prev);
}
buffer = concat_tag_values(buffer, p);
g_free(prev);
}
song_tag_locale(const struct mpd_song *song, enum mpd_tag_type tag)
{
const char *value = mpd_song_get_tag(song, tag, 0);
song_tag_locale(const struct mpd_song *song, enum mpd_tag_type tag)
{
const char *value = mpd_song_get_tag(song, tag, 0);
- char *result;
-#ifndef NCMPC_MINI
- char *all;
-#endif /* !NCMPC_MINI */
-
if (value == NULL)
return NULL;
#ifndef NCMPC_MINI
if (value == NULL)
return NULL;
#ifndef NCMPC_MINI
- all = song_more_tag_values(song, tag, value);
+ char *all = song_more_tag_values(song, tag, value);
if (all != NULL)
value = all;
#endif /* !NCMPC_MINI */
if (all != NULL)
value = all;
#endif /* !NCMPC_MINI */
- result = utf8_to_locale(value);
+ char *result = utf8_to_locale(value);
#ifndef NCMPC_MINI
g_free(all);
#ifndef NCMPC_MINI
g_free(all);
const struct mpd_song *song,
const gchar **last)
{
const struct mpd_song *song,
const gchar **last)
{
- const gchar *p, *end;
- gchar *temp;
- gsize n, length = 0;
- gboolean found = FALSE;
+ bool found = false;
+ /* "missed" helps handling the case of mere literal text like
+ found==true instead of found==false. */
+ bool missed = false;
+
+ s[0] = '\0';
- memset(s, 0, max);
if (song == NULL)
return 0;
if (song == NULL)
return 0;
+ const char *p;
+ size_t length = 0;
for (p = format; *p != '\0' && length<max;) {
/* OR */
if (p[0] == '|') {
++p;
for (p = format; *p != '\0' && length<max;) {
/* OR */
if (p[0] == '|') {
++p;
- if(!found) {
- memset(s, 0, max);
+ if(missed && !found) {
+ s[0] = '\0';
length = 0;
length = 0;
+ missed = false;
} else {
p = skip(p);
}
} else {
p = skip(p);
}
/* AND */
if (p[0] == '&') {
++p;
/* AND */
if (p[0] == '&') {
++p;
- if(!found) {
+ if(missed && !found) {
p = skip(p);
} else {
p = skip(p);
} else {
- found = FALSE;
+ found = false;
+ missed = false;
}
continue;
}
/* EXPRESSION START */
if (p[0] == '[') {
}
continue;
}
/* EXPRESSION START */
if (p[0] == '[') {
- temp = g_malloc0(max);
+ char *temp = g_malloc0(max);
if( _strfsong(temp, max, p+1, song, &p) >0 ) {
g_strlcat(s, temp, max);
length = strlen(s);
if( _strfsong(temp, max, p+1, song, &p) >0 ) {
g_strlcat(s, temp, max);
length = strlen(s);
- found = TRUE;
+ found = true;
+ } else {
+ missed = true;
}
g_free(temp);
continue;
}
g_free(temp);
continue;
/* EXPRESSION END */
if (p[0] == ']') {
if(last) *last = p+1;
/* 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;
length = 0;
}
return length;
/* pass-through non-escaped portions of the format string */
if (p[0] != '#' && p[0] != '%' && length<max) {
s[length++] = *p;
/* pass-through non-escaped portions of the format string */
if (p[0] != '#' && p[0] != '%' && length<max) {
s[length++] = *p;
+ s[length] = '\0';
p++;
continue;
}
p++;
continue;
}
/* let the escape character escape itself */
if (p[0] == '#' && p[1] != '\0' && length<max) {
s[length++] = *(p+1);
/* let the escape character escape itself */
if (p[0] == '#' && p[1] != '\0' && length<max) {
s[length++] = *(p+1);
+ s[length] = '\0';
p+=2;
continue;
}
p+=2;
continue;
}
/* advance past the esc character */
/* find the extent of this format specifier (stop at \0, ' ', or esc) */
/* advance past the esc character */
/* find the extent of this format specifier (stop at \0, ' ', or esc) */
- temp = NULL;
- end = p+1;
+ char *temp = NULL;
+ const char *end = p + 1;
while(*end >= 'a' && *end <= 'z') {
end++;
}
while(*end >= 'a' && *end <= 'z') {
end++;
}
- n = end - p + 1;
+ size_t n = end - p + 1;
if(*end != '%')
n--;
else if (strncmp("%file%", p, n) == 0)
temp = utf8_to_locale(mpd_song_get_uri(song));
if(*end != '%')
n--;
else if (strncmp("%file%", p, n) == 0)
temp = utf8_to_locale(mpd_song_get_uri(song));
- else if (strncmp("%artist%", p, n) == 0)
+ else if (strncmp("%artist%", p, n) == 0) {
temp = song_tag_locale(song, MPD_TAG_ARTIST);
temp = song_tag_locale(song, MPD_TAG_ARTIST);
- else if (strncmp("%title%", p, n) == 0)
+ if (temp == NULL) {
+ temp = song_tag_locale(song, MPD_TAG_PERFORMER);
+ if (temp == NULL)
+ temp = song_tag_locale(song, MPD_TAG_COMPOSER);
+ }
+ } 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);
temp = song_tag_locale(song, MPD_TAG_TITLE);
- else if (strncmp("%album%", p, n) == 0)
+ if (temp == NULL)
+ temp = song_tag_locale(song, MPD_TAG_NAME);
+ } else if (strncmp("%album%", p, n) == 0)
temp = song_tag_locale(song, MPD_TAG_ALBUM);
else if (strncmp("%shortalbum%", p, n) == 0) {
temp = song_tag_locale(song, MPD_TAG_ALBUM);
temp = song_tag_locale(song, MPD_TAG_ALBUM);
else if (strncmp("%shortalbum%", p, n) == 0) {
temp = song_tag_locale(song, MPD_TAG_ALBUM);
}
else if (strncmp("%track%", p, n) == 0)
temp = song_tag_locale(song, MPD_TAG_TRACK);
}
else if (strncmp("%track%", p, n) == 0)
temp = song_tag_locale(song, MPD_TAG_TRACK);
+ else if (strncmp("%disc%", p, n) == 0)
+ temp = song_tag_locale(song, MPD_TAG_DISC);
else if (strncmp("%name%", p, n) == 0)
temp = song_tag_locale(song, MPD_TAG_NAME);
else if (strncmp("%date%", p, n) == 0)
else if (strncmp("%name%", p, n) == 0)
temp = song_tag_locale(song, MPD_TAG_NAME);
else if (strncmp("%date%", p, n) == 0)
if( temp == NULL) {
gsize templen=n;
/* just pass-through any unknown specifiers (including esc) */
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;
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;
length+=templen;
+ g_free(ident);
+
+ missed = true;
} else {
gsize templen = strlen(temp);
} else {
gsize templen = strlen(temp);
- found = TRUE;
+ found = true;
if( length+templen > max )
templen = max-length;
g_strlcat(s, temp, max);
if( length+templen > max )
templen = max-length;
g_strlcat(s, temp, max);