refactor: introduce main_adapter and remove main overloads

This commit is contained in:
Marcus Holland-Moritz 2024-08-02 17:44:55 +02:00
parent 33ed66ce0a
commit 099a7b3727
19 changed files with 104 additions and 171 deletions

View File

@ -683,8 +683,8 @@ list(APPEND LIBDWARFS_EXTRACTOR_SRC
)
list(APPEND LIBDWARFS_TOOL_SRC
src/dwarfs/tool/call_sys_main_iolayer.cpp
src/dwarfs/tool/iolayer.cpp
src/dwarfs/tool/main_adapter.cpp
src/dwarfs/tool/safe_main.cpp
src/dwarfs/tool/sys_char.cpp
src/dwarfs/tool/tool.cpp

View File

@ -1,38 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/**
* \author Marcus Holland-Moritz (github@mhxnet.de)
* \copyright Copyright (c) Marcus Holland-Moritz
*
* This file is part of dwarfs.
*
* dwarfs is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dwarfs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <span>
#include <dwarfs/tool/sys_char.h>
namespace dwarfs::tool {
struct iolayer;
int call_sys_main_iolayer(std::span<std::string_view> args, iolayer const& iol,
int (*main)(int, sys_char**, iolayer const&));
int call_sys_main_iolayer(std::span<std::string> args, iolayer const& iol,
int (*main)(int, sys_char**, iolayer const&));
} // namespace dwarfs::tool

View File

@ -21,24 +21,33 @@
#pragma once
#include <iosfwd>
#include <span>
#include <string>
#include <string_view>
#include <dwarfs/tool/sys_char.h>
#include <dwarfs/tool/tool_fwd.h>
namespace dwarfs::tool {
struct iolayer;
}
class main_adapter {
public:
using main_fn_type = int (*)(int, sys_char**, iolayer const&);
#define DWARFS_TOOL_MAIN_DECL(tool_name) \
namespace dwarfs::tool { \
int tool_name##_main(std::span<std::string> args, iolayer const& iol); \
int tool_name##_main(std::span<std::string_view> args, iolayer const& iol); \
int tool_name##_main(int argc, sys_char** argv, iolayer const& iol); \
int tool_name##_main(int argc, sys_char** argv); \
}
explicit main_adapter(main_fn_type main_fn)
: main_fn_(main_fn) {}
int operator()(int argc, sys_char** argv) const;
int operator()(std::span<std::string> args, iolayer const& iol) const;
int operator()(std::span<std::string_view> args, iolayer const& iol) const;
int safe(int argc, sys_char** argv) const;
int safe(std::span<std::string> args, iolayer const& iol) const;
int safe(std::span<std::string_view> args, iolayer const& iol) const;
private:
main_fn_type main_fn_{nullptr};
};
} // namespace dwarfs::tool

View File

@ -26,8 +26,6 @@
#include <boost/program_options.hpp>
#include <dwarfs/tool/call_sys_main_iolayer.h>
#ifdef DWARFS_BUILTIN_MANPAGE
#include <dwarfs/tool/manpage.h>
#endif

View File

@ -21,10 +21,16 @@
#pragma once
#include <dwarfs/tool/tool_fwd.h>
#include <dwarfs/tool/sys_char.h>
DWARFS_TOOL_MAIN_DECL(mkdwarfs)
DWARFS_TOOL_MAIN_DECL(dwarfsck)
DWARFS_TOOL_MAIN_DECL(dwarfsextract)
DWARFS_TOOL_MAIN_DECL(dwarfsbench)
DWARFS_TOOL_MAIN_DECL(dwarfs)
namespace dwarfs::tool {
struct iolayer;
int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol);
int dwarfsck_main(int argc, sys_char** argv, iolayer const& iol);
int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol);
int dwarfsbench_main(int argc, sys_char** argv, iolayer const& iol);
int dwarfs_main(int argc, sys_char** argv, iolayer const& iol);
} // namespace dwarfs::tool

View File

@ -19,10 +19,11 @@
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/
#include <dwarfs/tool/safe_main.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs_tool_main.h>
int SYS_MAIN(int argc, dwarfs::tool::sys_char** argv) {
return dwarfs::tool::safe_main(
[&] { return dwarfs::tool::dwarfs_main(argc, argv); });
using namespace dwarfs::tool;
int SYS_MAIN(int argc, sys_char** argv) {
return main_adapter(dwarfs_main).safe(argc, argv);
}

View File

@ -21,17 +21,17 @@
#include <vector>
#include <dwarfs/tool/call_sys_main_iolayer.h>
extern "C" int dwarfs_wcwidth(int ucs);
#include <dwarfs/tool/iolayer.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs/tool/safe_main.h>
namespace dwarfs::tool {
namespace {
template <typename T>
int call_sys_main_iolayer_impl(std::span<T> args, iolayer const& iol,
int (*main)(int, sys_char**, iolayer const&)) {
int call_sys_main_iolayer(std::span<T> args, iolayer const& iol,
main_adapter::main_fn_type main_fn) {
std::vector<sys_string> argv;
std::vector<sys_char*> argv_ptrs;
argv.reserve(args.size());
@ -40,19 +40,36 @@ int call_sys_main_iolayer_impl(std::span<T> args, iolayer const& iol,
argv.emplace_back(string_to_sys_string(std::string(arg)));
argv_ptrs.emplace_back(argv.back().data());
}
return main(argv_ptrs.size(), argv_ptrs.data(), iol);
return main_fn(argv_ptrs.size(), argv_ptrs.data(), iol);
}
} // namespace
int call_sys_main_iolayer(std::span<std::string_view> args, iolayer const& iol,
int (*main)(int, sys_char**, iolayer const&)) {
return call_sys_main_iolayer_impl(args, iol, main);
int main_adapter::operator()(int argc, sys_char** argv) const {
return main_fn_(argc, argv, iolayer::system_default());
}
int call_sys_main_iolayer(std::span<std::string> args, iolayer const& iol,
int (*main)(int, sys_char**, iolayer const&)) {
return call_sys_main_iolayer_impl(args, iol, main);
int main_adapter::operator()(std::span<std::string> args,
iolayer const& iol) const {
return call_sys_main_iolayer(args, iol, main_fn_);
}
int main_adapter::operator()(std::span<std::string_view> args,
iolayer const& iol) const {
return call_sys_main_iolayer(args, iol, main_fn_);
}
int main_adapter::safe(int argc, sys_char** argv) const {
return safe_main([&] { return (*this)(argc, argv); });
}
int main_adapter::safe(std::span<std::string> args, iolayer const& iol) const {
return safe_main([&] { return (*this)(args, iol); });
}
int main_adapter::safe(std::span<std::string_view> args,
iolayer const& iol) const {
return safe_main([&] { return (*this)(args, iol); });
}
} // namespace dwarfs::tool

View File

@ -96,7 +96,6 @@
#include <dwarfs/performance_monitor.h>
#include <dwarfs/scope_exit.h>
#include <dwarfs/string.h>
#include <dwarfs/tool/call_sys_main_iolayer.h>
#include <dwarfs/tool/iolayer.h>
#include <dwarfs/tool/tool.h>
#include <dwarfs/util.h>
@ -1653,16 +1652,4 @@ int dwarfs_main(int argc, sys_char** argv, iolayer const& iol) {
#endif
}
int dwarfs_main(int argc, sys_char** argv) {
return dwarfs_main(argc, argv, iolayer::system_default());
}
int dwarfs_main(std::span<std::string> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, dwarfs_main);
}
int dwarfs_main(std::span<std::string_view> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, dwarfs_main);
}
} // namespace dwarfs::tool

View File

@ -19,10 +19,11 @@
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/
#include <dwarfs/tool/safe_main.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs_tool_main.h>
int SYS_MAIN(int argc, dwarfs::tool::sys_char** argv) {
return dwarfs::tool::safe_main(
[&] { return dwarfs::tool::dwarfsbench_main(argc, argv); });
using namespace dwarfs::tool;
int SYS_MAIN(int argc, sys_char** argv) {
return main_adapter(dwarfsbench_main).safe(argc, argv);
}

View File

@ -32,7 +32,6 @@
#include <dwarfs/mmap.h>
#include <dwarfs/options.h>
#include <dwarfs/thread_pool.h>
#include <dwarfs/tool/call_sys_main_iolayer.h>
#include <dwarfs/tool/iolayer.h>
#include <dwarfs/tool/tool.h>
#include <dwarfs/util.h>
@ -134,16 +133,4 @@ int dwarfsbench_main(int argc, sys_char** argv, iolayer const& iol) {
return 0;
}
int dwarfsbench_main(int argc, sys_char** argv) {
return dwarfsbench_main(argc, argv, iolayer::system_default());
}
int dwarfsbench_main(std::span<std::string> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, dwarfsbench_main);
}
int dwarfsbench_main(std::span<std::string_view> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, dwarfsbench_main);
}
} // namespace dwarfs::tool

View File

@ -19,10 +19,11 @@
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/
#include <dwarfs/tool/safe_main.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs_tool_main.h>
int SYS_MAIN(int argc, dwarfs::tool::sys_char** argv) {
return dwarfs::tool::safe_main(
[&] { return dwarfs::tool::dwarfsck_main(argc, argv); });
using namespace dwarfs::tool;
int SYS_MAIN(int argc, sys_char** argv) {
return main_adapter(dwarfsck_main).safe(argc, argv);
}

View File

@ -45,7 +45,6 @@
#include <dwarfs/options.h>
#include <dwarfs/os_access.h>
#include <dwarfs/thread_pool.h>
#include <dwarfs/tool/call_sys_main_iolayer.h>
#include <dwarfs/tool/iolayer.h>
#include <dwarfs/tool/program_options_helpers.h>
#include <dwarfs/tool/tool.h>
@ -365,16 +364,4 @@ int dwarfsck_main(int argc, sys_char** argv, iolayer const& iol) {
return 0;
}
int dwarfsck_main(int argc, sys_char** argv) {
return dwarfsck_main(argc, argv, iolayer::system_default());
}
int dwarfsck_main(std::span<std::string> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, dwarfsck_main);
}
int dwarfsck_main(std::span<std::string_view> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, dwarfsck_main);
}
} // namespace dwarfs::tool

View File

@ -19,10 +19,11 @@
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/
#include <dwarfs/tool/safe_main.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs_tool_main.h>
int SYS_MAIN(int argc, dwarfs::tool::sys_char** argv) {
return dwarfs::tool::safe_main(
[&] { return dwarfs::tool::dwarfsextract_main(argc, argv); });
using namespace dwarfs::tool;
int SYS_MAIN(int argc, sys_char** argv) {
return main_adapter(dwarfsextract_main).safe(argc, argv);
}

View File

@ -35,7 +35,6 @@
#include <dwarfs/os_access.h>
#include <dwarfs/performance_monitor.h>
#include <dwarfs/string.h>
#include <dwarfs/tool/call_sys_main_iolayer.h>
#include <dwarfs/tool/iolayer.h>
#include <dwarfs/tool/program_options_helpers.h>
#include <dwarfs/tool/tool.h>
@ -230,16 +229,4 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
return rv;
}
int dwarfsextract_main(int argc, sys_char** argv) {
return dwarfsextract_main(argc, argv, iolayer::system_default());
}
int dwarfsextract_main(std::span<std::string> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, dwarfsextract_main);
}
int dwarfsextract_main(std::span<std::string_view> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, dwarfsextract_main);
}
} // namespace dwarfs::tool

View File

@ -19,10 +19,11 @@
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/
#include <dwarfs/tool/safe_main.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs_tool_main.h>
int SYS_MAIN(int argc, dwarfs::tool::sys_char** argv) {
return dwarfs::tool::safe_main(
[&] { return dwarfs::tool::mkdwarfs_main(argc, argv); });
using namespace dwarfs::tool;
int SYS_MAIN(int argc, sys_char** argv) {
return main_adapter(mkdwarfs_main).safe(argc, argv);
}

View File

@ -82,7 +82,6 @@
#include <dwarfs/string.h>
#include <dwarfs/terminal.h>
#include <dwarfs/thread_pool.h>
#include <dwarfs/tool/call_sys_main_iolayer.h>
#include <dwarfs/tool/iolayer.h>
#include <dwarfs/tool/program_options_helpers.h>
#include <dwarfs/tool/tool.h>
@ -1403,16 +1402,4 @@ int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol) {
return errors > 0 ? 2 : 0;
}
int mkdwarfs_main(int argc, sys_char** argv) {
return mkdwarfs_main(argc, argv, iolayer::system_default());
}
int mkdwarfs_main(std::span<std::string> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, mkdwarfs_main);
}
int mkdwarfs_main(std::span<std::string_view> args, iolayer const& iol) {
return call_sys_main_iolayer(args, iol, mkdwarfs_main);
}
} // namespace dwarfs::tool

View File

@ -34,7 +34,7 @@
#include <range/v3/view/join.hpp>
#include <range/v3/view/map.hpp>
#include <dwarfs/tool/safe_main.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs/tool/tool.h>
#include <dwarfs_tool_main.h>
@ -48,12 +48,12 @@ using namespace dwarfs::tool;
#define EXE_EXT ""
#endif
std::map<std::string_view, int (*)(int, sys_char**)> const functions{
{"dwarfs", &dwarfs_main},
{"mkdwarfs", &mkdwarfs_main},
{"dwarfsck", &dwarfsck_main},
{"dwarfsextract", &dwarfsextract_main},
// {"dwarfsbench", &dwarfsbench_main},
std::map<std::string_view, main_adapter::main_fn_type> const functions{
{"dwarfs", dwarfs_main},
{"mkdwarfs", mkdwarfs_main},
{"dwarfsck", dwarfsck_main},
{"dwarfsextract", dwarfsextract_main},
// {"dwarfsbench", dwarfsbench_main},
};
} // namespace
@ -66,7 +66,7 @@ int SYS_MAIN(int argc, sys_char** argv) {
if (auto ext = path.extension().string(); ext.empty() || ext == EXE_EXT) {
auto stem = path.stem().string();
if (auto it = functions.find(stem); it != functions.end()) {
return safe_main([&] { return it->second(argc, argv); });
return main_adapter(it->second).safe(argc, argv);
}
// see if the stem has an appended version and try removing that
@ -77,7 +77,7 @@ int SYS_MAIN(int argc, sys_char** argv) {
it != functions.end()) {
std::cerr << "running " << stem << " as " << stem.substr(0, pos)
<< "\n";
return safe_main([&] { return it->second(argc, argv); });
return main_adapter(it->second).safe(argc, argv);
}
}
}
@ -92,8 +92,7 @@ int SYS_MAIN(int argc, sys_char** argv) {
argv_copy.reserve(argc - 1);
argv_copy.emplace_back(argv[0]);
std::copy(argv + 2, argv + argc, std::back_inserter(argv_copy));
return safe_main(
[&] { return it->second(argc - 1, argv_copy.data()); });
return main_adapter(it->second).safe(argc - 1, argv_copy.data());
}
}
}

View File

@ -35,6 +35,7 @@
#include <dwarfs/block_range.h>
#include <dwarfs/error.h>
#include <dwarfs/filesystem_v2.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs_tool_main.h>
#include <dwarfs/internal/cached_block.h>
@ -173,7 +174,7 @@ TEST_P(options_test, cache_stress) {
std::vector<std::string> args{"mkdwarfs", "-i", "/", "-o", "-",
"-l3", "-S16", "-C", compression};
EXPECT_EQ(0, mkdwarfs_main(args, iol.get()));
EXPECT_EQ(0, tool::main_adapter(tool::mkdwarfs_main)(args, iol.get()));
mm = std::make_shared<test::mmap_mock>(iol.out());
}

View File

@ -45,6 +45,7 @@
#include <dwarfs/history.h>
#include <dwarfs/iovec_read_buf.h>
#include <dwarfs/logger.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs/util.h>
#include <dwarfs_tool_main.h>
@ -119,7 +120,7 @@ class tool_main_test : public testing::Test {
class tester_common {
public:
using main_ptr_t = int (*)(std::span<std::string>, iolayer const&);
using main_ptr_t = tool::main_adapter::main_fn_type;
tester_common(main_ptr_t mp, std::string toolname,
std::shared_ptr<test::os_access_mock> pos)
@ -133,7 +134,7 @@ class tester_common {
int run(std::vector<std::string> args) {
args.insert(args.begin(), toolname_);
return main_(args, iol->get());
return tool::main_adapter(main_)(args, iol->get());
}
int run(std::initializer_list<std::string> args) {
@ -409,7 +410,7 @@ class mkdwarfs_main_test : public tool_main_test {
public:
int run(std::vector<std::string> args) {
args.insert(args.begin(), "mkdwarfs");
return mkdwarfs_main(args, iol->get());
return tool::main_adapter(tool::mkdwarfs_main)(args, iol->get());
}
};
@ -417,7 +418,7 @@ class dwarfsck_main_test : public tool_main_test {
public:
int run(std::vector<std::string> args) {
args.insert(args.begin(), "dwarfsck");
return dwarfsck_main(args, iol->get());
return tool::main_adapter(tool::dwarfsck_main)(args, iol->get());
}
};
@ -425,7 +426,7 @@ class dwarfsextract_main_test : public tool_main_test {
public:
int run(std::vector<std::string> args) {
args.insert(args.begin(), "dwarfsextract");
return dwarfsextract_main(args, iol->get());
return tool::main_adapter(tool::dwarfsextract_main)(args, iol->get());
}
};