summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Levine <plevine457@gmail.com>2023-09-05 03:34:44 -0400
committerSam James <sam@gentoo.org>2023-09-18 10:48:22 +0100
commitd4d007aac8769809cdf3396100ce5030f980bfa2 (patch)
tree6b202039f9eaea252ec14dc8821c7471a2c7d1ad /sys-block
parentgui-wm/hyprland: drop 0.27.2-r1 (diff)
downloadgentoo-d4d007aac8769809cdf3396100ce5030f980bfa2.tar.gz
gentoo-d4d007aac8769809cdf3396100ce5030f980bfa2.tar.bz2
gentoo-d4d007aac8769809cdf3396100ce5030f980bfa2.zip
sys-block/thin-provisioning-tools: fix bug 911775
Many name clashes between boost::optional and std::optional are resolved with explicit namespace qualification. Because of a problem with a ADL and a global "operator<<" function name not being included in gtest's environment, they had to be defined in "namespace boost {". Utterly hackish but only affects two testcase code files. Finally, there was an issue of a "one-past the end" access causing a segfault that was fixed by allocating an extra element to a zeroed std::vector. Closes: https://bugs.gentoo.org/911775 Signed-off-by: Peter Levine <plevine457@gmail.com> Closes: https://github.com/gentoo/gentoo/pull/32597 Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'sys-block')
-rw-r--r--sys-block/thin-provisioning-tools/files/thin-provisioning-tools-0.9.0-boost-gtest.patch622
-rw-r--r--sys-block/thin-provisioning-tools/thin-provisioning-tools-0.9.0-r4.ebuild70
2 files changed, 692 insertions, 0 deletions
diff --git a/sys-block/thin-provisioning-tools/files/thin-provisioning-tools-0.9.0-boost-gtest.patch b/sys-block/thin-provisioning-tools/files/thin-provisioning-tools-0.9.0-boost-gtest.patch
new file mode 100644
index 000000000000..ae9288db8be9
--- /dev/null
+++ b/sys-block/thin-provisioning-tools/files/thin-provisioning-tools-0.9.0-boost-gtest.patch
@@ -0,0 +1,622 @@
+Bug: https://bugs.gentoo.org/911775
+
+--- a/base/base64.cc
++++ b/base/base64.cc
+@@ -68,13 +68,13 @@
+ throw std::runtime_error("internal error, in split");
+ }
+
+- optional<unsigned> char_to_index(char c) {
++ boost::optional<unsigned> char_to_index(char c) {
+ // FIXME: very slow
+ for (unsigned i = 0; i < 64; i++)
+ if (table_[i] == c)
+- return optional<unsigned>(i);
++ return boost::optional<unsigned>(i);
+
+- return optional<unsigned>();
++ return boost::optional<unsigned>();
+ }
+
+ decoded_or_error success(vector<unsigned char> const &decoded) {
+@@ -92,7 +92,7 @@
+ }
+
+ decoded_or_error decode_quad(char c1, char c2, char c3, char c4) {
+- typedef optional<unsigned> oi;
++ typedef boost::optional<unsigned> oi;
+ unsigned char d1, d2, d3;
+ vector<unsigned char> decoded;
+
+--- a/base/run.h
++++ b/base/run.h
+@@ -1,7 +1,7 @@
+ #ifndef BASE_DATA_RANGE_H
+ #define BASE_DATA_RANGE_H
+
+-#include <boost/optional.hpp>
++#include <boost/optional/optional_io.hpp>
+ #include <ostream>
+
+ //----------------------------------------------------------------
+--- a/block-cache/copier.cc
++++ b/block-cache/copier.cc
+@@ -90,19 +90,19 @@
+ copier::wait_complete()
+ {
+ if (complete_.empty()) {
+- return optional<copy_op>();
++ return boost::optional<copy_op>();
+
+ } else {
+ auto op = complete_.front();
+ complete_.pop_front();
+- return optional<copy_op>(op);
++ return boost::optional<copy_op>(op);
+ }
+ }
+
+ void
+ copier::wait_(unsigned &micro)
+ {
+- optional<io_engine::wait_result> mp;
++ boost::optional<io_engine::wait_result> mp;
+
+ if (!pending())
+ return;
+--- a/block-cache/io_engine.cc
++++ b/block-cache/io_engine.cc
+@@ -125,13 +125,13 @@
+ return r == 1;
+ }
+
+-optional<io_engine::wait_result>
++boost::optional<io_engine::wait_result>
+ aio_engine::wait()
+ {
+ return wait_(NULL);
+ }
+
+-optional<io_engine::wait_result>
++boost::optional<io_engine::wait_result>
+ aio_engine::wait(unsigned &microsec)
+ {
+ timespec start = micro_to_ts(microsec);
+@@ -156,7 +156,7 @@
+ }
+
+ if (r == 0) {
+- return optional<wait_result>();
++ return boost::optional<wait_result>();
+ }
+
+ iocb *cb = reinterpret_cast<iocb *>(event.obj);
+@@ -164,19 +164,19 @@
+
+ if (event.res == cb->u.c.nbytes) {
+ cbs_.free(cb);
+- return optional<wait_result>(make_pair(true, context));
++ return boost::optional<wait_result>(make_pair(true, context));
+
+ } else if (static_cast<int>(event.res) < 0) {
+ cbs_.free(cb);
+- return optional<wait_result>(make_pair(false, context));
++ return boost::optional<wait_result>(make_pair(false, context));
+
+ } else {
+ cbs_.free(cb);
+- return optional<wait_result>(make_pair(false, context));
++ return boost::optional<wait_result>(make_pair(false, context));
+ }
+
+ // shouldn't get here
+- return optional<wait_result>(make_pair(false, 0));
++ return boost::optional<wait_result>(make_pair(false, 0));
+ }
+
+ struct timespec
+--- a/caching/cache_restore.cc
++++ b/caching/cache_restore.cc
+@@ -40,8 +40,8 @@
+ override_version(1) {
+ }
+
+- optional<string> input;
+- optional<string> output;
++ boost::optional<string> input;
++ boost::optional<string> output;
+
+ uint32_t metadata_version;
+ bool clean_shutdown;
+@@ -154,11 +154,11 @@
+ return 0;
+
+ case 'i':
+- fs.input = optional<string>(string(optarg));
++ fs.input = boost::optional<string>(string(optarg));
+ break;
+
+ case 'o':
+- fs.output = optional<string>(string(optarg));
++ fs.output = boost::optional<string>(string(optarg));
+ break;
+
+ case 'q':
+--- a/caching/cache_writeback.cc
++++ b/caching/cache_writeback.cc
+@@ -150,7 +150,7 @@
+ }
+
+ void check_for_completed_copies(bool block = false) {
+- optional<copy_op> mop;
++ boost::optional<copy_op> mop;
+
+ do {
+ if (block)
+--- a/era/era_invalidate.cc
++++ b/era/era_invalidate.cc
+@@ -27,7 +27,7 @@
+ }
+
+ bool metadata_snapshot_;
+- optional<uint32_t> era_threshold_;
++ boost::optional<uint32_t> era_threshold_;
+ };
+
+ //--------------------------------
+@@ -88,7 +88,7 @@
+ walk_writeset_tree(md.tm_, *md.writeset_tree_, v, dv);
+ }
+
+- void mark_blocks_since(metadata const &md, optional<uint32_t> const &threshold, set<uint32_t> &result) {
++ void mark_blocks_since(metadata const &md, boost::optional<uint32_t> const &threshold, set<uint32_t> &result) {
+ if (!threshold)
+ // Can't get here, just putting in to pacify the compiler
+ throw std::runtime_error("threshold not set");
+--- a/era/era_restore.cc
++++ b/era/era_restore.cc
+@@ -28,8 +28,8 @@
+ : quiet(false) {
+ }
+
+- optional<string> input;
+- optional<string> output;
++ boost::optional<string> input;
++ boost::optional<string> output;
+ bool quiet;
+ };
+
+@@ -99,11 +99,11 @@
+ return 0;
+
+ case 'i':
+- fs.input = optional<string>(string(optarg));
++ fs.input = boost::optional<string>(string(optarg));
+ break;
+
+ case 'o':
+- fs.output = optional<string>(string(optarg));
++ fs.output = boost::optional<string>(string(optarg));
+ break;
+
+ case 'q':
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -162,7 +162,7 @@
+ TOP_BUILDDIR:=@top_builddir@
+ CFLAGS+=-fPIC
+ CFLAGS+=@LFS_FLAGS@
+-CXXFLAGS+=-fPIC -fno-strict-aliasing -std=c++11
++CXXFLAGS+=-fPIC -fno-strict-aliasing
+
+ ifeq ("@DEVTOOLS@", "yes")
+ CXXFLAGS+=-DDEV_TOOLS
+--- a/persistent-data/hex_dump.h
++++ b/persistent-data/hex_dump.h
+@@ -19,6 +19,7 @@
+ #ifndef HEX_DUMP_H
+ #define HEX_DUMP_H
+
++#include <cstddef>
+ #include <iosfwd>
+
+ //----------------------------------------------------------------
+--- a/persistent-data/transaction_manager.cc
++++ b/persistent-data/transaction_manager.cc
+@@ -48,7 +48,7 @@
+ transaction_manager::write_ref
+ transaction_manager::new_block(validator v)
+ {
+- optional<block_address> mb = sm_->new_block();
++ boost::optional<block_address> mb = sm_->new_block();
+ if (!mb)
+ throw runtime_error("transaction_manager::new_block() couldn't allocate new block");
+
+@@ -67,7 +67,7 @@
+ return make_pair(bm_->write_lock(orig, v), need_inc);
+
+ read_ref src = bm_->read_lock(orig, v);
+- optional<block_address> mb = sm_->new_block();
++ boost::optional<block_address> mb = sm_->new_block();
+ if (!mb)
+ throw runtime_error("transaction_manager::shadow() couldn't allocate new block");
+
+--- a/thin-provisioning/metadata_checker.cc
++++ b/thin-provisioning/metadata_checker.cc
+@@ -182,7 +182,7 @@
+ error_state examine_mapping_tree_(transaction_manager::ptr tm,
+ superblock_detail::superblock const &sb,
+ nested_output &out,
+- optional<space_map::ptr> data_sm,
++ boost::optional<space_map::ptr> data_sm,
+ bool ignore_non_fatal) {
+ out << "examining mapping tree" << end_message();
+ nested_output::nest _ = out.push();
+@@ -213,7 +213,7 @@
+ error_state examine_mapping_tree(transaction_manager::ptr tm,
+ superblock_detail::superblock const &sb,
+ nested_output &out,
+- optional<space_map::ptr> data_sm,
++ boost::optional<space_map::ptr> data_sm,
+ bool ignore_non_fatal) {
+ error_state err = examine_devices_tree_(tm, sb, out, ignore_non_fatal);
+ err << examine_mapping_tree_(tm, sb, out, data_sm, ignore_non_fatal);
+@@ -403,7 +403,7 @@
+ // until that there's a better solution in space
+ // and time complexity
+ space_map::ptr data_sm{open_disk_sm(*tm, &sb.data_space_map_root_)};
+- optional<space_map::ptr> core_sm;
++ boost::optional<space_map::ptr> core_sm;
+ err_ << examine_data_mappings(tm, sb, options_.data_mapping_opts_, out_, core_sm);
+
+ if (err_ == FATAL)
+@@ -418,7 +418,7 @@
+ err_ << compare_space_maps(data_sm, *core_sm, out_);
+ } else
+ err_ << examine_data_mappings(tm, sb, options_.data_mapping_opts_, out_,
+- optional<space_map::ptr>());
++ boost::optional<space_map::ptr>());
+
+ metadata_checked_ = true;
+ }
+@@ -509,7 +509,7 @@
+ superblock_detail::superblock const &sb,
+ check_options::data_mapping_options option,
+ nested_output &out,
+- optional<space_map::ptr> data_sm) {
++ boost::optional<space_map::ptr> data_sm) {
+ error_state err = NO_ERROR;
+
+ switch (option) {
+--- a/thin-provisioning/metadata_dumper.cc
++++ b/thin-provisioning/metadata_dumper.cc
+@@ -125,7 +125,7 @@
+ };
+
+ // See comment on get_map_ids
+- optional<set<uint32_t> >
++ boost::optional<set<uint32_t> >
+ get_dev_ids(transaction_manager &tm, block_address root) {
+ d_thin_id_extractor de;
+ fatal_details_damage dv;
+@@ -134,7 +134,7 @@
+ try {
+ walk_device_tree(tree, de, dv, true);
+ } catch (...) {
+- return optional<set<uint32_t>>();
++ return boost::optional<set<uint32_t>>();
+ }
+
+ return de.dd_;
+@@ -150,7 +150,7 @@
+
+ // The walk will do more sanity checks than we did when scanning the metadata, so
+ // it's possible that it will fail and throw a metadata damage exception.
+- optional<set<uint32_t> >
++ boost::optional<set<uint32_t> >
+ get_map_ids(transaction_manager &tm, block_address root) {
+ m_thin_id_extractor me;
+ fatal_mapping_damage mv;
+@@ -159,7 +159,7 @@
+ try {
+ walk_mapping_tree(tree, me, mv, true);
+ } catch (...) {
+- return optional<set<uint32_t>>();
++ return boost::optional<set<uint32_t>>();
+ }
+
+ return me.dd_;
+@@ -288,7 +288,7 @@
+ uint32_t time;
+ };
+
+- optional<roots>
++ boost::optional<roots>
+ find_best_roots(transaction_manager &tm) {
+ vector<node_info> mapping_roots;
+ vector<node_info> device_roots;
+@@ -334,7 +334,7 @@
+ if (pairs.size())
+ return mk_roots(pairs[0]);
+ else
+- return optional<roots>();
++ return boost::optional<roots>();
+ }
+
+ private:
+@@ -623,12 +623,12 @@
+ }
+ }
+
+- optional<node_info> lookup_info(block_address b) const {
++ boost::optional<node_info> lookup_info(block_address b) const {
+ auto it = infos_.find(b);
+ if (it == infos_.end())
+- return optional<node_info>();
++ return boost::optional<node_info>();
+
+- return optional<node_info>(it->second);
++ return boost::optional<node_info>(it->second);
+ }
+
+ block_manager &bm_;
+@@ -846,16 +846,16 @@
+ return sb;
+ }
+
+- optional<superblock_detail::superblock>
++ boost::optional<superblock_detail::superblock>
+ maybe_read_superblock(block_manager::ptr bm)
+ {
+ try {
+ auto sb = read_superblock(bm);
+- return optional<superblock_detail::superblock>(sb);
++ return boost::optional<superblock_detail::superblock>(sb);
+ } catch (...) {
+ }
+
+- return optional<superblock_detail::superblock>();
++ return boost::optional<superblock_detail::superblock>();
+ }
+
+ void
+--- a/thin-provisioning/thin_dump.cc
++++ b/thin-provisioning/thin_dump.cc
+@@ -50,7 +50,7 @@
+ string format;
+ bool repair;
+ bool use_metadata_snap;
+- optional<block_address> snap_location;
++ boost::optional<block_address> snap_location;
+ };
+
+ metadata::ptr open_metadata(string const &path, struct flags &flags) {
+--- a/thin-provisioning/thin_ls.cc
++++ b/thin-provisioning/thin_ls.cc
+@@ -238,7 +238,7 @@
+
+ void pass1(metadata::ptr md, mapping_set &mappings, ::uint64_t dev_id) {
+ dev_tree::key k = {dev_id};
+- optional<::uint64_t> dev_root = md->mappings_top_level_->lookup(k);
++ boost::optional<::uint64_t> dev_root = md->mappings_top_level_->lookup(k);
+
+ if (!dev_root)
+ throw runtime_error("couldn't find mapping tree root");
+@@ -254,7 +254,7 @@
+
+ block_address count_exclusives(metadata::ptr md, mapping_set const &mappings, ::uint64_t dev_id) {
+ dev_tree::key k = {dev_id};
+- optional<::uint64_t> dev_root = md->mappings_top_level_->lookup(k);
++ boost::optional<::uint64_t> dev_root = md->mappings_top_level_->lookup(k);
+
+ if (!dev_root)
+ throw runtime_error("couldn't find mapping tree root");
+@@ -324,7 +324,7 @@
+ metadata::ptr md;
+
+ if (flags.use_metadata_snap)
+- md.reset(new metadata(bm, optional<block_address>()));
++ md.reset(new metadata(bm, boost::optional<block_address>()));
+ else
+ md.reset(new metadata(bm));
+
+--- a/unit-tests/bitset_t.cc
++++ b/unit-tests/bitset_t.cc
+@@ -60,14 +60,14 @@
+ tm_(bm_, sm_) {
+ }
+
+- bitset::ptr
++ persistent_data::bitset::ptr
+ create_bitset() {
+- return bitset::ptr(new bitset(tm_));
++ return persistent_data::bitset::ptr(new persistent_data::bitset(tm_));
+ }
+
+- bitset::ptr
++ persistent_data::bitset::ptr
+ open_bitset(block_address root, unsigned count) {
+- return bitset::ptr(new bitset(tm_, root, count));
++ return persistent_data::bitset::ptr(new persistent_data::bitset(tm_, root, count));
+ }
+
+ private:
+@@ -81,7 +81,7 @@
+
+ TEST_F(BitsetTests, create_empty_bitset)
+ {
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+ ASSERT_THROW(bs->get(0), runtime_error);
+ }
+
+@@ -89,7 +89,7 @@
+ {
+ unsigned const COUNT = 100000;
+
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+ bs->grow(COUNT, false);
+
+ for (unsigned i = 0; i < COUNT; i++)
+@@ -100,7 +100,7 @@
+ {
+ unsigned const COUNT = 100000;
+
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+ bs->grow(COUNT, true);
+
+ for (unsigned i = 0; i < COUNT; i++)
+@@ -111,7 +111,7 @@
+ {
+ unsigned const COUNT = 100000;
+
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+ bs->grow(COUNT, false);
+ ASSERT_THROW(bs->grow(COUNT / 2, false), runtime_error);
+ }
+@@ -120,7 +120,7 @@
+ {
+ unsigned const COUNT = 100000;
+ unsigned const STEP = 37;
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+
+ vector<unsigned> chunks;
+ unsigned c;
+@@ -150,7 +150,7 @@
+ TEST_F(BitsetTests, set_out_of_bounds_throws)
+ {
+ unsigned const COUNT = 100000;
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+
+ ASSERT_THROW(bs->set(0, true), runtime_error);
+ bs->grow(COUNT, true);
+@@ -160,7 +160,7 @@
+ TEST_F(BitsetTests, set_works)
+ {
+ unsigned const COUNT = 100000;
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+
+ bs->grow(COUNT, true);
+ for (unsigned i = 0; i < COUNT; i += 7)
+@@ -176,7 +176,7 @@
+ block_address root;
+
+ {
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+
+ bs->grow(COUNT, true);
+ for (unsigned i = 0; i < COUNT; i += 7)
+@@ -186,7 +186,7 @@
+ }
+
+ {
+- bitset::ptr bs = open_bitset(root, COUNT);
++ persistent_data::bitset::ptr bs = open_bitset(root, COUNT);
+ for (unsigned i = 0; i < COUNT; i++)
+ ASSERT_THAT(bs->get(i), Eq(i % 7 ? true : false));
+ }
+@@ -198,7 +198,7 @@
+ block_address root;
+
+ {
+- bitset::ptr bs = create_bitset();
++ persistent_data::bitset::ptr bs = create_bitset();
+
+ bs->grow(COUNT, true);
+ for (unsigned i = 0; i < COUNT; i += 7)
+@@ -211,7 +211,7 @@
+ }
+
+ {
+- bitset::ptr bs = open_bitset(root, COUNT);
++ persistent_data::bitset::ptr bs = open_bitset(root, COUNT);
+ bitset_checker c(COUNT, 7);
+ bs->walk_bitset(c);
+ }
+--- a/unit-tests/copier_t.cc
++++ b/unit-tests/copier_t.cc
+@@ -32,23 +32,27 @@
+ namespace {
+ unsigned const BLOCK_SIZE = 64u;
+ using wait_result = io_engine::wait_result;
++}
+
+- ostream &operator <<(ostream &out, optional<wait_result> const &mwr) {
++namespace boost {
++ ostream &operator <<(ostream &out, boost::optional<wait_result> const &mwr) {
+ if (mwr) {
+ out << "Just[wait_result[" << mwr->first << ", " << mwr->second << "]]";
+ } else
+ out << "Nothing";
+ return out;
+ }
++}
+
++namespace {
+ class io_engine_mock : public io_engine {
+ public:
+ MOCK_METHOD3(open_file, handle(string const &, mode, sharing));
+ MOCK_METHOD1(close_file, void(handle));
+ MOCK_METHOD6(issue_io, bool(handle, dir, sector_t, sector_t, void *, unsigned));
+
+- MOCK_METHOD0(wait, optional<wait_result>());
+- MOCK_METHOD1(wait, optional<wait_result>(unsigned &));
++ MOCK_METHOD0(wait, boost::optional<wait_result>());
++ MOCK_METHOD1(wait, boost::optional<wait_result>(unsigned &));
+ };
+
+ class CopierTests : public Test {
+@@ -72,8 +76,8 @@
+ BLOCK_SIZE, 1 * 1024 * 1024));
+ }
+
+- static optional<wait_result> make_wr(bool success, unsigned context) {
+- return optional<wait_result>(wait_result(success, context));
++ static boost::optional<wait_result> make_wr(bool success, unsigned context) {
++ return boost::optional<wait_result>(wait_result(success, context));
+ }
+
+ void issue_successful_op(copier &c, copy_op &op, unsigned context) {
+@@ -258,7 +262,7 @@
+ WillOnce(Return(true));
+
+ EXPECT_CALL(engine_, wait(micro)).
+- WillOnce(DoAll(SetArgReferee<0>(0u), Return(optional<wait_result>())));
++ WillOnce(DoAll(SetArgReferee<0>(0u), Return(boost::optional<wait_result>())));
+
+ auto mop = c->wait(micro);
+ ASSERT_FALSE(mop);
+--- a/unit-tests/rolling_hash_t.cc
++++ b/unit-tests/rolling_hash_t.cc
+@@ -127,10 +127,10 @@
+ unsigned min = 100000, max = 0;
+
+ bytes bs = random_bytes(1024 * 1024 * 100);
+- vector<unsigned> counts(window_size_, 0);
++ vector<unsigned> counts(window_size_ + 1, 0);
+
+ for (unsigned i = 0; i < bs.size(); i++) {
+- optional<unsigned> b = h_.step(bs[i]);
++ boost::optional<unsigned> b = h_.step(bs[i]);
+ if (b) {
+ counts[*b]++;
+
+--- a/unit-tests/span_iterator_t.cc
++++ b/unit-tests/span_iterator_t.cc
+@@ -81,7 +81,9 @@
+
+ base::run_set<block_address> forbidden;
+ };
++}
+
++namespace boost {
+ ostream &operator <<(ostream &out, maybe_span const &m) {
+ out << "maybe_span[";
+ if (m)
diff --git a/sys-block/thin-provisioning-tools/thin-provisioning-tools-0.9.0-r4.ebuild b/sys-block/thin-provisioning-tools/thin-provisioning-tools-0.9.0-r4.ebuild
new file mode 100644
index 000000000000..ce538347406e
--- /dev/null
+++ b/sys-block/thin-provisioning-tools/thin-provisioning-tools-0.9.0-r4.ebuild
@@ -0,0 +1,70 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit autotools flag-o-matic
+
+DESCRIPTION="A suite of tools for thin provisioning on Linux"
+HOMEPAGE="https://github.com/jthornber/thin-provisioning-tools"
+
+if [[ ${PV} != *9999 ]]; then
+ SRC_URI="https://github.com/jthornber/${PN}/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+ KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86 ~amd64-linux ~x86-linux"
+else
+ inherit git-r3
+ EGIT_REPO_URI='https://github.com/jthornber/thin-provisioning-tools.git'
+fi
+
+LICENSE="GPL-3"
+SLOT="0"
+IUSE="static test"
+RESTRICT="!test? ( test )"
+
+LIB_DEPEND="dev-libs/expat[static-libs(+)]
+ dev-libs/libaio[static-libs(+)]"
+RDEPEND="!static? ( ${LIB_DEPEND//\[static-libs(+)]} )"
+DEPEND="${RDEPEND}
+ static? ( ${LIB_DEPEND} )
+ test? (
+ >=dev-cpp/gtest-1.8.0
+ )
+ dev-libs/boost"
+
+PATCHES=(
+ "${FILESDIR}"/${PN}-0.7.0-build-fixes.patch
+ "${FILESDIR}"/${PN}-0.9.0-build-fixes.patch
+ "${FILESDIR}"/0.9.0-remove-boost_iostreams.patch
+ "${FILESDIR}"/${PN}-0.9.0-metadata_checker-Rename-function-to-reflect-command-.patch
+ "${FILESDIR}"/${PN}-0.9.0-thin_check-Allow-using-clear-needs-check-and-skip-ma.patch
+ "${FILESDIR}"/${PN}-0.9.0-boost-gtest.patch
+)
+
+src_prepare() {
+ default
+ eautoreconf
+}
+
+src_configure() {
+ use static && append-ldflags -static
+ local myeconfargs=(
+ --prefix="${EPREFIX}"/
+ --bindir="${EPREFIX}"/sbin
+ --with-optimisation=''
+ $(use_enable test testing)
+ )
+ STRIP=true econf "${myeconfargs[@]}"
+}
+
+src_compile() {
+ emake V=
+}
+
+src_test() {
+ emake V= unit-test
+}
+
+src_install() {
+ emake V= DESTDIR="${D}" DATADIR="${ED}/usr/share" install
+ dodoc README.md TODO.org
+}