From 6db7f07bd58439dec820731df07c1c479459866a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Mangano?= Date: Sat, 26 Dec 2020 13:00:20 +0100 Subject: [PATCH] Factor CLI argument transcoding --- src/cli.cc | 27 ++++++++++++++++----------- src/opustags.h | 2 +- t/cli.cc | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/cli.cc b/src/cli.cc index 805bd2c..bf080a5 100644 --- a/src/cli.cc +++ b/src/cli.cc @@ -60,7 +60,7 @@ ot::status ot::parse_options(int argc, char** argv, ot::options& opt, FILE* comm { static ot::encoding_converter to_utf8("", "UTF-8"); std::string utf8; - std::string::size_type equal; + const char* equal; ot::status rc; bool set_all = false; opt = {}; @@ -86,21 +86,16 @@ ot::status ot::parse_options(int argc, char** argv, ot::options& opt, FILE* comm opt.overwrite = true; break; case 'd': - rc = to_utf8(optarg, utf8); - if (rc != ot::st::ok) - return {st::bad_arguments, "Could not encode argument into UTF-8: " + rc.message}; - opt.to_delete.emplace_back(std::move(utf8)); + opt.to_delete.emplace_back(optarg); break; case 'a': case 's': - rc = to_utf8(optarg, utf8); - if (rc != ot::st::ok) - return {st::bad_arguments, "Could not encode argument into UTF-8: " + rc.message}; - if ((equal = utf8.find('=')) == std::string::npos) + equal = strchr(optarg, '='); + if (equal == nullptr) return {st::bad_arguments, "Comment does not contain an equal sign: "s + optarg + "."}; if (c == 's') - opt.to_delete.emplace_back(utf8.substr(0, equal)); - opt.to_add.emplace_back(std::move(utf8)); + opt.to_delete.emplace_back(optarg, equal - optarg); + opt.to_add.emplace_back(optarg); break; case 'S': opt.delete_all = true; @@ -130,6 +125,16 @@ ot::status ot::parse_options(int argc, char** argv, ot::options& opt, FILE* comm opt.paths_in.emplace_back(argv[i]); } + // Convert arguments to UTF-8. + for (std::list* args : { &opt.to_add, &opt.to_delete }) { + for (std::string& arg : *args) { + rc = to_utf8(arg, utf8); + if (rc != ot::st::ok) + return {st::bad_arguments, "Could not encode argument into UTF-8: " + rc.message}; + arg = std::move(utf8); + } + } + if (opt.in_place && opt.path_out) return {st::bad_arguments, "Cannot combine --in-place and --output."}; diff --git a/src/opustags.h b/src/opustags.h index 85c87b5..995221a 100644 --- a/src/opustags.h +++ b/src/opustags.h @@ -450,7 +450,7 @@ struct options { * * Option: --delete, --set */ - std::vector to_delete; + std::list to_delete; /** * Delete all the existing comments. * diff --git a/t/cli.cc b/t/cli.cc index b965852..4133812 100644 --- a/t/cli.cc +++ b/t/cli.cc @@ -71,7 +71,7 @@ void check_good_arguments() opt = parse({"opustags", "x", "--output", "y", "-D", "-s", "X=Y Z", "-d", "a=b"}); if (opt.paths_in.size() != 1 || opt.paths_in.front() != "x" || !opt.path_out || opt.path_out != "y" || !opt.delete_all || opt.overwrite || opt.to_delete.size() != 2 || - opt.to_delete[0] != "X" || opt.to_delete[1] != "a=b" || + opt.to_delete.front() != "X" || *std::next(opt.to_delete.begin()) != "a=b" || opt.to_add != std::list{"X=Y Z"}) throw failure("unexpected option parsing result for case #1");