diff options
author | Kalle Wallin <kaw@linux.se> | 2004-06-14 18:32:31 +0000 |
---|---|---|
committer | Kalle Wallin <kaw@linux.se> | 2004-06-14 18:32:31 +0000 |
commit | 39758c8503fb5390afaceeff3dd5b0bca75feb97 (patch) | |
tree | 94f42a18c5cb0da8778e8525ded49fb98012bbfc /src/strfsong.c | |
parent | 7844008980d4d1b9cb7cbd4dda4ae912e12dd7a9 (diff) | |
download | mpd-39758c8503fb5390afaceeff3dd5b0bca75feb97.tar.gz mpd-39758c8503fb5390afaceeff3dd5b0bca75feb97.tar.xz mpd-39758c8503fb5390afaceeff3dd5b0bca75feb97.zip |
Major cleanup of the mpd client code (mpc->mpdclient)
git-svn-id: https://svn.musicpd.org/ncmpc/trunk@1481 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to '')
-rw-r--r-- | src/strfsong.c | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/src/strfsong.c b/src/strfsong.c new file mode 100644 index 000000000..a7eb011f8 --- /dev/null +++ b/src/strfsong.c @@ -0,0 +1,214 @@ +/* + * $Id$ + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <glib.h> + +#include "config.h" +#include "libmpdclient.h" +#include "ncmpc.h" +#include "support.h" +#include "strfsong.h" + +static char * +skip(char * p) +{ + int stack = 0; + + while (*p != '\0') { + if(*p == '[') stack++; + if(*p == '#' && p[1] != '\0') { + /* skip escaped stuff */ + ++p; + } + else if(stack) { + if(*p == ']') stack--; + } + else { + if(*p == '&' || *p == '|' || *p == ']') { + break; + } + } + ++p; + } + + return p; +} + +static gsize +_strfsong(gchar *s, + gsize max, + const gchar *format, + mpd_Song *song, + gchar **last) +{ + gchar *p, *end; + gchar *temp; + gsize n, length = 0; + gboolean found = FALSE; + + memset(s, 0, max); + if( song==NULL ) + return 0; + + for( p=(gchar *) format; *p != '\0' && length<max; ) + { + /* OR */ + if (p[0] == '|') + { + ++p; + if(!found) + { + memset(s, 0, max); + length = 0; + } + else + { + p = skip(p); + } + continue; + } + + /* AND */ + if (p[0] == '&') + { + ++p; + if(!found) + { + p = skip(p); + } + else + { + found = FALSE; + } + continue; + } + + /* EXPRESSION START */ + if (p[0] == '[') + { + temp = g_malloc0(max); + if( _strfsong(temp, max, p+1, song, &p) >0 ) + { + strncat(s, temp, max-length); + length = strlen(s); + found = TRUE; + } + g_free(temp); + continue; + } + + /* EXPRESSION END */ + if (p[0] == ']') + { + if(last) *last = p+1; + if(!found && length) + { + memset(s, 0, max); + length = 0; + } + return length; + } + + /* pass-through non-escaped portions of the format string */ + if (p[0] != '#' && p[0] != '%' && length<max) + { + strncat(s, p, 1); + length++; + ++p; + continue; + } + + /* let the escape character escape itself */ + if (p[0] == '#' && p[1] != '\0' && length<max) + { + strncat(s, p+1, 1); + length++; + p+=2; + continue; + } + + /* advance past the esc character */ + + /* find the extent of this format specifier (stop at \0, ' ', or esc) */ + temp = NULL; + end = p+1; + while(*end >= 'a' && *end <= 'z') + { + end++; + } + n = end - p + 1; + if(*end != '%') + n--; + else if (strncmp("%basename%", p, n) == 0) + temp = utf8_to_locale(basename(song->file)); + else if (strncmp("%file%", p, n) == 0) + temp = utf8_to_locale(song->file); + else if (strncmp("%artist%", p, n) == 0) + temp = song->artist ? utf8_to_locale(song->artist) : NULL; + else if (strncmp("%title%", p, n) == 0) + temp = song->title ? utf8_to_locale(song->title) : NULL; + else if (strncmp("%album%", p, n) == 0) + temp = song->album ? utf8_to_locale(song->album) : NULL; + else if (strncmp("%track%", p, n) == 0) + temp = song->track ? utf8_to_locale(song->track) : NULL; + else if (strncmp("%name%", p, n) == 0) + temp = song->name ? utf8_to_locale(song->name) : NULL; + else if (strncmp("%time%", p, n) == 0) + { + if (song->time != MPD_SONG_NO_TIME) { + gchar s[10]; + snprintf(s, 9, "%d:%d", song->time / 60, + song->time % 60 + 1); + /* nasty hack to use static buffer */ + temp = g_strdup(s); + } + } + + 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; + strncat(s, p, templen); + length+=templen; + } + else { + gsize templen = strlen(temp); + + found = TRUE; + if( length+templen > max ) + templen = max-length; + strncat(s, temp, templen); + length+=templen; + g_free(temp); + } + + /* advance past the specifier */ + p += n; + } + + if(last) *last = p; + + return length; +} + + +/* a modified version of mpc's songToFormatedString (util.c) + * added - %basename% + */ + +gsize +strfsong(gchar *s, gsize max, const gchar *format, mpd_Song *song) +{ + return _strfsong(s, max, format, song, NULL); +} + |