From 8ad1a04b681b988330381f41b6509d6809cc3298 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Fri, 14 Aug 2009 00:30:17 +0200 Subject: [PATCH] song format: support for nested braces --- src/display.cpp | 120 +++++---------------------- src/song.cpp | 211 ++++++++++++++++++++++++------------------------ src/song.h | 1 + 3 files changed, 128 insertions(+), 204 deletions(-) diff --git a/src/display.cpp b/src/display.cpp index f0499fe9..42800938 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -23,6 +23,20 @@ #include "helpers.h" #include "playlist.h" +namespace +{ + template void ParseColors(const std::basic_string &s, T &buf) + { + for (typename std::basic_string::const_iterator it = s.begin(); it != s.end(); ++it) + { + if (*it == '$') + buf << Color(*++it-'0'); + else + buf << *it; + } + } +} + std::string Display::Columns() { if (Config.columns.empty()) @@ -208,109 +222,18 @@ void Display::Songs(const MPD::Song &s, void *data, Menu *menu) basic_buffer buf; bool right = 0; - std::string::const_iterator goto_pos, prev_pos; - for (std::string::const_iterator it = song_template.begin(); it != song_template.end(); ++it) { - CHECK_LINKED_TAGS:; - if (*it == '{') + while (*it == '{') { - prev_pos = it; - MPD::Song::GetFunction get = 0; - for (; *it != '}'; ++it) - { - if (*it == '%') - { - switch (*++it) - { - case 'l': - get = &MPD::Song::GetLength; - break; - case 'F': - get = &MPD::Song::GetFile; - break; - case 'f': - get = &MPD::Song::GetName; - break; - case 'a': - get = &MPD::Song::GetArtist; - break; - case 'b': - get = &MPD::Song::GetAlbum; - break; - case 'y': - get = &MPD::Song::GetDate; - break; - case 'n': - get = &MPD::Song::GetTrack; - break; - case 'g': - get = &MPD::Song::GetGenre; - break; - case 'c': - get = &MPD::Song::GetComposer; - break; - case 'p': - get = &MPD::Song::GetPerformer; - break; - case 'd': - get = &MPD::Song::GetDisc; - break; - case 'C': - get = &MPD::Song::GetComment; - break; - case 't': - get = &MPD::Song::GetTitle; - break; - default: - break; - } - if (get == &MPD::Song::GetLength) - { - if (!s.GetTotalLength()) - break; - } - else if (get) - { - if ((s.*get)().empty()) - break; - } - } - } - if (*it == '}') - { - while (1) - { - if (*it == '}' && *(it+1) != '|') - break; - ++it; - } - goto_pos = ++it; - it = ++prev_pos; - } + std::string tags = s.Format_ParseBraces(it, song_template.end()); + if (!right) + ParseColors(tags, *menu); else - { - for (; *it != '}'; ++it) { } - ++it; - if (it == song_template.end()) - break; - if (*it == '{' || *it == '|') - { - if (*it == '|') - ++it; - goto CHECK_LINKED_TAGS; - } - } - } - - if (*it == '}') - { - if (goto_pos == song_template.end()) - break; - it = goto_pos; - if (*it == '{') - goto CHECK_LINKED_TAGS; + ParseColors(TO_WSTRING(tags), buf); } + if (it == song_template.end()) + break; if (*it != '%' && *it != '$') { @@ -416,6 +339,7 @@ void Display::Songs(const MPD::Song &s, void *data, Menu *menu) else buf << Color(*it-'0'); } + } if (right) { diff --git a/src/song.cpp b/src/song.cpp index dc97cf5d..5346dbec 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -289,118 +289,115 @@ void MPD::Song::SetPosition(int pos) itsSong->pos = pos; } +std::string MPD::Song::Format_ParseBraces(std::string::const_iterator &it, std::string::const_iterator end_it) const +{ + std::string result; + bool has_some_tags = 0; + MPD::Song::GetFunction get = 0; + while (*++it != '}') + { + while (*it == '{') + { + std::string tags = Format_ParseBraces(it, end_it); + if (!tags.empty()) + { + has_some_tags = 1; + result += tags; + } + } + if (*it == '}') + break; + else if (it == end_it) + return ""; + + if (*it == '%') + { + switch (*++it) + { + case 'l': + get = &MPD::Song::GetLength; + break; + case 'F': + get = &MPD::Song::GetFile; + break; + case 'f': + get = &MPD::Song::GetName; + break; + case 'a': + get = &MPD::Song::GetArtist; + break; + case 'b': + get = &MPD::Song::GetAlbum; + break; + case 'y': + get = &MPD::Song::GetDate; + break; + case 'n': + get = &MPD::Song::GetTrack; + break; + case 'g': + get = &MPD::Song::GetGenre; + break; + case 'c': + get = &MPD::Song::GetComposer; + break; + case 'p': + get = &MPD::Song::GetPerformer; + break; + case 'd': + get = &MPD::Song::GetDisc; + break; + case 'C': + get = &MPD::Song::GetComment; + break; + case 't': + get = &MPD::Song::GetTitle; + break; + default: + break; + } + if (get) + { + std::string tag = (this->*get)(); + if (!tag.empty() && (get != &MPD::Song::GetLength || GetTotalLength())) + { + has_some_tags = 1; + result += tag; + } + else + break; + } + } + else + result += *it; + } + if (*it != '}' || !has_some_tags) + { + for (; *it != '}'; ++it) { } + if (*++it == '|') + return Format_ParseBraces(++it, end_it); + else + return ""; + } + else + { + if (*++it == '|') + for (; *it != '}' || *++it == '|'; ++it) { } + return result; + } +} + std::string MPD::Song::toString(const std::string &format) const { std::string result; - std::string::const_iterator goto_pos, prev_pos; - for (std::string::const_iterator it = format.begin(); it != format.end(); ++it) { - CHECK_LINKED_TAGS:; - if (*it == '{') - { - prev_pos = it; - GetFunction get = 0; - for (; *it != '}'; ++it) - { - if (*it == '%') - { - switch (*++it) - { - case 'l': - get = &Song::GetLength; - break; - case 'F': - get = &Song::GetFile; - break; - case 'f': - get = &Song::GetName; - break; - case 'a': - get = &Song::GetArtist; - break; - case 'b': - get = &Song::GetAlbum; - break; - case 'y': - get = &Song::GetDate; - break; - case 'n': - get = &Song::GetTrack; - break; - case 'g': - get = &Song::GetGenre; - break; - case 'c': - get = &Song::GetComposer; - break; - case 'p': - get = &Song::GetPerformer; - break; - case 'd': - get = &Song::GetDisc; - break; - case 'C': - get = &Song::GetComment; - break; - case 't': - get = &Song::GetTitle; - break; - default: - break; - } - if (get == &Song::GetLength) - { - if (!GetTotalLength()) - break; - } - else if (get) - { - if ((this->*get)().empty()) - break; - } - } - } - if (*it == '}') - { - while (1) - { - if (*it == '}' && *(it+1) != '|') - break; - ++it; - } - goto_pos = ++it; - it = ++prev_pos; - } - else - { - for (; *it != '}'; ++it) { } - ++it; - if (it == format.end()) - break; - if (*it == '{' || *it == '|') - { - if (*it == '|') - ++it; - goto CHECK_LINKED_TAGS; - } - } - } + while (*it == '{') + result += Format_ParseBraces(it, format.end()); + if (it == format.end()) + break; - if (*it == '}') - { - if (goto_pos == format.end()) - break; - it = goto_pos; - if (*it == '{') - goto CHECK_LINKED_TAGS; - } - - if (*it != '%') - { - result += *it; - } - else if (*it == '%') + if (*it == '%') { switch (*++it) { @@ -447,6 +444,8 @@ std::string MPD::Song::toString(const std::string &format) const break; } } + else + result += *it; } return result; } diff --git a/src/song.h b/src/song.h index de69223d..bb0ca0b3 100644 --- a/src/song.h +++ b/src/song.h @@ -92,6 +92,7 @@ namespace MPD Song &operator=(const Song &); static std::string ShowTime(int); + std::string Format_ParseBraces(std::string::const_iterator &it, std::string::const_iterator end_it) const; private: void SetHashAndSlash();