From bc9502fbc36946f1d96d3f188e18346baddbf1d5 Mon Sep 17 00:00:00 2001 From: Aki Date: Sat, 20 Aug 2022 22:44:21 +0200 Subject: Added stub of CLI utility for handling archives This will eventually deprecate Datafile --- ArchiveEx/CMakeLists.txt | 8 +++ ArchiveEx/dat.cpp | 140 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 ArchiveEx/dat.cpp diff --git a/ArchiveEx/CMakeLists.txt b/ArchiveEx/CMakeLists.txt index b2a1948..62e414e 100644 --- a/ArchiveEx/CMakeLists.txt +++ b/ArchiveEx/CMakeLists.txt @@ -11,3 +11,11 @@ target_link_libraries( ArchiveEx PRIVATE Zlib::zlib ) +add_executable( + dat + dat.cpp + ) +target_link_libraries( + dat + PRIVATE ArchiveEx + ) diff --git a/ArchiveEx/dat.cpp b/ArchiveEx/dat.cpp new file mode 100644 index 0000000..ae1304d --- /dev/null +++ b/ArchiveEx/dat.cpp @@ -0,0 +1,140 @@ +#include + +#include +#include +#include +#include +#include + +#include + + +enum class Action +{ + NOTHING, + LIST, + UPDATE, + EXTRACT, +}; + + +struct Options +{ + bool help {false}; + Action action {Action::NOTHING}; + bool create {false}; + const char* archive {nullptr}; + std::vector files {}; +}; + + +class ArgsError : std::exception +{ +public: + ArgsError(int opt, const char* msg) : option {opt}, message {msg} {} + int option; + const char* message; +}; + + +static Options ParseArgs(int argc, char* argv[]); +static void PrintUsage(std::ostream& out=std::cerr); +static void PrintHelp(std::ostream& out=std::cout); + + +static const char* program {"dat"}; + + +int +main(int argc, char* argv[]) +try { + program = argv[0]; + const auto opts = ParseArgs(argc, argv); + if (opts.help) { + PrintUsage(std::cout); + PrintHelp(); + return 0; + } + ArchiveEx::Archive archive(opts.archive, opts.create); + switch (opts.action) { + case Action::NOTHING: + break; + case Action::LIST: + archive.PrintNamesOfEntries(); + break; + case Action::UPDATE: + for (const auto& file : opts.files) + archive.Insert(file.c_str()); // Support recursive directories tar-like + break; + case Action::EXTRACT: + break; // Not implemented + } +} +catch (const ArgsError& err) { + std::cerr << err.message; + if (err.option > 0) + std::cerr << ": " << static_cast(err.option); + std::cerr << std::endl; + PrintUsage(); + return 1; +} +catch (const char* err) { + std::cerr << err << std::endl; + return 1; +} + + +Options +ParseArgs(int argc, char* argv[]) +{ + int opt; + Options opts; + while (-1 != (opt = getopt(argc, argv, ":hluxc"))) { + switch (opt) { + case 'h': + opts.help = true; + return opts; // No need to waste time as program won't do anything else anyway. + case 'l': + opts.action = Action::LIST; + break; + case 'u': + opts.action = Action::UPDATE; + break; + case 'x': + opts.action = Action::EXTRACT; + break; + case 'c': + opts.create = true; + break; + case ':': + throw ArgsError(optopt, "missing argument for option"); + default: + throw ArgsError(optopt, "invalid option"); + } + } + if (optind >= argc) + throw ArgsError(0, "missing archive name"); + opts.archive = argv[optind++]; + for (; optind < argc; ++optind) + opts.files.emplace_back(argv[optind]); + return opts; +} + + +void +PrintUsage(std::ostream& out) +{ + out << "Usage: " << program << " [-hluxc] archive [file [files...]]" << std::endl; +} + + +void +PrintHelp(std::ostream& out) +{ + out << "Options:" << std::endl; + out << " -h\tPrints this help message and exits." << std::endl; + out << " -l\tLists files in the archive." << std::endl; + out << " -u\tInserts files from file system into archive." << std::endl; + out << " -x\tExtracts files from the archive." << std::endl; + out << " -c\tCreate the archive if it does not exist." << std::endl; +} -- cgit v1.1