This commit is contained in:
Armin Friedl 2021-05-10 18:49:01 +02:00
parent 0663f42aec
commit d95f3d0f32
Signed by: armin
GPG key ID: 48C726EEE7FBCBC8
5 changed files with 97 additions and 86 deletions

View file

@ -1,59 +1,46 @@
#include <tclap/ArgException.h>
#include <tclap/CmdLine.h>
#include <tclap/StdOutput.h>
#include <tclap/SwitchArg.h>
#include <tclap/UnlabeledMultiArg.h>
#include <tclap/ValueArg.h>
#pragma once
#include <fmt/core.h>
#include <fmt/format.h>
#include <filesystem>
template <>
struct TCLAP::ArgTraits<std::filesystem::path> {
typedef ValueLike ValueCategory;
};
#include <optional>
#include <set>
namespace xwim {
namespace fs = std::filesystem;
enum class Action { EXTRACT, COMPRESS };
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());
}
}
}
struct UserOpt {
std::optional<Action> action;
bool interactive;
std::optional<std::filesystem::path> out;
std::set<std::filesystem::path> paths;
};
struct XwimConfig {
Action action;
std::filesystem::path output;
std::set<std::filesystem::path> input;
};
XwimConfig guess_wim(UserOpt user_opt);
void do_wim(XwimConfig);
} // namespace xwim
template <>
struct fmt::formatter<xwim::Action> {
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const xwim::Action& action, FormatContext& ctx) {
switch (action) {
case xwim::Action::EXTRACT:
return format_to(ctx.out(), "EXTRACT");
case xwim::Action::COMPRESS:
return format_to(ctx.out(), "COMPRESS");
};
return format_to(ctx.out(), "");
}
};

View file

@ -14,10 +14,6 @@
#include "Archiver.hpp"
#include "Common.hpp"
namespace xwim {
using namespace std;
namespace fs = std::filesystem;
#if defined(unix) || defined(__unix__) || defined(__unix)
std::string default_extension = ".tar.gz";
#elif defined(_win32) || defined(__win32__) || defined(__windows__)
@ -26,6 +22,10 @@ std::string default_extension = ".zip";
std::string default_extension = ".zip";
#endif
namespace xwim {
using namespace std;
namespace fs = std::filesystem;
Xwim::Xwim() : action{Action::UNKNOWN} {}
void Xwim::try_infer() {

View file

@ -9,13 +9,14 @@
#include <stdexcept>
#include "Common.hpp"
#include "Opt.hpp"
#include "Archiver.hpp"
namespace xwim {
using namespace std;
namespace fs = std::filesystem;
enum class Action { UNKNOWN, EXTRACT, COMPRESS };
Xwim xwim(UserOpt user_opt);
class Xwim {
private:
@ -43,21 +44,3 @@ class Xwim {
};
} // namespace xwim
template <>
struct fmt::formatter<xwim::Action> {
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
auto format(const xwim::Action& action, FormatContext& ctx) {
switch (action) {
case xwim::Action::UNKNOWN:
return format_to(ctx.out(), "UNKNOWN");
case xwim::Action::EXTRACT:
return format_to(ctx.out(), "EXTRACT");
case xwim::Action::COMPRESS:
return format_to(ctx.out(), "COMPRESS");
};
return format_to(ctx.out(), "");
}
};

View file

@ -1,31 +1,69 @@
#include <spdlog/common.h>
#include <spdlog/logger.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 <filesystem>
#include <memory>
#include <optional>
#include "Common.hpp"
#include "Opt.hpp"
#include "Log.hpp"
#include "Opt.hpp"
#include "Xwim.hpp"
using namespace xwim;
using namespace std;
template <>
struct TCLAP::ArgTraits<std::filesystem::path> {
typedef ValueLike ValueCategory;
};
UserOpt parse_args(int argc, char** argv) {
// 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 <files>", cmd_line, false};
TCLAP::SwitchArg arg_noninteractive
{"ni", "noninteractive", "Fail if action cannot be determined", cmd_line, false};
TCLAP::ValueArg<std::filesystem::path> arg_out
{"o", "out", "Out <path>", false, std::filesystem::path{}, "A path on the filesystem", cmd_line};
TCLAP::UnlabeledMultiArg<std::filesystem::path> arg_paths
{"Paths", "Filesystem paths to extract or compress", true, "A path on the filesystem", cmd_line};
// clang-format on
cmd_line.parse(argc, argv);
UserOpt user_opt;
if(arg_compress.getValue()) user_opt.action = Action::COMPRESS;
if(arg_extract.getValue()) user_opt.action = Action::EXTRACT;
if(arg_out.isSet()) user_opt.out = arg_out.getValue();
user_opt.interactive = !arg_noninteractive.getValue();
user_opt.paths = std::set<fs::path>{arg_paths.getValue().begin(), arg_paths.getValue().end()};
return user_opt;
}
int main(int argc, char** argv) {
log::init();
Opt opt;
opt.parse(argc, argv);
opt.validate();
Xwim xwim{};
try {
xwim.dwim();
} catch (XwimError& e) {
spdlog::error(e.what());
}
UserOpt user_opt = parse_args(argc, argv);
XwimConfig xwim_config = guess_wim(user_opt);
do_wim(xwim_config);
}

View file

@ -1,4 +1,5 @@
xwim_src = ['main.cpp', 'Xwim.cpp', 'Archiver.cpp']
xwim_dwim = ['dwim/Opt.cpp']
xwim_archiver = ['archiver/LibArchiver.cpp']
is_static = get_option('default_library')=='static'
@ -8,4 +9,6 @@ xwim_libs = [dependency('libarchive', required: true, static: is_static),
dependency('spdlog', required: true, static: is_static),
dependency('tclap', required: true, static: is_static)]
executable('xwim', xwim_src+xwim_archiver, dependencies: xwim_libs)
executable('xwim',
xwim_src+xwim_archiver+xwim_dwim,
dependencies: xwim_libs)