ignore special chars that occurs in tag values

ncmpcpp shouldn't treat '$' characters that
are part of a tag as special format chars.
This commit is contained in:
Andrzej Rybczak
2009-09-26 18:29:52 +02:00
parent 3e75ff6455
commit 4efaa18927
4 changed files with 90 additions and 48 deletions

View File

@@ -221,12 +221,17 @@ void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
if (is_now_playing) if (is_now_playing)
*menu << Config.now_playing_prefix; *menu << Config.now_playing_prefix;
std::string line = s.toString(*static_cast<std::string *>(data)); std::string line = s.toString(*static_cast<std::string *>(data), "$");
for (std::string::const_iterator it = line.begin(); it != line.end(); ++it) for (std::string::const_iterator it = line.begin(); it != line.end(); ++it)
{ {
if (*it == '$') if (*it == '$')
{ {
if (isdigit(*++it)) if (++it == line.end()) // end of format
{
*menu << '$';
break;
}
else if (isdigit(*it)) // color
{ {
*menu << Color(*it-'0'); *menu << Color(*it-'0');
} }
@@ -240,8 +245,15 @@ void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
*menu << XY(menu->GetWidth()-buf.Str().length(), menu->Y()) << buf; *menu << XY(menu->GetWidth()-buf.Str().length(), menu->Y()) << buf;
return; return;
} }
else else // not a color nor right align, just a random character
*menu << *it; *menu << *--it;
}
else if (*it == MPD::Song::FormatEscapeCharacter)
{
// treat '$' as a normal character if song format escape char is prepended to it
if (++it == line.end() || *it != '$')
--it;
*menu << *it;
} }
else else
*menu << *it; *menu << *it;

View File

@@ -92,48 +92,73 @@ template <typename C> void String2Buffer(const std::basic_string<C> &s, basic_bu
{ {
for (typename std::basic_string<C>::const_iterator it = s.begin(); it != s.end(); ++it) for (typename std::basic_string<C>::const_iterator it = s.begin(); it != s.end(); ++it)
{ {
if (*it != '$') if (*it == '$')
buf << *it;
else if (isdigit(*++it))
buf << Color(*it-'0');
else
{ {
switch (*it) if (++it == s.end())
{ {
case 'b': buf << '$';
buf << fmtBold; break;
break; }
case 'u': else if (isdigit(*it))
buf << fmtUnderline; {
break; buf << Color(*it-'0');
case 'a': }
buf << fmtAltCharset; else
break; {
case 'r': switch (*it)
buf << fmtReverse; {
break; case 'b':
case '/': buf << fmtBold;
switch (*++it) break;
{ case 'u':
case 'b': buf << fmtUnderline;
buf << fmtBoldEnd; break;
case 'a':
buf << fmtAltCharset;
break;
case 'r':
buf << fmtReverse;
break;
case '/':
if (++it == s.end())
{
buf << "$/";
break; break;
case 'u': }
buf << fmtUnderlineEnd; switch (*it)
break; {
case 'a': case 'b':
buf << fmtAltCharsetEnd; buf << fmtBoldEnd;
break; break;
case 'r': case 'u':
buf << fmtReverseEnd; buf << fmtUnderlineEnd;
break; break;
} case 'a':
break; buf << fmtAltCharsetEnd;
default: break;
buf << *it; case 'r':
break; buf << fmtReverseEnd;
break;
default:
buf << '$' << *--it;
break;
}
break;
default:
buf << *--it;
break;
}
} }
} }
else if (*it == MPD::Song::FormatEscapeCharacter)
{
// treat '$' as a normal character if song format escape char is prepended to it
if (++it == s.end() || *it != '$')
--it;
buf << *it;
}
else
buf << *it;
} }
} }

View File

@@ -305,7 +305,7 @@ void MPD::Song::SetPosition(int pos)
itsSong->pos = pos; itsSong->pos = pos;
} }
std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const std::string MPD::Song::ParseFormat(std::string::const_iterator &it, const char *escape_chars) const
{ {
std::string result; std::string result;
bool has_some_tags = 0; bool has_some_tags = 0;
@@ -314,7 +314,7 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
{ {
while (*it == '{') while (*it == '{')
{ {
std::string tags = ParseFormat(it); std::string tags = ParseFormat(it, escape_chars);
if (!tags.empty()) if (!tags.empty())
{ {
has_some_tags = 1; has_some_tags = 1;
@@ -379,6 +379,10 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
if (get) if (get)
{ {
std::string tag = (this->*get)(); std::string tag = (this->*get)();
if (escape_chars) // prepend format escape character to all given chars to escape
for (const char *ch = escape_chars; *ch; ++ch)
for (size_t i = tag.find(*ch); i != std::string::npos; i = tag.find(*ch, i += 2))
tag.replace(i, 1, std::string(1, FormatEscapeCharacter) + ch);
if (!tag.empty() && (get != &MPD::Song::GetLength || GetTotalLength())) if (!tag.empty() && (get != &MPD::Song::GetLength || GetTotalLength()))
{ {
has_some_tags = 1; has_some_tags = 1;
@@ -402,7 +406,7 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
--brace_counter; --brace_counter;
} }
if (*++it == '|') if (*++it == '|')
return ParseFormat(++it); return ParseFormat(++it, escape_chars);
else else
return ""; return "";
} }
@@ -423,10 +427,10 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
} }
} }
std::string MPD::Song::toString(const std::string &format) const std::string MPD::Song::toString(const std::string &format, const char *escape_chars) const
{ {
std::string::const_iterator it = format.begin(); std::string::const_iterator it = format.begin();
return ParseFormat(it); return ParseFormat(it, escape_chars);
} }
MPD::Song &MPD::Song::operator=(const MPD::Song &s) MPD::Song &MPD::Song::operator=(const MPD::Song &s)

View File

@@ -78,7 +78,8 @@ namespace MPD
void SetNewName(const std::string &name) { itsNewName = name == GetName() ? "" : name; } void SetNewName(const std::string &name) { itsNewName = name == GetName() ? "" : name; }
std::string GetNewName() const { return itsNewName; } std::string GetNewName() const { return itsNewName; }
std::string toString(const std::string &) const; std::string toString(const std::string &, const char *escape_chars = 0) const;
static const char FormatEscapeCharacter = 1;
void NullMe() { itsSong = 0; } void NullMe() { itsSong = 0; }
void CopyPtr(bool copy) { copyPtr = copy; } void CopyPtr(bool copy) { copyPtr = copy; }
@@ -97,7 +98,7 @@ namespace MPD
private: private:
void SetHashAndSlash(); void SetHashAndSlash();
std::string ParseFormat(std::string::const_iterator &it) const; std::string ParseFormat(std::string::const_iterator &it, const char *escape_chars) const;
mpd_Song *itsSong; mpd_Song *itsSong;
std::string itsNewName; std::string itsNewName;