Skip to content

Commit

Permalink
Add option to metaflac to write to different file
Browse files Browse the repository at this point in the history
  • Loading branch information
ktmf01 committed Oct 28, 2024
1 parent 73b5502 commit a7d69df
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 12 deletions.
7 changes: 6 additions & 1 deletion man/metaflac.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,13 @@ modification time is set to the current time):

# OPTIONS

**-o** *filename***, \--output-name=***filename*
: Output to a new file instead of changing or rewriting the input
file.

**\--preserve-modtime**
: Preserve the original modification time in spite of edits.
: Preserve the original modification time in spite of edits. This does
nothing when -o or --output-name are specified.

**\--with-filename**
: Prefix each output line with the FLAC file name (the default if more
Expand Down
10 changes: 8 additions & 2 deletions src/metaflac/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,10 @@ FLAC__bool do_major_operation_on_file(const char *filename, const CommandLineOpt
if(ok && needs_write) {
if(options->use_padding)
FLAC__metadata_chain_sort_padding(chain);
ok = FLAC__metadata_chain_write(chain, options->use_padding, options->preserve_modtime);
if(options->output_name == 0)
ok = FLAC__metadata_chain_write(chain, options->use_padding, options->preserve_modtime);
else
ok = FLAC__metadata_chain_write_new_file(chain, options->output_name, options->use_padding);
if(!ok) {
FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status(chain);
print_error_with_chain_status(chain, "%s: ERROR: writing FLAC file", filename);
Expand Down Expand Up @@ -469,7 +472,10 @@ FLAC__bool do_shorthand_operations_on_file(const char *filename, const CommandLi
if(ok && needs_write) {
if(use_padding)
FLAC__metadata_chain_sort_padding(chain);
ok = FLAC__metadata_chain_write(chain, use_padding, options->preserve_modtime);
if(options->output_name == 0)
ok = FLAC__metadata_chain_write(chain, use_padding, options->preserve_modtime);
else
ok = FLAC__metadata_chain_write_new_file(chain, options->output_name, use_padding);
if(!ok) {
FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status(chain);
print_error_with_chain_status(chain, "%s: ERROR: writing FLAC file", filename);
Expand Down
20 changes: 14 additions & 6 deletions src/metaflac/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
*/
struct share__option long_options_[] = {
/* global options */
{ "output-name", 1, 0, 'o' }, /* NOTE: if this option moves in this list, change the index in parse_options */
{ "preserve-modtime", 0, 0, 0 },
{ "with-filename", 0, 0, 0 },
{ "no-filename", 0, 0, 0 },
Expand Down Expand Up @@ -158,6 +159,7 @@ void init_options(CommandLineOptions *options)

options->num_files = 0;
options->filenames = 0;
options->output_name = 0;
}

FLAC__bool parse_options(int argc, char *argv[], CommandLineOptions *options)
Expand All @@ -166,11 +168,14 @@ FLAC__bool parse_options(int argc, char *argv[], CommandLineOptions *options)
int option_index = 1;
FLAC__bool had_error = false;

while ((ret = share__getopt_long(argc, argv, "", long_options_, &option_index)) != -1) {
while ((ret = share__getopt_long(argc, argv, "o:", long_options_, &option_index)) != -1) {
switch (ret) {
case 0:
had_error |= !parse_option(option_index, share__optarg, options);
break;
case 'o':
had_error |= !parse_option(0, share__optarg, options);
break;
case '?':
case ':':
had_error = true;
Expand Down Expand Up @@ -213,6 +218,10 @@ FLAC__bool parse_options(int argc, char *argv[], CommandLineOptions *options)

/* check for only one FLAC file used with certain options */
if(!had_error && options->num_files > 1) {
if(0 != options->output_name) {
flac_fprintf(stderr, "ERROR: you may only specify one FLAC input file when specifying an output filename\n");
had_error = true;
}
if(0 != find_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM)) {
flac_fprintf(stderr, "ERROR: you may only specify one FLAC file when using '--import-cuesheet-from'\n");
had_error = true;
Expand Down Expand Up @@ -327,10 +336,6 @@ void free_options(CommandLineOptions *options)
if(0 != arg->value.block_type.entries)
free(arg->value.block_type.entries);
break;
case ARG__FROM_FILE:
if(0 != arg->value.from_file.file_name)
free(arg->value.from_file.file_name);
break;
default:
break;
}
Expand Down Expand Up @@ -380,6 +385,9 @@ FLAC__bool parse_option(int option_index, const char *option_argument, CommandLi
else if(0 == strcmp(opt, "no-cued-seekpoints")) {
options->cued_seekpoints = false;
}
else if(0 == strcmp(opt, "output-name")) {
options->output_name = option_argument;
}
else if(0 == strcmp(opt, "show-md5sum")) {
(void) append_shorthand_operation(options, OP__SHOW_MD5SUM);
}
Expand Down Expand Up @@ -731,7 +739,7 @@ FLAC__bool parse_option(int option_index, const char *option_argument, CommandLi
else if(0 == strcmp(opt, "from-file")) {
arg = append_argument(options, ARG__FROM_FILE);
FLAC__ASSERT(0 != option_argument);
arg->value.from_file.file_name = local_strdup(option_argument);
arg->value.from_file.file_name = option_argument;
}
else {
FLAC__ASSERT(0);
Expand Down
3 changes: 2 additions & 1 deletion src/metaflac/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ typedef struct {
} Argument_DataFormat;

typedef struct {
char *file_name;
const char *file_name;
} Argument_FromFile;

typedef struct {
Expand Down Expand Up @@ -212,6 +212,7 @@ typedef struct {
} args;
unsigned num_files;
char **filenames;
const char *output_name;
} CommandLineOptions;

void init_options(CommandLineOptions *options);
Expand Down
3 changes: 3 additions & 0 deletions src/metaflac/usage.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ static void usage_summary(FILE *out)
flac_fprintf(out, "You may perform one major operation, or many shorthand operations at a time.\n");
flac_fprintf(out, "\n");
flac_fprintf(out, "Options:\n");
flac_fprintf(out, "-o, --output-name=FILENAME Write changes to a new file, instead of doing all\n");
flac_fprintf(out, " operations on the input files\n");
flac_fprintf(out, "--preserve-modtime Preserve the original modification time in spite of edits\n");
flac_fprintf(out, " This option does nothing when combined with --output-name\n");
flac_fprintf(out, "--with-filename Prefix each output line with the FLAC file name\n");
flac_fprintf(out, " (the default if more than one FLAC file is specified).\n");
flac_fprintf(out, " This option has no effect for options exporting to a\n");
Expand Down
72 changes: 70 additions & 2 deletions test/test_metaflac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ fi

testdir="metaflac-test-files"
flacfile="metaflac1.flac"
flacfile_secondary="metaflac2.flac"

flac${EXE} --help 1>/dev/null 2>/dev/null || die "ERROR can't find flac executable"
metaflac${EXE} --help 1>/dev/null 2>/dev/null || die "ERROR can't find metaflac executable"
Expand Down Expand Up @@ -166,10 +167,19 @@ check_flac
metaflac_test case02 "--add-padding" "--list"

# some flavors of /bin/sh (e.g. Darwin's) won't even handle quoted spaces, so we underscore:
run_metaflac -o $flacfile_secondary --set-tag="ARTIST=The_artist_formerly_known_as_the_artist..." $flacfile
check_flac
metaflac_test case02 "whether -o does not change input file" "--list"

run_metaflac --set-tag="ARTIST=The_artist_formerly_known_as_the_artist..." $flacfile
check_flac
metaflac_test case03 "--set-tag=ARTIST" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case03 "-o --set-tag=ARTIST" "--list"

run_metaflac --set-tag="ARTIST=Chuck_Woolery" $flacfile
check_flac
metaflac_test case04 "--set-tag=ARTIST" "--list"
Expand Down Expand Up @@ -215,10 +225,19 @@ run_metaflac --add-padding=0 $flacfile
check_flac
metaflac_test case18 "--add-padding=0" "--list"

run_metaflac -o $flacfile_secondary --sort-padding $flacfile
check_flac
metaflac_test case18 "whether -o does not change input file" "--list"

run_metaflac --sort-padding $flacfile
check_flac
metaflac_test case19 "--sort-padding" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case19 "-o --sort-padding" "--list"

run_metaflac --add-padding=0 $flacfile
check_flac
metaflac_test case20 "--add-padding=0" "--list"
Expand All @@ -227,22 +246,58 @@ run_metaflac --remove-all-tags $flacfile
check_flac
metaflac_test case21 "--remove-all-tags" "--list"

run_metaflac -o $flacfile_secondary --remove --block-number=1,99 --dont-use-padding $flacfile
check_flac
metaflac_test case21 "whether -o does not change input file" "--list"

run_metaflac --remove --block-number=1,99 --dont-use-padding $flacfile
check_flac
metaflac_test case22 "--remove --block-number=1,99 --dont-use-padding" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case22 "-o --remove --block-number=1,99 --dont-use-padding" "--list"

run_metaflac -o $flacfile_secondary --remove --block-number=99 --dont-use-padding $flacfile
check_flac
metaflac_test case22 "whether -o does not change input file" "--list"

run_metaflac --remove --block-number=99 --dont-use-padding $flacfile
check_flac
metaflac_test case23 "--remove --block-number=99 --dont-use-padding" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case23 "-o --remove --block-number=99 --dont-use-padding" "--list"

run_metaflac -o $flacfile_secondary --remove --block-type=PADDING $flacfile
check_flac
metaflac_test case23 "whether -o does not change input file" "--list"

run_metaflac --remove --block-type=PADDING $flacfile
check_flac
metaflac_test case24 "--remove --block-type=PADDING" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case24 "-o --remove --block-type=PADDING" "--list"

run_metaflac -o $flacfile_secondary --remove --block-type=PADDING --dont-use-padding $flacfile
check_flac
metaflac_test case24 "whether -o does not change input file" "--list"

run_metaflac --remove --block-type=PADDING --dont-use-padding $flacfile
check_flac
metaflac_test case25 "--remove --block-type=PADDING --dont-use-padding" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case25 "-o --remove --block-type=PADDING --dont-use-padding" "--list"

run_metaflac --add-padding=0 $flacfile $flacfile
check_flac
metaflac_test case26 "--add-padding=0 * 2" "--list"
Expand Down Expand Up @@ -462,17 +517,30 @@ fi
if run_metaflac_to_metaflac_silent "--list --data-format=binary --except-block-type=STREAMINFO,SEEKTABLE,VORBIS_COMMENT $flacfile2" "--append $flacfile" ; then
:
else
die "ERROR, couldn't add vorbis comment metadata block"
die "ERROR, couldn't append metadata block"
fi

metaflac_test_nofilter case66 "--append" "--list"

if run_metaflac_to_metaflac_silent "--list --data-format=binary --except-block-type=STREAMINFO,SEEKTABLE,VORBIS_COMMENT $flacfile2" "-o $flacfile_secondary --append --block-number=0 $flacfile" ; then
:
else
die "ERROR, couldn't insert metadata block"
fi
check_flac
metaflac_test_nofilter case66 "whether -o does not change input file" "--list"

if run_metaflac_to_metaflac_silent "--list --data-format=binary --except-block-type=STREAMINFO,SEEKTABLE,VORBIS_COMMENT $flacfile2" "--append --block-number=0 $flacfile" ; then
:
else
die "ERROR, couldn't add vorbis comment metadata block"
die "ERROR, couldn't insert metadata block"
fi

metaflac_test_nofilter case67 "--append --block-number=0" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test_nofilter case67 "-o --append --block-number=0" "--list"

rm -f metaflac-test-files/out.meta metaflac-test-files/out1.meta

0 comments on commit a7d69df

Please sign in to comment.