Compare commits
2 commits
master
...
separate-p
Author | SHA1 | Date | |
---|---|---|---|
d95f3d0f32 | |||
0663f42aec |
6 changed files with 97 additions and 70 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
.clangd/
|
||||
.cache/
|
||||
build/
|
||||
target/
|
||||
compile_commands.json
|
||||
|
|
46
src/Opt.hpp
Normal file
46
src/Opt.hpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
namespace xwim {
|
||||
|
||||
enum class Action { EXTRACT, COMPRESS };
|
||||
|
||||
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(), "");
|
||||
}
|
||||
};
|
|
@ -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() {
|
||||
|
|
21
src/Xwim.hpp
21
src/Xwim.hpp
|
@ -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(), "");
|
||||
}
|
||||
};
|
||||
|
|
86
src/main.cpp
86
src/main.cpp
|
@ -10,66 +10,60 @@
|
|||
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "Common.hpp"
|
||||
#include "Log.hpp"
|
||||
#include "Opt.hpp"
|
||||
#include "Xwim.hpp"
|
||||
|
||||
using namespace xwim;
|
||||
using namespace std;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
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();
|
||||
|
||||
TCLAP::CmdLine cmd{"xwim - Do What I Mean Extractor", ' ', "0.3.0"};
|
||||
|
||||
TCLAP::SwitchArg arg_compress{"c", "compress", "Compress <files>", cmd,
|
||||
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 {
|
||||
xwim.try_infer();
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue