--- id3v2-0.1.11.orig/id3v2.cpp 2004-05-04 14:30:15.000000000 -0400 +++ id3v2-0.1.11/id3v2.cpp 2005-08-25 10:27:13.000000000 -0400 @@ -7,6 +7,7 @@ #include #include #include +#include #include #ifdef WIN32 #include @@ -42,6 +43,7 @@ std::cout << " -C, --convert Converts id3v1 tag to id3v2" << std::endl; std::cout << " -1, --id3v1-only Writes only id3v1 tag" << std::endl; std::cout << " -2, --id3v2-only Writes only id3v2 tag" << std::endl; + std::cout << " -o, --format Obtain tag info from filename format" << std::endl; std::cout << " -a, --artist \"ARTIST\" Set the artist information" << std::endl; std::cout << " -A, --album \"ALBUM\" Set the album title information" << std::endl; std::cout << " -t, --song \"SONG\" Set the song title information" << std::endl; @@ -57,6 +59,7 @@ std::cout << " id3v2 --TIT3 \"Monkey!\" file.mp3" << std::endl; std::cout << "would set the \"Subtitle/Description\" frame to \"Monkey!\". " << std::endl; std::cout << std::endl; + std::cout << "Filename format expandos: %a=artist, %A=album, %t=song, %T=track" << std::endl; } @@ -82,6 +85,68 @@ extern void InitGenres(); #endif // SORT_RUNTIME +struct frameInfo { + enum ID3_FrameID id; + char *data; +} frameList[MAXNOFRAMES]; + +int frameCounter = 0; + +static void parse_expando(char **str, char **format, ID3_FrameID which) +{ + char buf[255], *p = buf; + char *s = *str; + char *f = *format; + int i; + int done = 0; + + f++; + + while (isspace(*f)) + f++; + + while (*s) { + if (*s == *f) + break; + + *p++ = *s++; + } + + *p = '\0'; + p = buf; + p += strlen(buf) - 1; + + while (*p && isspace(*p)) + *p-- = '\0'; + + p = buf; + + while (*p && isspace(*p)) + *p++; + + if (which == ID3FID_TRACKNUM) { + while (*p == '0') + *p++; + } + + for (i = 0; i < frameCounter; i++) { + if (frameList[i].id == which) { + frameList[i].data = strdup(p); + done = 1; + break; + } + } + + if (!done) { + frameList[frameCounter].id = which; + frameList[frameCounter].data = strdup(p); + frameCounter++; + } + + *str = s; + *format = f; +} + int main( int argc, char *argv[]) { int iOpt; @@ -89,13 +154,7 @@ int ii; char tmp[TMPSIZE]; FILE * fp; - - struct frameInfo { - enum ID3_FrameID id; - char *data; - } frameList[MAXNOFRAMES]; - - int frameCounter = 0; + char *format = NULL; while (true) { @@ -126,6 +185,7 @@ { "id3v2-only", no_argument, &iLongOpt, '2' }, // infomation to tag + { "format", required_argument, &iLongOpt, 'o' }, { "artist", required_argument, &iLongOpt, 'a' }, { "album", required_argument, &iLongOpt, 'A' }, { "song", required_argument, &iLongOpt, 't' }, @@ -209,7 +269,7 @@ { "WXXX", required_argument, &optFrameID, ID3FID_WWWUSER }, { 0, 0, 0, 0 } }; - iOpt = getopt_long (argc, argv, "12hfLvlRdsDCa:A:t:c:g:y:T:", + iOpt = getopt_long (argc, argv, "12hfLvlRdsDCa:A:t:c:g:y:T:o:", long_options, &option_index); if (iOpt == -1 && argCounter == 0) @@ -261,6 +321,8 @@ UpdFlags = ID3TT_ID3V2; break; // Tagging stuff + case 'o': format = strdup(optarg); + break; case 'a': frameList[frameCounter].id = ID3FID_LEADARTIST; frameList[frameCounter].data = optarg; @@ -328,6 +390,7 @@ { ID3_Tag myTag; struct stat filestat; + char *p, *z; // std::cout << "Tagging " << argv[nIndex] << ": "; @@ -340,6 +403,45 @@ break; } + if (format) { + for (p = format, z = argv[nIndex]; *p && *z;) { + if (*p == '%') { + p++; + + switch (*p) { + case 'a': + parse_expando(&z, &p, ID3FID_LEADARTIST); + break; + case 'A': + parse_expando(&z, &p, ID3FID_ALBUM); + break; + case 't': + parse_expando(&z, &p, ID3FID_TITLE); + break; + case 'T': + parse_expando(&z, &p, ID3FID_TRACKNUM); + break; + default: break; + } + } + else { + if (*p == *z) { + p++; + z++; + continue; + } + else { + quit: + fprintf(stderr, "%s: filename format parse error\n", argv[nIndex]); + exit(1); + } + } + } + + if ((*z && !*p) || (*p && !*z)) + goto quit; + } + /* cludgy to check if we have the proper perms */ fp = fopen(argv[nIndex], "r+"); if (fp == NULL) { /* file didn't open */