--- mp3gain.c.old 2004-12-23 15:47:04.000000000 -0500 +++ mp3gain.c 2006-03-13 22:15:28.000000000 -0500 @@ -46,7 +46,8 @@ #include #include -#include +#include +#include #include "apetag.h" #ifndef WIN32 @@ -1181,10 +1182,11 @@ static void errUsage(char *progname) { showVersion(progname); - fprintf(stderr,"copyright(c) 2001-2004 by Glen Sawyer\n"); + fprintf(stderr,"copyright(c) 2001-2004 by Glen Sawyer\n"); + fprintf(stderr,"portions copyright(c) 2006 by Stephan Sokolow\n"); fprintf(stderr,"uses mpglib, which can be found at http://www.mpg123.de\n"); fprintf(stderr,"Usage: %s [options] [ ...]\n",progname); - fprintf(stderr," --use %c? or %ch for a full list of options\n",SWITCH_CHAR,SWITCH_CHAR); + fprintf(stderr," --use %c?, %ch, or --help for a full list of options\n",SWITCH_CHAR,SWITCH_CHAR); fclose(stdout); fclose(stderr); exit(1); @@ -1195,7 +1197,8 @@ static void fullUsage(char *progname) { showVersion(progname); - fprintf(stderr,"copyright(c) 2001-2004 by Glen Sawyer\n"); + fprintf(stderr,"copyright(c) 2001-2004 by Glen Sawyer\n"); + fprintf(stderr,"portions copyright(c) 2006 by Stephan Sokolow\n"); fprintf(stderr,"uses mpglib, which can be found at http://www.mpg123.de\n"); fprintf(stderr,"Usage: %s [options] [ ...]\n",progname); fprintf(stderr,"options:\n"); @@ -1227,9 +1230,14 @@ fprintf(stderr,"\t%cs d - delete stored tag info (no other processing)\n",SWITCH_CHAR); fprintf(stderr,"\t%cs s - skip (ignore) stored tag info (do not read or write tags)\n",SWITCH_CHAR); fprintf(stderr,"\t%cs r - force re-calculation (do not read tag info)\n",SWITCH_CHAR); - fprintf(stderr,"\t%cu - undo changes made by mp3gain (based on stored tag info)\n",SWITCH_CHAR); - fprintf(stderr,"\t%cw - \"wrap\" gain change if gain+change > 255 or gain+change < 0\n",SWITCH_CHAR); - fprintf(stderr,"\t (use \"%c? wrap\" switch for a complete explanation)\n",SWITCH_CHAR); + fprintf(stderr,"\t%cu - undo changes made by mp3gain (based on stored tag info)\n",SWITCH_CHAR); + fprintf(stderr,"\t%cw - \"wrap\" gain change if gain+change > 255 or gain+change < 0\n",SWITCH_CHAR); + fprintf(stderr,"\t (use \"%c? wrap\" switch for a complete explanation)\n",SWITCH_CHAR); + fprintf(stderr,"\t-- - force everything beyond this point to be treated as arguments.\n"); + fprintf(stderr,"long options:\n"); + fprintf(stderr,"\t--auto - same as %cr %ck %cp\n", SWITCH_CHAR, SWITCH_CHAR, SWITCH_CHAR); + fprintf(stderr,"\t--help - show this message\n"); + fprintf(stderr,"\t--recursive - TODO\n"); fprintf(stderr,"If you specify %cr and %ca, only the second one will work\n",SWITCH_CHAR,SWITCH_CHAR); fprintf(stderr,"If you do not specify %cc, the program will stop and ask before\n applying gain change to a file that might clip\n",SWITCH_CHAR); fclose(stdout); @@ -1245,7 +1253,20 @@ fprintf(stderr, "haveTrackPeak %d trackPeak %f\n",info->haveTrackPeak, info->trackPeak); fprintf(stderr, "haveMinMaxGain %d min %d max %d\n",info->haveMinMaxGain, info->minGain, info->maxGain); } - + +void showHelp(int argc, char **argv, int i) { + if ((argv[i][2] == 'w')||(argv[i][2] == 'W')) { + wrapExplanation(); + } else { + if (i+1 < argc) { + if ((argv[i+1][0] == 'w')||(argv[i+1][0] =='W')) + wrapExplanation(); + } else { + fullUsage(argv[0]); + } + } + fullUsage(argv[0]); +} #ifdef WIN32 int __cdecl main(int argc, char **argv) { /*make sure this one is standard C declaration*/ @@ -1282,7 +1303,7 @@ int fileStart; int numFiles; int databaseFormat = 0; - int i; + int i, j; int *fileok; int goAhead; int directGain = 0; @@ -1303,7 +1324,10 @@ double curAlbumPeak = 0; unsigned char curAlbumMinGain = 0; unsigned char curAlbumMaxGain = 0; - char chtmp; + char chtmp; + + /* Variables used in the improved option parser */ + int parseOptions = !0; gSuccess = 1; @@ -1316,28 +1340,28 @@ fileStart = 1; numFiles = 0; - for (i = 1; i < argc; i++) { -#ifdef WIN32 - if ((argv[i][0] == '/')||((argv[i][0] == '-') && (strlen(argv[i])==2))) { /* don't need to force single-character command parameters */ -#else - if (((argv[i][0] == '/')||(argv[i][0] == '-'))&& - (strlen(argv[i])==2)) { -#endif - fileStart++; - switch(argv[i][1]) { - case 'a': - case 'A': + for (i = 1; i < argc; i++) { + /* + TODO: Implement support for: + - consider including the glob-parsing support from vorbisgain's so-called recursive support. + */ + if ((parseOptions) && (argv[i][0] == SWITCH_CHAR) && (strlen(argv[i]) >= 2) ) { + fileStart++; + + if (!strcmp(argv[i],"--")) { /* Support for the standard "--" option to force the end of the option parsing. */ + parseOptions = 0; + continue; + } else if (argv[i][1] != '-') { /* Ensure that this isn't a long option. */ + for (j = 1; j < strlen(argv[i]); j++) { + switch(tolower(argv[i][j])) { + case 'a': applyTrack = 0; applyAlbum = !0; break; - - case 'c': - case 'C': + case 'c': ignoreClipWarning = !0; break; - - case 'd': - case 'D': + case 'd': if (argv[i][2] != '\0') { dBGainMod = atof(argv[i]+2); } @@ -1352,14 +1376,10 @@ } } break; - - case 'f': - case 'F': + case 'f': Reckless = 1; break; - - case 'g': - case 'G': + case 'g': directGain = !0; directSingleChannelGain = 0; if (argv[i][2] != '\0') { @@ -1376,32 +1396,14 @@ } } break; - - case 'h': - case 'H': - case '?': - if ((argv[i][2] == 'w')||(argv[i][2] == 'W')) { - wrapExplanation(); - } - else { - if (i+1 < argc) { - if ((argv[i+1][0] == 'w')||(argv[i+1][0] =='W')) - wrapExplanation(); - } - else { - fullUsage(argv[0]); - } - } - fullUsage(argv[0]); - break; - - case 'k': - case 'K': - autoClip = !0; - break; - - case 'l': - case 'L': + case 'h': + case '?': + showHelp(argc, argv, i); + break; + case 'k': + autoClip = !0; + break; + case 'l': directSingleChannelGain = !0; directGain = 0; if (argv[i][2] != '\0') { @@ -1429,9 +1431,7 @@ } } break; - - case 'm': - case 'M': + case 'm': if (argv[i][2] != '\0') { mp3GainMod = atoi(argv[i]+2); } @@ -1446,30 +1446,20 @@ } } break; - - case 'o': - case 'O': + case 'o': databaseFormat = !0; break; - - case 'p': - case 'P': + case 'p': saveTime = !0; break; - - case 'q': - case 'Q': + case 'q': QuietMode = !0; break; - - case 'r': - case 'R': + case 'r': applyTrack = !0; applyAlbum = 0; break; - - case 's': - case 'S': + case 's': chtmp = 0; if (argv[i][2] == '\0') { if (i+1 < argc) { @@ -1482,59 +1472,56 @@ } else { chtmp = argv[i][2]; } - switch (chtmp) { - case 'c': - case 'C': - checkTagOnly = !0; - break; - case 'd': - case 'D': - deleteTag = !0; - break; - case 's': - case 'S': - skipTag = !0; - break; - case 'r': - case 'R': - forceRecalculateTag = !0; - break; - default: - errUsage(argv[0]); - } - - break; - - case 't': - case 'T': + switch (tolower(chtmp)) { + case 'c': + checkTagOnly = !0; + break; + case 'd': + deleteTag = !0; + break; + case 's': + skipTag = !0; + break; + case 'r': + forceRecalculateTag = !0; + break; + default: + errUsage(argv[0]); + } + break; + case 't': UsingTemp = !0; break; - - case 'u': - case 'U': + case 'u': undoChanges = !0; break; - - case 'v': - case 'V': + case 'v': showVersion(argv[0]); - fclose(stdout); - fclose(stderr); + fclose(stdout); + fclose(stderr); exit(0); - - case 'w': - case 'W': + case 'w': wrapGain = !0; break; - - case 'x': - case 'X': + case 'x': maxAmpOnly = !0; break; - - default: - fprintf(stderr,"I don't recognize option %s\n",argv[i]); - } + default: + fprintf(stderr,"I don't recognize option %s\n",argv[i]); + } + } + } else if (!strncmp(argv[i],"--",2)) { /* This is a long option and must be parsed as such */ + if (!strcasecmp(argv[i],"--auto")) { + autoClip = !0; /* -k */ + saveTime = !0; /* -p */ + applyTrack = !0; /* -r */ + applyAlbum = 0; /* -r */ + } else if (!strcasecmp(argv[i],"--help")) { + showHelp(argc, argv, i); + } else if (!strcasecmp(argv[i],"--recursive")) { + fprintf(stderr,"Sorry, --recursive has not been implemented yet.\n\t However, the following command seems to be equivalent:\n\t`find /path/to/mp3s -iname \"*.mp3\" -exec mp3gain -r {} \\;`\n\tThe use of --auto in place of -r is recommended.\n"); + } + } } } /* now stored in tagInfo--- maxsample = malloc(sizeof(Float_t) * argc); */