Don't treat empty output filename specially (fix #27)

Instead, make opt.path_out a std::optional<std::string>.
This commit is contained in:
Reuben Thomas 2020-08-31 20:03:36 +01:00 committed by Frédéric Mangano-Tarumi
parent ef15e7ad13
commit 73a54d7ab7
3 changed files with 15 additions and 16 deletions

View File

@ -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,

View File

@ -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<std::string> 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.

View File

@ -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()