diff --git a/src/cli.cc b/src/cli.cc index 3c1ec86..bfb591f 100644 --- a/src/cli.cc +++ b/src/cli.cc @@ -71,11 +71,9 @@ ot::status ot::parse_options(int argc, char** argv, ot::options& opt, FILE* comm opt.print_help = true; break; case 'o': - if (!opt.path_out.empty()) + if (opt.path_out) return {st::bad_arguments, "Cannot specify --output more than once."}; opt.path_out = optarg; - if (opt.path_out.empty()) - return {st::bad_arguments, "Output file path cannot be empty."}; break; case 'i': in_place = true; @@ -123,7 +121,7 @@ ot::status ot::parse_options(int argc, char** argv, ot::options& opt, FILE* comm if (opt.path_in.empty()) return {st::bad_arguments, "Input file path cannot be empty."}; if (in_place) { - if (!opt.path_out.empty()) + if (opt.path_out) return {st::bad_arguments, "Cannot combine --in-place and --output."}; if (opt.path_in == "-") return {st::bad_arguments, "Cannot modify standard input in place."}; @@ -337,7 +335,7 @@ ot::status ot::run(const ot::options& opt) ot::ogg_reader reader(input.get()); /* Read-only mode. */ - if (opt.path_out.empty()) + if (!opt.path_out) return process(reader, nullptr, opt); /* Read-write mode. @@ -367,24 +365,24 @@ ot::status ot::run(const ot::options& opt) struct stat output_info; if (opt.path_out == "-") { output = stdout; - } else if (stat(opt.path_out.c_str(), &output_info) == 0) { + } else if (stat(opt.path_out->c_str(), &output_info) == 0) { /* The output file exists. */ if (!S_ISREG(output_info.st_mode)) { /* Special files are opened for writing directly. */ - if ((final_output = fopen(opt.path_out.c_str(), "w")) == nullptr) + if ((final_output = fopen(opt.path_out->c_str(), "w")) == nullptr) rc = {ot::st::standard_error, - "Could not open '" + opt.path_out + "' for writing: " + - strerror(errno)}; + "Could not open '" + opt.path_out.value() + "' for writing: " + + strerror(errno)}; output = final_output.get(); } else if (opt.overwrite) { - rc = temporary_output.open(opt.path_out.c_str()); + rc = temporary_output.open(opt.path_out->c_str()); output = temporary_output.get(); } else { rc = {ot::st::error, - "'" + opt.path_out + "' already exists. Use -y to overwrite."}; + "'" + opt.path_out.value() + "' already exists. Use -y to overwrite."}; } } else if (errno == ENOENT) { - rc = temporary_output.open(opt.path_out.c_str()); + rc = temporary_output.open(opt.path_out->c_str()); output = temporary_output.get(); } else { rc = {ot::st::error, diff --git a/src/opustags.h b/src/opustags.h index 1fb3802..2f865f6 100644 --- a/src/opustags.h +++ b/src/opustags.h @@ -380,12 +380,12 @@ struct options { */ std::string path_in; /** - * Path to the optional file. The special "-" string means stdout. When empty, opustags runs - * in read-only mode. For in-place editing, path_out is defined equal to path_in. + * Optional path to output file. The special "-" string means stdout. When absent, opustags + * runs in read-only mode. For in-place editing, path_out is defined equal to path_in. * * Options: --output, --in-place */ - std::string path_out; + std::optional path_out; /** * By default, opustags won't overwrite the output file if it already exists. This can be * forced with --overwrite. It is also enabled by --in-place. diff --git a/t/cli.cc b/t/cli.cc index 25df2e1..4746961 100644 --- a/t/cli.cc +++ b/t/cli.cc @@ -97,7 +97,6 @@ void check_bad_arguments() error_code_case(args, message, ot::st::bad_arguments, name); }; error_case({"opustags"}, "No arguments specified. Use -h for help.", "no arguments"); - error_case({"opustags", "--output", ""}, "Output file path cannot be empty.", "empty output path"); error_case({"opustags", "-a", "X"}, "Comment does not contain an equal sign: X.", "bad comment for -a"); error_case({"opustags", "--set", "X"}, "Comment does not contain an equal sign: X.", "bad comment for --set"); error_case({"opustags", "-a"}, "Missing value for option '-a'.", "short option with missing value"); @@ -115,6 +114,8 @@ void check_bad_arguments() error_case({"opustags", "-o", "x", "--output", "y", "z"}, "Cannot specify --output more than once.", "double output"); error_code_case({"opustags", "-S", "x"}, "Malformed tag: INVALID", ot::st::error, "attempt to read invalid argument with -S"); + error_case({"opustags", "-o", "", "--output", "y", "z"}, + "Cannot specify --output more than once.", "double output with first filename empty"); } static void check_delete_comments()