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/
|
.clangd/
|
||||||
|
.cache/
|
||||||
build/
|
build/
|
||||||
target/
|
target/
|
||||||
compile_commands.json
|
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 "Archiver.hpp"
|
||||||
#include "Common.hpp"
|
#include "Common.hpp"
|
||||||
|
|
||||||
namespace xwim {
|
|
||||||
using namespace std;
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
#if defined(unix) || defined(__unix__) || defined(__unix)
|
#if defined(unix) || defined(__unix__) || defined(__unix)
|
||||||
std::string default_extension = ".tar.gz";
|
std::string default_extension = ".tar.gz";
|
||||||
#elif defined(_win32) || defined(__win32__) || defined(__windows__)
|
#elif defined(_win32) || defined(__win32__) || defined(__windows__)
|
||||||
|
@ -26,6 +22,10 @@ std::string default_extension = ".zip";
|
||||||
std::string default_extension = ".zip";
|
std::string default_extension = ".zip";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace xwim {
|
||||||
|
using namespace std;
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
Xwim::Xwim() : action{Action::UNKNOWN} {}
|
Xwim::Xwim() : action{Action::UNKNOWN} {}
|
||||||
|
|
||||||
void Xwim::try_infer() {
|
void Xwim::try_infer() {
|
||||||
|
|
21
src/Xwim.hpp
21
src/Xwim.hpp
|
@ -9,13 +9,14 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "Common.hpp"
|
#include "Common.hpp"
|
||||||
|
#include "Opt.hpp"
|
||||||
#include "Archiver.hpp"
|
#include "Archiver.hpp"
|
||||||
|
|
||||||
namespace xwim {
|
namespace xwim {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
enum class Action { UNKNOWN, EXTRACT, COMPRESS };
|
Xwim xwim(UserOpt user_opt);
|
||||||
|
|
||||||
class Xwim {
|
class Xwim {
|
||||||
private:
|
private:
|
||||||
|
@ -43,21 +44,3 @@ class Xwim {
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace 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 <cstdlib>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "Common.hpp"
|
#include "Common.hpp"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
|
#include "Opt.hpp"
|
||||||
#include "Xwim.hpp"
|
#include "Xwim.hpp"
|
||||||
|
|
||||||
using namespace xwim;
|
using namespace xwim;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct TCLAP::ArgTraits<std::filesystem::path> {
|
struct TCLAP::ArgTraits<std::filesystem::path> {
|
||||||
typedef ValueLike ValueCategory;
|
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) {
|
int main(int argc, char** argv) {
|
||||||
log::init();
|
log::init();
|
||||||
|
|
||||||
TCLAP::CmdLine cmd{"xwim - Do What I Mean Extractor", ' ', "0.3.0"};
|
UserOpt user_opt = parse_args(argc, argv);
|
||||||
|
XwimConfig xwim_config = guess_wim(user_opt);
|
||||||
TCLAP::SwitchArg arg_compress{"c", "compress", "Compress <files>", cmd,
|
do_wim(xwim_config);
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
xwim_src = ['main.cpp', 'Xwim.cpp', 'Archiver.cpp']
|
xwim_src = ['main.cpp', 'Xwim.cpp', 'Archiver.cpp']
|
||||||
|
xwim_dwim = ['dwim/Opt.cpp']
|
||||||
xwim_archiver = ['archiver/LibArchiver.cpp']
|
xwim_archiver = ['archiver/LibArchiver.cpp']
|
||||||
|
|
||||||
is_static = get_option('default_library')=='static'
|
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('spdlog', required: true, static: is_static),
|
||||||
dependency('tclap', 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