Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
cmake-build-debug/

# Visual Studio 2015 cache/options directory
.vs/
Expand Down
83 changes: 55 additions & 28 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

# ---- Project ----

# Note: update this to your new project's name and version
project(
Glob
VERSION 1.0
LANGUAGES CXX
Glob
VERSION 1.0
LANGUAGES CXX
)

# ---- Options ----
option(GLOB_USE_GHC_FILESYSTEM "Use ghc::filesystem instead of std::filesystem" OFF)
option(GLOB_TESTS "Run glob gtests" ON)

# ---- Include guards ----

if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
message(
FATAL_ERROR
"In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there."
)
endif()
if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
message(
FATAL_ERROR
"In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there."
)
endif ()

# ---- Add dependencies via CPM ----
# see https://github.com/TheLartians/CPM.cmake for more info
Expand All @@ -28,11 +28,21 @@ include(cmake/CPM.cmake)

# PackageProject.cmake will be used to make our target installable
CPMAddPackage(
NAME PackageProject.cmake
GITHUB_REPOSITORY TheLartians/PackageProject.cmake
VERSION 1.3
NAME PackageProject.cmake
GITHUB_REPOSITORY TheLartians/PackageProject.cmake
VERSION 1.3
)

CPMAddPackage(
NAME googletest
GITHUB_REPOSITORY google/googletest
GIT_TAG v1.16.0
VERSION 1.16.0
OPTIONS "INSTALL_GTEST OFF" "gtest_force_shared_crt"
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

# ---- Add source files ----

# Note: globbing sources is considered bad practice as CMake's generators may not detect new files
Expand All @@ -47,23 +57,23 @@ file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/
# INTERFACE_COMPILE_FEATURES cxx_std_17)

add_library(Glob ${headers} ${sources})
SET_TARGET_PROPERTIES(Glob PROPERTIES OUTPUT_NAME glob)
set_target_properties(Glob PROPERTIES OUTPUT_NAME glob)
set_target_properties(Glob PROPERTIES CXX_STANDARD 17)

if ( GLOB_USE_GHC_FILESYSTEM )
# Switch to ghc::filesystem.
target_link_libraries(Glob PRIVATE ghcFilesystem::ghc_filesystem)
target_compile_definitions(Glob PUBLIC GLOB_USE_GHC_FILESYSTEM)
endif()
if (GLOB_USE_GHC_FILESYSTEM)
# Switch to ghc::filesystem.
target_link_libraries(Glob PRIVATE ghcFilesystem::ghc_filesystem)
target_compile_definitions(Glob PUBLIC GLOB_USE_GHC_FILESYSTEM)
endif ()

# being a cross-platform target, we enforce standards conformance on MSVC
target_compile_options(Glob PUBLIC "$<$<BOOL:${MSVC}>:/permissive->")

# Link dependencies (if required) target_link_libraries(Glob PUBLIC cxxopts)

target_include_directories(
Glob PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}-${PROJECT_VERSION}>
Glob PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}-${PROJECT_VERSION}>
)

# ---- Create an installable target ----
Expand All @@ -74,11 +84,28 @@ target_include_directories(
string(TOLOWER ${PROJECT_NAME}/version.h VERSION_HEADER_LOCATION)

packageProject(
NAME ${PROJECT_NAME}
VERSION ${PROJECT_VERSION}
BINARY_DIR ${PROJECT_BINARY_DIR}
INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION}
VERSION_HEADER "${VERSION_HEADER_LOCATION}"
DEPENDENCIES ""
NAME ${PROJECT_NAME}
VERSION ${PROJECT_VERSION}
BINARY_DIR ${PROJECT_BINARY_DIR}
INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION}
VERSION_HEADER "${VERSION_HEADER_LOCATION}"
DEPENDENCIES ""
)

# --- setup tests ---
if (GLOB_TESTS)
enable_testing()

add_executable(glob_tests test/rglob_test.cpp test/compile_pattern_test.cpp)
set_property(TARGET glob_tests PROPERTY CXX_STANDARD 17)
target_link_libraries(glob_tests PRIVATE gtest_main ${PROJECT_NAME})
add_test(NAME glob_tests COMMAND glob_tests)

add_executable(glob_tests_single test/rglob_test.cpp test/compile_pattern_test.cpp)
set_property(TARGET glob_tests_single PROPERTY CXX_STANDARD 17)
target_compile_definitions(glob_tests_single PRIVATE USE_SINGLE_HEADER=1)
target_link_libraries(glob_tests_single PRIVATE gtest_main)
target_include_directories(glob_tests_single PRIVATE single_include)
add_test(NAME glob_tests_single COMMAND glob_tests_single)
endif ()
2 changes: 1 addition & 1 deletion cmake/CPM.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(CPM_DOWNLOAD_VERSION 0.35.1)
set(CPM_DOWNLOAD_VERSION 0.40.8)

if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
Expand Down
2 changes: 2 additions & 0 deletions include/glob/glob.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#pragma once
#include <string>
#include <vector>
#include <regex>

#ifdef GLOB_USE_GHC_FILESYSTEM
#include <ghc/filesystem.hpp>
Expand Down Expand Up @@ -45,4 +46,5 @@ std::vector<fs::path> glob(const std::initializer_list<std::string> &pathnames);
/// Initializer list overload for convenience
std::vector<fs::path> rglob(const std::initializer_list<std::string> &pathnames);

std::regex compile_pattern_to_regex(std::string_view pattern);
} // namespace glob
10 changes: 7 additions & 3 deletions single_include/glob/glob.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ std::string translate(const std::string &pattern) {
}

static inline
std::regex compile_pattern(const std::string &pattern) {
std::regex compile_pattern_to_regex(const std::string &pattern) {
return std::regex(translate(pattern), std::regex::ECMAScript);
}

static inline
bool fnmatch(const fs::path &name, const std::string &pattern) {
return std::regex_match(name.string(), compile_pattern(pattern));
return std::regex_match(name.string(), compile_pattern_to_regex(pattern));
}

static inline
Expand Down Expand Up @@ -252,6 +252,10 @@ std::vector<fs::path> glob2(const fs::path &dirname, [[maybe_unused]] const std:
bool dironly) {
// std::cout << "In glob2\n";
std::vector<fs::path> result;
// look into the base directory as well, but only if it exists
if (fs::exists(dirname)) {
result.push_back(".");
}
assert(is_recursive(pattern));
for (auto &dir : rlistdir(dirname, dironly)) {
result.push_back(dir);
Expand Down Expand Up @@ -364,7 +368,7 @@ std::vector<fs::path> glob(const std::string &pathname, bool recursive = false,
if (name.parent_path().empty()) {
subresult = d / name;
}
result.push_back(subresult);
result.push_back(subresult.lexically_normal());
}
}

Expand Down
Loading