Separate options definition and parsing

This commit is contained in:
Armin Friedl 2021-05-01 09:27:40 +02:00
parent 89dd5186f5
commit 0663f42aec
Signed by: armin
GPG key ID: 48C726EEE7FBCBC8
3 changed files with 66 additions and 50 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
.clangd/ .clangd/
.cache/
build/ build/
target/ target/
compile_commands.json compile_commands.json

59
src/Opt.hpp Normal file
View file

@ -0,0 +1,59 @@
#include <tclap/ArgException.h>
#include <tclap/CmdLine.h>
#include <tclap/StdOutput.h>
#include <tclap/SwitchArg.h>
#include <tclap/UnlabeledMultiArg.h>
#include <tclap/ValueArg.h>
#include <filesystem>
template <>
struct TCLAP::ArgTraits<std::filesystem::path> {
typedef ValueLike ValueCategory;
};
namespace xwim {
namespace fs = std::filesystem;
class Opt {
private:
// clang-format off
TCLAP::CmdLine cmd_line
{"xwim - Do What I Mean Extractor", ' ', "0.5.0"};
TCLAP::SwitchArg arg_compress
{"c", "compress", "Compress <files>", cmd_line, false};
TCLAP::SwitchArg arg_extract
{"x", "extract", "Extract <file>", cmd_line, false};
TCLAP::ValueArg<fs::path> arg_out
{"o", "out", "Out <path>", false, fs::path{}, "A path on the filesystem", cmd_line};
TCLAP::UnlabeledMultiArg<fs::path> arg_paths
{"Paths", "Filesystem paths to extract or compress", true, "A path on the filesystem", cmd_line};
// clang-format on
public:
void parse(int argc, char** argv) { cmd_line.parse(argc, argv); }
void validate() {
if (arg_extract.isSet() && arg_compress.isSet()) {
// This is a bit ugly but `none-or-xor` only available in
// tclap-1.4 which is not well supported in current
// distributions
auto out = TCLAP::StdOutput{};
TCLAP::ArgException e{
"Cannot compress `-c` and extract `-x` simultaneously"};
try {
out.failure(cmd_line, e);
} catch (TCLAP::ExitException& e) {
exit(e.getExitStatus());
}
}
}
};
} // namespace xwim

View file

@ -1,73 +1,29 @@
#include <spdlog/common.h> #include <spdlog/common.h>
#include <spdlog/logger.h> #include <spdlog/logger.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <tclap/ArgException.h>
#include <tclap/CmdLine.h>
#include <tclap/StdOutput.h>
#include <tclap/SwitchArg.h>
#include <tclap/UnlabeledMultiArg.h>
#include <tclap/ValueArg.h>
#include <cstdlib> #include <cstdlib>
#include <filesystem> #include <filesystem>
#include <memory>
#include "Common.hpp" #include "Common.hpp"
#include "Opt.hpp"
#include "Log.hpp" #include "Log.hpp"
#include "Xwim.hpp" #include "Xwim.hpp"
using namespace xwim; using namespace xwim;
using namespace std; using namespace std;
namespace fs = std::filesystem;
template <>
struct TCLAP::ArgTraits<std::filesystem::path> {
typedef ValueLike ValueCategory;
};
int main(int argc, char** argv) { int main(int argc, char** argv) {
log::init(); log::init();
TCLAP::CmdLine cmd{"xwim - Do What I Mean Extractor", ' ', "0.3.0"}; Opt opt;
opt.parse(argc, argv);
opt.validate();
TCLAP::SwitchArg arg_compress{"c", "compress", "Compress <files>", cmd, Xwim xwim{};
false};
TCLAP::SwitchArg arg_extract{"x", "extract", "Extract <file>", cmd, false};
TCLAP::ValueArg<fs::path> arg_outfile{
"o", "out", "Out <file-or-path>",
false, fs::path{}, "A path on the filesystem",
cmd};
TCLAP::UnlabeledMultiArg<fs::path> arg_infiles{
"Files", "Archive to extract or files to compress", true,
"A path on the filesystem", cmd};
Xwim xwim;
cmd.parse(argc, argv);
if (arg_extract.isSet() && arg_compress.isSet()) {
// This is a bit ugly but `none-or-xor` only available in
// tclap-1.4 which is not well supported in current
// distributions
auto out = TCLAP::StdOutput{};
TCLAP::ArgException e{
"Cannot compress `-c` and extract `-x` simultaneously"};
try {
out.failure(cmd, e);
} catch (TCLAP::ExitException& e) {
exit(e.getExitStatus());
}
}
// `none-or-xor` ensured already
if (arg_extract.isSet()) xwim.setExtract();
if (arg_compress.isSet()) xwim.setCompress();
if (arg_outfile.isSet()) xwim.setOut(arg_outfile.getValue());
if (arg_infiles.isSet()) xwim.setIns(arg_infiles.getValue());
try { try {
xwim.try_infer();
xwim.dwim(); xwim.dwim();
} catch (XwimError& e) { } catch (XwimError& e) {
spdlog::error(e.what()); spdlog::error(e.what());