diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f542a4..48e3e5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,6 +149,8 @@ set(GIT2CPP_SRC ${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.hpp ${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.cpp ${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.hpp + ${GIT2CPP_SOURCE_DIR}/wrapper/strarray_wrapper.cpp + ${GIT2CPP_SOURCE_DIR}/wrapper/strarray_wrapper.hpp ${GIT2CPP_SOURCE_DIR}/wrapper/tag_wrapper.cpp ${GIT2CPP_SOURCE_DIR}/wrapper/tag_wrapper.hpp ${GIT2CPP_SOURCE_DIR}/wrapper/tree_wrapper.cpp diff --git a/src/subcommand/log_subcommand.cpp b/src/subcommand/log_subcommand.cpp index bf1840b..61ead6d 100644 --- a/src/subcommand/log_subcommand.cpp +++ b/src/subcommand/log_subcommand.cpp @@ -12,6 +12,7 @@ #include #include "../utils/terminal_pager.hpp" +#include "../wrapper/strarray_wrapper.hpp" log_subcommand::log_subcommand(const libgit2_object&, CLI::App& app) { @@ -87,17 +88,17 @@ namespace std::vector get_tags_for_commit(repository_wrapper& repo, const git_oid& commit_oid) { std::vector tags; - git_strarray tag_names = {0}; + strarray_owned_wrapper tag_names; - if (git_tag_list(&tag_names, repo) != 0) + if (git_tag_list(tag_names, repo) != 0) { return tags; } - for (size_t i = 0; i < tag_names.count; i++) + for (size_t i = 0; i < tag_names.size(); i++) { - std::string tag_name = tag_names.strings[i]; - std::string ref_name = "refs/tags/" + std::string(tag_name); + auto tag_name = std::string(tag_names[i]); + std::string ref_name = "refs/tags/" + tag_name; reference_wrapper tag_ref = repo.find_reference(ref_name); object_wrapper peeled = tag_ref.peel(); @@ -108,7 +109,6 @@ namespace } } - git_strarray_dispose(&tag_names); // TODO: refactor git_strarray_wrapper to use it here return tags; } diff --git a/src/subcommand/push_subcommand.cpp b/src/subcommand/push_subcommand.cpp index ea8fd4a..39c066f 100644 --- a/src/subcommand/push_subcommand.cpp +++ b/src/subcommand/push_subcommand.cpp @@ -7,10 +7,11 @@ #include #include "../utils/ansi_code.hpp" -#include "../utils/common.hpp" +// #include "../utils/common.hpp" #include "../utils/credentials.hpp" #include "../utils/progress.hpp" #include "../wasm/scope.hpp" +#include "../wrapper/strarray_wrapper.hpp" push_subcommand::push_subcommand(const libgit2_object&, CLI::App& app) { @@ -182,7 +183,7 @@ void push_subcommand::run() { refspecs_push.push_back("refs/heads/" + refspec); } - git_strarray_wrapper refspecs_wrapper(refspecs_push); + strarray_view_wrapper refspecs_wrapper(refspecs_push); git_strarray* refspecs_ptr = refspecs_wrapper; auto remotes_before_push = get_remotes(repo, remote_name); diff --git a/src/utils/common.cpp b/src/utils/common.cpp index 4bb7d32..a9aeb77 100644 --- a/src/utils/common.cpp +++ b/src/utils/common.cpp @@ -60,59 +60,6 @@ status_messages get_status_msg(git_status_t st) return get_status_msg_map().find(st)->second; } -git_strarray_wrapper::git_strarray_wrapper(std::vector patterns) - : m_patterns(std::move(patterns)) -{ - init_str_array(); -} - -git_strarray_wrapper::git_strarray_wrapper(git_strarray_wrapper&& rhs) - : m_patterns(std::move(rhs.m_patterns)) -{ - init_str_array(); - rhs.reset_str_array(); -} - -git_strarray_wrapper& git_strarray_wrapper::operator=(git_strarray_wrapper&& rhs) -{ - using std::swap; - swap(m_patterns, rhs.m_patterns); - swap(m_array.strings, rhs.m_array.strings); - swap(m_array.count, rhs.m_array.count); - return *this; -} - -git_strarray_wrapper::~git_strarray_wrapper() -{ - reset_str_array(); -} - -git_strarray_wrapper::operator git_strarray*() -{ - return &m_array; -} - -void git_strarray_wrapper::reset_str_array() -{ - delete[] m_array.strings; - m_array = {nullptr, 0}; -} - -void git_strarray_wrapper::init_str_array() -{ - m_array.strings = new char*[m_patterns.size()]; - m_array.count = m_patterns.size(); - for (size_t i = 0; i < m_patterns.size(); ++i) - { - m_array.strings[i] = const_cast(m_patterns[i].c_str()); - } -} - -size_t git_strarray_wrapper::size() -{ - return m_patterns.size(); -} - std::string read_file(const std::string& path) { std::ifstream file(path, std::ios::binary); diff --git a/src/utils/common.hpp b/src/utils/common.hpp index afb0d88..86fc1b4 100644 --- a/src/utils/common.hpp +++ b/src/utils/common.hpp @@ -40,39 +40,6 @@ status_messages get_status_msg(git_status_t); using stream_colour_fn = std::ostream& (*) (std::ostream&); -class git_strarray_wrapper -{ -public: - - git_strarray_wrapper() - : m_patterns{} - , m_array{nullptr, 0} - { - } - - git_strarray_wrapper(std::vector patterns); - - git_strarray_wrapper(const git_strarray_wrapper&) = delete; - git_strarray_wrapper& operator=(const git_strarray_wrapper&) = delete; - - git_strarray_wrapper(git_strarray_wrapper&& rhs); - git_strarray_wrapper& operator=(git_strarray_wrapper&&); - - ~git_strarray_wrapper(); - - operator git_strarray*(); - - size_t size(); - -private: - - std::vector m_patterns; - git_strarray m_array; - - void reset_str_array(); - void init_str_array(); -}; - std::string read_file(const std::string& path); std::vector split_input_at_newlines(std::string_view str); diff --git a/src/wrapper/index_wrapper.cpp b/src/wrapper/index_wrapper.cpp index 9e26725..ee5d958 100644 --- a/src/wrapper/index_wrapper.cpp +++ b/src/wrapper/index_wrapper.cpp @@ -9,6 +9,7 @@ #include "../utils/common.hpp" #include "../utils/git_exception.hpp" #include "../wrapper/repository_wrapper.hpp" +#include "../wrapper/strarray_wrapper.hpp" index_wrapper::~index_wrapper() { @@ -40,7 +41,7 @@ void index_wrapper::add_all() void index_wrapper::add_impl(std::vector patterns) { - git_strarray_wrapper array{patterns}; + strarray_view_wrapper array{patterns}; throw_if_error(git_index_add_all(*this, array, 0, NULL, NULL)); } @@ -51,7 +52,7 @@ void index_wrapper::remove_entry(const std::string& path) void index_wrapper::remove_entries(std::vector paths) { - git_strarray_wrapper array{paths}; + strarray_view_wrapper array{paths}; throw_if_error(git_index_remove_all(*this, array, NULL, NULL)); } diff --git a/src/wrapper/repository_wrapper.hpp b/src/wrapper/repository_wrapper.hpp index 1c5899e..3fb4417 100644 --- a/src/wrapper/repository_wrapper.hpp +++ b/src/wrapper/repository_wrapper.hpp @@ -134,7 +134,7 @@ class repository_wrapper : public wrapper_base diff_wrapper diff_index_to_workdir(std::optional index, git_diff_options* diffopts); // Tags - // git_strarray_wrapper tag_list_match(std::string pattern); + // strarray_view_wrapper tag_list_match(std::string pattern); std::vector tag_list_match(std::string pattern); private: diff --git a/src/wrapper/strarray_wrapper.cpp b/src/wrapper/strarray_wrapper.cpp new file mode 100644 index 0000000..465c23c --- /dev/null +++ b/src/wrapper/strarray_wrapper.cpp @@ -0,0 +1,97 @@ +#include "strarray_wrapper.hpp" + +strarray_owned_wrapper::strarray_owned_wrapper() + : m_array{nullptr, 0} +{ +} + +strarray_owned_wrapper::strarray_owned_wrapper(git_strarray&& arr) + : m_array(std::move(arr)) +{ +} + +strarray_owned_wrapper::strarray_owned_wrapper(strarray_owned_wrapper&& rhs) + : m_array(std::move(rhs.m_array)) +{ + rhs.m_array = git_strarray{nullptr, 0}; +} + +strarray_owned_wrapper& strarray_owned_wrapper::operator=(strarray_owned_wrapper&& rhs) +{ + std::swap(m_array.strings, rhs.m_array.strings); + std::swap(m_array.count, rhs.m_array.count); + return *this; +} + +strarray_owned_wrapper::~strarray_owned_wrapper() +{ + git_strarray_dispose(&m_array); +} + +strarray_owned_wrapper::operator git_strarray*() +{ + return &m_array; +} + +size_t strarray_owned_wrapper::size() const +{ + return m_array.count; +} + +std::string_view strarray_owned_wrapper::operator[](size_t i) const +{ + return {m_array.strings[i]}; +} + +strarray_view_wrapper::strarray_view_wrapper(std::vector patterns) + : m_patterns(std::move(patterns)) +{ + init_str_array(); +} + +strarray_view_wrapper::strarray_view_wrapper(strarray_view_wrapper&& rhs) + : m_patterns(std::move(rhs.m_patterns)) +{ + init_str_array(); + rhs.reset_str_array(); +} + +strarray_view_wrapper& strarray_view_wrapper::operator=(strarray_view_wrapper&& rhs) +{ + using std::swap; + swap(m_patterns, rhs.m_patterns); + swap(m_array.strings, rhs.m_array.strings); + swap(m_array.count, rhs.m_array.count); + return *this; +} + +strarray_view_wrapper::~strarray_view_wrapper() +{ + reset_str_array(); +} + +strarray_view_wrapper::operator git_strarray*() +{ + return &m_array; +} + +void strarray_view_wrapper::reset_str_array() +{ + delete[] m_array.strings; + m_array = {nullptr, 0}; +} + +void strarray_view_wrapper::init_str_array() +{ + m_array.strings = new char*[m_patterns.size()]; + m_array.count = m_patterns.size(); + for (size_t i = 0; i < m_patterns.size(); ++i) + { + m_array.strings[i] = const_cast(m_patterns[i].c_str()); + } +} + +size_t strarray_view_wrapper::size() const +{ + return m_patterns.size(); +} diff --git a/src/wrapper/strarray_wrapper.hpp b/src/wrapper/strarray_wrapper.hpp new file mode 100644 index 0000000..87f416b --- /dev/null +++ b/src/wrapper/strarray_wrapper.hpp @@ -0,0 +1,71 @@ +#pragma once + +#include +#include +#include + +#include + +// Wrapper of git_strarray that frees the contained +// strings (i.e. calls git_strarray_dispose) upon destruction. +class strarray_owned_wrapper +{ +public: + + strarray_owned_wrapper(); + explicit strarray_owned_wrapper(git_strarray&& arr); + + strarray_owned_wrapper(const strarray_owned_wrapper&) = delete; + strarray_owned_wrapper operator=(const strarray_owned_wrapper&) = delete; + + strarray_owned_wrapper(strarray_owned_wrapper&& rhs); + strarray_owned_wrapper& operator=(strarray_owned_wrapper&& rhs); + + ~strarray_owned_wrapper(); + + operator git_strarray*(); + + size_t size() const; + + std::string_view operator[](size_t i) const; + +private: + + git_strarray m_array; +}; + +// Wrapper of git_strarray containing pointers to strings +// stored in a stnadard container. Does not free them upon +// destruction. +class strarray_view_wrapper +{ +public: + + strarray_view_wrapper() + : m_patterns{} + , m_array{nullptr, 0} + { + } + + strarray_view_wrapper(std::vector patterns); + + strarray_view_wrapper(const strarray_view_wrapper&) = delete; + strarray_view_wrapper& operator=(const strarray_view_wrapper&) = delete; + + strarray_view_wrapper(strarray_view_wrapper&& rhs); + strarray_view_wrapper& operator=(strarray_view_wrapper&& rhs); + + ~strarray_view_wrapper(); + + operator git_strarray*(); + + size_t size() const; + +private: + + std::vector m_patterns; + git_strarray m_array; + + void reset_str_array(); + void init_str_array(); +};