diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 0000000..8b447b4 --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,31 @@ +# ====================================================================================== +# __ ____ __ __ ____ ___ +# ( ) (_ _)( \/ )( ___)/ __) +# )(__ _)(_ ) ( )__) \__ \ +# (____)(____)(_/\/\_)(____)(___/ +# +# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. +# +# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. +# +# ====================================================================================== + +# configuration file for the bumpversion tool: https://github.com/c4urself/bump2version +# This tool is run by semantic-release when the version is bumped. + +[bumpversion] +current_version = 0.0.1 +tag = False +commit = False + +[bumpversion:file:CMakeLists.txt] +search = VERSION {current_version} +replace = VERSION {new_version} + +[bumpversion:file:package.json] +search = "version": "{current_version}" +replace = "version": "{new_version}" + +[bumpversion:file:CITATION.cff] +search = version: {current_version} +replace = version: {new_version} diff --git a/.editorconfig b/.editorconfig index 20f18c5..5e119e0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -31,6 +31,6 @@ trim_trailing_whitespace = false [LICENSE] indent_style = space -[*.{yml,yaml,json,clang-*}] +[*.{yml,yaml,json,cff,clang-*}] indent_style = space indent_size = 2 diff --git a/.envrc b/.envrc index 197e490..4552088 100644 --- a/.envrc +++ b/.envrc @@ -24,74 +24,18 @@ # # SKIP - comma-separated list of pre-commit hook IDs that will be skipped # CMAKE_APPLE_SILICON_PROCESSOR - tell CMake if your Mac is an M1 (arm64) or not (x86_64) -# EMSCRIPTEN_ROOT - path to the root of the Emscripten SDK. This file attempts to locate it automatically but your .env can override it. +# EMSCRIPTEN_ROOT - path to the root of the Emscripten SDK. This file attempts to locate it automatically but your .env can override it. +# ANDROID_NDK_ROOT - path to the Android NDK to use. This file attempts to locate it automatically but your .env can override it. +# IOS_SIMULATOR_DEVICE_ID - device ID of simulator to use for running iOS tests +# TVOS_SIMULATOR_DEVICE_ID - device ID of simulator to use for running tvOS tests +# WATCHOS_SIMULATOR_DEVICE_ID - device ID of simulator to use for running watchOS tests # # see CMake's environment variables documentation: https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html strict_env direnv_version 2.32.2 -export CMAKE_GENERATOR="Ninja Multi-Config" - -export CMAKE_CONFIG_TYPE=Debug - -export CMAKE_COLOR_DIAGNOSTICS=ON - -export CMAKE_EXPORT_COMPILE_COMMANDS=ON - -export CTEST_OUTPUT_ON_FAILURE=ON -export CTEST_PROGRESS_OUTPUT=ON -export CTEST_NO_TESTS_ACTION=error - -if has nproc; then - NUM_PROCS=$(nproc --all) -elif has getconf; then - NUM_PROCS=$(getconf _NPROCESSORS_ONLN) -else - NUM_PROCS=$([ $(uname) = 'Darwin' ] && - sysctl -n hw.logicalcpu_max || - lscpu -p | egrep -v '^#' | wc -l - ) -fi - -export CMAKE_BUILD_PARALLEL_LEVEL="$NUM_PROCS" -export CTEST_PARALLEL_LEVEL="$NUM_PROCS" - -if [[ $(uname -p) == 'arm' ]]; then - export CMAKE_APPLE_SILICON_PROCESSOR=arm64 -else - export CMAKE_APPLE_SILICON_PROCESSOR=x86_64 -fi - -export CMAKE_OSX_ARCHITECTURES="x86_64;arm64" -export MACOSX_DEPLOYMENT_TARGET="11.0" - -export VERBOSE=ON - -# in case anyone happens to be using CPM.cmake -export CPM_SOURCE_CACHE="$(pwd)/Cache" - -# default to GCC (direnv doesn't support Windows, so gcc should work everywhere direnv is used) -export CC="gcc" -export CXX="g++" -export FC="gfortran" - -export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' - -export PRE_COMMIT_COLOR=always - -# check if the Emscripten SDK is installed -if has emcc; then - # need to call asdf-which if using asdf - # TODO: more robust check to see if emsdk is installed using ASDF? - if has asdf; then - EMCC_PATH=$(asdf which emcc) - else - EMCC_PATH=$(which emcc) - fi - - export EMSCRIPTEN_ROOT=$(expand_path $EMCC_PATH/..) -fi +source_env linfra/.envrc source_env_if_exists .envrc.user dotenv_if_exists .env diff --git a/.gitattributes b/.gitattributes index 07e64e0..56b1fd9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -26,6 +26,7 @@ # For conformance with .editorconfig LICENSE space_indent +CITATION.cff 2_space_indent *.yml 2_space_indent *.yaml 2_space_indent *.json 2_space_indent diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..88bd1e0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,45 @@ +# ====================================================================================== +# __ ____ __ __ ____ ___ +# ( ) (_ _)( \/ )( ___)/ __) +# )(__ _)(_ ) ( )__) \__ \ +# (____)(____)(_/\/\_)(____)(___/ +# +# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. +# +# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. +# +# ====================================================================================== + +version: 2 + +updates: + +- package-ecosystem: npm + directory: / + schedule: + interval: daily + commit-message: + prefix: chore(deps) [skip ci] + include: scope + reviewers: + - benthevining + +- package-ecosystem: github-actions + directory: / + schedule: + interval: daily + commit-message: + prefix: chore(deps) [skip ci] + include: scope + reviewers: + - benthevining + +- package-ecosystem: gitsubmodule + directory: / + schedule: + interval: daily + commit-message: + prefix: chore(deps) [skip ci] + include: scope + reviewers: + - benthevining diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 545575e..e9300cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,7 @@ run-name: CI (${{ github.actor }}) on: workflow_dispatch: push: + branches: [main] pull_request: concurrency: @@ -32,7 +33,7 @@ permissions: jobs: - ci: + build-and-test: if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} @@ -41,7 +42,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-latest] preset: [clang, emscripten, gcc, iOS, tvOS, watchOS] - config: [Debug, Release] + shared-libs: ['ON', 'OFF'] exclude: - os: windows-latest preset: gcc @@ -60,20 +61,20 @@ jobs: include: - os: windows-latest preset: vs - config: Debug + shared-libs: 'ON' - os: windows-latest preset: vs - config: Release + shared-libs: 'OFF' - os: macos-latest preset: xcode - config: Debug + shared-libs: 'ON' - os: macos-latest preset: xcode - config: Release + shared-libs: 'OFF' runs-on: ${{ matrix.os }} - name: Build (${{ matrix.os }}, ${{ matrix.preset }}, ${{ matrix.config }}) + name: Build (${{ matrix.os }}, ${{ matrix.preset }}, ${{ matrix.shared-libs }}) timeout-minutes: 10 @@ -95,21 +96,80 @@ jobs: run: echo "EMSCRIPTEN_ROOT=$(which emcc)/.." >> $GITHUB_ENV - name: Configure CMake - run: cmake --preset ${{ matrix.preset }} + run: cmake --preset ${{ matrix.preset }} -D BUILD_SHARED_LIBS=${{ matrix.shared-libs }} - - name: Run build - run: cmake --build --preset ${{ matrix.preset }} --config ${{ matrix.config }} + - name: Run Debug build + run: cmake --build --preset ${{ matrix.preset }} --config Debug - - name: Run tests + - name: Run Debug tests if: ${{ ! ( matrix.preset == 'iOS' || matrix.preset == 'tvOS' || matrix.preset == 'watchOS' ) }} - run: ctest --preset ${{ matrix.preset }} -C ${{ matrix.config }} + run: ctest --preset ${{ matrix.preset }} -C Debug + + - name: Run Release build + run: cmake --build --preset ${{ matrix.preset }} --config Release + + - name: Run Release tests + if: ${{ ! ( matrix.preset == 'iOS' || matrix.preset == 'tvOS' || matrix.preset == 'watchOS' ) }} + run: ctest --preset ${{ matrix.preset }} -C Release - name: Generate package - run: cpack --preset ${{ matrix.preset }} -C ${{ matrix.config }} -B $GITHUB_WORKSPACE/deploy + run: cpack --preset ${{ matrix.preset }} -B $GITHUB_WORKSPACE/deploy - name: Upload artefact uses: actions/upload-artifact@main with: - name: ${{ matrix.os }}-${{ matrix.preset }}-${{ matrix.config }} + name: ${{ matrix.os }}-${{ matrix.preset }}-${{ matrix.shared-libs }} path: deploy/**.zip if-no-files-found: error + + + create-release: + + if: ${{ !contains(github.event.head_commit.message, '[skip ci]') && github.ref == 'refs/heads/main' }} + + needs: build-and-test + + name: Create release + + runs-on: ubuntu-latest + + timeout-minutes: 20 + + permissions: + contents: write + packages: write + deployments: write + + steps: + + - name: Checkout code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # pin@v3.6.0 + with: + node-version: lts/* + + - name: Install NPM dependencies + uses: bahmutov/npm-install@7b5291ae7bf768fecff627796beaf8a95c9c2bfd # pin@v1.8.29 + with: + useLockFile: false + useRollingCache: true + + - name: Install dependencies + run: pip install --upgrade bumpversion + + - name: Download artifacts + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # pin@v3 + with: + path: ${{ github.workspace }}/deploy + + - name: Zip source code + run: git archive --format=tar --output=source-code.tar --worktree-attributes HEAD + + - name: Run semantic release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx semantic-release diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a7c06a1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "linfra"] + path = linfra + url = https://github.com/benthevining/linfra diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e6dbb5b..d01f2de 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -87,13 +87,6 @@ repos: always_run: true pass_filenames: false - # only .json files allowed in cmake/presets/ - - id: json-xtn-in-toolchain-dir - name: Ensure only .json files in cmake/presets/ - entry: Files in the cmake/presets/ directory must have the .json extension - language: fail - files: cmake/presets/.*(? - $ - $) + lfilesystem + PUBLIC $ + $ + $) -install (FILES "${public_header}" "${export_header}" ${private_headers} - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lfilesystem" COMPONENT lfilesystem_dev) +install ( + FILES "${public_header}" + "${export_header}" + "${version_header}" + ${util_headers} + ${entries_headers} + ${watcher_headers} + ${specialdir_headers} + ${volume_headers} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lfilesystem" + COMPONENT lfilesystem_dev) if (APPLE) - enable_language (OBJCXX) + enable_language (OBJCXX) - target_link_libraries (lfilesystem PRIVATE "-framework Foundation") + target_link_libraries (lfilesystem PRIVATE "-framework Foundation") - if (NOT IOS) - target_link_libraries (lfilesystem PRIVATE "-framework AppKit") - endif () + if (NOT IOS) + target_link_libraries (lfilesystem PRIVATE "-framework AppKit") + endif () elseif (WIN32) - target_compile_definitions (lfilesystem PRIVATE NOMINMAX) + target_compile_definitions (lfilesystem PRIVATE NOMINMAX) elseif (LINUX) - include (CheckCXXSourceCompiles) + include (CheckCXXSourceCompiles) - check_cxx_source_compiles ( - " + check_cxx_source_compiles ( + [=[ #include #include int main (int, char**) { -const std::string path { \"/some/file/path.txt\" }; +const std::string path { "/some/file/path.txt" }; [[maybe_unused]] auto result = pathconf (path.data(), _PC_CASE_SENSITIVE); return 0; } -" - limes_files_can_use_pathconf) +]=] + limes_files_can_use_pathconf) - if (limes_files_can_use_pathconf) - target_compile_definitions (lfilesystem PRIVATE LFILE_IMPL_USE_PATHCONF=1) - else () - target_compile_definitions (lfilesystem PRIVATE LFILE_IMPL_USE_PATHCONF=0) - endif () + if (limes_files_can_use_pathconf) + target_compile_definitions (lfilesystem PRIVATE LFILE_IMPL_USE_PATHCONF=1) + else () + target_compile_definitions (lfilesystem PRIVATE LFILE_IMPL_USE_PATHCONF=0) + endif () endif () -if (EMSCRIPTEN) - target_compile_options (lfilesystem PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING -fexceptions) - target_link_options (lfilesystem PRIVATE -fexceptions) +target_link_libraries (lfilesystem PRIVATE ${CMAKE_DL_LIBS}) + +set (util_sources src/lfilesystem_CFile.cpp src/lfilesystem_DynamicLibrary.cpp + src/lfilesystem_Paths.cpp src/lfilesystem_Permissions.cpp) + +set (entries_sources src/lfilesystem_Directory.cpp src/lfilesystem_File.cpp + src/lfilesystem_FilesystemEntry.cpp src/lfilesystem_SymLink.cpp) + +set (specialdir_sources src/lfilesystem_SpecialDirs_Common.cpp) + +set (volume_sources src/lfilesystem_Volume_Common.cpp) + +if (APPLE) + list (APPEND entries_sources src/native/lfilesystem_Entries_Mac.mm) + list (APPEND specialdir_sources src/native/lfilesystem_SpecialDirs_Mac.mm) + list (APPEND volume_sources src/native/lfilesystem_Volume_Mac.mm) +elseif (WIN32) + list (APPEND entries_sources src/native/lfilesystem_Entries_Windows.cpp) + list (APPEND specialdir_sources src/native/lfilesystem_SpecialDirs_Windows.cpp) + list (APPEND volume_sources src/native/lfilesystem_Volume_Windows.cpp) +else () + list (APPEND entries_sources src/native/lfilesystem_Entries_Linux.cpp) + list (APPEND volume_sources src/native/lfilesystem_Volume_Linux.cpp) + + if (ANDROID) + list (APPEND specialdir_sources src/native/lfilesystem_SpecialDirs_Android.cpp) + else () + list (APPEND specialdir_sources src/native/lfilesystem_SpecialDirs_Linux.cpp) + endif () endif () -target_link_libraries (lfilesystem PRIVATE ${CMAKE_DL_LIBS}) +set (watcher_sources src/lfilesystem_SimpleWatcher.cpp) + +if (IOS OR ANDROID OR EMSCRIPTEN) + list (APPEND watcher_sources src/native/lfilesystem_FileWatcher_Unsupported.cpp) +elseif (APPLE) + list (APPEND watcher_sources src/native/lfilesystem_FileWatcher_Mac.mm) +elseif (WIN32) + list (APPEND watcher_sources src/native/lfilesystem_FileWatcher_Windows.cpp) +else () + list (APPEND watcher_sources src/native/lfilesystem_FileWatcher_Linux.cpp) +endif () -add_subdirectory (src) +target_sources (lfilesystem PRIVATE ${util_sources} ${entries_sources} ${watcher_sources} + ${specialdir_sources} ${volume_sources}) + +source_group (util FILES ${util_headers} ${util_sources}) +source_group (entries FILES ${entries_headers} ${entries_sources}) +source_group (watcher FILES ${watcher_headers} ${watcher_sources}) +source_group (special-dirs FILES ${specialdir_headers} ${specialdir_sources}) +source_group (volumes FILES ${volume_headers} ${volume_sources}) + +if (LFILE_CLI) + add_subdirectory (cli) +endif () install ( - TARGETS lfilesystem - EXPORT lfilesystem - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lfilesystem - NAMELINK_COMPONENT lfilesystem_dev - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lfilesystem_dev - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lfilesystem - INCLUDES - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + TARGETS lfilesystem + EXPORT lfilesystem + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lfilesystem + NAMELINK_COMPONENT lfilesystem_dev + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lfilesystem_dev + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lfilesystem + INCLUDES + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") install ( - EXPORT lfilesystem - NAMESPACE limes:: - FILE Targets.cmake - DESTINATION "${LFILE_INSTALL_DEST}" - COMPONENT lfilesystem_dev) + EXPORT lfilesystem + NAMESPACE limes:: + FILE Targets.cmake + DESTINATION "${LFILE_INSTALL_DEST}" + COMPONENT lfilesystem_dev) include (CMakePackageConfigHelpers) write_basic_package_version_file (lfilesystem-config-version.cmake VERSION "${lfilesystem_VERSION}" - COMPATIBILITY SameMajorVersion) + COMPATIBILITY SameMajorVersion) configure_package_config_file (cmake/lfilesystem-config.in lfilesystem-config.cmake - INSTALL_DESTINATION "${LFILE_INSTALL_DEST}" NO_SET_AND_CHECK_MACRO) + INSTALL_DESTINATION "${LFILE_INSTALL_DEST}" NO_SET_AND_CHECK_MACRO) install (FILES "${CMAKE_CURRENT_BINARY_DIR}/lfilesystem-config-version.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/lfilesystem-config.cmake" - DESTINATION "${LFILE_INSTALL_DEST}" COMPONENT lfilesystem_dev) + "${CMAKE_CURRENT_BINARY_DIR}/lfilesystem-config.cmake" + DESTINATION "${LFILE_INSTALL_DEST}" COMPONENT lfilesystem_dev) include (CPackComponent) cpack_add_component ( - lfilesystem - DISPLAY_NAME "Limes filesystem library" - DESCRIPTION - "The Limes C++ filesystem library. This is the runtime component needed by end users." - GROUP limes_files) + lfilesystem + DISPLAY_NAME "Limes filesystem library" + DESCRIPTION + "The Limes C++ filesystem library. This is the runtime component needed by end users." + GROUP limes_files) cpack_add_component ( - lfilesystem_dev - DISPLAY_NAME "Limes filesystem library headers" - DESCRIPTION - "Development package for the Limes C++ filesystem library. This component includes the library's header files and CMake package files." - GROUP limes_files - DEPENDS lfilesystem) + lfilesystem_dev + DISPLAY_NAME "Limes filesystem library headers" + DESCRIPTION + "Development package for the Limes C++ filesystem library. This component includes the library's header files and CMake package files." + GROUP limes_files + DEPENDS lfilesystem) cpack_add_component_group (limes_files DISPLAY_NAME "Limes filesystem" - DESCRIPTION "Limes filesystem library" PARENT_GROUP limes) + DESCRIPTION "Limes filesystem library" PARENT_GROUP limes) if (LFILE_TESTS) - enable_testing () + enable_testing () - add_subdirectory (tests) + add_subdirectory (tests) - include (CTest) + include (CTest) endif () if (LFILE_DOCS) - add_subdirectory (docs) + add_subdirectory (docs) endif () if (lfilesystem_IS_TOP_LEVEL) - include (CPack) + include (CPack) endif () diff --git a/CMakePresets.json b/CMakePresets.json index 0e7ba91..5359f41 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -5,14 +5,7 @@ "patch": 0 }, "include": [ - "cmake/presets/clang.json", - "cmake/presets/emscripten.json", - "cmake/presets/gcc.json", - "cmake/presets/ios.json", - "cmake/presets/tvos.json", - "cmake/presets/vs.json", - "cmake/presets/watchos.json", - "cmake/presets/xcode.json" + "linfra/CMakePresets.json" ], "version": 6 } diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt new file mode 100644 index 0000000..6052c08 --- /dev/null +++ b/cli/CMakeLists.txt @@ -0,0 +1,43 @@ +# ====================================================================================== +# __ ____ __ __ ____ ___ +# ( ) (_ _)( \/ )( ___)/ __) +# )(__ _)(_ ) ( )__) \__ \ +# (____)(____)(_/\/\_)(____)(___/ +# +# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. +# +# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. +# +# ====================================================================================== + +add_executable (lfile) +add_executable (limes::lfile ALIAS lfile) + +set (common_files main.cpp modes.cpp modes.h) + +set (modes_files modes/cat.h modes/basename.h modes/cp.h modes/df.h) + +target_sources (lfile PRIVATE ${common_files} ${modes_files}) + +source_group (common FILES ${common_files}) +source_group (modes FILES ${modes_files}) + +target_link_libraries (lfile PRIVATE limes::lfilesystem) + +target_include_directories (lfile PRIVATE "${CMAKE_CURRENT_LIST_DIR}") + +limes_copy_dlls (lfile) + +install ( + TARGETS lfile + EXPORT lfilesystem + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lfilesystem + NAMELINK_COMPONENT lfilesystem_dev + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lfilesystem_dev + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lfilesystem + INCLUDES + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + +if (LFILE_TESTS) + add_subdirectory (test) +endif () diff --git a/cli/main.cpp b/cli/main.cpp new file mode 100644 index 0000000..e256112 --- /dev/null +++ b/cli/main.cpp @@ -0,0 +1,88 @@ +/* + * ====================================================================================== + * __ ____ __ __ ____ ___ + * ( ) (_ _)( \/ )( ___)/ __) + * )(__ _)(_ ) ( )__) \__ \ + * (____)(____)(_/\/\_)(____)(___/ + * + * This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. + * + * Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. + * + * ====================================================================================== + */ + +#include "./modes.h" +#include +#include +#include + +// TODO: add --version + +static void printUsage() +{ + std::cout << "Usage:\n\n" + << "lfile []\n\n" + << "You can run lfile help for detailed help for a specific subcommand.\n" + << "Available modes:\n\n"; + + for (const auto& mode : limes::files::cli::getAllModes()) + std::cout << " * " << mode->getName() << '\n'; + + std::cout << std::endl; +} + +static inline bool isHelpSubcommand (std::string_view subcmd) noexcept +{ + return subcmd == "help" || subcmd == "Help" || subcmd == "--help" || subcmd == "-h" || subcmd == "-help"; +} + +int main (int argc, char** argv) +{ + if (argc < 2) + { + printUsage(); + return EXIT_FAILURE; + } + + const std::string_view modeStr { argv[1] }; + + if (isHelpSubcommand (modeStr)) + { + printUsage(); + return EXIT_SUCCESS; + } + + const auto* mode = limes::files::cli::getMode (modeStr); + + if (mode == nullptr) + { + std::cout << "Unknown mode requested: '" << modeStr << "'\n\n"; + printUsage(); + return EXIT_FAILURE; + } + + if (argc > 2) + { + const std::string_view subcmd { argv[2] }; + + if (isHelpSubcommand (subcmd)) + { + mode->outputHelp(); + return EXIT_SUCCESS; + } + } + + try + { + // consume the 'lfile' from the command line argument list + if (mode->execute (argc - 1, argv + 1)) + return EXIT_SUCCESS; + + return EXIT_FAILURE; + } + catch(...) + { + return EXIT_FAILURE; + } +} diff --git a/cli/modes.cpp b/cli/modes.cpp new file mode 100644 index 0000000..089dba9 --- /dev/null +++ b/cli/modes.cpp @@ -0,0 +1,97 @@ +/* + * ====================================================================================== + * __ ____ __ __ ____ ___ + * ( ) (_ _)( \/ )( ___)/ __) + * )(__ _)(_ ) ( )__) \__ \ + * (____)(____)(_/\/\_)(____)(___/ + * + * This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. + * + * Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. + * + * ====================================================================================== + */ + +#include "./modes.h" +#include +#include "./modes/cat.h" +#include "./modes/basename.h" +#include "./modes/cp.h" +#include "./modes/df.h" + +// TODO: check if file/directory exists +// TODO: get mount path of file +/* +cd (cd + run command) +chgrp +chmod +chown +cksum +cmp +compress +dd +dirname +du +file +find +link +ln +ls +mkdir +mkfifo +mv +pathchk +pwd +readlink +rm +rmdir +split +touch +ulimit +uncompress +unlink + */ + +namespace limes::files::cli +{ + +const Mode* getMode (std::string_view mode) +{ + const auto& allModes = getAllModes(); + + const auto result = std::find_if (std::begin (allModes), + std::end (allModes), + [mode](const auto& m) + { + return m->getName() == mode; + }); + + if (result == std::end (allModes)) + return nullptr; + + return result->get(); +} + +struct AllModes final +{ + Modes modes; + + AllModes() + { + modes.reserve (4); + + modes.emplace_back (std::make_unique()); + modes.emplace_back (std::make_unique()); + modes.emplace_back (std::make_unique()); + modes.emplace_back (std::make_unique()); + } +}; + +const Modes& getAllModes() +{ + static AllModes holder; + + return holder.modes; +} + +} // namespace limes::files::cli diff --git a/cli/modes.h b/cli/modes.h new file mode 100644 index 0000000..9f0869a --- /dev/null +++ b/cli/modes.h @@ -0,0 +1,45 @@ +/* + * ====================================================================================== + * __ ____ __ __ ____ ___ + * ( ) (_ _)( \/ )( ___)/ __) + * )(__ _)(_ ) ( )__) \__ \ + * (____)(____)(_/\/\_)(____)(___/ + * + * This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. + * + * Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. + * + * ====================================================================================== + */ + +#pragma once + +#include +#include +#include +#include + +namespace limes::files::cli +{ + +class Mode +{ +public: + virtual ~Mode() = default; + + [[nodiscard]] virtual std::string_view getName() const = 0; + + virtual void outputHelp() const = 0; + + [[nodiscard]] virtual bool execute (int argc, char** argv) const = 0; + +private: +}; + +using Modes = std::vector>; + +[[nodiscard]] const Mode* getMode (std::string_view mode); + +[[nodiscard]] const Modes& getAllModes(); + +} // namespace limes::files::cli diff --git a/cli/modes/basename.h b/cli/modes/basename.h new file mode 100644 index 0000000..d8136e7 --- /dev/null +++ b/cli/modes/basename.h @@ -0,0 +1,62 @@ +/* + * ====================================================================================== + * __ ____ __ __ ____ ___ + * ( ) (_ _)( \/ )( ___)/ __) + * )(__ _)(_ ) ( )__) \__ \ + * (____)(____)(_/\/\_)(____)(___/ + * + * This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. + * + * Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. + * + * ====================================================================================== + */ + +#pragma once + +#include "../modes.h" +#include +#include +#include + +namespace limes::files::cli::modes +{ + +/** TODO: suffix business... + Should the path be printed unquoted? + */ +class Basename final : public Mode +{ +public: + [[nodiscard]] std::string_view getName() const final + { + return "basename"; + } + + void outputHelp() const final + { + std::cout << "Usage:\n\n" + << "lfile basename \n\n" + << "Prints the directory portion of the given path." + << std::endl; + } + + [[nodiscard]] bool execute (int argc, char** argv) const final + { + if (argc < 2) + { + outputHelp(); + return false; + } + + const FilesystemEntry path { argv[1] }; + + const auto parentPath = path.isDirectory() ? path.getParentDirectory() : path.getDirectory(); + + std::cout << parentPath.getPath() << std::endl; + + return true; + } +}; + +} diff --git a/cli/modes/cat.h b/cli/modes/cat.h new file mode 100644 index 0000000..99c2a9d --- /dev/null +++ b/cli/modes/cat.h @@ -0,0 +1,90 @@ +/* + * ====================================================================================== + * __ ____ __ __ ____ ___ + * ( ) (_ _)( \/ )( ___)/ __) + * )(__ _)(_ ) ( )__) \__ \ + * (____)(____)(_/\/\_)(____)(___/ + * + * This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. + * + * Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. + * + * ====================================================================================== + */ + +#pragma once + +#include "../modes.h" +#include +#include +#include + +namespace limes::files::cli::modes +{ + +/** TODO: + + -b Number the non-blank output lines, starting at 1. + + -e Display non-printing characters (see the -v option), and display a dollar sign ('$') at the end of each line. + + -l Set an exclusive advisory lock on the standard output file descriptor. This lock is set using fcntl(2) with + the F_SETLKW command. If the output file is already locked, cat will block until the lock is acquired. + + -n Number the output lines, starting at 1. + + -s Squeeze multiple adjacent empty lines, causing the output to be single spaced. + + -t Display non-printing characters (see the -v option), and display tab characters as '^I'. + + -u Disable output buffering. + + -v Display non-printing characters so they are visible. Control characters print as '^X' for control-X; the delete + character (octal 0177) prints as '^?'. Non-ASCII characters (with the high bit set) are printed as 'M-' (for + meta) followed by the character for the low 7 bits. + */ +class Cat final : public Mode +{ +public: + [[nodiscard]] std::string_view getName() const final + { + return "cat"; + } + + void outputHelp() const final + { + std::cout << "Usage:\n\n" + << "lfile cat \n\n" + << "Prints contents of files to standard output.\n" + << "Relative filepaths will be interpreted relative to the current working directory." + << std::endl; + } + + [[nodiscard]] bool execute (int argc, char** argv) const final + { + if (argc < 2) + { + outputHelp(); + return false; + } + + for (auto i = 1; i < argc; ++i) + { + File file { argv[i] }; + + file.makeAbsoluteRelativeToCWD(); + + if (! file.exists()) + { + std::cerr << "File " << file.getAbsolutePath() << " does not exist!" << std::endl; + return false; + } + + std::cout << file << std::endl; + } + + return true; + } +}; + +} diff --git a/cli/modes/cp.h b/cli/modes/cp.h new file mode 100644 index 0000000..fa06b85 --- /dev/null +++ b/cli/modes/cp.h @@ -0,0 +1,127 @@ +/* + * ====================================================================================== + * __ ____ __ __ ____ ___ + * ( ) (_ _)( \/ )( ___)/ __) + * )(__ _)(_ ) ( )__) \__ \ + * (____)(____)(_/\/\_)(____)(___/ + * + * This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. + * + * Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. + * + * ====================================================================================== + */ + +#pragma once + +#include "../modes.h" +#include +#include +#include +#include + +namespace limes::files::cli::modes +{ + +/** TODO: options */ +class CP final : public Mode +{ +public: + [[nodiscard]] std::string_view getName() const final + { + return "cp"; + } + + void outputHelp() const final + { + std::cout << "Usage:\n\n" + << "lfile cp [options] \n" + << "lfile cp [options] \n\n" + << "In the second synopsis form, must exist." + << std::endl; + } + + [[nodiscard]] bool execute (int argc, char** argv) const final + { + if (argc < 2) + { + outputHelp(); + return false; + } + + // consume the 'cp' from the command line + argc -= 1; + argv += 1; + + // consume options here, adjust argc/argv accordingly + + if (argc == 2) + { + File source { argv[0] }; + FilesystemEntry dest { argv[1] }; + + source.makeAbsoluteRelativeToCWD(); + dest.makeAbsoluteRelativeToCWD(); + + if (! source.exists()) + { + std::cerr << "Source file " << source.getAbsolutePath() << " does not exist!" << std::endl; + return false; + } + + if (dest.isDirectory()) + return copyFileToDirectory (source, *dest.getDirectoryObject()); + + const File d { dest.getAbsolutePath() }; + + return d.overwrite (source.loadAsString()); + } + + Directory dest { argv[argc - 1] }; + + dest.makeAbsoluteRelativeToCWD(); + + if (! dest.exists()) + { + std::cerr << "Destination directory " << dest.getAbsolutePath() << " does not exist!" << std::endl; + return false; + } + + std::vector sourceFiles; + + sourceFiles.reserve (argc - 1); + + for (auto i = 0; i < argc - 1; ++i) + sourceFiles.emplace_back (argv[i]); + + for (auto& source : sourceFiles) + { + source.makeAbsoluteRelativeToCWD(); + + if (! source.exists()) + { + std::cerr << "Source file " << source.getAbsolutePath() << " does not exist!" << std::endl; + return false; + } + + if (! copyFileToDirectory (source, dest)) + ; +// return false; + } + + return true; + } + +private: + // TODO: this seems to always report failure? + static bool copyFileToDirectory (const File& file, const Directory& directory) + { + auto dest = directory.getChildFile (file.getFilename()); + + dest.replaceFileExtension (file.getFileExtension(), false); + + dest.overwrite (file.loadAsString()); + } +}; + +} diff --git a/cli/modes/df.h b/cli/modes/df.h new file mode 100644 index 0000000..ee2f445 --- /dev/null +++ b/cli/modes/df.h @@ -0,0 +1,45 @@ +/* + * ====================================================================================== + * __ ____ __ __ ____ ___ + * ( ) (_ _)( \/ )( ___)/ __) + * )(__ _)(_ ) ( )__) \__ \ + * (____)(____)(_/\/\_)(____)(___/ + * + * This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. + * + * Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. + * + * ====================================================================================== + */ + +#pragma once + +#include "../modes.h" +#include +#include +#include +#include + +namespace limes::files::cli::modes +{ + +class DF final : public Mode +{ +public: + [[nodiscard]] std::string_view getName() const final + { + return "df"; + } + + void outputHelp() const final + { + + } + + [[nodiscard]] bool execute (int argc, char** argv) const final + { + + } +}; + +} diff --git a/cli/test/Basename.cmake b/cli/test/Basename.cmake new file mode 100644 index 0000000..dd588d6 --- /dev/null +++ b/cli/test/Basename.cmake @@ -0,0 +1,19 @@ +# ====================================================================================== +# __ ____ __ __ ____ ___ +# ( ) (_ _)( \/ )( ___)/ __) +# )(__ _)(_ ) ( )__) \__ \ +# (____)(____)(_/\/\_)(____)(___/ +# +# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. +# +# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. +# +# ====================================================================================== + +include_guard (GLOBAL) + +add_test (NAME limes.files.cli.basename COMMAND limes::lfile basename + "${CMAKE_CURRENT_LIST_DIR}/foo") + +set_tests_properties (limes.files.cli.basename PROPERTIES PASS_REGULAR_EXPRESSION + "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cli/test/CMakeLists.txt b/cli/test/CMakeLists.txt new file mode 100644 index 0000000..cbdda3c --- /dev/null +++ b/cli/test/CMakeLists.txt @@ -0,0 +1,15 @@ +# ====================================================================================== +# __ ____ __ __ ____ ___ +# ( ) (_ _)( \/ )( ___)/ __) +# )(__ _)(_ ) ( )__) \__ \ +# (____)(____)(_/\/\_)(____)(___/ +# +# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. +# +# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. +# +# ====================================================================================== + +include ("${CMAKE_CURRENT_LIST_DIR}/Basename.cmake") +include ("${CMAKE_CURRENT_LIST_DIR}/Cat.cmake") +include ("${CMAKE_CURRENT_LIST_DIR}/CP.cmake") diff --git a/cli/test/CP.cmake b/cli/test/CP.cmake new file mode 100644 index 0000000..98862ac --- /dev/null +++ b/cli/test/CP.cmake @@ -0,0 +1,38 @@ +# ====================================================================================== +# __ ____ __ __ ____ ___ +# ( ) (_ _)( \/ )( ___)/ __) +# )(__ _)(_ ) ( )__) \__ \ +# (____)(____)(_/\/\_)(____)(___/ +# +# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. +# +# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. +# +# ====================================================================================== + +include_guard (GLOBAL) + +set (base_name "limes.files.cli.cp") + +# + +set (dest_file "${CMAKE_CURRENT_BINARY_DIR}/copied.cmake") + +file (REMOVE "${dest_file}") + +add_test (NAME "${base_name}.simple-copy" COMMAND limes::lfile cp "${CMAKE_CURRENT_LIST_FILE}" + "${dest_file}") + +# + +set (dest_dir "${CMAKE_CURRENT_BINARY_DIR}/copy-test-dest-directory") + +file (REMOVE_RECURSE "${dest_dir}") + +add_test (NAME "${base_name}.nonexist-dest-dir" + COMMAND limes::lfile cp "${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_PARENT_LIST_FILE}" + "${dest_dir}") + +set_tests_properties ( + "${base_name}.nonexist-dest-dir" + PROPERTIES PASS_REGULAR_EXPRESSION "Destination directory \"${dest_dir}\" does not exist!") diff --git a/cli/test/Cat.cmake b/cli/test/Cat.cmake new file mode 100644 index 0000000..ba675f0 --- /dev/null +++ b/cli/test/Cat.cmake @@ -0,0 +1,26 @@ +# ====================================================================================== +# __ ____ __ __ ____ ___ +# ( ) (_ _)( \/ )( ___)/ __) +# )(__ _)(_ ) ( )__) \__ \ +# (____)(____)(_/\/\_)(____)(___/ +# +# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. +# +# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. +# +# ====================================================================================== + +include_guard (GLOBAL) + +set ( + test_file_content + [[ +This is a test file generated by CMake to be read by the cat command-line tool. +]]) + +file (WRITE "${CMAKE_CURRENT_BINARY_DIR}/test-content.txt" "${test_file_content}") + +add_test (NAME limes.files.cli.cat COMMAND limes::lfile cat test-content.txt + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +set_tests_properties (limes.files.cli.cat PROPERTIES PASS_REGULAR_EXPRESSION "${test_file_content}") diff --git a/cmake/presets/base.json b/cmake/presets/base.json deleted file mode 100644 index e839d10..0000000 --- a/cmake/presets/base.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "buildPresets": [ - { - "cleanFirst": false, - "configuration": "Debug", - "hidden": true, - "jobs": 4, - "name": "base", - "verbose": true - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "binaryDir": "${sourceDir}/Builds/${presetName}", - "hidden": true, - "installDir": "${sourceDir}/Builds/deploy/${presetName}", - "name": "base", - "warnings": { - "deprecated": true, - "dev": true, - "uninitialized": false, - "unusedCli": false - } - } - ], - "packagePresets": [ - { - "configurations": [ - "Debug", - "Release" - ], - "generators": [ - "ZIP" - ], - "hidden": true, - "name": "base", - "packageDirectory": "${sourceDir}/deploy/${presetName}" - } - ], - "testPresets": [ - { - "configuration": "Debug", - "execution": { - "enableFailover": true, - "jobs": 4, - "noTestsAction": "error", - "repeat": { - "count": 5, - "mode": "until-pass" - }, - "scheduleRandom": true, - "stopOnFailure": false, - "timeout": 300 - }, - "filter": { - "include": { - "name": "^Limes.files.+" - } - }, - "hidden": true, - "name": "base", - "output": { - "labelSummary": true, - "outputJUnitFile": "${sourceDir}/logs/tests/junit/${presetName}.xml", - "outputLogFile": "${sourceDir}/logs/tests/${presetName}.log", - "outputOnFailure": true, - "shortProgress": true, - "testOutputTruncation": "middle" - } - } - ], - "version": 6 -} diff --git a/cmake/presets/clang.json b/cmake/presets/clang.json deleted file mode 100644 index f51410a..0000000 --- a/cmake/presets/clang.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "buildPresets": [ - { - "configurePreset": "clang", - "displayName": "Clang (debug)", - "inherits": "base", - "name": "clang" - }, - { - "configuration": "Release", - "displayName": "Clang (release)", - "inherits": "clang", - "name": "clang-r" - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "cacheVariables": { - "CMAKE_CXX_COMPILER": { - "type": "STRING", - "value": "clang++" - }, - "CMAKE_C_COMPILER": { - "type": "STRING", - "value": "clang" - }, - "CMAKE_OSX_ARCHITECTURES": { - "type": "STRING", - "value": "$env{CMAKE_APPLE_SILICON_PROCESSOR}" - } - }, - "displayName": "Clang", - "generator": "Ninja Multi-Config", - "inherits": "base", - "name": "clang" - } - ], - "include": [ - "base.json" - ], - "packagePresets": [ - { - "configurePreset": "clang", - "displayName": "Clang", - "inherits": "base", - "name": "clang" - } - ], - "testPresets": [ - { - "configurePreset": "clang", - "displayName": "Clang (debug)", - "inherits": "base", - "name": "clang" - }, - { - "configuration": "Release", - "displayName": "Clang (release)", - "inherits": "clang", - "name": "clang-r" - } - ], - "version": 6, - "workflowPresets": [ - { - "displayName": "Clang", - "name": "clang", - "steps": [ - { - "name": "clang", - "type": "configure" - }, - { - "name": "clang", - "type": "build" - }, - { - "name": "clang-r", - "type": "build" - }, - { - "name": "clang", - "type": "test" - }, - { - "name": "clang-r", - "type": "test" - }, - { - "name": "clang", - "type": "package" - } - ] - } - ] -} diff --git a/cmake/presets/emscripten.json b/cmake/presets/emscripten.json deleted file mode 100644 index 3993692..0000000 --- a/cmake/presets/emscripten.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "buildPresets": [ - { - "configurePreset": "emscripten", - "displayName": "WebAssembly (debug)", - "inherits": "base", - "name": "emscripten" - }, - { - "configuration": "Release", - "displayName": "WebAssembly (release)", - "inherits": "emscripten", - "name": "emscripten-r" - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "cacheVariables": { - "EMSCRIPTEN": { - "type": "BOOL", - "value": true - } - }, - "description": "Note that you must set the environment variable EMSCRIPTEN_ROOT to the path of your Emscripten SDK installation. You can find this by running which emcc (Unix) or where emcc (Windows)", - "displayName": "Emscripten", - "generator": "Ninja Multi-Config", - "inherits": "base", - "name": "emscripten", - "toolchainFile": "$env{EMSCRIPTEN_ROOT}/cmake/Modules/Platform/Emscripten.cmake" - } - ], - "include": [ - "base.json" - ], - "packagePresets": [ - { - "configurePreset": "emscripten", - "displayName": "WebAssembly", - "inherits": "base", - "name": "emscripten" - } - ], - "testPresets": [ - { - "configurePreset": "emscripten", - "displayName": "WebAssembly (debug)", - "inherits": "base", - "name": "emscripten" - }, - { - "configuration": "Release", - "displayName": "WebAssembly (release)", - "inherits": "emscripten", - "name": "emscripten-r" - } - ], - "version": 6, - "workflowPresets": [ - { - "displayName": "WebAssembly", - "name": "emscripten", - "steps": [ - { - "name": "emscripten", - "type": "configure" - }, - { - "name": "emscripten", - "type": "build" - }, - { - "name": "emscripten-r", - "type": "build" - }, - { - "name": "emscripten", - "type": "test" - }, - { - "name": "emscripten-r", - "type": "test" - }, - { - "name": "emscripten", - "type": "package" - } - ] - } - ] -} diff --git a/cmake/presets/gcc.json b/cmake/presets/gcc.json deleted file mode 100644 index e483fd9..0000000 --- a/cmake/presets/gcc.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "buildPresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Windows", - "type": "notEquals" - }, - "configurePreset": "gcc", - "displayName": "GCC (debug)", - "inherits": "base", - "name": "gcc" - }, - { - "configuration": "Release", - "displayName": "GCC (release)", - "inherits": "gcc", - "name": "gcc-r" - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "cacheVariables": { - "CMAKE_CXX_COMPILER": { - "type": "STRING", - "value": "g++" - }, - "CMAKE_C_COMPILER": { - "type": "STRING", - "value": "gcc" - }, - "CMAKE_Fortran_COMPILER": { - "type": "STRING", - "value": "gfortran" - } - }, - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Windows", - "type": "notEquals" - }, - "displayName": "GCC", - "generator": "Ninja Multi-Config", - "inherits": "base", - "name": "gcc" - } - ], - "include": [ - "base.json" - ], - "packagePresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Windows", - "type": "notEquals" - }, - "configurePreset": "gcc", - "displayName": "GCC", - "inherits": "base", - "name": "gcc" - } - ], - "testPresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Windows", - "type": "notEquals" - }, - "configurePreset": "gcc", - "displayName": "GCC (debug)", - "inherits": "base", - "name": "gcc" - }, - { - "configuration": "Release", - "displayName": "GCC (release)", - "inherits": "gcc", - "name": "gcc-r" - } - ], - "version": 6, - "workflowPresets": [ - { - "displayName": "GCC", - "name": "gcc", - "steps": [ - { - "name": "gcc", - "type": "configure" - }, - { - "name": "gcc", - "type": "build" - }, - { - "name": "gcc-r", - "type": "build" - }, - { - "name": "gcc", - "type": "test" - }, - { - "name": "gcc-r", - "type": "test" - }, - { - "name": "gcc", - "type": "package" - } - ] - } - ] -} diff --git a/cmake/presets/ios.json b/cmake/presets/ios.json deleted file mode 100644 index 875199d..0000000 --- a/cmake/presets/ios.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "buildPresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Darwin", - "type": "equals" - }, - "configurePreset": "iOS", - "displayName": "iOS (debug)", - "inherits": "base", - "name": "iOS" - }, - { - "configuration": "Release", - "displayName": "iOS (release)", - "inherits": "iOS", - "name": "iOS-r" - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "cacheVariables": { - "CMAKE_SYSTEM_NAME": { - "type": "STRING", - "value": "iOS" - }, - "CMAKE_XCODE_EFFECTIVE_PLATFORMS": { - "type": "STRING", - "value": "-iphoneos" - }, - "IOS": { - "type": "BOOL", - "value": "ON" - } - }, - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Darwin", - "type": "equals" - }, - "displayName": "iOS", - "generator": "Xcode", - "inherits": "base", - "name": "iOS" - } - ], - "include": [ - "base.json" - ], - "packagePresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Darwin", - "type": "equals" - }, - "configurePreset": "iOS", - "displayName": "iOS", - "inherits": "base", - "name": "iOS" - } - ], - "version": 6, - "workflowPresets": [ - { - "displayName": "iOS", - "name": "iOS", - "steps": [ - { - "name": "iOS", - "type": "configure" - }, - { - "name": "iOS", - "type": "build" - }, - { - "name": "iOS-r", - "type": "build" - }, - { - "name": "iOS", - "type": "package" - } - ] - } - ] -} diff --git a/cmake/presets/tvos.json b/cmake/presets/tvos.json deleted file mode 100644 index f077040..0000000 --- a/cmake/presets/tvos.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "buildPresets": [ - { - "configurePreset": "tvOS", - "displayName": "tvOS (debug)", - "inherits": "iOS", - "name": "tvOS" - }, - { - "configuration": "Release", - "displayName": "tvOS (release)", - "inherits": "tvOS", - "name": "tvOS-r" - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "cacheVariables": { - "CMAKE_SYSTEM_NAME": { - "type": "STRING", - "value": "tvOS" - }, - "CMAKE_XCODE_EFFECTIVE_PLATFORMS": { - "type": "STRING", - "value": "-appletvos" - } - }, - "displayName": "tvOS", - "inherits": "iOS", - "name": "tvOS" - } - ], - "include": [ - "ios.json" - ], - "packagePresets": [ - { - "configurePreset": "tvOS", - "displayName": "tvOS", - "inherits": "iOS", - "name": "tvOS" - } - ], - "version": 6, - "workflowPresets": [ - { - "displayName": "tvOS", - "name": "tvOS", - "steps": [ - { - "name": "tvOS", - "type": "configure" - }, - { - "name": "tvOS", - "type": "build" - }, - { - "name": "tvOS-r", - "type": "build" - }, - { - "name": "tvOS", - "type": "package" - } - ] - } - ] -} diff --git a/cmake/presets/vs.json b/cmake/presets/vs.json deleted file mode 100644 index 7863722..0000000 --- a/cmake/presets/vs.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "buildPresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Windows", - "type": "equals" - }, - "configurePreset": "vs", - "displayName": "MSVC (debug)", - "inherits": "base", - "name": "vs", - "nativeToolOptions": [ - "-flp1:logfile=${sourceDir}/logs/builds/Debug/errors.log;errorsonly", - "-flp2:logfile=${sourceDir}/logs/builds/Debug/warnings.log;warningsonly", - "-clp:PerformanceSummary;Summary" - ] - }, - { - "configuration": "Release", - "displayName": "MSVC (release)", - "inherits": "vs", - "name": "vs-r", - "nativeToolOptions": [ - "-flp1:logfile=${sourceDir}/logs/builds/Release/errors.log;errorsonly", - "-flp2:logfile=${sourceDir}/logs/builds/Release/warnings.log;warningsonly", - "-clp:PerformanceSummary;Summary" - ] - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Windows", - "type": "equals" - }, - "displayName": "MSVC", - "generator": "Visual Studio 17 2022", - "inherits": "base", - "name": "vs" - } - ], - "include": [ - "base.json" - ], - "packagePresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Windows", - "type": "equals" - }, - "configurePreset": "vs", - "displayName": "MSVC", - "inherits": "base", - "name": "vs" - } - ], - "testPresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Windows", - "type": "equals" - }, - "configurePreset": "vs", - "displayName": "MSVC (debug)", - "inherits": "base", - "name": "vs" - }, - { - "configuration": "Release", - "displayName": "MSVC (release)", - "inherits": "vs", - "name": "vs-r" - } - ], - "version": 6, - "workflowPresets": [ - { - "displayName": "MSVC", - "name": "vs", - "steps": [ - { - "name": "vs", - "type": "configure" - }, - { - "name": "vs", - "type": "build" - }, - { - "name": "vs-r", - "type": "build" - }, - { - "name": "vs", - "type": "test" - }, - { - "name": "vs-r", - "type": "test" - }, - { - "name": "vs", - "type": "package" - } - ] - } - ] -} diff --git a/cmake/presets/watchos.json b/cmake/presets/watchos.json deleted file mode 100644 index d789272..0000000 --- a/cmake/presets/watchos.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "buildPresets": [ - { - "configurePreset": "watchOS", - "displayName": "watchOS (debug)", - "inherits": "iOS", - "name": "watchOS" - }, - { - "configuration": "Release", - "displayName": "watchOS (release)", - "inherits": "watchOS", - "name": "watchOS-r" - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "cacheVariables": { - "CMAKE_SYSTEM_NAME": { - "type": "STRING", - "value": "watchOS" - }, - "CMAKE_XCODE_EFFECTIVE_PLATFORMS": { - "type": "STRING", - "value": "-watchos" - } - }, - "displayName": "watchOS", - "inherits": "iOS", - "name": "watchOS" - } - ], - "include": [ - "ios.json" - ], - "packagePresets": [ - { - "configurePreset": "watchOS", - "displayName": "watchOS", - "inherits": "iOS", - "name": "watchOS" - } - ], - "version": 6, - "workflowPresets": [ - { - "displayName": "watchOS", - "name": "watchOS", - "steps": [ - { - "name": "watchOS", - "type": "configure" - }, - { - "name": "watchOS", - "type": "build" - }, - { - "name": "watchOS-r", - "type": "build" - }, - { - "name": "watchOS", - "type": "package" - } - ] - } - ] -} diff --git a/cmake/presets/xcode.json b/cmake/presets/xcode.json deleted file mode 100644 index 264b8c0..0000000 --- a/cmake/presets/xcode.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "buildPresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Darwin", - "type": "equals" - }, - "configurePreset": "xcode", - "displayName": "XCode (debug)", - "inherits": "base", - "name": "xcode" - }, - { - "configuration": "Release", - "displayName": "XCode (release)", - "inherits": "xcode", - "name": "xcode-r" - } - ], - "cmakeMinimumRequired": { - "major": 3, - "minor": 25, - "patch": 0 - }, - "configurePresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Darwin", - "type": "equals" - }, - "displayName": "XCode", - "generator": "Xcode", - "inherits": "base", - "name": "xcode" - } - ], - "include": [ - "base.json" - ], - "packagePresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Darwin", - "type": "equals" - }, - "configurePreset": "xcode", - "displayName": "XCode", - "inherits": "base", - "name": "xcode" - } - ], - "testPresets": [ - { - "condition": { - "lhs": "${hostSystemName}", - "rhs": "Darwin", - "type": "equals" - }, - "configurePreset": "xcode", - "displayName": "XCode (debug)", - "inherits": "base", - "name": "xcode" - }, - { - "configuration": "Release", - "displayName": "XCode (release)", - "inherits": "xcode", - "name": "xcode-r" - } - ], - "version": 6, - "workflowPresets": [ - { - "displayName": "XCode", - "name": "xcode", - "steps": [ - { - "name": "xcode", - "type": "configure" - }, - { - "name": "xcode", - "type": "build" - }, - { - "name": "xcode-r", - "type": "build" - }, - { - "name": "xcode", - "type": "test" - }, - { - "name": "xcode-r", - "type": "test" - }, - { - "name": "xcode", - "type": "package" - } - ] - } - ] -} diff --git a/cmake/version.in b/cmake/version.in new file mode 100644 index 0000000..bccb22e --- /dev/null +++ b/cmake/version.in @@ -0,0 +1,9 @@ +#pragma once + +#define LFILE_VERSION_MAJOR @lfilesystem_VERSION_MAJOR@ + +#define LFILE_VERSION_MINOR @lfilesystem_VERSION_MINOR@ + +#define LFILE_VERSION_PATCH @lfilesystem_VERSION_PATCH@ + +#define LFILE_VERSION "@lfilesystem_VERSION@" diff --git a/config/.cmake-format.json b/config/.cmake-format.json deleted file mode 100644 index f61a824..0000000 --- a/config/.cmake-format.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "encode": { - "emit_byteorder_mark": false, - "input_encoding": "utf-8", - "output_encoding": "utf-8" - }, - "format": { - "autosort": true, - "command_case": "canonical", - "dangle_align": "prefix-indent", - "dangle_parens": false, - "disable": false, - "enable_sort": true, - "fractional_tab_policy": "use-space", - "keyword_case": "upper", - "line_ending": "unix", - "line_width": 100, - "max_lines_hwrap": 2, - "max_pargs_hwrap": 6, - "max_prefix_chars": 10, - "max_rows_cmdline": 2, - "max_subgroups_hwrap": 4, - "min_prefix_chars": 4, - "require_valid_layout": false, - "separate_ctrl_name_with_space": true, - "separate_fn_name_with_space": true, - "tab_size": 4, - "use_tabchars": true - }, - "lint": { - "argument_var_pattern": "[a-z][a-z0-9_]+", - "disabled_codes": [ - "C0111", - "C0301", - "C0307", - "R0915", - "C0103" - ], - "function_pattern": "^limes_", - "global_var_pattern": "^LFILE_", - "internal_var_pattern": "[a-zA-Z][0-9a-zA-Z_]+", - "keyword_pattern": "[A-Z][0-9A-Z_]+", - "local_var_pattern": "[a-zA-Z][a-zA-Z0-9_]+", - "macro_pattern": "^limes_", - "max_arguments": 5, - "max_branches": 20, - "max_conditionals_custom_parser": 2, - "max_localvars": 15, - "max_returns": 6, - "max_statement_spacing": 2, - "max_statements": 50, - "min_statement_spacing": 1, - "private_var_pattern": "[0-9a-z_]+", - "public_var_pattern": "[a-zA-Z][0-9a-zA-Z_]+" - }, - "markup": { - "bullet_char": "*", - "canonicalize_hashrulers": false, - "enable_markup": true, - "enum_char": ".", - "explicit_trailing_pattern": "#<", - "fence_pattern": "^\\s*([`~]{3}[`~]*)(.*)$", - "first_comment_is_literal": true, - "hashruler_min_length": 10, - "literal_comment_pattern": "^#\\[\\[", - "ruler_pattern": "^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$" - } -} diff --git a/config/.ecrc b/config/.ecrc deleted file mode 100644 index 922f24d..0000000 --- a/config/.ecrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "SpacesAftertabs": true -} diff --git a/config/.gitlint b/config/.gitlint deleted file mode 100644 index 839e2ff..0000000 --- a/config/.gitlint +++ /dev/null @@ -1,43 +0,0 @@ -# ====================================================================================== -# __ ____ __ __ ____ ___ -# ( ) (_ _)( \/ )( ___)/ __) -# )(__ _)(_ ) ( )__) \__ \ -# (____)(____)(_/\/\_)(____)(___/ -# -# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. -# -# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. -# -# ====================================================================================== - -# configuration file for the gitlint tool, which is run by pre-commit: https://jorisroovers.com/gitlint/ -# The most important part is that commit messages must follow the -# conventional commits specification: https://www.conventionalcommits.org/en/v1.0.0/ -# Valid commit categories are listed under the contrib-title-conventional-commits key - -[general] - -ignore = title-trailing-punctuation, body-is-missing - -fail-without-commits = true - -contrib = contrib-title-conventional-commits - -verbosity = 2 - -ignore-merge-commits = false -ignore-revert-commits = false -ignore-fixup-commits = false -ignore-squash-commits = false - -[title-max-length] -line-length = 200 - -[title-min-length] -min-length = 10 - -[body-max-line-length] -line-length = 250 - -[contrib-title-conventional-commits] -types = fix, feat, chore, docs, style, refactor, test, ci diff --git a/config/limes_header.txt b/config/limes_header.txt deleted file mode 100644 index 585f604..0000000 --- a/config/limes_header.txt +++ /dev/null @@ -1,11 +0,0 @@ -====================================================================================== - __ ____ __ __ ____ ___ -( ) (_ _)( \/ )( ___)/ __) - )(__ _)(_ ) ( )__) \__ \ -(____)(____)(_/\/\_)(____)(___/ - - This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. - - Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. - -====================================================================================== diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 4cec291..acc050c 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -10,64 +10,40 @@ # # ====================================================================================== +limes_default_doxygen_settings () + set (DOXYGEN_EXAMPLE_PATH "${CMAKE_CURRENT_LIST_DIR}/examples") file (GLOB examples LIST_DIRECTORIES false CONFIGURE_DEPENDS "${DOXYGEN_EXAMPLE_PATH}/*.cpp") if (LFILE_TESTS) - add_library (lfilesystem_examples STATIC EXCLUDE_FROM_ALL ) + add_library (lfilesystem_examples STATIC EXCLUDE_FROM_ALL ) - target_sources (lfilesystem_examples PRIVATE ${examples}) + target_sources (lfilesystem_examples PRIVATE ${examples}) - target_link_libraries (lfilesystem_examples PRIVATE limes::lfilesystem) + target_link_libraries (lfilesystem_examples PRIVATE limes::lfilesystem) - add_test (NAME "Limes.files.examples" COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" - --config $ --target lfilesystem_examples) + add_test (NAME "Limes.files.examples" COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" + --config $ --target lfilesystem_examples) endif () -find_package (Doxygen OPTIONAL_COMPONENTS dot) +set (LFILE_DOC_TAGFILE "${CMAKE_CURRENT_LIST_DIR}/../doc/lfilesystem.tag" + CACHE FILEPATH "Path where the Doxygen tagfile for lfilesystem will be generated") -if (NOT DOXYGEN_FOUND) - message (WARNING "Doxygen not found, cannot build documentation") - return () -endif () +mark_as_advanced (LFILE_DOC_TAGFILE) file (GLOB headers LIST_DIRECTORIES false CONFIGURE_DEPENDS - "${CMAKE_CURRENT_LIST_DIR}/../include/lfilesystem/*.h") + "${CMAKE_CURRENT_LIST_DIR}/../include/lfilesystem/*.h") -set (DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../doc") -set (DOXYGEN_WARN_LOGFILE "${CMAKE_CURRENT_LIST_DIR}/../logs/doxygen.log") -set (DOXYGEN_ALWAYS_DETAILED_SEC YES) -set (DOXYGEN_FULL_PATH_NAMES NO) -set (DOXYGEN_JAVADOC_AUTOBRIEF YES) -set (DOXYGEN_BUILTIN_STL_SUPPORT YES) -set (DOXYGEN_DISTRIBUTE_GROUP_DOC YES) -set (DOXYGEN_GROUP_NESTED_COMPOUNDS YES) -set (DOXYGEN_EXTRACT_PRIV_VIRTUAL YES) -set (DOXYGEN_EXTRACT_STATIC YES) -set (DOXYGEN_HIDE_FRIEND_COMPOUNDS YES) -set (DOXYGEN_SORT_BRIEF_DOCS YES) -set (DOXYGEN_SORT_MEMBERS_CTORS_1ST YES) -set (DOXYGEN_SORT_GROUP_NAMES YES) -set (DOXYGEN_SORT_BY_SCOPE_NAME YES) -set (DOXYGEN_SOURCE_BROWSER YES) -set (DOXYGEN_HTML_TIMESTAMP YES) -set (DOXYGEN_HTML_DYNAMIC_SECTIONS YES) -set (DOXYGEN_HTML_INDEX_NUM_ENTRIES 1) -set (DOXYGEN_GENERATE_TREEVIEW YES) -set (DOXYGEN_FULL_SIDEBAR YES) -set (DOXYGEN_EXT_LINKS_IN_WINDOW YES) -set (DOXYGEN_COLLABORATION_GRAPH NO) -set (DOXYGEN_TEMPLATE_RELATIONS YES) -set (DOXYGEN_DOT_IMAGE_FORMAT svg) -set (DOXYGEN_INTERACTIVE_SVG YES) -set (DOXYGEN_USE_MDFILE_AS_MAINPAGE "${CMAKE_CURRENT_LIST_DIR}/../README.md") +set (DOXYGEN_GENERATE_TAGFILE "${LFILE_DOC_TAGFILE}") doxygen_add_docs ( - lfilesystem_docs ${headers} ${examples} "${DOXYGEN_USE_MDFILE_AS_MAINPAGE}" USE_STAMP_FILE - WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/.." - COMMENT "Building lfilesystem documentation...") + lfilesystem_docs ${headers} ${examples} "${DOXYGEN_USE_MDFILE_AS_MAINPAGE}" USE_STAMP_FILE + WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/.." + COMMENT "Building lfilesystem documentation...") set_property ( - TARGET lfilesystem_docs APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${DOXYGEN_OUTPUT_DIRECTORY}" - "${DOXYGEN_WARN_LOGFILE}") + TARGET lfilesystem_docs APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${DOXYGEN_OUTPUT_DIRECTORY}" + "${DOXYGEN_WARN_LOGFILE}" "${DOXYGEN_GENERATE_TAGFILE}") + +limes_add_docs_coverage (lfilesystem_docs) diff --git a/include/lfilesystem/lfilesystem.h b/include/lfilesystem/lfilesystem.h index 80dea64..98baffe 100644 --- a/include/lfilesystem/lfilesystem.h +++ b/include/lfilesystem/lfilesystem.h @@ -105,6 +105,16 @@ @todo remove internal dependencies on exceptions (Emscripten tests) @todo get all CI builds working + + @todo how to test this library with a NAS / external drives? + + @todo FileList, RecentlyOpenedFilesList classes + + @todo mounted volume listener (reference juce::MountedVolumeListChangeDetector) + + @todo compress/decompress, tarball creator/extractor + + @todo tests on iOS? */ /** @file @@ -137,17 +147,18 @@ #pragma once // IWYU pragma: begin_exports -#include "./lfilesystem_CFile.h" -#include "./lfilesystem_Directory.h" -#include "./lfilesystem_DynamicLibrary.h" -#include "./lfilesystem_File.h" -#include "./lfilesystem_FilesystemEntry.h" -#include "./lfilesystem_FileWatcher.h" -#include "./lfilesystem_Misc.h" -#include "./lfilesystem_Paths.h" -#include "./lfilesystem_Permissions.h" -#include "./lfilesystem_SimpleWatcher.h" -#include "./lfilesystem_SpecialDirectories.h" -#include "./lfilesystem_SymLink.h" -#include "./lfilesystem_Volume.h" +#include "lfilesystem/lfilesystem_Version.h" +#include "lfilesystem/lfilesystem_CFile.h" +#include "lfilesystem/lfilesystem_Directory.h" +#include "lfilesystem/lfilesystem_DynamicLibrary.h" +#include "lfilesystem/lfilesystem_File.h" +#include "lfilesystem/lfilesystem_FilesystemEntry.h" +#include "lfilesystem/lfilesystem_FileWatcher.h" +#include "lfilesystem/lfilesystem_Misc.h" +#include "lfilesystem/lfilesystem_Paths.h" +#include "lfilesystem/lfilesystem_Permissions.h" +#include "lfilesystem/lfilesystem_SimpleWatcher.h" +#include "lfilesystem/lfilesystem_SpecialDirectories.h" +#include "lfilesystem/lfilesystem_SymLink.h" +#include "lfilesystem/lfilesystem_Volume.h" // IWYU pragma: end_exports diff --git a/include/lfilesystem/lfilesystem_CFile.h b/include/lfilesystem/lfilesystem_CFile.h index 8b9ae6a..8b9e484 100644 --- a/include/lfilesystem/lfilesystem_CFile.h +++ b/include/lfilesystem/lfilesystem_CFile.h @@ -92,8 +92,8 @@ class LFILE_EXPORT CFile final /** Move assignment operator. */ CFile& operator= (CFile&& other) noexcept; - CFile (const CFile&) = delete; - CFile& operator=(const CFile&) = delete; + CFile (const CFile&) = delete; + CFile& operator= (const CFile&) = delete; /** @name Accessors */ ///@{ diff --git a/include/lfilesystem/lfilesystem_Directory.h b/include/lfilesystem/lfilesystem_Directory.h index 4d215d9..d847951 100644 --- a/include/lfilesystem/lfilesystem_Directory.h +++ b/include/lfilesystem/lfilesystem_Directory.h @@ -55,10 +55,10 @@ class LFILE_EXPORT Directory final : public FilesystemEntry public: using FilesystemEntry::FilesystemEntry; - Directory (const Directory&) = default; + Directory (const Directory&) = default; Directory& operator= (const Directory&) = default; - Directory (Directory&&) = default; + Directory (Directory&&) = default; Directory& operator= (Directory&&) = default; /** @name Typedefs @@ -274,10 +274,10 @@ class LFILE_EXPORT Directory final : public FilesystemEntry explicit Iterator(); - Iterator (const Iterator&) = default; + Iterator (const Iterator&) = default; Iterator& operator= (const Iterator&) = default; - Iterator (Iterator&&) = default; + Iterator (Iterator&&) = default; Iterator& operator= (Iterator&&) = default; private: diff --git a/include/lfilesystem/lfilesystem_DynamicLibrary.h b/include/lfilesystem/lfilesystem_DynamicLibrary.h index 7bd9b60..2c13800 100644 --- a/include/lfilesystem/lfilesystem_DynamicLibrary.h +++ b/include/lfilesystem/lfilesystem_DynamicLibrary.h @@ -78,7 +78,7 @@ class LFILE_EXPORT DynamicLibrary final DynamicLibrary (DynamicLibrary&& other) noexcept; DynamicLibrary& operator= (DynamicLibrary&& other) noexcept; - DynamicLibrary (const DynamicLibrary&) = delete; + DynamicLibrary (const DynamicLibrary&) = delete; DynamicLibrary& operator= (const DynamicLibrary&) = delete; #if (defined(_WIN32) || defined(WIN32)) && ! defined(DOXYGEN) @@ -129,7 +129,7 @@ class LFILE_EXPORT DynamicLibrary final @see Listener::libraryClosed() */ - void close(); + void close() noexcept; /** Closes and reloads the library. This locates the file on disk from which the library was loaded, then closes the library and reopens it diff --git a/include/lfilesystem/lfilesystem_File.h b/include/lfilesystem/lfilesystem_File.h index 0ded26f..ae830af 100644 --- a/include/lfilesystem/lfilesystem_File.h +++ b/include/lfilesystem/lfilesystem_File.h @@ -24,7 +24,7 @@ #include #include #include "lfilesystem/lfilesystem_Export.h" -#include "lfilesystem/lfilesystem_FilesystemEntry.h" // for FilesystemEntry, Path +#include "lfilesystem/lfilesystem_FilesystemEntry.h" // for FilesystemEntry, Path #include "lfilesystem/lfilesystem_CFile.h" /** @file @@ -63,10 +63,10 @@ class LFILE_EXPORT File : public FilesystemEntry public: using FilesystemEntry::FilesystemEntry; - File (const File&) = default; + File (const File&) = default; File& operator= (const File&) = default; - File (File&&) = default; + File (File&&) = default; File& operator= (File&&) = default; /** @name Path queries */ @@ -232,7 +232,7 @@ class LFILE_EXPORT File : public FilesystemEntry @see getHardLinkCount() */ - std::optional createHardLink (const Path& path) const; + std::optional createHardLink (const Path& path) const noexcept; /** Returns the number of hard links referring to this underlying filesystem object. @@ -310,10 +310,10 @@ class LFILE_EXPORT File : public FilesystemEntry explicit Iterator(); - Iterator (const Iterator&) = default; + Iterator (const Iterator&) = default; Iterator& operator= (const Iterator&) = default; - Iterator (Iterator&&) = default; + Iterator (Iterator&&) = default; Iterator& operator= (Iterator&&) = default; private: @@ -401,7 +401,7 @@ class LFILE_EXPORT TempFile final : public File */ ~TempFile() final; - TempFile (const TempFile&) = delete; + TempFile (const TempFile&) = delete; TempFile& operator= (const TempFile&) = delete; /** @name Moving */ @@ -428,14 +428,14 @@ class LFILE_EXPORT TempFile final : public File @ingroup limes_files @relates File */ -std::ostream& operator<< (std::ostream& os, const File& file); +LFILE_EXPORT std::ostream& operator<< (std::ostream& os, const File& file); /** Reads content from the input stream, and overwrites the file with it. @ingroup limes_files @relates File */ -std::istream& operator>> (std::istream& is, const File& file); +LFILE_EXPORT std::istream& operator>> (std::istream& is, const File& file); } // namespace limes::files diff --git a/include/lfilesystem/lfilesystem_FileWatcher.h b/include/lfilesystem/lfilesystem_FileWatcher.h index 1b26829..f69d348 100644 --- a/include/lfilesystem/lfilesystem_FileWatcher.h +++ b/include/lfilesystem/lfilesystem_FileWatcher.h @@ -84,10 +84,10 @@ class LFILE_EXPORT FileWatcher /** Destructor. */ virtual ~FileWatcher(); - FileWatcher (const FileWatcher&) = delete; + FileWatcher (const FileWatcher&) = delete; FileWatcher& operator= (const FileWatcher&) = delete; - FileWatcher (FileWatcher&&) = delete; + FileWatcher (FileWatcher&&) = delete; FileWatcher& operator= (FileWatcher&&) = delete; /** Called when a file's content is accessed. @@ -178,4 +178,4 @@ class LFILE_EXPORT FileWatcher [[maybe_unused]] FilesystemEntry watchedPath; }; -} // namespace files +} // namespace limes::files diff --git a/include/lfilesystem/lfilesystem_FilesystemEntry.h b/include/lfilesystem/lfilesystem_FilesystemEntry.h index 96c1472..880f169 100644 --- a/include/lfilesystem/lfilesystem_FilesystemEntry.h +++ b/include/lfilesystem/lfilesystem_FilesystemEntry.h @@ -108,17 +108,17 @@ class LFILE_EXPORT FilesystemEntry an error if the passed path doesn't actually exist on disk. The path will be normalized using the \c normalizePath() function. */ - explicit FilesystemEntry (const Path& pathToUse); + explicit FilesystemEntry (const Path& pathToUse) noexcept; ///@} /** Destructor. */ virtual ~FilesystemEntry() = default; - FilesystemEntry (const FilesystemEntry&) = default; + FilesystemEntry (const FilesystemEntry&) = default; FilesystemEntry& operator= (const FilesystemEntry&) = default; - FilesystemEntry (FilesystemEntry&&) = default; + FilesystemEntry (FilesystemEntry&&) = default; FilesystemEntry& operator= (FilesystemEntry&&) = default; /** @name Path assignment */ @@ -586,7 +586,7 @@ class LFILE_EXPORT FilesystemEntry @ingroup limes_files @relates FilesystemEntry */ -std::ostream& operator<< (std::ostream& os, const FilesystemEntry& value); +LFILE_EXPORT std::ostream& operator<< (std::ostream& os, const FilesystemEntry& value); } // namespace limes::files diff --git a/include/lfilesystem/lfilesystem_Misc.h b/include/lfilesystem/lfilesystem_Misc.h index 9d5a768..f41f0ac 100644 --- a/include/lfilesystem/lfilesystem_Misc.h +++ b/include/lfilesystem/lfilesystem_Misc.h @@ -82,7 +82,9 @@ namespace limes::files */ [[nodiscard]] LFILE_EXPORT constexpr std::uintmax_t maxPathLength() noexcept { -#if defined(_WIN32) || defined(WIN32) +#ifdef __ANDROID__ + return static_cast(PATH_MAX); +#elif defined(_WIN32) || defined(WIN32) return static_cast (MAX_PATH); #elif defined(NAME_MAX) return static_cast (NAME_MAX); @@ -97,4 +99,4 @@ namespace limes::files /** @}*/ -} // namespace files +} // namespace limes::files diff --git a/include/lfilesystem/lfilesystem_Paths.h b/include/lfilesystem/lfilesystem_Paths.h index af74553..b669630 100644 --- a/include/lfilesystem/lfilesystem_Paths.h +++ b/include/lfilesystem/lfilesystem_Paths.h @@ -34,7 +34,7 @@ using Path = std::filesystem::path; @see normalizePath() @ingroup limes_files */ -[[nodiscard]] LFILE_EXPORT bool isValidPath (const Path& path); +[[nodiscard]] LFILE_EXPORT bool isValidPath (const Path& path) noexcept; /** This function takes an input path and does some linting and transformations to create a consistent, canonical form of the path. If \c isValidPath() @@ -51,7 +51,7 @@ using Path = std::filesystem::path; @see isValidPath() @ingroup limes_files */ -[[nodiscard]] LFILE_EXPORT Path normalizePath (const Path& path); +[[nodiscard]] LFILE_EXPORT Path normalizePath (const Path& path) noexcept; /** Returns the largest prefix path fragment common to \c path1 and \c path2 . @@ -61,6 +61,6 @@ using Path = std::filesystem::path; @ingroup limes_files */ -[[nodiscard]] LFILE_EXPORT Path largestCommonPrefix (const Path& path1, const Path& path2); +[[nodiscard]] LFILE_EXPORT Path largestCommonPrefix (const Path& path1, const Path& path2) noexcept; } // namespace limes::files diff --git a/include/lfilesystem/lfilesystem_Permissions.h b/include/lfilesystem/lfilesystem_Permissions.h index 722ef09..0528351 100644 --- a/include/lfilesystem/lfilesystem_Permissions.h +++ b/include/lfilesystem/lfilesystem_Permissions.h @@ -52,7 +52,7 @@ class LFILE_EXPORT Permissions final Permissions() = default; /** Creates a Permissions object holding the specified permissions value. */ - Permissions (FSPerms p) noexcept; // cppcheck-suppress noExplicitConstructor + Permissions (FSPerms p) noexcept; // cppcheck-suppress noExplicitConstructor ///@} @@ -73,10 +73,10 @@ class LFILE_EXPORT Permissions final ///@} - Permissions (const Permissions&) = default; + Permissions (const Permissions&) = default; Permissions& operator= (const Permissions&) = default; - Permissions (Permissions&&) = default; + Permissions (Permissions&&) = default; Permissions& operator= (Permissions&&) = default; /** Assigns a new permissions bitmask to this object. */ @@ -256,6 +256,6 @@ class LFILE_EXPORT Permissions final @ingroup limes_files @relates Permissions */ -std::ostream& operator<< (std::ostream& os, const Permissions& value); +LFILE_EXPORT std::ostream& operator<< (std::ostream& os, const Permissions& value); } // namespace limes::files diff --git a/include/lfilesystem/lfilesystem_SimpleWatcher.h b/include/lfilesystem/lfilesystem_SimpleWatcher.h index 8f6724c..dd094ce 100644 --- a/include/lfilesystem/lfilesystem_SimpleWatcher.h +++ b/include/lfilesystem/lfilesystem_SimpleWatcher.h @@ -70,4 +70,4 @@ class LFILE_EXPORT SimpleFileWatcher final : public FileWatcher const Callback callback; }; -} // namespace files +} // namespace limes::files diff --git a/include/lfilesystem/lfilesystem_SpecialDirectories.h b/include/lfilesystem/lfilesystem_SpecialDirectories.h index 2e5f95b..8858f79 100644 --- a/include/lfilesystem/lfilesystem_SpecialDirectories.h +++ b/include/lfilesystem/lfilesystem_SpecialDirectories.h @@ -23,7 +23,7 @@ @ingroup limes_files - @todo more special dirs + @todo more dirs: cache, pictures, music, video @todo Android implementations. None of these functions are implemented for Android, it will probably require some native JNI code. diff --git a/include/lfilesystem/lfilesystem_SymLink.h b/include/lfilesystem/lfilesystem_SymLink.h index a866bfc..e47eeb9 100644 --- a/include/lfilesystem/lfilesystem_SymLink.h +++ b/include/lfilesystem/lfilesystem_SymLink.h @@ -42,10 +42,10 @@ class LFILE_EXPORT SymLink final : public FilesystemEntry public: using FilesystemEntry::FilesystemEntry; - SymLink (const SymLink&) = default; + SymLink (const SymLink&) = default; SymLink& operator= (const SymLink&) = default; - SymLink (SymLink&&) = default; + SymLink (SymLink&&) = default; SymLink& operator= (SymLink&&) = default; /** Creates a symbolic link object (the link itself will also be created on the filesystem). @@ -130,8 +130,8 @@ class LFILE_EXPORT SymLink final : public FilesystemEntry ///@} private: - [[nodiscard]] FilesystemEntry follow_recurse (std::size_t counter, std::size_t limit) const; - [[nodiscard]] bool references_recurse (const FilesystemEntry& entry, std::size_t counter, std::size_t limit) const; + [[nodiscard]] FilesystemEntry follow_recurse (std::size_t counter, std::size_t limit) const noexcept; + [[nodiscard]] bool references_recurse (const FilesystemEntry& entry, std::size_t counter, std::size_t limit) const noexcept; }; } // namespace limes::files diff --git a/include/lfilesystem/lfilesystem_Volume.h b/include/lfilesystem/lfilesystem_Volume.h index 8c9f02a..b4618fe 100644 --- a/include/lfilesystem/lfilesystem_Volume.h +++ b/include/lfilesystem/lfilesystem_Volume.h @@ -54,6 +54,7 @@ class FilesystemEntry; @todo ConstructionError custom exception type? This could allow more specific error checking. The error could contain the original passed path. @todo supportsHardLinks()? + @todo get root path as Directory */ class LFILE_EXPORT Volume final { @@ -174,7 +175,7 @@ class LFILE_EXPORT Volume final @ingroup limes_files @relates Volume */ -std::ostream& operator<< (std::ostream& os, const Volume& value); +LFILE_EXPORT std::ostream& operator<< (std::ostream& os, const Volume& value); /** This namespace contains free functions for easily querying properties of the volume that the current working directory is mounted on. The advantage of these functions is that if @@ -231,4 +232,4 @@ namespace volume } // namespace volume -} // namespace files +} // namespace limes::files diff --git a/linfra b/linfra new file mode 160000 index 0000000..8869c14 --- /dev/null +++ b/linfra @@ -0,0 +1 @@ +Subproject commit 8869c14a5100218cc4753e2bb037a1c1b8c4826a diff --git a/package.json b/package.json new file mode 100644 index 0000000..b4a8281 --- /dev/null +++ b/package.json @@ -0,0 +1,284 @@ +{ + "author": { + "email": "ben.the.vining@gmail.com", + "name": "Ben Vining" + }, + "dependencies": { + "@semantic-release/changelog": "6.0.2", + "@semantic-release/exec": "6.0.3", + "@semantic-release/git": "10.0.1", + "conventional-changelog-conventionalcommits": "5.0.0", + "semantic-release": "20.1.0" + }, + "description": "C++ filesystem library", + "homepage": "https://github.com/benthevining/lfilesystem", + "keywords": [ + "C++", + "libraries", + "utility", + "filesystem" + ], + "license": "GPL3", + "name": "lfilesystem", + "release": { + "branches": [ + "main" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "section": "Bug Fixes", + "type": "fix" + }, + { + "section": "Features", + "type": "feat" + }, + { + "hidden": true, + "type": "chore" + }, + { + "hidden": true, + "type": "docs" + }, + { + "hidden": true, + "type": "style" + }, + { + "hidden": true, + "type": "refactor" + }, + { + "hidden": true, + "type": "test" + }, + { + "hidden": true, + "type": "ci" + } + ] + } + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "section": "Bug Fixes", + "type": "fix" + }, + { + "section": "Features", + "type": "feat" + }, + { + "hidden": true, + "type": "chore" + }, + { + "hidden": true, + "type": "docs" + }, + { + "hidden": true, + "type": "style" + }, + { + "hidden": true, + "type": "refactor" + }, + { + "hidden": true, + "type": "test" + }, + { + "hidden": true, + "type": "ci" + } + ] + } + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md", + "changelogTitle": "# Changelog" + } + ], + [ + "@semantic-release/exec", + { + "prepareCmd": "bumpversion --allow-dirty --new-version \"${nextRelease.version}\" patch" + } + ], + [ + "@semantic-release/git", + { + "assets": [ + "CMakeLists.txt", + "package.json", + "CITATION.cff" + ] + } + ], + [ + "@semantic-release/github", + { + "assets": [ + { + "label": "Changelog", + "path": "CHANGELOG.md" + }, + { + "label": "Source code", + "path": "source-code.tar" + }, + { + "label": "Linux Clang (Shared)", + "name": "Linux-Clang-Shared.zip", + "path": "deploy/ubuntu-latest-clang-ON.zip" + }, + { + "label": "Linux Clang (Static)", + "name": "Linux-Clang-Static.zip", + "path": "deploy/ubuntu-latest-clang-OFF.zip" + }, + { + "label": "Linux Emscripten (Shared)", + "name": "Linux-Emscripten-Debug.zip", + "path": "deploy/ubuntu-latest-emscripten-ON.zip" + }, + { + "label": "Linux Emscripten (Static)", + "name": "Linux-Emscripten-Static.zip", + "path": "deploy/ubuntu-latest-emscripten-OFF.zip" + }, + { + "label": "Linux GCC (Shared)", + "name": "Linux-GCC-Shared.zip", + "path": "deploy/ubuntu-latest-gcc-ON.zip" + }, + { + "label": "Linux GCC (Static)", + "name": "Linux-GCC-Static.zip", + "path": "deploy/ubuntu-latest-gcc-OFF.zip" + }, + { + "label": "Windows Clang (Shared)", + "name": "Windows-Clang-Shared.zip", + "path": "deploy/windows-latest-clang-ON.zip" + }, + { + "label": "Windows Clang (Static)", + "name": "Windows-Clang-Static.zip", + "path": "deploy/windows-latest-clang-OFF.zip" + }, + { + "label": "Windows Emscripten (Shared)", + "name": "Windows-Emscripten-Shared.zip", + "path": "deploy/windows-latest-emscripten-ON.zip" + }, + { + "label": "Windows Emscripten (Static)", + "name": "Windows-Emscripten-Static.zip", + "path": "deploy/windows-latest-emscripten-OFF.zip" + }, + { + "label": "MacOS Clang (Shared)", + "name": "MacOS-Clang-Shared.zip", + "path": "deploy/macos-latest-clang-ON.zip" + }, + { + "label": "MacOS Clang (Static)", + "name": "MacOS-Clang-Static.zip", + "path": "deploy/macos-latest-clang-OFF.zip" + }, + { + "label": "MacOS Emscripten (Shared)", + "name": "MacOS-Emscripten-Shared.zip", + "path": "deploy/macos-latest-emscripten-ON.zip" + }, + { + "label": "MacOS Emscripten (Static)", + "name": "MacOS-Emscripten-Static.zip", + "path": "deploy/macos-latest-emscripten-OFF.zip" + }, + { + "label": "MacOS GCC (Shared)", + "name": "MacOS-GCC-Shared.zip", + "path": "deploy/macos-latest-gcc-ON.zip" + }, + { + "label": "MacOS GCC (Static)", + "name": "MacOS-GCC-Static.zip", + "path": "deploy/macos-latest-gcc-OFF.zip" + }, + { + "label": "iOS (Shared)", + "name": "iOS-Shared.zip", + "path": "deploy/macos-latest-iOS-ON.zip" + }, + { + "label": "iOS (Static)", + "name": "iOS-Static.zip", + "path": "deploy/macos-latest-iOS-OFF.zip" + }, + { + "label": "tvOS (Shared)", + "name": "tvOS-Shared.zip", + "path": "deploy/macos-latest-tvOS-ON.zip" + }, + { + "label": "tvOS (Static)", + "name": "tvOS-Static.zip", + "path": "deploy/macos-latest-tvOS-OFF.zip" + }, + { + "label": "watchOS (Shared)", + "name": "watchOS-Shared.zip", + "path": "deploy/macos-latest-watchOS-ON.zip" + }, + { + "label": "watchOS (Static)", + "name": "watchOS-Static.zip", + "path": "deploy/macos-latest-watchOS-OFF.zip" + }, + { + "label": "Windows MSVC (Shared)", + "name": "Windows-MSVC-Shared.zip", + "path": "deploy/windows-latest-vs-ON.zip" + }, + { + "label": "Windows MSVC (Static)", + "name": "Windows-MSVC-Static.zip", + "path": "deploy/windows-latest-vs-OFF.zip" + }, + { + "label": "MacOS XCode (Shared)", + "name": "MacOS-XCode-Shared.zip", + "path": "deploy/macos-latest-xcode-ON.zip" + }, + { + "label": "MacOS XCode (Static)", + "name": "MacOS-XCode-Static.zip", + "path": "deploy/macos-latest-xcode-OFF.zip" + } + ] + } + ] + ] + }, + "repository": "github:benthevining/lfilesystem", + "version": "0.0.1" +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index efda5ee..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,55 +0,0 @@ -# ====================================================================================== -# __ ____ __ __ ____ ___ -# ( ) (_ _)( \/ )( ___)/ __) -# )(__ _)(_ ) ( )__) \__ \ -# (____)(____)(_/\/\_)(____)(___/ -# -# This file is part of the Limes open source library and is licensed under the terms of the GNU Public License. -# -# Commercial licenses are available; contact the maintainers at ben.the.vining@gmail.com to inquire for details. -# -# ====================================================================================== - -target_sources ( - lfilesystem - PRIVATE lfilesystem_CFile.cpp - lfilesystem_Directory.cpp - lfilesystem_DynamicLibrary.cpp - lfilesystem_File.cpp - lfilesystem_FilesystemEntry.cpp - lfilesystem_Paths.cpp - lfilesystem_Permissions.cpp - lfilesystem_SimpleWatcher.cpp - lfilesystem_SpecialDirs_Common.cpp - lfilesystem_SymLink.cpp - lfilesystem_Volume_Common.cpp) - -if (IOS OR ANDROID OR EMSCRIPTEN) - target_sources (lfilesystem PRIVATE native/lfilesystem_FileWatcher_Unsupported.cpp) -elseif (APPLE) - target_sources (lfilesystem PRIVATE native/lfilesystem_FileWatcher_Mac.mm) -elseif (WIN32) - target_sources (lfilesystem PRIVATE native/lfilesystem_FileWatcher_Windows.cpp) -else () - target_sources (lfilesystem PRIVATE native/lfilesystem_FileWatcher_Linux.cpp) -endif () - -if (APPLE) - target_sources ( - lfilesystem PRIVATE native/lfilesystem_Entries_Mac.mm native/lfilesystem_SpecialDirs_Mac.mm - native/lfilesystem_Volume_Mac.mm) -elseif (WIN32) - target_sources ( - lfilesystem - PRIVATE native/lfilesystem_Entries_Windows.cpp native/lfilesystem_SpecialDirs_Windows.cpp - native/lfilesystem_Volume_Windows.cpp) -else () - target_sources (lfilesystem PRIVATE native/lfilesystem_Entries_Linux.cpp - native/lfilesystem_Volume_Linux.cpp) - - if (ANDROID) - target_sources (lfilesystem PRIVATE native/lfilesystem_SpecialDirs_Android.cpp) - else () - target_sources (lfilesystem PRIVATE native/lfilesystem_SpecialDirs_Linux.cpp) - endif () -endif () diff --git a/src/lfilesystem_CFile.cpp b/src/lfilesystem_CFile.cpp index c2f832f..9aa7f2b 100644 --- a/src/lfilesystem_CFile.cpp +++ b/src/lfilesystem_CFile.cpp @@ -108,8 +108,12 @@ CFile::operator std::FILE*() const noexcept return pathCopy.make_preferred().string(); } -bool CFile::open (const Path& filepath, Mode mode) noexcept +bool CFile::open ([[maybe_unused]] const Path& filepath, + [[maybe_unused]] Mode mode) noexcept { +#ifdef __EMSCRIPTEN__ + return false; +#else close(); try @@ -124,6 +128,7 @@ bool CFile::open (const Path& filepath, Mode mode) noexcept return false; } +#endif } void CFile::close() noexcept diff --git a/src/lfilesystem_Directory.cpp b/src/lfilesystem_Directory.cpp index f8aa901..9bf1f38 100644 --- a/src/lfilesystem_Directory.cpp +++ b/src/lfilesystem_Directory.cpp @@ -18,10 +18,11 @@ #include // for vector #include // for string #include -#include "lfilesystem/lfilesystem_FilesystemEntry.h" // for FilesystemEntry, Path -#include "lfilesystem/lfilesystem_File.h" // for File -#include "lfilesystem/lfilesystem_SymLink.h" // for SymLink -#include "lfilesystem/lfilesystem_Misc.h" // for PATHseparator +#include +#include "lfilesystem/lfilesystem_FilesystemEntry.h" // for FilesystemEntry, Path +#include "lfilesystem/lfilesystem_File.h" // for File +#include "lfilesystem/lfilesystem_SymLink.h" // for SymLink +#include "lfilesystem/lfilesystem_Misc.h" // for PATHseparator #include "lfilesystem/lfilesystem_Directory.h" #include "lfilesystem/lfilesystem_SpecialDirectories.h" @@ -68,25 +69,24 @@ bool Directory::contains (const std::string_view& childName) const std::end (children), [&childName] (const FilesystemEntry& e) { return e.getName() == childName; }) - != std::end (children); + != std::end (children); } bool Directory::createIfDoesntExist() const noexcept { +#ifdef __EMSCRIPTEN__ + return false; +#else if (! isValid()) return false; if (exists()) return false; - try - { - return std::filesystem::create_directories (getAbsolutePath()); - } - catch(...) - { - return false; - } + std::error_code ec; + + return std::filesystem::create_directories (getAbsolutePath(), ec); +#endif } Path Directory::getRelativePath (const Path& inputPath) const @@ -261,7 +261,7 @@ bool Directory::containsSubdirectories() const for (const auto& dir_entry : IteratorType { getAbsolutePath() }) { // NB. without this check, the iterator will return symlinks to directories - if (dir_entry.is_directory() && ! dir_entry.is_symlink()) // cppcheck-suppress useStlAlgorithm + if (dir_entry.is_directory() && ! dir_entry.is_symlink()) // cppcheck-suppress useStlAlgorithm return true; } @@ -437,4 +437,4 @@ Directory::Iterator::pointer Directory::Iterator::operator->() const return &entries->at (idx); } -} // namespace files +} // namespace limes::files diff --git a/src/lfilesystem_DynamicLibrary.cpp b/src/lfilesystem_DynamicLibrary.cpp index c966e4e..e30488f 100644 --- a/src/lfilesystem_DynamicLibrary.cpp +++ b/src/lfilesystem_DynamicLibrary.cpp @@ -51,13 +51,7 @@ DynamicLibrary::DynamicLibrary (const std::string_view& nameOrPath) noexcept DynamicLibrary::~DynamicLibrary() { - try - { - close(); - } - catch (...) - { - } + close(); } DynamicLibrary::DynamicLibrary (DynamicLibrary&& other) noexcept @@ -116,7 +110,7 @@ bool DynamicLibrary::reload() return result; } -[[nodiscard]] static inline std::string formatLibraryName (const std::string_view& input) +[[nodiscard]] static inline std::string formatLibraryName (const std::string_view& input) noexcept { auto result = std::string { input }; @@ -127,7 +121,7 @@ bool DynamicLibrary::reload() result += ".dll"; #else if (! result.starts_with ("lib")) - result = std::string { "lib" } + result; + result = std::string { "lib" } + result; #endif return result; @@ -137,33 +131,25 @@ bool DynamicLibrary::open (const std::string_view& nameOrPath) noexcept { const auto result = [this, nameOrPath] { - try - { - close(); + close(); - if (nameOrPath.empty()) - return false; + if (nameOrPath.empty()) + return false; #if defined(_WIN32) || defined(WIN32) - const auto newHandle = ::LoadLibraryA (formatLibraryName (nameOrPath).c_str()); + const auto newHandle = ::LoadLibraryA (formatLibraryName (nameOrPath).c_str()); // #elif defined(__EMSCRIPTEN__) // TODO: use emscripten_dlopen #else - const auto newHandle = ::dlopen (formatLibraryName (nameOrPath).c_str(), RTLD_LOCAL | RTLD_NOW); + const auto newHandle = ::dlopen (formatLibraryName (nameOrPath).c_str(), RTLD_LOCAL | RTLD_NOW); #endif - if (newHandle == nullptr) - return false; + if (newHandle == nullptr) + return false; - handle.store (newHandle); + handle.store (newHandle); - return true; - } - catch (...) - { - close(); - return false; - } + return true; }(); if (! suppressNotifs) @@ -173,7 +159,7 @@ bool DynamicLibrary::open (const std::string_view& nameOrPath) noexcept return result; } -void DynamicLibrary::close() +void DynamicLibrary::close() noexcept { const auto h = handle.load(); @@ -195,23 +181,16 @@ void DynamicLibrary::close() void* DynamicLibrary::findFunction (const std::string_view& functionName) noexcept { - try - { - const auto h = handle.load(); + const auto h = handle.load(); - if (h == nullptr || functionName.empty()) - return nullptr; + if (h == nullptr || functionName.empty()) + return nullptr; #if defined(_WIN32) || defined(WIN32) - return reinterpret_cast (::GetProcAddress (h, functionName.data())); + return reinterpret_cast (::GetProcAddress (h, functionName.data())); #else - return ::dlsym (h, functionName.data()); + return ::dlsym (h, functionName.data()); #endif - } - catch (...) - { - return nullptr; - } } // This takes some ugly code on Apple, which is in this file down below... @@ -219,10 +198,10 @@ void* DynamicLibrary::findFunction (const std::string_view& functionName) noexce [[nodiscard]] static const char* pathname_for_handle (void* handle) noexcept; #endif -// TODO: Emscripten implementation + File DynamicLibrary::getFile() const { -#ifdef __EMSCRIPTEN__ +#if defined(__EMSCRIPTEN__) || defined(__ANDROID__) return File {}; #else @@ -292,7 +271,7 @@ using segment_command_t = segment_command; using nlist_t = struct nlist; # endif -[[nodiscard]] static inline const char* first_external_symbol_for_image (const mach_header_t* header) +[[nodiscard]] static inline const char* first_external_symbol_for_image (const mach_header_t* header) noexcept { Dl_info info; @@ -315,16 +294,16 @@ using nlist_t = struct nlist; [[fallthrough]]; case LC_SEGMENT_64 : { - auto* seg_cmd = reinterpret_cast(cmd); + auto* seg_cmd = reinterpret_cast (cmd); - if (! std::strcmp (seg_cmd->segname, SEG_TEXT)) // NOLINT - seg_text = seg_cmd; // NOLINT - else if (! std::strcmp (seg_cmd->segname, SEG_LINKEDIT)) // NOLINT - seg_linkedit = seg_cmd; // NOLINT + if (! std::strcmp (seg_cmd->segname, SEG_TEXT)) // NOLINT + seg_text = seg_cmd; // NOLINT + else if (! std::strcmp (seg_cmd->segname, SEG_LINKEDIT)) // NOLINT + seg_linkedit = seg_cmd; // NOLINT break; } case LC_SYMTAB : - symtab = reinterpret_cast(cmd); + symtab = reinterpret_cast (cmd); break; } } @@ -349,38 +328,31 @@ using nlist_t = struct nlist; [[nodiscard]] static const char* pathname_for_handle (void* handle) noexcept { - try + for (auto i = ::_dyld_image_count(); i > 0; --i) { - for (auto i = ::_dyld_image_count(); i > 0; --i) + if (const auto* first_symbol = first_external_symbol_for_image (reinterpret_cast (::_dyld_get_image_header (i)))) { - if (const auto* first_symbol = first_external_symbol_for_image (reinterpret_cast (::_dyld_get_image_header (i)))) - { - if (std::strlen (first_symbol) <= 1) - continue; + if (std::strlen (first_symbol) <= 1) + continue; - // in order to trigger findExportedSymbol instead of findExportedSymbolInImageOrDependentImages. - // See `dlsym` implementation at http://opensource.apple.com/source/dyld/dyld-239.3/src/dyldAPIs.cpp - // note that this is not a member function of DynamicLibrary, so this doesn't change the actual - // held by the calling object - handle = reinterpret_cast ((intptr_t) handle | 1); + // in order to trigger findExportedSymbol instead of findExportedSymbolInImageOrDependentImages. + // See `dlsym` implementation at http://opensource.apple.com/source/dyld/dyld-239.3/src/dyldAPIs.cpp + // note that this is not a member function of DynamicLibrary, so this doesn't change the actual + // held by the calling object + handle = reinterpret_cast ((intptr_t) handle | 1); - first_symbol++; // in order to remove the leading underscore + first_symbol++; // in order to remove the leading underscore - auto* address = ::dlsym (handle, first_symbol); + auto* address = ::dlsym (handle, first_symbol); - Dl_info info; + Dl_info info; - if (::dladdr (address, &info) != 0) - return info.dli_fname; - } + if (::dladdr (address, &info) != 0) + return info.dli_fname; } - - return nullptr; - } - catch (...) - { - return nullptr; } + + return nullptr; } #endif /* __APPLE__ */ diff --git a/src/lfilesystem_File.cpp b/src/lfilesystem_File.cpp index 469f4be..62b6989 100644 --- a/src/lfilesystem_File.cpp +++ b/src/lfilesystem_File.cpp @@ -22,10 +22,11 @@ #include #include #include +#include #include "lfilesystem/lfilesystem_File.h" #include "lfilesystem/lfilesystem_SpecialDirectories.h" -#include "lfilesystem/lfilesystem_Directory.h" // for Directory -#include "lfilesystem/lfilesystem_FilesystemEntry.h" // for Path +#include "lfilesystem/lfilesystem_Directory.h" // for Directory +#include "lfilesystem/lfilesystem_FilesystemEntry.h" // for Path #ifdef __APPLE__ # include @@ -121,8 +122,13 @@ bool File::replaceFileExtension (const std::string_view& newFileExtension, return false; } -bool File::write_data (const char* const data, std::size_t numBytes, bool overwrite) const noexcept +bool File::write_data ([[maybe_unused]] const char* const data, + [[maybe_unused]] std::size_t numBytes, + [[maybe_unused]] bool overwrite) const noexcept { +#ifdef __EMSCRIPTEN__ + return false; +#else if (numBytes == 0) return deleteIfExists(); @@ -136,10 +142,11 @@ bool File::write_data (const char* const data, std::size_t numBytes, bool overwr return true; } - catch(...) + catch (...) { return false; } +#endif } bool File::overwrite (const char* const data, std::size_t numBytes) const noexcept @@ -154,7 +161,11 @@ bool File::overwrite (const std::string_view& text) const noexcept std::unique_ptr File::getInputStream() const { +#ifdef __EMSCRIPTEN__ + return nullptr; +#else return std::make_unique (getAbsolutePath().c_str()); +#endif } bool File::append (const char* const data, std::size_t numBytes) const noexcept @@ -167,24 +178,36 @@ bool File::append (const std::string_view& text) const noexcept return write_data (text.data(), text.size(), false); } -bool File::prepend (const char* const data, std::size_t numBytes) const noexcept +bool File::prepend ([[maybe_unused]] const char* const data, + [[maybe_unused]] std::size_t numBytes) const noexcept { +#ifdef __EMSCRIPTEN__ + return false; +#else const std::string_view str { data, numBytes }; return prepend (str); +#endif } -bool File::prepend (const std::string_view& text) const noexcept +bool File::prepend ([[maybe_unused]] const std::string_view& text) const noexcept { +#ifdef __EMSCRIPTEN__ + return false; +#else auto data = loadAsString(); data = std::string { text } + data; return overwrite (data); +#endif } std::optional File::duplicate() const noexcept { +#ifdef __EMSCRIPTEN__ + return std::nullopt; +#else if (! exists()) return std::nullopt; @@ -230,12 +253,18 @@ std::optional File::duplicate() const noexcept } return newFile; +#endif } -bool File::resize (std::uintmax_t newSizeInBytes, bool allowTruncation, bool allowIncreasing) const noexcept +bool File::resize ([[maybe_unused]] std::uintmax_t newSizeInBytes, + [[maybe_unused]] bool allowTruncation, + [[maybe_unused]] bool allowIncreasing) const noexcept { +#ifdef __EMSCRIPTEN__ + return false; +#else if (! (allowTruncation || allowIncreasing)) - return false; // should this return true? + return false; // should this return true? if (! exists()) return false; @@ -251,36 +280,32 @@ bool File::resize (std::uintmax_t newSizeInBytes, bool allowTruncation, bool all if (initialSize < newSizeInBytes && ! allowIncreasing) return false; - try - { - std::filesystem::resize_file (getAbsolutePath(), newSizeInBytes); - return true; - } - catch (...) - { - return false; - } + std::error_code ec; + + std::filesystem::resize_file (getAbsolutePath(), newSizeInBytes, ec); + + return true; +#endif } -std::optional File::createHardLink (const Path& path) const +std::optional File::createHardLink ([[maybe_unused]] const Path& path) const noexcept { +#ifdef __EMSCRIPTEN__ + return std::nullopt; +#else if (! exists()) return std::nullopt; - try - { - File link { path }; + File link { path }; - link.makeAbsoluteRelativeToCWD(); + link.makeAbsoluteRelativeToCWD(); - std::filesystem::create_hard_link (getAbsolutePath(), link.getAbsolutePath()); + std::error_code ec; - return link; - } - catch (...) - { - return std::nullopt; - } + std::filesystem::create_hard_link (getAbsolutePath(), link.getAbsolutePath(), ec); + + return link; +#endif } std::uintmax_t File::getHardLinkCount() const noexcept @@ -290,18 +315,16 @@ std::uintmax_t File::getHardLinkCount() const noexcept if (! exists()) return error; - try - { - return std::filesystem::hard_link_count (getAbsolutePath()); - } - catch (...) - { - return error; - } + std::error_code ec; + + return std::filesystem::hard_link_count (getAbsolutePath(), ec); } std::string File::loadAsString() const noexcept { +#ifdef __EMSCRIPTEN__ + return {}; +#else try { std::ifstream stream { getAbsolutePath().c_str() }; @@ -314,11 +337,12 @@ std::string File::loadAsString() const noexcept { return {}; } +#endif } -static inline std::vector splitString (std::string_view stringToSplit, - std::string_view delimiter, - bool includeDelimiterInResults) +[[maybe_unused]] static inline std::vector splitString (std::string_view stringToSplit, + std::string_view delimiter, + bool includeDelimiterInResults) { const auto delimiterStartChar = delimiter.front(); @@ -355,28 +379,39 @@ static inline std::vector splitString (std::string_view stringToSpl std::vector File::loadAsLines() const { +#ifdef __EMSCRIPTEN__ + return {}; +#else auto tokens = splitString (loadAsString(), "\n", false); // if the newline char was \r\n, then strings will now end with \r std::transform (tokens.begin(), tokens.end(), tokens.begin(), [] (auto str) { - if (str.ends_with ('\r')) - return str.substr (0, str.length() - 1); + if (str.ends_with ('\r')) + return str.substr (0, str.length() - 1); - return str; - }); + return str; + }); return tokens; +#endif } std::unique_ptr File::getOutputStream() const { +#ifdef __EMSCRIPTEN__ + return nullptr; +#else return std::make_unique (getAbsolutePath().c_str()); +#endif } CFile File::getCfile (CFile::Mode mode) const noexcept { +#ifdef __EMSCRIPTEN__ + return {}; +#else if (! exists()) return {}; @@ -388,6 +423,7 @@ CFile File::getCfile (CFile::Mode mode) const noexcept { return {}; } +#endif } /*-------------------------------------------------------------------------------------------------------------------------*/ @@ -557,15 +593,7 @@ TempFile::TempFile (const Path& filepath, bool destroyOnDelete) TempFile::~TempFile() { if (shouldDelete) - { - try - { - deleteIfExists(); - } - catch (...) - { - } - } + deleteIfExists(); } TempFile::TempFile (TempFile&& other) noexcept diff --git a/src/lfilesystem_FilesystemEntry.cpp b/src/lfilesystem_FilesystemEntry.cpp index 3b0cce0..36f31af 100644 --- a/src/lfilesystem_FilesystemEntry.cpp +++ b/src/lfilesystem_FilesystemEntry.cpp @@ -12,14 +12,15 @@ * ====================================================================================== */ -#include // for tm -#include // for exception -#include // for path, copy, operator/, absolute, cera... -#include // for string, ofstream -#include // for operator<, operator> -#include "lfilesystem/lfilesystem_Directory.h" // for Directory -#include "lfilesystem/lfilesystem_File.h" // for File -#include "lfilesystem/lfilesystem_SymLink.h" // for SymLink +#include // for tm +#include // for exception +#include // for path, copy, operator/, absolute, cera... +#include // for string, ofstream +#include // for operator<, operator> +#include +#include "lfilesystem/lfilesystem_Directory.h" // for Directory +#include "lfilesystem/lfilesystem_File.h" // for File +#include "lfilesystem/lfilesystem_SymLink.h" // for SymLink #include "lfilesystem/lfilesystem_SpecialDirectories.h" #include "lfilesystem/lfilesystem_Volume.h" #include "lfilesystem/lfilesystem_FilesystemEntry.h" @@ -40,7 +41,7 @@ namespace limes::files { -FilesystemEntry::FilesystemEntry (const Path& pathToUse) +FilesystemEntry::FilesystemEntry (const Path& pathToUse) noexcept : path (normalizePath (pathToUse)) { } @@ -84,25 +85,27 @@ FilesystemEntry& FilesystemEntry::changeName (const std::string_view& newName) return *this; } -static inline bool areSameIgnoringCase (const std::string_view& lhs, const std::string_view& rhs) +static inline bool areSameIgnoringCase (const std::string_view& lhs, const std::string_view& rhs) noexcept { return std::equal (lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [] (char a, char b) { - return std::tolower (static_cast (a)) == std::tolower (static_cast (b)); - }); + return std::tolower (static_cast (a)) == std::tolower (static_cast (b)); + }); } bool FilesystemEntry::operator== (const FilesystemEntry& other) const noexcept { + std::error_code ec; + // std::filesystem::equivalent can only be used if both paths exist if (exists() && other.exists()) { if (isRelativePath() && other.isRelativePath()) - return std::filesystem::equivalent (path, other.path); + return std::filesystem::equivalent (path, other.path, ec); - return std::filesystem::equivalent (getAbsolutePath(), other.getAbsolutePath()); + return std::filesystem::equivalent (getAbsolutePath(), other.getAbsolutePath(), ec); } const auto caseSensitive = [p = getAbsolutePath()] @@ -313,14 +316,7 @@ std::optional FilesystemEntry::getFileObject() const noexcept if (! isFile()) return std::nullopt; - try - { - return File { path }; - } - catch (...) - { - return std::nullopt; - } + return File { path }; } std::optional FilesystemEntry::getDirectoryObject() const noexcept @@ -331,14 +327,7 @@ std::optional FilesystemEntry::getDirectoryObject() const noexcept if (! isDirectory()) return std::nullopt; - try - { - return Directory { path }; - } - catch (...) - { - return std::nullopt; - } + return Directory { path }; } std::optional FilesystemEntry::getSymLinkObject() const noexcept @@ -349,14 +338,7 @@ std::optional FilesystemEntry::getSymLinkObject() const noexcept if (! isSymLink()) return std::nullopt; - try - { - return SymLink { path }; - } - catch (...) - { - return std::nullopt; - } + return SymLink { path }; } bool FilesystemEntry::isAbsolutePath() const noexcept @@ -421,19 +403,21 @@ bool FilesystemEntry::createIfDoesntExist() const noexcept if (isSymLink()) return false; + std::error_code ec; + + if (isDirectory()) + return std::filesystem::create_directories (getAbsolutePath(), ec); + try { - if (isDirectory()) - return std::filesystem::create_directories (getAbsolutePath()); - [[maybe_unused]] std::ofstream output { getAbsolutePath() }; - - return exists(); } - catch(...) + catch (...) { return false; } + + return exists(); } bool FilesystemEntry::deleteIfExists() const noexcept @@ -441,16 +425,11 @@ bool FilesystemEntry::deleteIfExists() const noexcept if (! exists() || ! isValid()) return false; - try - { - const auto filesRemoved = std::filesystem::remove_all (getAbsolutePath()); + std::error_code ec; - return filesRemoved > 0 && ! exists(); - } - catch (...) - { - return false; - } + const auto filesRemoved = std::filesystem::remove_all (getAbsolutePath(), ec); + + return filesRemoved > 0 && ! exists(); } void FilesystemEntry::touch() const @@ -484,14 +463,9 @@ std::uintmax_t FilesystemEntry::sizeInBytes() const bool FilesystemEntry::setPermissions (FSPerms permissions, PermOptions options) const noexcept { - try - { - std::filesystem::permissions (getAbsolutePath(), permissions, options); - } - catch(...) - { - return false; - } + std::error_code ec; + + std::filesystem::permissions (getAbsolutePath(), permissions, options, ec); return true; } @@ -514,17 +488,13 @@ bool FilesystemEntry::rename (const Path& newPath) noexcept const auto pathBefore = path; - try - { - const auto newPath = newEntry.getAbsolutePath(); - std::filesystem::rename (path, newPath); - path = newPath; - } - catch(...) - { - path = pathBefore; - return false; - } + const auto newResolvedPath = newEntry.getAbsolutePath(); + + std::error_code ec; + + std::filesystem::rename (path, newResolvedPath, ec); + + path = newResolvedPath; return true; } @@ -535,14 +505,9 @@ bool FilesystemEntry::copyTo (const Path& dest, CopyOptions options) const noexc newEntry.makeAbsoluteRelativeTo (getDirectory()); - try - { - std::filesystem::copy (getAbsolutePath(), newEntry.getAbsolutePath(), options); - } - catch(...) - { - return false; - } + std::error_code ec; + + std::filesystem::copy (getAbsolutePath(), newEntry.getAbsolutePath(), options, ec); return true; } @@ -582,14 +547,9 @@ bool FilesystemEntry::copyFrom (const Path& source, CopyOptions options) const n sourceEntry.makeAbsoluteRelativeTo (getDirectory()); - try - { - std::filesystem::copy (sourceEntry.getAbsolutePath(), getAbsolutePath(), options); - } - catch(...) - { - return false; - } + std::error_code ec; + + std::filesystem::copy (sourceEntry.getAbsolutePath(), getAbsolutePath(), options, ec); return true; } @@ -601,10 +561,14 @@ bool FilesystemEntry::copyFrom (const FilesystemEntry& source, CopyOptions optio std::optional FilesystemEntry::getVolume() const noexcept { +#ifdef __EMSCRIPTEN__ + return std::nullopt; +#else if (exists()) return Volume::tryCreate (getAbsolutePath()); return std::nullopt; +#endif } bool FilesystemEntry::filenameBeginsWithDot() const diff --git a/src/lfilesystem_Paths.cpp b/src/lfilesystem_Paths.cpp index 5acf01e..e5573c6 100644 --- a/src/lfilesystem_Paths.cpp +++ b/src/lfilesystem_Paths.cpp @@ -27,13 +27,13 @@ namespace limes::files { -static inline bool stringContains (std::string_view string, std::string_view substringToFind) +static inline bool stringContains (std::string_view string, std::string_view substringToFind) noexcept { return string.find (substringToFind) != std::string_view::npos; } -[[nodiscard]] static inline std::string upToFirstOccurrenceOf (std::string input, - std::string_view stringToFind) +[[nodiscard]] static inline std::string upToFirstOccurrenceOf (std::string input, + std::string_view stringToFind) noexcept { const auto pos = input.find (stringToFind); @@ -43,8 +43,8 @@ static inline bool stringContains (std::string_view string, std::string_view sub return input.substr (0, pos); } -[[nodiscard]] static inline std::string upToLastOccurrenceOf (std::string input, - std::string_view stringToFind) +[[nodiscard]] static inline std::string upToLastOccurrenceOf (std::string input, + std::string_view stringToFind) noexcept { const auto pos = input.rfind (stringToFind); @@ -54,8 +54,8 @@ static inline bool stringContains (std::string_view string, std::string_view sub return input.substr (0, pos); } -[[nodiscard]] static inline std::string fromFirstOccurrenceOf (std::string input, - std::string_view stringToFind) +[[nodiscard]] static inline std::string fromFirstOccurrenceOf (std::string input, + std::string_view stringToFind) noexcept { const auto pos = input.find (stringToFind); @@ -65,9 +65,9 @@ static inline bool stringContains (std::string_view string, std::string_view sub return input.substr (pos + stringToFind.length(), input.length()); } -[[nodiscard]] static inline std::string replaceInString (std::string input, +[[nodiscard]] static inline std::string replaceInString (std::string input, std::string_view stringToReplace, - std::string_view replaceWith) + std::string_view replaceWith) noexcept { std::size_t pos = 0; @@ -81,7 +81,7 @@ static inline bool stringContains (std::string_view string, std::string_view sub return input; } -bool isValidPath (const Path& path) +bool isValidPath (const Path& path) noexcept { if (path.empty()) return false; @@ -99,7 +99,7 @@ bool isValidPath (const Path& path) #if ! (defined(_WIN32) || defined(WIN32)) -[[nodiscard]] static inline Path expandTilde (const std::string& path) +[[nodiscard]] static inline Path expandTilde (const std::string& path) noexcept { const auto homePath = dirs::home().getAbsolutePath(); @@ -130,7 +130,7 @@ bool isValidPath (const Path& path) #endif /* ! Windows */ -static inline void normalizeDoubleDot (std::string& path) +static inline void normalizeDoubleDot (std::string& path) noexcept { if (path == std::string { ".." }) return; @@ -150,14 +150,13 @@ static inline void normalizeDoubleDot (std::string& path) before = upToLastOccurrenceOf (before, "/"); before = upToLastOccurrenceOf (before, "/"); - const auto firstPart = path.substr (0, before.length()); - //const auto secondPart = path.substr (path.length() - after.length(), std::string::npos); + const auto len = before.length(); - path = firstPart + after; + path.replace (len, path.length() - len, after); } } -static inline void removeTrailingDirSeparators (std::string& path) +static inline void removeTrailingDirSeparators (std::string& path) noexcept { while (path.ends_with ('/')) path.pop_back(); @@ -168,7 +167,7 @@ static inline void removeTrailingDirSeparators (std::string& path) #endif } -static inline void normalizeSlashDotSlash (std::string& path) +static inline void normalizeSlashDotSlash (std::string& path) noexcept { path = replaceInString (path, "/./", "/"); @@ -177,7 +176,7 @@ static inline void normalizeSlashDotSlash (std::string& path) #endif } -static inline void normalizeDotSlash (std::string& path) +static inline void normalizeDotSlash (std::string& path) noexcept { if (path == std::string { "./" }) { @@ -200,7 +199,7 @@ static inline void normalizeDotSlash (std::string& path) #endif } -[[nodiscard]] static inline bool isOnlyDirectorySeparator (const std::string& path) +[[nodiscard]] static inline bool isOnlyDirectorySeparator (const std::string& path) noexcept { #if defined(_WIN32) || defined(WIN32) if (path == std::string { '\\' }) @@ -217,7 +216,7 @@ static inline void normalizeDotSlash (std::string& path) // replace all \.\ with \ (Windows only) // resolve /../ // expand a leading ~ (non-Windows only) -Path normalizePath (const Path& path) +Path normalizePath (const Path& path) noexcept { if (! isValidPath (path)) return Path {}; @@ -250,8 +249,7 @@ Path normalizePath (const Path& path) } [[nodiscard]] static inline std::vector splitString (std::string_view stringToSplit, - std::string_view delimiter, - bool includeDelimiterInResults) + std::string_view delimiter) noexcept { const auto delimiterStartChar = delimiter.front(); @@ -270,7 +268,7 @@ Path normalizePath (const Path& path) ++pos; if (pos != stringToSplit.begin()) - tokens.push_back ({ tokenStart, includeDelimiterInResults ? pos : delimiterStart }); + tokens.push_back ({ tokenStart, delimiterStart }); tokenStart = pos; } @@ -286,7 +284,7 @@ Path normalizePath (const Path& path) return tokens; } -Path largestCommonPrefix (const Path& path1, const Path& path2) +Path largestCommonPrefix (const Path& path1, const Path& path2) noexcept { const auto a = normalizePath (path1); const auto b = normalizePath (path2); @@ -301,8 +299,8 @@ Path largestCommonPrefix (const Path& path1, const Path& path2) const auto bStr = b.string(); // TODO: support \ on Windows - const auto aChunks = splitString (aStr, "/", false); - const auto bChunks = splitString (bStr, "/", false); + const auto aChunks = splitString (aStr, "/"); + const auto bChunks = splitString (bStr, "/"); Path result; @@ -322,4 +320,4 @@ Path largestCommonPrefix (const Path& path1, const Path& path2) return normalizePath (result); } -} // namespace files +} // namespace limes::files diff --git a/src/lfilesystem_Permissions.cpp b/src/lfilesystem_Permissions.cpp index 33cb2fb..e3dd1db 100644 --- a/src/lfilesystem_Permissions.cpp +++ b/src/lfilesystem_Permissions.cpp @@ -247,4 +247,4 @@ std::ostream& operator<< (std::ostream& os, const Permissions& value) return os; } -} // namespace files +} // namespace limes::files diff --git a/src/lfilesystem_SimpleWatcher.cpp b/src/lfilesystem_SimpleWatcher.cpp index 225d24a..80de25b 100644 --- a/src/lfilesystem_SimpleWatcher.cpp +++ b/src/lfilesystem_SimpleWatcher.cpp @@ -72,4 +72,4 @@ void SimpleFileWatcher::otherEventType (const FilesystemEntry& f) callback (f); } -} // namespace files +} // namespace limes::files diff --git a/src/lfilesystem_SymLink.cpp b/src/lfilesystem_SymLink.cpp index 218f64f..fedf1e9 100644 --- a/src/lfilesystem_SymLink.cpp +++ b/src/lfilesystem_SymLink.cpp @@ -12,11 +12,12 @@ * ====================================================================================== */ -#include // for create_directory_symlink, create_... +#include // for create_directory_symlink, create_... #include +#include #include "lfilesystem/lfilesystem_Directory.h" #include "lfilesystem/lfilesystem_SymLink.h" -#include "lfilesystem/lfilesystem_FilesystemEntry.h" // for FilesystemEntry, Path +#include "lfilesystem/lfilesystem_FilesystemEntry.h" // for FilesystemEntry, Path namespace limes::files { @@ -47,19 +48,14 @@ SymLink::SymLink (const Path& symLinkPath, const FilesystemEntry& linkTarget) FilesystemEntry SymLink::follow (std::size_t recursionDepth) const noexcept { - try - { - return follow_recurse (0UL, recursionDepth); - } - catch (...) - { - return {}; - } + return follow_recurse (0UL, recursionDepth); } -FilesystemEntry SymLink::follow_recurse (std::size_t counter, std::size_t limit) const +FilesystemEntry SymLink::follow_recurse (std::size_t counter, std::size_t limit) const noexcept { - const FilesystemEntry target { std::filesystem::read_symlink (getAbsolutePath()) }; + std::error_code ec; + + const FilesystemEntry target { std::filesystem::read_symlink (getAbsolutePath(), ec) }; if (counter >= limit) return target; @@ -72,19 +68,14 @@ FilesystemEntry SymLink::follow_recurse (std::size_t counter, std::size_t limit) bool SymLink::references (const FilesystemEntry& entry, std::size_t recursionDepth) const noexcept { - try - { - return references_recurse (entry, 0UL, recursionDepth); - } - catch (...) - { - return false; - } + return references_recurse (entry, 0UL, recursionDepth); } -bool SymLink::references_recurse (const FilesystemEntry& entry, std::size_t counter, std::size_t limit) const +bool SymLink::references_recurse (const FilesystemEntry& entry, std::size_t counter, std::size_t limit) const noexcept { - const FilesystemEntry target { std::filesystem::read_symlink (getAbsolutePath()) }; + std::error_code ec; + + const FilesystemEntry target { std::filesystem::read_symlink (getAbsolutePath(), ec) }; if (target == entry) return true; @@ -112,33 +103,29 @@ bool SymLink::isDangling() const noexcept return ! follow().exists(); } -std::optional SymLink::create (const Path& linkPath, const FilesystemEntry& target) noexcept +std::optional SymLink::create (const Path& linkPath, + const FilesystemEntry& target) noexcept { if (! target.exists()) return std::nullopt; - try - { - SymLink link { linkPath }; + SymLink link { linkPath }; - link.makeAbsoluteRelativeToCWD(); + link.makeAbsoluteRelativeToCWD(); - // the functions below will fail if the link path already exists as a file - link.deleteIfExists(); + // the functions below will fail if the link path already exists as a file + link.deleteIfExists(); - const auto targetPath = target.getAbsolutePath(); + const auto targetPath = target.getAbsolutePath(); - if (target.isDirectory()) - std::filesystem::create_directory_symlink (targetPath, link.getAbsolutePath()); - else - std::filesystem::create_symlink (targetPath, link.getAbsolutePath()); + std::error_code ec; - return link; - } - catch (...) - { - return std::nullopt; - } + if (target.isDirectory()) + std::filesystem::create_directory_symlink (targetPath, link.getAbsolutePath(), ec); + else + std::filesystem::create_symlink (targetPath, link.getAbsolutePath(), ec); + + return link; } std::optional SymLink::create (const Path& linkPath, const Path& target) noexcept diff --git a/src/lfilesystem_Volume_Common.cpp b/src/lfilesystem_Volume_Common.cpp index 860c032..2d07fe7 100644 --- a/src/lfilesystem_Volume_Common.cpp +++ b/src/lfilesystem_Volume_Common.cpp @@ -21,8 +21,12 @@ namespace limes::files { -std::optional Volume::tryCreate (const Path& path) noexcept +std::optional Volume::tryCreate ([[maybe_unused]] const Path& path) noexcept { +#ifdef __EMSCRIPTEN__ + // assume this will never work on Emscripten, to avoid having to catch an exception + return std::nullopt; +#else try { return Volume { path }; @@ -31,6 +35,7 @@ std::optional Volume::tryCreate (const Path& path) noexcept { return std::nullopt; } +#endif } std::uintmax_t Volume::bytesFree() const @@ -140,4 +145,4 @@ bool caseSensitive() } // namespace volume -} // namespace files +} // namespace limes::files diff --git a/src/native/lfilesystem_Entries_Linux.cpp b/src/native/lfilesystem_Entries_Linux.cpp index 65d45b6..174c70f 100644 --- a/src/native/lfilesystem_Entries_Linux.cpp +++ b/src/native/lfilesystem_Entries_Linux.cpp @@ -157,12 +157,12 @@ namespace module_path && buffer[length - 3] == 'a' && buffer[length - 4] == '.') { - const auto fd = open (path, O_RDONLY); + const auto fd = open (path.data(), O_RDONLY); if (fd == -1) continue; - const auto* const begin = static_cast (mmap (0, offset, PROT_READ, MAP_SHARED, fd, 0)); + auto* const begin = static_cast (mmap (0, offset, PROT_READ, MAP_SHARED, fd, 0)); if (begin == MAP_FAILED) { @@ -174,9 +174,9 @@ namespace module_path p >= begin; --p) { - if (*reinterpret_cast (p) == 0x04034b50UL) // local file header signature found + if (*reinterpret_cast (p) == 0x04034b50UL) // local file header signature found { - const auto length_ = *(reinterpret_cast (p + 26)); + const auto length_ = *(reinterpret_cast (p + 26)); if (length + 2 + length_ < static_cast (sizeof (buffer))) { @@ -189,7 +189,7 @@ namespace module_path } } - munmap (begin, offset); + munmap (static_cast(begin), offset); close (fd); } # endif /* __ANDROID__ */ @@ -209,4 +209,4 @@ namespace module_path } // namespace module_path -} // namespace files +} // namespace limes::files diff --git a/src/native/lfilesystem_Entries_Windows.cpp b/src/native/lfilesystem_Entries_Windows.cpp index 4a08d79..fc3f5c0 100644 --- a/src/native/lfilesystem_Entries_Windows.cpp +++ b/src/native/lfilesystem_Entries_Windows.cpp @@ -75,9 +75,9 @@ bool FilesystemEntry::revealToUserInFileBrowser() const if (! dll.isOpen()) return false; - LIMES_LOAD_WIN_DYLIB_FUNC (dll, ILCreateFromPathW, ilCreateFromPathW, ITEMIDLIST*, (LPCWSTR)); // cppcheck-suppress cstyleCast - LIMES_LOAD_WIN_DYLIB_FUNC (dll, ILFree, ilFree, void, (ITEMIDLIST*) ); // cppcheck-suppress cstyleCast - LIMES_LOAD_WIN_DYLIB_FUNC (dll, SHOpenFolderAndSelectItems, shOpenFolderAndSelectItems, HRESULT, (ITEMIDLIST*, UINT, void*, DWORD)); // cppcheck-suppress cstyleCast + LIMES_LOAD_WIN_DYLIB_FUNC (dll, ILCreateFromPathW, ilCreateFromPathW, ITEMIDLIST*, (LPCWSTR)); // cppcheck-suppress cstyleCast + LIMES_LOAD_WIN_DYLIB_FUNC (dll, ILFree, ilFree, void, (ITEMIDLIST*) ); // cppcheck-suppress cstyleCast + LIMES_LOAD_WIN_DYLIB_FUNC (dll, SHOpenFolderAndSelectItems, shOpenFolderAndSelectItems, HRESULT, (ITEMIDLIST*, UINT, void*, DWORD)); // cppcheck-suppress cstyleCast if (ilCreateFromPathW == nullptr || shOpenFolderAndSelectItems == nullptr || ilFree == nullptr) return false; @@ -206,4 +206,4 @@ namespace module_path } // namespace module_path -} // namespace files +} // namespace limes::files diff --git a/src/native/lfilesystem_FileWatcher_Linux.cpp b/src/native/lfilesystem_FileWatcher_Linux.cpp index 5fe461a..dcbcde3 100644 --- a/src/native/lfilesystem_FileWatcher_Linux.cpp +++ b/src/native/lfilesystem_FileWatcher_Linux.cpp @@ -227,7 +227,7 @@ class LFILE_NO_EXPORT FileWatcher::Impl final std::unique_ptr thread; }; - UpdaterThread updaterThread; // should be static, but that caused unresolved external symbol errors in MSVC... + UpdaterThread updaterThread; // should be static, but that caused unresolved external symbol errors in MSVC... }; /*---------------------------------------------------------------------------------------------------------------------*/ @@ -304,4 +304,4 @@ FilesystemEntry FileWatcher::getWatchedPath() const noexcept return watchedPath; } -} // namespace files +} // namespace limes::files diff --git a/src/native/lfilesystem_FileWatcher_Unsupported.cpp b/src/native/lfilesystem_FileWatcher_Unsupported.cpp index 77c9f1b..7baec0b 100644 --- a/src/native/lfilesystem_FileWatcher_Unsupported.cpp +++ b/src/native/lfilesystem_FileWatcher_Unsupported.cpp @@ -59,4 +59,4 @@ FilesystemEntry FileWatcher::getWatchedPath() const noexcept return watchedPath; } -} // namespace files +} // namespace limes::files diff --git a/src/native/lfilesystem_FileWatcher_Windows.cpp b/src/native/lfilesystem_FileWatcher_Windows.cpp index b97197e..9da7ad8 100644 --- a/src/native/lfilesystem_FileWatcher_Windows.cpp +++ b/src/native/lfilesystem_FileWatcher_Windows.cpp @@ -263,4 +263,4 @@ FilesystemEntry FileWatcher::getWatchedPath() const noexcept return watchedPath; } -} // namespace files +} // namespace limes::files diff --git a/src/native/lfilesystem_SpecialDirs_Android.cpp b/src/native/lfilesystem_SpecialDirs_Android.cpp index db6b209..3c4c2e7 100644 --- a/src/native/lfilesystem_SpecialDirs_Android.cpp +++ b/src/native/lfilesystem_SpecialDirs_Android.cpp @@ -37,7 +37,7 @@ static inline Directory getAndroidAppDataDir() // return { juceString ((jstring) jString.get()) }; // } - // return {}; + return {}; } static inline Directory getAndroidDocumentsDir() @@ -48,7 +48,7 @@ static inline Directory getAndroidDocumentsDir() // if (auto* env = getEnv()) // return resolveAndroidDir (LocalRef (env->CallStaticObjectMethod (AndroidEnvironment, AndroidEnvironment.getDataDirectory))); - // return {}; + return {}; } [[nodiscard]] LFILE_EXPORT Directory android_home() @@ -83,7 +83,7 @@ Directory userAppData() Directory downloads() { - // TODO + return {}; } } // namespace limes::files::dirs diff --git a/src/native/lfilesystem_SpecialDirs_Linux.cpp b/src/native/lfilesystem_SpecialDirs_Linux.cpp index 7881249..694a176 100644 --- a/src/native/lfilesystem_SpecialDirs_Linux.cpp +++ b/src/native/lfilesystem_SpecialDirs_Linux.cpp @@ -36,7 +36,7 @@ Directory apps() return Directory { "/usr" }; } -static inline void trim_string (std::string& string) +static inline void trim_string (std::string& string) noexcept { if (string.empty()) return; @@ -52,7 +52,7 @@ static inline void trim_string (std::string& string) string.end()); } -static inline std::string replaceInString (std::string input, std::string_view stringToReplace, std::string_view replaceWith) +static inline std::string replaceInString (std::string input, std::string_view stringToReplace, std::string_view replaceWith) noexcept { std::size_t pos = 0UL; @@ -66,7 +66,7 @@ static inline std::string replaceInString (std::string input, std::string_view s return input; } -static inline std::string fromFirstOccurrenceOf (std::string input, std::string_view stringToFind) +static inline std::string fromFirstOccurrenceOf (std::string input, std::string_view stringToFind) noexcept { const auto pos = input.find (stringToFind); @@ -76,9 +76,9 @@ static inline std::string fromFirstOccurrenceOf (std::string input, std::string_ return input.substr (pos + stringToFind.length(), input.length()); } -static inline std::string unquotedString (std::string string) +static inline std::string unquotedString (std::string string) noexcept { - auto dropFirstChars = [&string](std::size_t numChars) + auto dropFirstChars = [&string] (std::size_t numChars) { string = string.substr (numChars, string.length()); }; @@ -92,7 +92,7 @@ static inline std::string unquotedString (std::string string) else if (string.starts_with ('\'')) dropFirstChars (1UL); - auto dropLastChars = [&string](std::size_t numChars) + auto dropLastChars = [&string] (std::size_t numChars) { for (auto i = 0UL; i < numChars; ++i) { diff --git a/src/native/lfilesystem_SpecialDirs_Windows.cpp b/src/native/lfilesystem_SpecialDirs_Windows.cpp index dca85f8..a387ff4 100644 --- a/src/native/lfilesystem_SpecialDirs_Windows.cpp +++ b/src/native/lfilesystem_SpecialDirs_Windows.cpp @@ -56,11 +56,11 @@ Directory commonDocuments() Directory apps() { // TODO - ?? -//#if LIMES_32BIT -// return getWinFolderPath (FOLDERID_ProgramFiles); -//#else + //#if LIMES_32BIT + // return getWinFolderPath (FOLDERID_ProgramFiles); + //#else return getWinFolderPath (FOLDERID_ProgramFilesX86); -//#endif + //#endif } Directory desktop() @@ -83,4 +83,4 @@ Directory downloads() return getWinFolderPath (FOLDERID_Downloads); } -} // namespace files::dirs +} // namespace limes::files::dirs diff --git a/src/native/lfilesystem_Volume_Linux.cpp b/src/native/lfilesystem_Volume_Linux.cpp index 087a183..14e529b 100644 --- a/src/native/lfilesystem_Volume_Linux.cpp +++ b/src/native/lfilesystem_Volume_Linux.cpp @@ -65,6 +65,10 @@ namespace limes::files static inline Path findMountPath (const Path& inputPath) { +#ifdef __ANDROID__ + // TODO + throwError (inputPath); +#else struct stat s; if (stat (inputPath.c_str(), &s) != 0) @@ -94,6 +98,7 @@ static inline Path findMountPath (const Path& inputPath) } throwError (inputPath); +#endif } Volume::Volume (const Path& path) @@ -286,4 +291,4 @@ std::vector Volume::getAll() noexcept return volumes; } -} // namespace files +} // namespace limes::files diff --git a/src/native/lfilesystem_Volume_Windows.cpp b/src/native/lfilesystem_Volume_Windows.cpp index 3f4c6ef..0abb2b1 100644 --- a/src/native/lfilesystem_Volume_Windows.cpp +++ b/src/native/lfilesystem_Volume_Windows.cpp @@ -189,9 +189,9 @@ std::vector Volume::getAll() noexcept if (FindHandle == INVALID_HANDLE_VALUE) return volumes; - WCHAR DeviceName[MAX_PATH] = L""; - DWORD Error = ERROR_SUCCESS; - BOOL Found = FALSE; + WCHAR DeviceName[MAX_PATH] = L""; + DWORD Error = ERROR_SUCCESS; + BOOL Found = FALSE; for (;;) { @@ -224,4 +224,4 @@ std::vector Volume::getAll() noexcept return volumes; } -} // namespace files +} // namespace limes::files diff --git a/tests/CFile.cpp b/tests/CFile.cpp index 65957f4..b240515 100644 --- a/tests/CFile.cpp +++ b/tests/CFile.cpp @@ -29,6 +29,7 @@ TEST_CASE ("CFile - null", TAGS) REQUIRE (f.getPath().empty()); } +#ifndef __EMSCRIPTEN__ TEST_CASE ("CFile", TAGS) { const auto path = files::dirs::cwd().getChild ("temp.txt").getAbsolutePath(); @@ -59,11 +60,12 @@ TEST_CASE ("CFile", TAGS) const files::Path newPath { files::dirs::cwd().getChild ("another_file.omg").getAbsolutePath() }; // TODO: this only fails on Windows -#ifndef _WIN32 +# ifndef _WIN32 REQUIRE (file.rename (newPath)); REQUIRE (f.getPath() == newPath); REQUIRE (file.deleteIfExists()); -#endif +# endif } +#endif #undef TAGS diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f1a1216..f95fcb7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,59 +10,39 @@ # # ====================================================================================== -include (FetchContent) +set (CMAKE_FOLDER tests) -FetchContent_Declare ( - Catch2 - GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG origin/devel - GIT_SHALLOW ON - FIND_PACKAGE_ARGS 3 GLOBAL) - -FetchContent_MakeAvailable (Catch2) - -if (catch2_SOURCE_DIR) - list (APPEND CMAKE_MODULE_PATH "${catch2_SOURCE_DIR}/extras") -endif () - -include (Catch) +limes_get_catch2 () add_executable (lfilesystem_tests) -set_target_properties (lfilesystem_tests PROPERTIES MACOSX_BUNDLE OFF) - target_sources ( - lfilesystem_tests - PRIVATE CFile.cpp - Directory.cpp - File.cpp - FilesystemEntry.cpp - FileWatcher.cpp - PathFunctions.cpp - Permissions.cpp - SpecialDirs.cpp - SymLink.cpp - Volume.cpp) - -target_link_libraries (lfilesystem_tests PRIVATE Catch2::Catch2WithMain limes::lfilesystem) + lfilesystem_tests + PRIVATE CFile.cpp + Directory.cpp + File.cpp + FilesystemEntry.cpp + FileWatcher.cpp + PathFunctions.cpp + Permissions.cpp + SpecialDirs.cpp + SymLink.cpp + Volume.cpp) + +limes_configure_test_target ( + lfilesystem_tests + BUNDLE_ID Limes.lfilesystem.tests + VERSION_MAJOR "${lfilesystem_VERSION_MAJOR}" + FULL_VERSION "${lfilesystem_VERSION}" + TEST_PREFIX limes.files.unit.) + +target_link_libraries (lfilesystem_tests PRIVATE limes::lfilesystem) target_compile_definitions (lfilesystem_tests - PRIVATE "LIMES_TEST_DATA_DIR=\"${CMAKE_CURRENT_LIST_DIR}/data\"") - -catch_discover_tests ( - lfilesystem_tests - EXTRA_ARGS - --warn - NoAssertions - --order - rand - --verbosity - high - TEST_PREFIX - "Limes.files.unit.") + PRIVATE "LIMES_TEST_DATA_DIR=\"${CMAKE_CURRENT_LIST_DIR}/data\"") add_subdirectory (StructuredTree) add_subdirectory (ExecLocation) # add_subdirectory (DynamicLibrary) -include (FindPackage/CreateTests.cmake) +# include (FindPackage/CreateTests.cmake) diff --git a/tests/Directory.cpp b/tests/Directory.cpp index 0a772c2..5b3ade5 100644 --- a/tests/Directory.cpp +++ b/tests/Directory.cpp @@ -22,6 +22,7 @@ namespace files = limes::files; +#ifndef __EMSCRIPTEN__ TEST_CASE ("Directory - getChildFile()", TAGS) { const auto cwd = files::dirs::cwd(); @@ -53,6 +54,7 @@ TEST_CASE ("Directory - getChildFile()", TAGS) REQUIRE (cwd.getChildFile ("a1/a2/a3/../../a4") == cwd.getChildFile ("a1/a4")); REQUIRE (cwd.getChildFile ("a1/a2/a3/./.././../a4") == cwd.getChildFile ("a1/a4")); } +#endif TEST_CASE ("Directory", TAGS) { diff --git a/tests/DynamicLibrary/CMakeLists.txt b/tests/DynamicLibrary/CMakeLists.txt index 8b7963d..853f7b4 100644 --- a/tests/DynamicLibrary/CMakeLists.txt +++ b/tests/DynamicLibrary/CMakeLists.txt @@ -17,4 +17,4 @@ target_sources (limes_test_shared_lib PRIVATE shared_lib.cpp) target_link_libraries (limes_test_shared_lib PUBLIC Limes::limes_files) target_compile_definitions ( - limes_files_tests PRIVATE "LIMES_TEST_DYLIB_PATH=\"$\"") + limes_files_tests PRIVATE "LIMES_TEST_DYLIB_PATH=\"$\"") diff --git a/tests/ExecLocation/CMakeLists.txt b/tests/ExecLocation/CMakeLists.txt index cfc297c..8d6203d 100644 --- a/tests/ExecLocation/CMakeLists.txt +++ b/tests/ExecLocation/CMakeLists.txt @@ -16,10 +16,10 @@ target_sources (limes_files_exec_location_printer PRIVATE main.cpp) target_link_libraries (limes_files_exec_location_printer PRIVATE limes::lfilesystem) -set_target_properties (limes_files_exec_location_printer PROPERTIES MACOSX_BUNDLE OFF) - -add_executable (limes::limes_files_exec_location_printer ALIAS limes_files_exec_location_printer) +limes_configure_app_bundle ( + limes_files_exec_location_printer BUNDLE_ID Limes.lfilesystem.execLocationPrinter + VERSION_MAJOR "${lfilesystem_VERSION_MAJOR}" FULL_VERSION "${lfilesystem_VERSION}") # Need to send the correct path as an argument to the test so that we can use generator expressions -add_test (NAME Limes.files.ExecLocation COMMAND limes::limes_files_exec_location_printer - "$") +add_test (NAME limes.files.ExecLocation COMMAND limes_files_exec_location_printer + "$") diff --git a/tests/FileWatcher.cpp b/tests/FileWatcher.cpp index 8f11dc8..c3a63af 100644 --- a/tests/FileWatcher.cpp +++ b/tests/FileWatcher.cpp @@ -36,7 +36,7 @@ TEST_CASE ("FileWatcher", "[core][files][watcher]") const auto file = cwd.getChildFile ("watcher_test.txt"); -#if (defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IPHONE)) +#if (defined(__ANDROID__) || defined(__EMSCRIPTEN__) || (defined(__APPLE__) && TARGET_OS_IPHONE)) REQUIRE (! lf::FileWatcher::supportedBySystem()); diff --git a/tests/FindPackage/CreateTests.cmake b/tests/FindPackage/CreateTests.cmake index 60c0352..de78b86 100644 --- a/tests/FindPackage/CreateTests.cmake +++ b/tests/FindPackage/CreateTests.cmake @@ -12,38 +12,45 @@ include_guard (GLOBAL) -set (base_name "Limes.files.FindPackage") +set (base_name "limes.files.FindPackage") set (install_dir "${CMAKE_CURRENT_BINARY_DIR}/install_tree") set (build_dir "${CMAKE_CURRENT_BINARY_DIR}/FindPackage") add_test (NAME "${base_name}.install" - COMMAND "${CMAKE_COMMAND}" --install "${lfilesystem_BINARY_DIR}" --config $ - --prefix "${install_dir}" --component lfilesystem_dev) + COMMAND "${CMAKE_COMMAND}" --install "${lfilesystem_BINARY_DIR}" --config $ + --prefix "${install_dir}") set_tests_properties ("${base_name}.install" PROPERTIES FIXTURES_SETUP LimesFilesFindPackageInstall) +# cmake-format: off add_test ( NAME "${base_name}.configure" - COMMAND - "${CMAKE_COMMAND}" -S "${CMAKE_CURRENT_LIST_DIR}" -B "${build_dir}" -G "${CMAKE_GENERATOR}" - -D "CMAKE_C_COMPILER=${CMAKE_C_COMPILER}" -D "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" -D - "CMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}" -D "CMAKE_PREFIX_PATH=${install_dir}" -D - "CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}") + COMMAND "${CMAKE_COMMAND}" + -S "${CMAKE_CURRENT_LIST_DIR}" + -B "${build_dir}" + -G "${CMAKE_GENERATOR}" + -D "CMAKE_C_COMPILER=${CMAKE_C_COMPILER}" + -D "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" + -D "CMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}" + -D "CMAKE_PREFIX_PATH=${install_dir}" + -D "CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}" + -D "BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}") +# cmake-format: on set_tests_properties ( - "${base_name}.configure" PROPERTIES FIXTURES_SETUP LimesFilesFindPackageConfigure - FIXTURES_REQUIRED LimesFilesFindPackageInstall) + "${base_name}.configure" PROPERTIES FIXTURES_SETUP LimesFilesFindPackageConfigure + FIXTURES_REQUIRED LimesFilesFindPackageInstall) add_test (NAME "${base_name}.build" COMMAND "${CMAKE_COMMAND}" --build "${build_dir}" --config - $) + $) set_tests_properties ("${base_name}.build" PROPERTIES FIXTURES_REQUIRED - LimesFilesFindPackageConfigure) + LimesFilesFindPackageConfigure) add_test (NAME "${base_name}.clean" COMMAND "${CMAKE_COMMAND}" -E rm -rf "${build_dir}" - "${install_dir}") + "${install_dir}") set_tests_properties ( - "${base_name}.clean" PROPERTIES FIXTURES_CLEANUP - "LimesFilesFindPackageConfigure;LimesFilesFindPackageInstall") + "${base_name}.clean" PROPERTIES FIXTURES_CLEANUP + "LimesFilesFindPackageConfigure;LimesFilesFindPackageInstall") diff --git a/tests/StructuredTree/CMakeLists.txt b/tests/StructuredTree/CMakeLists.txt index 06c6c63..571203a 100644 --- a/tests/StructuredTree/CMakeLists.txt +++ b/tests/StructuredTree/CMakeLists.txt @@ -14,18 +14,18 @@ add_executable (limes_files_tree_tester) target_sources (limes_files_tree_tester PRIVATE main.cpp CreateTree.cmake) -set_target_properties (limes_files_tree_tester PROPERTIES MACOSX_BUNDLE OFF) +limes_configure_app_bundle ( + limes_files_tree_tester BUNDLE_ID Limes.lfilesystem.treeTester + VERSION_MAJOR "${lfilesystem_VERSION_MAJOR}" FULL_VERSION "${lfilesystem_VERSION}") target_link_libraries (limes_files_tree_tester PRIVATE Catch2::Catch2WithMain limes::lfilesystem) -add_executable (limes::limes_files_tree_tester ALIAS limes_files_tree_tester) - -set (base_name "Limes.files.StructuredTree") +set (base_name "limes.files.StructuredTree") set (tree_root "${CMAKE_CURRENT_BINARY_DIR}/FileTree") add_test (NAME "${base_name}.setup" COMMAND "${CMAKE_COMMAND}" -D "TREE_ROOT=${tree_root}" -P - "${CMAKE_CURRENT_LIST_DIR}/CreateTree.cmake") + "${CMAKE_CURRENT_LIST_DIR}/CreateTree.cmake") set_tests_properties ("${base_name}.setup" PROPERTIES FIXTURES_SETUP LimesFilesTree) @@ -33,7 +33,6 @@ add_test (NAME "${base_name}.cleanup" COMMAND "${CMAKE_COMMAND}" -E rm -rf "${tr set_tests_properties ("${base_name}.cleanup" PROPERTIES FIXTURES_CLEANUP LimesFilesTree) -add_test (NAME "${base_name}.test" COMMAND limes::limes_files_tree_tester - WORKING_DIRECTORY "${tree_root}") +add_test (NAME "${base_name}.test" COMMAND limes_files_tree_tester WORKING_DIRECTORY "${tree_root}") set_tests_properties ("${base_name}.test" PROPERTIES FIXTURES_REQUIRED LimesFilesTree) diff --git a/tests/StructuredTree/CreateTree.cmake b/tests/StructuredTree/CreateTree.cmake index 2e17278..5e269a9 100644 --- a/tests/StructuredTree/CreateTree.cmake +++ b/tests/StructuredTree/CreateTree.cmake @@ -11,7 +11,7 @@ # ====================================================================================== if (NOT DEFINED TREE_ROOT) - message (FATAL_ERROR "TREE_ROOT must be defined!") + message (FATAL_ERROR "TREE_ROOT must be defined!") endif () file (REMOVE_RECURSE "${TREE_ROOT}") @@ -19,7 +19,7 @@ file (REMOVE_RECURSE "${TREE_ROOT}") file (MAKE_DIRECTORY "${TREE_ROOT}") foreach (filename IN ITEMS example.txt sample.omg .trial) - file (TOUCH "${TREE_ROOT}/${filename}") + file (TOUCH "${TREE_ROOT}/${filename}") endforeach () set (subdirs Foo Bar Baz) @@ -30,13 +30,13 @@ set (Baz_children "") foreach (subdirName IN LISTS subdirs) - set (subdirPath "${TREE_ROOT}/${subdirName}") + set (subdirPath "${TREE_ROOT}/${subdirName}") - file (MAKE_DIRECTORY "${subdirPath}") + file (MAKE_DIRECTORY "${subdirPath}") - foreach (filename IN LISTS ${subdirName}_children) - file (TOUCH "${subdirPath}/${filename}") - endforeach () + foreach (filename IN LISTS ${subdirName}_children) + file (TOUCH "${subdirPath}/${filename}") + endforeach () endforeach () diff --git a/tests/Volume.cpp b/tests/Volume.cpp index f517688..f86cdf4 100644 --- a/tests/Volume.cpp +++ b/tests/Volume.cpp @@ -16,6 +16,7 @@ #include #include +#ifndef __EMSCRIPTEN__ TEST_CASE ("Volume", "[core][files][volume]") { namespace lf = limes::files; @@ -84,3 +85,4 @@ TEST_CASE ("Volume", "[core][files][volume]") REQUIRE (*v2 == v); } } +#endif