62
67
{ "remove-tag", 1, 0, 0 },
63
68
{ "remove-first-tag", 1, 0, 0 },
64
69
{ "set-tag", 1, 0, 0 },
70
{ "set-tag-from-file", 1, 0, 0 },
65
71
{ "import-tags-from", 1, 0, 0 },
66
72
{ "export-tags-to", 1, 0, 0 },
67
{ "show-vc-vendor", 0, 0, 0 }, /* deprecated */
68
{ "show-vc-field", 1, 0, 0 }, /* deprecated */
69
{ "remove-vc-all", 0, 0, 0 }, /* deprecated */
70
{ "remove-vc-field", 1, 0, 0 }, /* deprecated */
71
{ "remove-vc-firstfield", 1, 0, 0 }, /* deprecated */
72
{ "set-vc-field", 1, 0, 0 }, /* deprecated */
73
{ "import-vc-from", 1, 0, 0 }, /* deprecated */
74
{ "export-vc-to", 1, 0, 0 }, /* deprecated */
75
73
{ "import-cuesheet-from", 1, 0, 0 },
76
74
{ "export-cuesheet-to", 1, 0, 0 },
75
{ "import-picture-from", 1, 0, 0 },
76
{ "export-picture-to", 1, 0, 0 },
77
77
{ "add-seekpoint", 1, 0, 0 },
78
78
{ "add-replay-gain", 0, 0, 0 },
79
{ "remove-replay-gain", 0, 0, 0 },
79
80
{ "add-padding", 1, 0, 0 },
80
81
/* major operations */
81
82
{ "help", 0, 0, 0 },
101
102
static void append_new_argument(CommandLineOptions *options, Argument argument);
102
103
static Operation *append_major_operation(CommandLineOptions *options, OperationType type);
103
104
static Operation *append_shorthand_operation(CommandLineOptions *options, OperationType type);
105
static Argument *find_argument(CommandLineOptions *options, ArgumentType type);
104
106
static Operation *find_shorthand_operation(CommandLineOptions *options, OperationType type);
105
107
static Argument *append_argument(CommandLineOptions *options, ArgumentType type);
106
108
static FLAC__bool parse_md5(const char *src, FLAC__byte dest[16]);
107
109
static FLAC__bool parse_uint32(const char *src, FLAC__uint32 *dest);
108
110
static FLAC__bool parse_uint64(const char *src, FLAC__uint64 *dest);
109
static FLAC__bool parse_filename(const char *src, char **dest);
111
static FLAC__bool parse_string(const char *src, char **dest);
110
112
static FLAC__bool parse_vorbis_comment_field_name(const char *field_ref, char **name, const char **violation);
111
113
static FLAC__bool parse_add_seekpoint(const char *in, char **out, const char **violation);
112
114
static FLAC__bool parse_add_padding(const char *in, unsigned *out);
203
/* check for only one FLAC file used with --import-cuesheet-from/--export-cuesheet-to */
204
if((0 != find_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM) || 0 != find_shorthand_operation(options, OP__EXPORT_CUESHEET_TO)) && options->num_files > 1) {
205
fprintf(stderr, "ERROR: you may only specify one FLAC file when using '--import-cuesheet-from' or '--export-cuesheet-to'\n");
205
/* check for only one FLAC file used with certain options */
206
if(options->num_files > 1) {
207
if(0 != find_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM)) {
208
fprintf(stderr, "ERROR: you may only specify one FLAC file when using '--import-cuesheet-from'\n");
211
if(0 != find_shorthand_operation(options, OP__EXPORT_CUESHEET_TO)) {
212
fprintf(stderr, "ERROR: you may only specify one FLAC file when using '--export-cuesheet-to'\n");
215
if(0 != find_shorthand_operation(options, OP__EXPORT_PICTURE_TO)) {
216
fprintf(stderr, "ERROR: you may only specify one FLAC file when using '--export-picture-to'\n");
220
0 != find_shorthand_operation(options, OP__IMPORT_VC_FROM) &&
221
0 == strcmp(find_shorthand_operation(options, OP__IMPORT_VC_FROM)->argument.filename.value, "-")
223
fprintf(stderr, "ERROR: you may only specify one FLAC file when using '--import-tags-from=-'\n");
209
228
if(options->args.checks.has_block_type && options->args.checks.has_except_block_type) {
450
477
undocumented_warning(opt);
452
else if(0 == strcmp(opt, "show-vendor-tag") || 0 == strcmp(opt, "show-vc-vendor")) {
453
if(0 == strcmp(opt, "show-vc-vendor"))
454
fprintf(stderr, "WARNING: --%s is deprecated, the new name is --show-vendor-tag\n", opt);
479
else if(0 == strcmp(opt, "show-vendor-tag")) {
455
480
(void) append_shorthand_operation(options, OP__SHOW_VC_VENDOR);
457
else if(0 == strcmp(opt, "show-tag") || 0 == strcmp(opt, "show-vc-field")) {
482
else if(0 == strcmp(opt, "show-tag")) {
458
483
const char *violation;
459
if(0 == strcmp(opt, "show-vc-field"))
460
fprintf(stderr, "WARNING: --%s is deprecated, the new name is --show-tag\n", opt);
461
484
op = append_shorthand_operation(options, OP__SHOW_VC_FIELD);
462
485
FLAC__ASSERT(0 != option_argument);
463
486
if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) {
469
else if(0 == strcmp(opt, "remove-all-tags") || 0 == strcmp(opt, "remove-vc-all")) {
470
if(0 == strcmp(opt, "remove-vc-all"))
471
fprintf(stderr, "WARNING: --%s is deprecated, the new name is --remove-all-tags\n", opt);
492
else if(0 == strcmp(opt, "remove-all-tags")) {
472
493
(void) append_shorthand_operation(options, OP__REMOVE_VC_ALL);
474
else if(0 == strcmp(opt, "remove-tag") || 0 == strcmp(opt, "remove-vc-field")) {
495
else if(0 == strcmp(opt, "remove-tag")) {
475
496
const char *violation;
476
if(0 == strcmp(opt, "remove-vc-field"))
477
fprintf(stderr, "WARNING: --%s is deprecated, the new name is --remove-tag\n", opt);
478
497
op = append_shorthand_operation(options, OP__REMOVE_VC_FIELD);
479
498
FLAC__ASSERT(0 != option_argument);
480
499
if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) {
486
else if(0 == strcmp(opt, "remove-first-tag") || 0 == strcmp(opt, "remove-vc-firstfield")) {
505
else if(0 == strcmp(opt, "remove-first-tag")) {
487
506
const char *violation;
488
if(0 == strcmp(opt, "remove-vc-firstfield"))
489
fprintf(stderr, "WARNING: --%s is deprecated, the new name is --remove-first-tag\n", opt);
490
507
op = append_shorthand_operation(options, OP__REMOVE_VC_FIRSTFIELD);
491
508
FLAC__ASSERT(0 != option_argument);
492
509
if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) {
498
else if(0 == strcmp(opt, "set-tag") || 0 == strcmp(opt, "set-vc-field")) {
499
const char *violation;
500
if(0 == strcmp(opt, "set-vc-field"))
501
fprintf(stderr, "WARNING: --%s is deprecated, the new name is --set-tag\n", opt);
502
op = append_shorthand_operation(options, OP__SET_VC_FIELD);
503
FLAC__ASSERT(0 != option_argument);
504
if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) {
505
FLAC__ASSERT(0 != violation);
506
fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n %s\n", opt, option_argument, violation);
510
else if(0 == strcmp(opt, "import-tags-from") || 0 == strcmp(opt, "import-vc-from")) {
511
if(0 == strcmp(opt, "import-vc-from"))
512
fprintf(stderr, "WARNING: --%s is deprecated, the new name is --import-tags-from\n", opt);
515
else if(0 == strcmp(opt, "set-tag")) {
516
const char *violation;
517
op = append_shorthand_operation(options, OP__SET_VC_FIELD);
518
FLAC__ASSERT(0 != option_argument);
519
op->argument.vc_field.field_value_from_file = false;
520
if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) {
521
FLAC__ASSERT(0 != violation);
522
fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n %s\n", opt, option_argument, violation);
526
else if(0 == strcmp(opt, "set-tag-from-file")) {
527
const char *violation;
528
op = append_shorthand_operation(options, OP__SET_VC_FIELD);
529
FLAC__ASSERT(0 != option_argument);
530
op->argument.vc_field.field_value_from_file = true;
531
if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) {
532
FLAC__ASSERT(0 != violation);
533
fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n %s\n", opt, option_argument, violation);
537
else if(0 == strcmp(opt, "import-tags-from")) {
513
538
op = append_shorthand_operation(options, OP__IMPORT_VC_FROM);
514
539
FLAC__ASSERT(0 != option_argument);
515
if(!parse_filename(option_argument, &(op->argument.filename.value))) {
540
if(!parse_string(option_argument, &(op->argument.filename.value))) {
516
541
fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
520
else if(0 == strcmp(opt, "export-tags-to") || 0 == strcmp(opt, "export-vc-to")) {
521
if(0 == strcmp(opt, "export-vc-to"))
522
fprintf(stderr, "WARNING: --%s is deprecated, the new name is --export-tags-to\n", opt);
545
else if(0 == strcmp(opt, "export-tags-to")) {
523
546
op = append_shorthand_operation(options, OP__EXPORT_VC_TO);
524
547
FLAC__ASSERT(0 != option_argument);
525
if(!parse_filename(option_argument, &(op->argument.filename.value))) {
548
if(!parse_string(option_argument, &(op->argument.filename.value))) {
526
549
fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
542
565
else if(0 == strcmp(opt, "export-cuesheet-to")) {
543
566
op = append_shorthand_operation(options, OP__EXPORT_CUESHEET_TO);
544
567
FLAC__ASSERT(0 != option_argument);
545
if(!parse_filename(option_argument, &(op->argument.filename.value))) {
546
fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
568
if(!parse_string(option_argument, &(op->argument.filename.value))) {
569
fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
573
else if(0 == strcmp(opt, "import-picture-from")) {
574
op = append_shorthand_operation(options, OP__IMPORT_PICTURE_FROM);
575
FLAC__ASSERT(0 != option_argument);
576
if(!parse_string(option_argument, &(op->argument.specification.value))) {
577
fprintf(stderr, "ERROR (--%s): missing specification\n", opt);
581
else if(0 == strcmp(opt, "export-picture-to")) {
582
const Argument *arg = find_argument(options, ARG__BLOCK_NUMBER);
583
op = append_shorthand_operation(options, OP__EXPORT_PICTURE_TO);
584
FLAC__ASSERT(0 != option_argument);
585
if(!parse_string(option_argument, &(op->argument.export_picture_to.filename))) {
586
fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
589
op->argument.export_picture_to.block_number_link = arg? &(arg->value.block_number) : 0;
550
591
else if(0 == strcmp(opt, "add-seekpoint")) {
551
592
const char *violation;
556
597
fprintf(stderr, "ERROR (--%s): malformed seekpoint specification \"%s\",\n %s\n", opt, option_argument, violation);
559
op = find_shorthand_operation(options, OP__ADD_SEEKPOINT);
561
op = append_shorthand_operation(options, OP__ADD_SEEKPOINT);
562
local_strcat(&(op->argument.add_seekpoint.specification), spec);
563
local_strcat(&(op->argument.add_seekpoint.specification), ";");
601
op = find_shorthand_operation(options, OP__ADD_SEEKPOINT);
603
op = append_shorthand_operation(options, OP__ADD_SEEKPOINT);
604
local_strcat(&(op->argument.add_seekpoint.specification), spec);
605
local_strcat(&(op->argument.add_seekpoint.specification), ";");
566
609
else if(0 == strcmp(opt, "add-replay-gain")) {
567
610
(void) append_shorthand_operation(options, OP__ADD_REPLAY_GAIN);
612
else if(0 == strcmp(opt, "remove-replay-gain")) {
613
const FLAC__byte * const tags[5] = {
614
GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS,
615
GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN,
616
GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK,
617
GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN,
618
GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK
621
for(i = 0; i < sizeof(tags)/sizeof(tags[0]); i++) {
622
op = append_shorthand_operation(options, OP__REMOVE_VC_FIELD);
623
op->argument.vc_field_name.value = local_strdup((const char *)tags[i]);
569
626
else if(0 == strcmp(opt, "add-padding")) {
570
627
op = append_shorthand_operation(options, OP__ADD_PADDING);
571
628
FLAC__ASSERT(0 != option_argument);