From 5f5b2b5770384d9a16505b749303746751358156 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 8 Jul 2016 14:49:40 +0100 Subject: [PATCH] New core library. --- CMakeLists.txt | 1 + include/dindexer-core/searchpaths.hpp | 66 +++++++++++++ src/core/CMakeLists.txt | 35 +++++++ src/core/searchpaths.cpp | 136 ++++++++++++++++++++++++++ 4 files changed, 238 insertions(+) create mode 100644 include/dindexer-core/searchpaths.hpp create mode 100644 src/core/CMakeLists.txt create mode 100644 src/core/searchpaths.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b1f926e..8ef6463 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,7 @@ add_subdirectory(src/machinery) add_subdirectory(lib/pbl) add_subdirectory(lib/glob2regex) add_subdirectory(src/backends) +add_subdirectory(src/core) #Actions add_subdirectory(src/main) diff --git a/include/dindexer-core/searchpaths.hpp b/include/dindexer-core/searchpaths.hpp new file mode 100644 index 0000000..6ab5664 --- /dev/null +++ b/include/dindexer-core/searchpaths.hpp @@ -0,0 +1,66 @@ +/* Copyright 2015, 2016, Michele Santullo + * This file is part of "dindexer". + * + * "dindexer" 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. + * + * "dindexer" 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 "dindexer". If not, see . + */ + +#ifndef idDD90110B9C7E44C4AAF8B46A663B11DC +#define idDD90110B9C7E44C4AAF8B46A663B11DC + +#include +#include +#include +#include +#include + +namespace dincore { + class SearchPaths { + public: + enum SearchType { + Directory, + File, + Any + }; + using Predicate = std::function; + + SearchPaths ( void ) = default; + explicit SearchPaths ( std::vector&& parList ); + SearchPaths ( std::initializer_list parInit ); + ~SearchPaths ( void ) noexcept; + + void add_path ( std::string&& parPath ); + std::string first_hit ( boost::string_ref parFile, SearchType parType=Any ) const; + std::string first_hit ( Predicate parPredicate, SearchType parType=Any ) const; + + private: + std::vector m_paths; + }; + + class ShallowSearchPaths { + public: + ShallowSearchPaths ( void ) = default; + explicit ShallowSearchPaths ( std::vector&& parList ); + ShallowSearchPaths ( std::initializer_list parInit ); + ~ShallowSearchPaths ( void ) noexcept; + + void add_path ( boost::string_ref parPath ); + std::string first_hit ( boost::string_ref parFile, SearchPaths::SearchType parType=SearchPaths::Any ) const; + std::string first_hit ( SearchPaths::Predicate parPredicate, SearchPaths::SearchType parType=SearchPaths::Any ) const; + + private: + std::vector m_paths; + }; +} //namespace dincore + +#endif diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 0000000..fd9d26e --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,35 @@ +project(${bare_name}-core CXX) + +add_library(${PROJECT_NAME} + searchpaths.cpp +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE ${bare_name}-if +) + +target_include_directories(${PROJECT_NAME} + PRIVATE ${DINDEXER_PUB_INCLUDE_DIR}/${bare_name}-core +) + +target_compile_features(${PROJECT_NAME} + INTERFACE cxx_nullptr + INTERFACE cxx_range_for + INTERFACE cxx_lambdas + INTERFACE cxx_decltype_auto + INTERFACE cxx_defaulted_functions + INTERFACE cxx_deleted_functions + INTERFACE cxx_auto_type + INTERFACE cxx_decltype_incomplete_return_types + INTERFACE cxx_defaulted_move_initializers + INTERFACE cxx_noexcept + INTERFACE cxx_rvalue_references + INTERFACE cxx_generalized_initializers + INTERFACE cxx_variadic_templates +) + +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib/static +) diff --git a/src/core/searchpaths.cpp b/src/core/searchpaths.cpp new file mode 100644 index 0000000..573361b --- /dev/null +++ b/src/core/searchpaths.cpp @@ -0,0 +1,136 @@ +/* Copyright 2015, 2016, Michele Santullo + * This file is part of "dindexer". + * + * "dindexer" 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. + * + * "dindexer" 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 "dindexer". If not, see . + */ + +#include "searchpaths.hpp" +#include +#include +#include +#include +#include + +namespace dincore { + namespace { + const std::string& STR_to_string (const std::string& parString) { + return parString; + } + + std::string STR_to_string (boost::string_ref parString) { + return std::string(parString.data(), parString.size()); + } + + template + std::string first_hit_impl (const std::vector& parPaths, SearchPaths::Predicate parPredicate, SearchPaths::SearchType parType) { + using boost::filesystem::path; + using boost::filesystem::is_directory; + using boost::filesystem::directory_iterator; + using boost::filesystem::directory_entry; + using boost::make_iterator_range; + + for (const auto& curr_dir_path : parPaths) { + path curr_path(STR_to_string(curr_dir_path)); + auto listing = make_iterator_range(directory_iterator(curr_path), directory_iterator()); + for (const directory_entry& entry : listing) { + if ( + (parType == SearchPaths::Any) or + (parType == SearchPaths::Directory and is_directory(entry)) or + (parType == SearchPaths::File and not is_directory(entry)) + ) { + auto str_path = entry.path().string(); + if (parPredicate(curr_dir_path, str_path)) + return str_path; + } + } + } + return std::string(); + } + + //std::string make_file_path (boost::string_ref parPath, boost::string_ref parName) { + // assert(not parName.empty()); + // if (parName.empty()) + // return std::string(parPath.data(), parPath.size()); + + // std::string retval; + // const std::size_t slash = (not parPath.empty() and parPath[parPath.size() - 1] != '/' ? 1 : 0); + // retval.reserve(parPath.size() + parName.size() + slash); + // std::copy(parPath.begin(), parPath.end(), retval.begin()); + // retval[parPath.size()] = '/'; + // std::copy(parName.begin(), parName.end(), retval.begin() + parPath.size() + slash); + // return retval; + //} + + bool is_same_filename (boost::string_ref parBaseDir, const std::string& parFullPath, boost::string_ref parFilename) { + assert(parBaseDir.size() < parFullPath.size()); + return boost::string_ref(parFullPath).substr(parBaseDir.size() + 1) == parFilename; + } + } //unnamed namespace + + SearchPaths::SearchPaths (std::vector&& parList) : + m_paths(std::move(parList)) + { + } + + SearchPaths::SearchPaths (std::initializer_list parInit) : + m_paths(parInit) + { + } + + SearchPaths::~SearchPaths() noexcept = default; + + void SearchPaths::add_path (std::string&& parPath) { + if (std::find(m_paths.begin(), m_paths.end(), parPath) == m_paths.end()) { + m_paths.emplace_back(std::move(parPath)); + } + } + + std::string SearchPaths::first_hit (boost::string_ref parFile, SearchType parType) const { + using std::placeholders::_1; + using std::placeholders::_2; + return first_hit_impl(m_paths, std::bind(&is_same_filename, _1, _2, parFile), parType); + } + + std::string SearchPaths::first_hit (Predicate parPredicate, SearchType parType) const { + return first_hit_impl(m_paths, parPredicate, parType); + } + + ShallowSearchPaths::ShallowSearchPaths (std::vector&& parList) : + m_paths(std::move(parList)) + { + } + + ShallowSearchPaths::ShallowSearchPaths (std::initializer_list parInit) : + m_paths(parInit) + { + } + + ShallowSearchPaths::~ShallowSearchPaths() noexcept = default; + + void ShallowSearchPaths::add_path (boost::string_ref parPath) { + if (std::find(m_paths.begin(), m_paths.end(), parPath) == m_paths.end()) { + m_paths.push_back(parPath); + } + } + + std::string ShallowSearchPaths::first_hit (boost::string_ref parFile, SearchPaths::SearchType parType) const { + using std::placeholders::_1; + using std::placeholders::_2; + return first_hit_impl(m_paths, std::bind(&is_same_filename, _1, _2, parFile), parType); + } + + std::string ShallowSearchPaths::first_hit (SearchPaths::Predicate parPredicate, SearchPaths::SearchType parType) const { + return first_hit_impl(m_paths, parPredicate, parType); + } +} //namespace dincore