#include <taglib/tstringlist.h>
#include <getopt.h>
#include <vector>
+#include <sstream>
using namespace std;
enum action {LIST, REPLACE, INSERT, ERASE, AUDIO};
typedef pair<action,string> actionpair;
typedef vector<actionpair> actionqueue;
-typedef pair<string,string> tagpair;
+typedef pair<TagLib::String,TagLib::StringList> 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)
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)
"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"
" 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[])
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;
}