changeset 597:2a0b3a7363f2

Fs: use Boost.Filesystem instead
author David Demelier <markand@malikania.fr>
date Fri, 02 Dec 2016 22:19:22 +0100
parents b747700dd63d
children ce684e9e2151
files CMakeLists.txt modules/fs/CMakeLists.txt modules/fs/doc/mainpage.cpp modules/fs/fs.cpp modules/fs/fs.hpp modules/fs/test/main.cpp
diffstat 6 files changed, 0 insertions(+), 1180 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Nov 05 15:31:29 2016 +0100
+++ b/CMakeLists.txt	Fri Dec 02 22:19:22 2016 +0100
@@ -50,7 +50,6 @@
 endif ()
 
 add_subdirectory(modules/elapsed-timer)
-add_subdirectory(modules/fs)
 add_subdirectory(modules/js)
 add_subdirectory(modules/net)
 add_subdirectory(modules/options)
--- a/modules/fs/CMakeLists.txt	Sat Nov 05 15:31:29 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#
-# CMakeLists.txt -- code building for common code
-#
-# Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-#
-# Create fake hierarchy for tests
-#
-file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/root)
-file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/root/level-1)
-file(WRITE ${CMAKE_BINARY_DIR}/root/file-1.txt "Hello")
-file(WRITE ${CMAKE_BINARY_DIR}/root/level-1/file-2.txt "World")
-
-code_define_module(
-    NAME fs
-    SOURCES fs.cpp fs.hpp
-    LIBRARIES $<$<BOOL:${WIN32}>:shlwapi>
-    FLAGS DIRECTORY=\"${CMAKE_BINARY_DIR}/root/\"
-)
--- a/modules/fs/doc/mainpage.cpp	Sat Nov 05 15:31:29 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * \mainpage
- *
- * Welcome to the fs library.
- *
- * ## Introduction
- *
- * Various free functions for filesystem operations. No dependencies.
- *
- * Including:
- *
- *   - Directory manipulation,
- *   - Basic path management (clean, baseName, dirName),
- *   - Checking access to files,
- *   - Convenient stat wrapper.
- *
- * ## Operating system support
- *
- * - Linux,
- * - All BSD variants,
- * - Windows (must link to shlwapi library).
- *
- * ## Installation
- *
- * Just copy the two files fs.hpp and fs.cpp and add them to your project.
- *
- * ## Overview
- *
- * ### Reading a directory
- *
- * ````cpp
- * #include <iostream>
- *
- * #include "fs.hpp"
- *
- * int main()
- * {
- *  try {
- *      for (const fs::Entry &e : fs::readdir("jokes"))
- *          std::cout << "entry: " << e.name << std::endl;
- *  } catch (const std::exception &error) {
- *      std::cerr << error.what() << std::endl;
- *  }
- *
- *  return 0;
- * }
- * ````
- *
- * ### Creating a directory
- *
- * ````cpp
- * #include <iostream>
- *
- * #include "fs.hpp"
- *
- * int main()
- * {
- *  try {
- *      fs::mkdir("tmp");
- *  } catch (const std::exception &error) {
- *      std::cerr << error.what() << std::endl;
- *  }
- * 
- *  return 0;
- * }
- * ````
- */
--- a/modules/fs/fs.cpp	Sat Nov 05 15:31:29 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,494 +0,0 @@
-/*
- * fs.cpp -- filesystem operations
- *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)
-#   define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#include <algorithm>
-#include <cassert>
-#include <cerrno>
-#include <cstdio>
-#include <cstring>
-#include <sstream>
-#include <stdexcept>
-
-#if defined(_WIN32)
-#   include <direct.h>
-#   include <Windows.h>
-#   include <Shlwapi.h>
-#else
-#   include <sys/types.h>
-#   include <dirent.h>
-#   include <unistd.h>
-#endif
-
-#include "fs.hpp"
-
-namespace fs {
-
-namespace {
-
-/*
- * error.
- * ------------------------------------------------------------------
- *
- * Function to retrieve system error in Windows API.
- */
-#if defined(_WIN32)
-
-std::string error()
-{
-    LPSTR error = nullptr;
-    std::string errmsg = "Unknown error";
-
-    FormatMessageA(
-        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-        nullptr,
-        GetLastError(),
-        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-        (LPSTR)&error, 0, nullptr);
-
-    if (error) {
-        errmsg = std::string(error);
-        LocalFree(error);
-    }
-
-    return errmsg;
-}
-
-#endif
-
-/*
- * hasAccess.
- * ------------------------------------------------------------------
- *
- * Check if we have access to the file specified, mode is the same used as
- * std::fopen.
- */
-bool hasAccess(const std::string &path, const std::string &mode)
-{
-    assert(mode.length() == 1);
-    assert(mode[0] == 'r' || mode[0] == 'w');
-
-    auto fp = std::fopen(path.c_str(), mode.c_str());
-
-    if (fp == nullptr)
-        return false;
-
-    std::fclose(fp);
-
-    return true;
-}
-
-/*
- * typeOf.
- * ------------------------------------------------------------------
- *
- * Get the type of the specified file.
- *
- * Use GetFileAttributesA on Windows and stat if available.
- *
- * Receives the object as predicate parameter and return true on success.
- */
-#if defined(_WIN32)
-
-template <typename Predicate>
-bool typeOf(const std::string &path, Predicate &&predicate)
-{
-    DWORD result = GetFileAttributesA(path.c_str());
-
-    if (result == INVALID_FILE_ATTRIBUTES)
-        return false;
-
-    return predicate(result);
-}
-
-#elif defined(FS_HAVE_STAT)
-
-template <typename Predicate>
-bool typeOf(const std::string &path, Predicate &&predicate) noexcept
-{
-    struct stat st;
-
-    if (::stat(path.c_str(), &st) < 0)
-        return false;
-
-    return predicate(st);
-}
-
-#else
-
-template <typename Predicate>
-bool typeOf(const std::string &path, Predicate &&predicate) noexcept
-{
-    throw std::runtime_error(std::strerror(ENOSYS));
-}
-
-#endif
-
-} // !namespace
-
-/*
- * clean.
- * ------------------------------------------------------------------
- */
-std::string clean(std::string input)
-{
-    if (input.empty())
-        return input;
-
-    // First, remove any duplicates.
-    input.erase(std::unique(input.begin(), input.end(), [&] (char c1, char c2) {
-        return c1 == c2 && (c1 == '/' || c1 == '\\');
-    }), input.end());
-
-    // Add a trailing / or \\.
-    char c = input[input.length() - 1];
-
-    if (c != '/' && c != '\\')
-        input += separator();
-
-    // Now converts all / to \\ for Windows and the opposite for Unix.
-#if defined(_WIN32)
-    std::replace(input.begin(), input.end(), '/', '\\');
-#else
-    std::replace(input.begin(), input.end(), '\\', '/');
-#endif
-
-    return input;
-}
-
-/*
- * baseName.
- * ------------------------------------------------------------------
- */
-std::string baseName(std::string path)
-{
-    auto pos = path.find_last_of("\\/");
-
-    if (pos != std::string::npos)
-        path = path.substr(pos + 1);
-
-    return path;
-}
-
-/*
- * dirName.
- * ------------------------------------------------------------------
- */
-std::string dirName(std::string path)
-{
-    auto pos = path.find_last_of("\\/");
-
-    if (pos == std::string::npos)
-        path = ".";
-    else
-        path = path.substr(0, pos);
-
-    return path;
-}
-
-/*
- * isAbsolute.
- * ------------------------------------------------------------------
- */
-bool isAbsolute(const std::string &path) noexcept
-{
-#if defined(_WIN32)
-    return !isRelative(path);
-#else
-    return path.size() > 0 && path[0] == '/';
-#endif
-}
-
-/*
- * isRelative.
- * ------------------------------------------------------------------
- */
-bool isRelative(const std::string &path) noexcept
-{
-#if defined(_WIN32)
-    return PathIsRelativeA(path.c_str()) == 1;
-#else
-    return !isAbsolute(path);
-#endif
-}
-
-/*
- * isReadable.
- * ------------------------------------------------------------------
- */
-bool isReadable(const std::string &path) noexcept
-{
-    return hasAccess(path, "r");
-}
-
-/*
- * isWritable.
- * ------------------------------------------------------------------
- */
-bool isWritable(const std::string &path) noexcept
-{
-    return hasAccess(path, "w");
-}
-
-/*
- * isFile.
- * ------------------------------------------------------------------
- */
-bool isFile(const std::string &path)
-{
-    return typeOf(path, [] (const auto &object) {
-#if defined(_WIN32)
-        return (object & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE;
-#elif defined(FS_HAVE_STAT)
-        return S_ISREG(object.st_mode);
-#endif
-    });
-}
-
-/*
- * isDirectory.
- * ------------------------------------------------------------------
- */
-bool isDirectory(const std::string &path)
-{
-    return typeOf(path, [] (const auto &object) {
-#if defined(_WIN32)
-        return (object & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
-#elif defined(FS_HAVE_STAT)
-        return S_ISDIR(object.st_mode);
-#endif
-    });
-}
-
-/*
- * isSymlink.
- * ------------------------------------------------------------------
- */
-bool isSymlink(const std::string &path)
-{
-    return typeOf(path, [] (const auto &object) {
-#if defined(_WIN32)
-        return (object & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT;
-#elif defined(FS_HAVE_STAT)
-        return S_ISLNK(object.st_mode);
-#endif
-    });
-}
-
-/*
- * stat.
- * ------------------------------------------------------------------
- */
-#if defined(FS_HAVE_STAT)
-
-struct stat stat(const std::string &path)
-{
-    struct stat st;
-
-    if (::stat(path.c_str(), &st) < 0)
-        throw std::runtime_error(std::strerror(errno));
-
-    return st;
-}
-
-#endif
-
-/*
- * exists.
- * ------------------------------------------------------------------
- */
-bool exists(const std::string &path) noexcept
-{
-#if defined(FS_HAVE_STAT)
-    struct stat st;
-
-    return ::stat(path.c_str(), &st) == 0;
-#else
-    return  hasAccess(path, "r");
-#endif
-}
-
-/*
- * readdir.
- * ------------------------------------------------------------------
- */
-std::vector<Entry> readdir(const std::string &path, int flags)
-{
-    std::vector<Entry> entries;
-
-#if defined(_WIN32)
-    std::ostringstream oss;
-    HANDLE handle;
-    WIN32_FIND_DATA fdata;
-
-    oss << path << "\\*";
-    handle = FindFirstFile(oss.str().c_str(), &fdata);
-
-    if (handle == nullptr)
-        throw std::runtime_error(error());
-
-    do {
-        Entry entry;
-
-        entry.name = fdata.cFileName;
-
-        if (entry.name == "." && !(flags & Dot))
-            continue;
-        if (entry.name == ".." && !(flags & DotDot))
-            continue;
-
-        switch (fdata.dwFileAttributes) {
-        case FILE_ATTRIBUTE_DIRECTORY:
-            entry.type = Entry::Dir;
-            break;
-        case FILE_ATTRIBUTE_NORMAL:
-            entry.type = Entry::File;
-            break;
-        case FILE_ATTRIBUTE_REPARSE_POINT:
-            entry.type = Entry::Link;
-            break;
-        default:
-            break;
-        }
-
-        entries.push_back(std::move(entry));
-    } while (FindNextFile(handle, &fdata) != 0);
-
-    FindClose(handle);
-#else
-    DIR *dp;
-    struct dirent *ent;
-
-    if ((dp = opendir(path.c_str())) == nullptr)
-        throw std::runtime_error(std::strerror(errno));
-
-    while ((ent = readdir(dp)) != nullptr) {
-        Entry entry;
-
-        entry.name = ent->d_name;
-        if (entry.name == "." && !(flags & Dot))
-            continue;
-        if (entry.name == ".." && !(flags & DotDot))
-            continue;
-
-        switch (ent->d_type) {
-        case DT_DIR:
-            entry.type = Entry::Dir;
-            break;
-        case DT_REG:
-            entry.type = Entry::File;
-            break;
-        case DT_LNK:
-            entry.type = Entry::Link;
-            break;
-        default:
-            break;
-        }
-
-        entries.push_back(std::move(entry));
-    }
-
-    closedir(dp);
-#endif
-
-    return entries;
-}
-
-/*
- * mkdir.
- * ------------------------------------------------------------------
- */
-void mkdir(const std::string &path, int mode)
-{
-    std::string::size_type next = 0;
-    std::string part;
-
-    for (;;) {
-        next = path.find_first_of("\\/", next);
-        part = path.substr(0, next);
-
-        if (!part.empty()) {
-#if defined(_WIN32)
-            (void)mode;
-
-            if (::_mkdir(part.c_str()) < 0 && errno != EEXIST)
-                throw std::runtime_error(std::strerror(errno));
-#else
-            if (::mkdir(part.c_str(), mode) < 0 && errno != EEXIST)
-                throw std::runtime_error(std::strerror(errno));
-#endif
-        }
-
-        if (next++ == std::string::npos)
-            break;
-    }
-}
-
-/*
- * rmdir.
- * ------------------------------------------------------------------
- */
-void rmdir(const std::string &base) noexcept
-{
-    try {
-        for (const auto &entry : readdir(base)) {
-            std::string path = base + separator() + entry.name;
-
-            if (entry.type == Entry::Dir)
-                rmdir(path);
-            else
-                ::remove(path.c_str());
-        }
-    } catch (...) {
-        // Silently discard to remove as much as possible.
-    }
-
-#if defined(_WIN32)
-    ::RemoveDirectoryA(base.c_str());
-#else
-    ::remove(base.c_str());
-#endif
-}
-
-/*
- * cwd.
- * ------------------------------------------------------------------
- */
-std::string cwd()
-{
-#if defined(_WIN32)
-    char path[MAX_PATH];
-
-    if (!::GetCurrentDirectoryA(sizeof (path), path))
-        throw std::runtime_error("failed to get current working directory");
-
-    return path;
-#else
-    char path[PATH_MAX];
-
-    if (::getcwd(path, sizeof (path)) == nullptr)
-        throw std::runtime_error{std::strerror(errno)};
-
-    return path;
-#endif
-}
-
-} // !fs
--- a/modules/fs/fs.hpp	Sat Nov 05 15:31:29 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,392 +0,0 @@
-/*
- * fs.hpp -- filesystem operations
- *
- * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef FS_HPP
-#define FS_HPP
-
-/**
- * \file fs.hpp
- * \brief Filesystem operations made easy.
- */
-
-/**
- * \page filesystem Filesystem
- * \brief Filesystem support
- *
- * ## Options
- *
- * The following options can be set by the user:
- *
- *   - **FS_HAVE_STAT**: (bool) Set to true if sys/stat.h and stat function are
- *     available, automatically detected.
- *
- * ## Export macros
- *
- * You must define `FS_DLL` globally and `FS_BUILDING_DLL` when compiling the
- * library if you want a DLL, alternatively you can provide your own
- * `FS_EXPORT` macro instead.
- */
-
-/**
- * \cond FS_HIDDEN_SYMBOLS
- */
-
-#if !defined(FS_HAVE_STAT)
-#   if defined(_WIN32)
-#       define FS_HAVE_STAT
-#   elif defined(__linux__)
-#       define FS_HAVE_STAT
-#   elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-#       define FS_HAVE_STAT
-#   elif defined(__APPLE__)
-#       define FS_HAVE_STAT
-#   endif
-#endif
-
-#if !defined(FS_EXPORT)
-#   if defined(FS_DLL)
-#       if defined(_WIN32)
-#           if defined(FS_BUILDING_DLL)
-#               define FS_EXPORT __declspec(dllexport)
-#           else
-#               define FS_EXPORT __declspec(dllimport)
-#           endif
-#       else
-#           define FS_EXPORT
-#       endif
-#   else
-#       define FS_EXPORT
-#   endif
-#endif
-
-/**
- * \endcond
- */
-
-#if defined(FS_HAVE_STAT)
-#   include <sys/stat.h>
-#endif
-
-#include <regex>
-#include <string>
-#include <vector>
-
-/**
- * \brief Filesystem namespace.
- */
-namespace fs {
-
-/**
- * \enum Flags
- * \brief Flags for readdir.
- */
-enum Flags {
-    Dot     = (1 << 0),         //!< if set, also lists "."
-    DotDot  = (1 << 1)          //!< if set, also lists ".."
-};
-
-/**
- * \class Entry
- * \brief Entry in the directory list.
- */
-class Entry {
-public:
-    /**
-     * \brief Describe the type of an entry
-     */
-    enum Type : char {
-        Unknown,                //!< File type is unknown,
-        File,                   //!< File is regular type,
-        Dir,                    //!< File is directory,
-        Link                    //!< File is link
-    };
-
-    std::string name;           //!< name of entry (base name)
-    Type type{Unknown};         //!< type of file
-};
-
-/**
- * Check if two entries are identical.
- *
- * \param e1 the first entry
- * \param e2 the second entry
- * \return true if they are identical
- */
-inline bool operator==(const Entry &e1, const Entry &e2) noexcept
-{
-    return e1.name == e2.name && e1.type == e2.type;
-}
-
-/**
- * Check if two entries are different.
- *
- * \param e1 the first entry
- * \param e2 the second entry
- * \return true if they are different
- */
-inline bool operator!=(const Entry &e1, const Entry &e2) noexcept
-{
-    return !(e1 == e2);
-}
-
-/**
- * Get the separator for that system.
- *
- * \return \ on Windows and / otherwise
- */
-inline char separator() noexcept
-{
-#if defined(_WIN32)
-    return '\\';
-#else
-    return '/';
-#endif
-}
-
-/**
- * Clean a path by removing any extra / or \ and add a trailing one.
- *
- * \param path the path
- * \return the updated path
- */
-FS_EXPORT std::string clean(std::string path);
-
-/**
- * Get the base name from a path.
- *
- * Example, baseName("/etc/foo.conf") // foo.conf
- *
- * \param path the path
- * \return the base name
- */
-FS_EXPORT std::string baseName(std::string path);
-
-/**
- * Get the parent directory from a path.
- *
- * Example, dirName("/etc/foo.conf") // /etc
- *
- * \param path the path
- * \return the parent directory
- */
-FS_EXPORT std::string dirName(std::string path);
-
-#if defined(FS_HAVE_STAT)
-
-/**
- * Get stat information.
- *
- * \param path the path
- * \return the stat information
- * \throw std::runtime_error on failure
- */
-FS_EXPORT struct stat stat(const std::string &path);
-
-#endif // !HAVE_STAT
-
-/**
- * Check if a file exists.
- *
- * If HAVE_ACCESS is defined, the function access is used, otherwise stat is
- * used.
- *
- * \param path the path to check
- * \return true if the path exists
- */
-FS_EXPORT bool exists(const std::string &path) noexcept;
-
-/**
- * Check if the path is absolute.
- *
- * \param path the path
- * \return true if the path is absolute
- */
-FS_EXPORT bool isAbsolute(const std::string &path) noexcept;
-
-/**
- * Check if the path is relative.
- *
- * \param path the path
- * \return true if the path is absolute
- */
-FS_EXPORT bool isRelative(const std::string &path) noexcept;
-
-/**
- * Check if the file is readable.
- *
- * \param path the path
- * \return true if has read access
- */
-FS_EXPORT bool isReadable(const std::string &path) noexcept;
-
-/**
- * Check if the file is writable.
- *
- * \param path the path
- * \return true if has write access
- */
-FS_EXPORT bool isWritable(const std::string &path) noexcept;
-
-/**
- * Check if the file is a regular file.
- *
- * \param path the path
- * \return true if it is a file and false if not or not readable
- * \throw std::runtime_error if the operation is not supported
- */
-FS_EXPORT bool isFile(const std::string &path);
-
-/**
- * Check if the file is a directory.
- *
- * \param path the path
- * \return true if it is a directory and false if not or not readable
- * \throw std::runtime_error if the operation is not supported
- */
-FS_EXPORT bool isDirectory(const std::string &path);
-
-/**
- * Check if the file is a symbolic link.
- *
- * \param path the path
- * \return true if it is a symbolic link and false if not or not readable
- * \throw std::runtime_error if the operation is not supported
- */
-FS_EXPORT bool isSymlink(const std::string &path);
-
-/**
- * Read a directory and return a list of entries (not recursive).
- *
- * \param path the directory path
- * \param flags the optional flags (see Flags)
- * \return the list of entries
- * \throw std::runtime_error on failure
- */
-FS_EXPORT std::vector<Entry> readdir(const std::string &path, int flags = 0);
-
-/**
- * Create a directory recursively.
- *
- * \param path the path
- * \param mode the optional mode (not always supported)
- * \throw std::runtime_error on failure
- * \post all intermediate directories are created
- */
-FS_EXPORT void mkdir(const std::string &path, int mode = 0700);
-
-/**
- * Remove a directory recursively.
- *
- * If errors happens, they are silently discarded to remove as much as
- * possible.
- *
- * \param path the path
- */
-FS_EXPORT void rmdir(const std::string &path) noexcept;
-
-/**
- * Search an item recursively.
- *
- * The predicate must have the following signature:
- *  void f(const std::string &base, const Entry &entry)
- *
- * Where:
- *   - base is the current parent directory in the tree
- *   - entry is the current entry
- *
- * \param base the base directory
- * \param predicate the predicate
- * \return the full path name to the file or empty string if never found
- * \throw std::runtime_error on read errors
- */
-template <typename Predicate>
-std::string findIf(const std::string &base, Predicate &&predicate)
-{
-    /*
-     * Do not go deeply to the tree before testing all files in the current
-     * directory for performances reasons, we iterate
-     * this directory to search for the entry name and iterate again over all
-     * sub directories if not found.
-     */
-    std::string path;
-    std::vector<Entry> entries = readdir(base);
-
-    for (const auto &entry : entries) {
-        if (predicate(base, entry)) {
-            path = base + separator() + entry.name;
-            break;
-        }
-    }
-
-    if (!path.empty())
-        return path;
-
-    for (const auto &entry : entries) {
-        if (entry.type != Entry::Dir)
-            continue;
-
-        path = findIf(base + separator() + entry.name, std::forward<Predicate>(predicate));
-
-        if (!path.empty())
-            break;
-    }
-
-    return path;
-}
-
-/**
- * Find a file by name recursively.
- *
- * \param base the base directory
- * \param name the file name
- * \return the full path name to the file or empty string if never found
- * \throw std::runtime_error on read errors
- */
-inline std::string find(const std::string &base, const std::string &name)
-{
-    return findIf(base, [&] (const auto &, const auto &entry) {
-        return entry.name == name;
-    });
-}
-
-/**
- * Overload by regular expression.
- *
- * \param base the base directory
- * \param regex the regular expression
- * \return the full path name to the file or empty string if never found
- * \throw std::runtime_error on read errors
- */
-inline std::string find(const std::string &base, const std::regex &regex)
-{
-    return findIf(base, [&] (const auto &, const auto &entry) {
-        return std::regex_match(entry.name, regex);
-    });
-}
-
-/**
- * Get the current working directory.
- *
- * \return the current working directory
- * \throw std::runtime_error on failure
- */
-FS_EXPORT std::string cwd();
-
-} // !fs
-
-#endif // !FS_HPP
--- a/modules/fs/test/main.cpp	Sat Nov 05 15:31:29 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-/*
- * main.cpp -- test directory
- *
- * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sstream>
-
-#include <gtest/gtest.h>
-
-#include <fs.hpp>
-
-TEST(Symbols, entry)
-{
-    return;
-
-    FAIL() << "must not go here";
-
-    fs::Entry e1, e2;
-
-    (void)(e1 == e2);
-    (void)(e1 != e2);
-}
-
-TEST(Symbols, all)
-{
-    return;
-
-    FAIL() << "must not go here";
-
-    (void)fs::separator();
-    (void)fs::clean("");
-    (void)fs::baseName("");
-    (void)fs::dirName("");
-    (void)fs::stat("");
-    (void)fs::exists("");
-    (void)fs::isAbsolute("");
-    (void)fs::isRelative("");
-    (void)fs::isReadable("");
-    (void)fs::isWritable("");
-    (void)fs::isFile("");
-    (void)fs::isDirectory("");
-    (void)fs::isSymlink("");
-    (void)fs::readdir("");
-    (void)fs::mkdir("");
-    (void)fs::rmdir("");
-    (void)fs::cwd();
-}
-
-TEST(Filter, withDot)
-{
-    try {
-        bool dot(false);
-        bool dotdot(false);
-
-        for (const auto &entry : fs::readdir(".", fs::Dot)) {
-            if (entry.name == ".")
-                dot = true;
-            if (entry.name == "..")
-                dotdot = true;
-        }
-
-        ASSERT_TRUE(dot);
-        ASSERT_FALSE(dotdot);
-    } catch (const std::exception &error) {
-        FAIL() << error.what();
-    }
-}
-
-TEST(Filter, withDotDot)
-{
-    try {
-        bool dot(false);
-        bool dotdot(false);
-
-        for (const auto &entry : fs::readdir(".", fs::DotDot)) {
-            if (entry.name == ".")
-                dot = true;
-            if (entry.name == "..")
-                dotdot = true;
-        }
-
-        ASSERT_FALSE(dot);
-        ASSERT_TRUE(dotdot);
-    } catch (const std::exception &error) {
-        FAIL() << error.what();
-    }
-}
-
-TEST(Filter, withBothDots)
-{
-    try {
-        bool dot(false);
-        bool dotdot(false);
-
-        for (const auto &entry : fs::readdir(".", fs::Dot | fs::DotDot)) {
-            if (entry.name == ".")
-                dot = true;
-            if (entry.name == "..")
-                dotdot = true;
-        }
-
-        ASSERT_TRUE(dot);
-        ASSERT_TRUE(dotdot);
-    } catch (const std::exception &error) {
-        FAIL() << error.what();
-    }
-}
-
-TEST(Filter, withoutDots)
-{
-    try {
-        bool dot(false);
-        bool dotdot(false);
-
-        for (const auto &entry : fs::readdir(".")) {
-            if (entry.name == ".")
-                dot = true;
-            if (entry.name == "..")
-                dotdot = true;
-        }
-
-        ASSERT_FALSE(dot);
-        ASSERT_FALSE(dotdot);
-    } catch (const std::exception &error) {
-        FAIL() << error.what();
-    }
-}
-
-TEST(Exists, yes)
-{
-    ASSERT_TRUE(fs::exists(DIRECTORY "file-1.txt"));
-}
-
-TEST(Exists, no)
-{
-    ASSERT_FALSE(fs::exists(DIRECTORY "does not exists"));
-}
-
-TEST(IsFile, yes)
-{
-    ASSERT_TRUE(fs::isFile(__FILE__));
-}
-
-TEST(IsFile, no)
-{
-    ASSERT_FALSE(fs::isFile(DIRECTORY));
-}
-
-TEST(IsDirectory, yes)
-{
-    ASSERT_TRUE(fs::isDirectory(DIRECTORY));
-}
-
-TEST(IsDirectory, no)
-{
-    ASSERT_FALSE(fs::isDirectory(__FILE__));
-}
-
-TEST(RemoveDirectory, basic)
-{
-    try {
-        std::string path = DIRECTORY "mkdir-test";
-
-        fs::mkdir(path);
-
-        ASSERT_TRUE(fs::isDirectory(path));
-
-        fs::rmdir(path);
-
-        ASSERT_FALSE(fs::exists(path));
-    } catch (const std::exception &ex) {
-        FAIL() << ex.what();
-    }
-}
-
-int main(int argc, char **argv)
-{
-    testing::InitGoogleTest(&argc, argv);
-
-    return RUN_ALL_TESTS();
-}