From d2fdf4b137a60be9d899663f5f7d176d0659a47b Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Mon, 9 Feb 2015 00:33:01 +0100 Subject: [PATCH] Added backslash escape of equal signs in tags. --- usetaglib.cpp | 78 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/usetaglib.cpp b/usetaglib.cpp index 43f60bd..d8d51ed 100644 --- a/usetaglib.cpp +++ b/usetaglib.cpp @@ -23,35 +23,56 @@ #include #include #include +#include using namespace std; enum action {LIST, REPLACE, INSERT, ERASE, AUDIO}; typedef pair actionpair; typedef vector actionqueue; -typedef pair tagpair; +typedef pair keyandvalues; -TagLib::StringList argToStringList (const string &rawtagarg) +keyandvalues toKeyAndValues (const string &rawstring) { - TagLib::StringList newlist; - - size_t delpos = 0; - while (1) { - size_t nextdelpos = rawtagarg.find('=', delpos+1); - if (nextdelpos == -1) - break; - newlist.append(rawtagarg.substr(delpos,nextdelpos-delpos)); - delpos = nextdelpos+1; + stringstream tmpss; + TagLib::String key; + TagLib::StringList values; + int isplit=0; + + for (int ipos=0; ipos < rawstring.length(); ipos++) { + if ( rawstring[ipos] == '\\' ) { + switch (rawstring[ipos+1]) { + case '\\': + tmpss << '\\'; + break; + case '=': + tmpss << '='; + break; + default: + tmpss << '\\' << rawstring[ipos+1]; + break; + } + ipos++; + } + else + if ( rawstring[ipos] == '=' ) { + if ( isplit == 0 ) + key = tmpss.str(); + else + values.append(tmpss.str()); + isplit++; + tmpss.str(""); + } + else + tmpss << rawstring[ipos]; } - newlist.append(rawtagarg.substr(delpos,string::npos)); - - return newlist; -} -tagpair splitToTagPair (const string &rawarg) -{ - const size_t delpos = rawarg.find('='); - return make_pair(rawarg.substr(0, delpos), rawarg.substr(delpos+1, string::npos)); + if (isplit==0) + key = tmpss.str(); + else + values.append(tmpss.str()); + + return make_pair(key, values); } void action_eraseTag (TagLib::PropertyMap &propmap, const string &key) @@ -59,14 +80,14 @@ void action_eraseTag (TagLib::PropertyMap &propmap, const string &key) propmap.erase(key); } -void action_replaceTag (TagLib::PropertyMap &propmap, const tagpair &tagPair) +void action_replaceTag (TagLib::PropertyMap &propmap, const keyandvalues &keyAndValues) { - propmap.replace(tagPair.first, argToStringList(tagPair.second)); + propmap.replace(keyAndValues.first, keyAndValues.second); } -void action_insertTag (TagLib::PropertyMap &propmap, const tagpair &tagPair) +void action_insertTag (TagLib::PropertyMap &propmap, const keyandvalues &keyAndValues) { - propmap.insert(tagPair.first, argToStringList(tagPair.second)); + propmap.insert(keyAndValues.first, keyAndValues.second); } int action_printTags (const TagLib::FileRef f, TagLib::PropertyMap &propmap) @@ -145,7 +166,9 @@ void printExtraHelp () "TAGVAL\n" " TAGVAL has to be either a single string or a list of strings separated\n" " by equal signs (=). If a list is given, multiple tags of type TAGNAME\n" - " will be created and set to the respective values given in the list.\n" + " will be created and set to the respective values given by the list.\n" + " Note that equal signs have to be escaped with a leading backslash (\\=),\n" + " if they shall not be interpreted as list separators.\n" "\n" "EXAMPLES\n" " usetaglib file.ogg\n" @@ -153,7 +176,8 @@ void printExtraHelp () " usetaglib -r \"ALBUM=New Album\" -i ARTIST=Horst=Hubert file.mp3\n" " usetaglib -r ARTIST=Horst -l file1.ogg file2.mp3\n" " usetaglib -i \"ALBUMARTIST=Horst und Hubert\" file.ogg\n" - " usetaglib --insert=\"ALBUMARTIST=Horst und Hubert\" file.ogg\n"; + " usetaglib --insert=\"ALBUMARTIST=Horst und Hubert\" file.ogg\n" + " usetaglib --replace='ARTIST=This Band \\= Great' file.ogg\n"; } int main(int argc, char *argv[]) @@ -253,11 +277,11 @@ int main(int argc, char *argv[]) FCHANGED = true; break; case REPLACE: - action_replaceTag(propmap, splitToTagPair(actit->second)); + action_replaceTag(propmap, toKeyAndValues(actit->second)); FCHANGED = true; break; case INSERT: - action_insertTag(propmap, splitToTagPair(actit->second)); + action_insertTag(propmap, toKeyAndValues(actit->second)); FCHANGED = true; break; } -- 2.39.2