Coder Social home page Coder Social logo

cginternals / cppfs Goto Github PK

View Code? Open in Web Editor NEW
459.0 30.0 66.0 1.88 MB

Cross-platform C++ file system library supporting multiple backends

License: MIT License

CMake 22.58% C++ 76.16% Shell 0.21% Makefile 0.68% Dockerfile 0.37%
c-plus-plus c-plus-plus-11 library filesystem-library

cppfs's Introduction


cppfs is a cross-platform C++ library that provides an object-oriented abstraction for working with files and the file system.

GitHub release Travis Appveyor Tokei Tokei

cppfs can be used not only to access the local file system, but for remote and virtual file systems as well. By specializing the virtual backend interface, cppfs can be easily extended to support additional remote protocols or virtual file systems. The following backends are currently implemented:

  • Local file system (POSIX, win32)
  • SSH (libssh2)

Resources

Installation and Development
Features

Build Instructions

Please follow our CMake project setup guide to setup and build cppfs.

Basic Examples

Opening files and checking for existence and type:

#include <cppfs/fs.h>
#include <cppfs/FileHandle.h>

using namespace cppfs;

void openFile(const std::string & filename)
{
    FileHandle fh = fs::open(filename);

         if (fh.isFile())      { /* File ... */ }
    else if (fh.isDirectory()) { /* Directory ... */ }
    else if (!fh.exists())     { /* Not there ... */ }
}

Open a file for reading or writing:

#include <cppfs/fs.h>
#include <cppfs/FileHandle.h>

using namespace cppfs;

void openFile(const std::string & filename)
{
    FileHandle fh = fs::open(filename);

    if (fh.isFile())
    {
        auto in = fh.createInputStream();
        // ...

        auto out = fh.createOutputStream();
        // ...
    }
}

Listing directory entries:

#include <cppfs/fs.h>
#include <cppfs/FileHandle.h>

using namespace cppfs;

void lstDir(const std::string & path)
{
    FileHandle dir = fs::open(path);

    if (dir.isDirectory())
    {
        for (FileIterator it = dir.begin(); it != dir.end(); ++it)
        {
            std::string path = *it;
        }
    }
}

Features

Paths and URLs

The class FilePath is used to represent paths in the file system. It can be constructed from a string and converted back into a string.

FilePath path("data/readme.txt");
std::string pathOut = path.path();

Paths are stored in a unified format using only forward slashes ('/') as a separator. The unified format is compatible to all systems, but as a convenience for the user, it should be converted to the native format when displaying paths. To convert a path into the native format, call toNative.

FilePath path("data/readme.txt");
std::cout << "File path: " << path.toNative() << std::endl;

A FilePath can be used to obtain syntactical information about a path. It does however work purely on the string, it cannot provide information about the actual file or directory the path points to. The following functions are useful to get information about a path:

FilePath path = ...;

// Check if the path is empty ("")
bool empty = path.isEmpty();

// Check if the path is an absolute path (e.g., "/test.txt", or "C:/test.txt")
bool abs = path.isAbsolute();

// Check if the path is a relative path (e.g., "data/test.txt")
bool rel = path.isRelative();

// Check if path points to a file/directory (e.g., "/path/to/dir")
// or its content (e.g., "/path/to/dir/").
bool listContent = path.pointsToContent();

FilePath offers functions to obtain the individual components of a file path, such as the filename, extension, or path to the containing directory. All of these functions ignore trailing slashes on the path, so they operate on the object the path points to, not it contents.

FilePath path1("C:/path/to/file.txt");
FilePath path2("C:/path/to/directory/");

// Get full path
std::cout << path1.fullPath() << std::endl; // "C:/path/to/file.txt"
std::cout << path2.fullPath() << std::endl; // "C:/path/to/directory"

// Get filename components
std::cout << path1.fileName()  << std::endl; // "file.txt"
std::cout << path2.fileName()  << std::endl; // "directory"
std::cout << path1.baseName()  << std::endl; // "file"
std::cout << path2.baseName()  << std::endl; // "directory"
std::cout << path1.extension() << std::endl; // ".txt"
std::cout << path2.extension() << std::endl; // ""

// Get path to containing directory
std::cout << path1.directoryPath() << std::endl; // "C:/path/to/"
std::cout << path2.directoryPath() << std::endl; // "C:/path/to/"

// Get drive letter
std::cout << path1.driveLetter() << std::endl; // "C:"
std::cout << path2.driveLetter() << std::endl; // "C:"

Paths often need to be combined in order to determine the actual location of a file. To combine two paths, the function resolve can be used. The second path must be relative to combine the two paths, otherwise only the second path is returned. The combination of paths also takes place on a pure syntactical level, without checking if any of the paths really exist.

FilePath src("C:/projects");
FilePath rel("../documents/test.txt");
FilePath abs("C:/projects2/readme.txt");

FilePath path1 = src.resolve(rel);
std::cout << path1.fullPath() << std::endl; // "C:/projects/../documents/test.txt"

FilePath path2 = src.resolve(abs);
std::cout << path2.fullPath() << std::endl; // "C:/projects2/readme.txt"

When combining relative paths, the resulting strings may contain a lot of ".." and "." components. To resolve these on a syntactical level, the function resolved can be called. It will remove all occurences of "." and "..", as long as it is possible. Occurences of ".." at the beginning of a path will not be removed.

FilePath path("C:/projects/../documents/test.txt");
std::cout << path.resolved() << std::endl; // "C:/documents/test.txt"

Accessing the file system

The main class for accessing files and directories in cppfs is FileHandle. It can be used to get information about file system objects, to manipulate them (e.g., copy, rename, or delete), as well as to read and write files.

To obtain a file handle, the global function fs::open can be called. The type of file system that is accessed will be determined automatically by the given path or URL. File systems will be closed automatically when there are no longer any open file handles left.

// Open local file
FileHandle file1 = fs::open("data/readme.txt");

// Open file on SSH server
LoginCredentials login;
login.setValue("username",   "username");
login.setValue("password",   "password");
login.setValue("publicKey",  "/path/to/key.pub"); // Default: "$home/.ssh/id_rsa.pub"
login.setValue("privateKey", "/path/to/key");     // Default: "$home/.ssh/id_rsa"
login.setValue("port",       "999");              // Default: 22

FileHandle file2 = fs::open("ssh://example.com/home/user/readme.txt", &login);

At the moment, it is not possible to register new file systems at the global level. To use a custom file system, create an instance of it and use the AbstractFileSystem interface to access it.

class CustomFS : public AbstractFileSystem
{
    ...
};

CustomFS fs;
FileHandle file = fs.open("data/readme.txt");

Getting file information

A file handle can be used to access information about the file system object it points to. A file handle can also be copied, creating a second handle that points to the same file system object but does not inherit the state of the former handle. This operation only copies the path of the handle to the new object, so it is a cheap operation.

// Open file from local file system
FileHandle file = fs::open("data/readme.txt");

// Get a second handle to the same file
FileHandle file2 = file;

Once a file handle has been obtained, it can be used to query basic information about the file system object is points to.

FileHandle file = fs::open("data/readme.txt");

// Check type
     if (file.isFile())         std::cout << "file" << std::endl;
else if (file.isDirectory())    std::cout << "directory" << std::endl;
else if (file.isSymbolicLink()) std::cout << "symlink" << std::endl;
else if (!file.exists())        std::cout << "file does not exist" << std::endl;

// Get filename and path
std::string path = file.path();
std::string filename = file.fileName();

// Get file information
unsigned int  size  = file.size();
unsigned int  atime = file.accessTime();
unsigned int  mtime = file.modificationTime();
unsigned int  uid   = file.userId();
unsigned int  gid   = file.groupId();
unsigned long perm  = file.permissions();

File permissions can also be modified:

FileHandle file = fs::open("data/readme.txt");

file.setUserId(1000);
file.setGroupId(1000);
file.setPermissions(FilePermissions::UserRead | FilePermissions::GroupRead);

The file information is retrieved only when needed, i.e., on the first call of one of the above functions, and then cached in memory. When an operation on the handle modifies the file information, it is updated automatically. However, if a file is modified outside of the application or using a different handle to the same file, the file handle cannot know about the change. Therefore, it must be updated manually:

FileHandle file = fs::open("data/readme.txt");

// If the file has been modified outside the application ...
file.updateFileInfo();

File operations

Using the FileHandle, basic file operations can be performed. For binary operations, such as copy or move, the second file handle is considered to be the target of the operation. Depending on the operation, the target does not need to already exist. If the target points to a directory rather than a file, the target will be considered to be inside that directory (for example, a file will be copied into the given directory).

FileHandle dir  = fs::open("data");
FileHandle file = fs::open("readme.txt");
FileHandle dest;

// Create directory if it does not yet exist
if (!dir.isDirectory()) dir.createDirectory();

// Copy file into directory
file.copy(dir);

// Copy file to another file
dest = dir.open("readme2.txt");
file.copy(dest);

// Rename file
file.rename("readme3.txt");

// Move file into directory
file.move(dir);

// Create hard link
dest = dir.open("readme4.txt");
file.createLink(dest);

// Create symbolic link
dest = dir.open("readme5.txt");
file.createSymbolicLink(dest);

// Delete file
file.remove();

// Delete directory (only if empty)
dir.removeDirectory();

Reading and writing to files

To read and write files, standard C++ streams are applied. To open an input stream for a file, call createInputStream. To create an output stream, call createOutputStream.

FileHandle file = fs::open("readme.txt");

std::unique_ptr<std::istream> in = file.createInputStream();
// ...

std::unique_ptr<std::ostream> out = file.createOutputStream();
// ...

For convience, there are also functions for reading and writing entire files using strings:

FileHandle file = fs::open("readme.txt");

std::string content = file.readFile();

file.writeFile("no more text ...");

Advanced functions on files

Advanced file operation include the generation of hashes and base64 encoding of files. They can be called directly on a file handle:

FileHandle file = fs::open("readme.txt");

// Get SHA1 hash of a file
std::string hash = file.sha1();

// Get base64 encoding of a file
std::string base64 = file.base64();

// Write file from base64 encoding
file.writeFileBase64(base64);

Accessing and traversing directories

A FileHandle is used to access files as well as directories. To check if a file handle points to a directory, the function isDirectory can be used.

FileHandle dir = fs::open("data");
if (dir.isDirectory())
{
    // ...
}

To list all files in a directory, call listFiles:

FileHandle dir = fs::open("data");
std::vector<std::string> files = dir.listFiles();

For better control, the C++ iterator interface can be used:

FileHandle dir = fs::open("data");
for (FileIterator it = dir.begin(); it != dir.end(); ++it)
{
    std::string path = *it;
}

For automatically traversing a directory tree, the traverse function can be called. It can be passed either

  • a callback function for each file entry
  • a callback function for each file and one for each directory
  • a visitor object
FileHandle dir = fs::open("data");

// Traverse all file entries
dir.traverse([](FileHandle & fh) -> bool {
    std::cout << fh.path() << std::endl;
    return true; // continue
});

// Traverse all files and directories
dir.traverse([](FileHandle & fh) -> bool {
    std::cout << fh.path() << std::endl;
    return true; // continue
}, [](FileHandle & dir) -> bool {
    std::cout << dir.path() << std::endl;
    return true; // continue
});

When a handle to a directory has been obtained, it can be used to open file handles relative to that directory:

FileHandle dir = fs::open("data");

// Open parent directory
FileHandle parentDir = dir.parentDirectory();

// Open file in directory
FileHandle file1 = dir.open("readme.txt");

// Open file relative to directory
FileHandle file2 = dir.open("../readme.txt");

File trees and diffs

For higher level operations on directory trees, the classes Tree, Diff, and Change can be used. A Tree contains the information about all files and directories in a tree data structure. It can be obtained from a directory handle by calling readTree.

// Read directory tree from current directory
std::unique_ptr<Tree> tree1 = dir.readTree();

// Read directory tree from current directory, giving it a virtual root
std::unique_ptr<Tree> tree2 = dir.readTree("/root");

Given two directory trees, the differences between them can be calculated, resulting in a diff object. A diff contains a number of file system operations that need to be performed in order to transform from the source tree to the destination tree. This can be utilized to implement basic file syncing:

// Open directories
FileHandle srcDir = fs::open("data1");
FileHandle dstDir = fs::open("data2");

// Read both directory trees
auto srcTree = srcDir.readTree();
auto dstTree = dstDir.readTree();

// Calculate differences
auto diff = dstTree->createDiff(*srcTree);

// Sync directories
for (Change change : diff->changes())
{
    if (change.operation() == Change::CopyFile) {
        FileHandle src = srcDir.open(change.path());
        FileHandle dst = dstDir.open(change.path());
        src.copy(dst);
    }

    if (change.operation() == Change::CopyDir) {
        FileHandle src = srcDir.open(change.path());
        FileHandle dst = dstDir.open(change.path());
        src.copyDirectoryRec(dst);
    }

    if (change.operation() == Change::RemoveFile) {
        FileHandle dst = dstDir.open(change.path());
        dst.remove();
    }

    if (change.operation() == Change::RemoveDir) {
        FileHandle dst = dstDir.open(change.path());
        dst.removeDirectoryRec();
    }
}

cppfs's People

Contributors

cgcostume avatar gabm avatar hailios avatar kwallner avatar robiwano avatar sbusch42 avatar scheibel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cppfs's Issues

Build option for enabling/disabling SSH2 and Crypto(sha1)?

Hi,
I like the project so far, but I want to propose having some preprocessor options for enabling/disabling external library usage. For me, I'm only interested in local file operations and I end up commenting out the SHA1 calls in fs.cpp and FileHandle.cpp. It also references the SSH library too. It works fine if I exclude the ssh files from the build and comment out those references, but maybe a -DUSE_SSL2 and -DUSE_CRYPTO might help future users?
Forgive me if this is not the right format for an issue, I'm new to this.

Obtain CWD/PWD

Hey!

I was looking through the source files and could, thus far, not find out if cppfs supported obtaining the current working directory. Unfortunately, there are a lot of information on how to use getcwd() on Windows - in fact, multiple versions... This is very confusing, so I hoped to find a simple method right here in cppfs, which I like a lot from what I saw so far! :)

So if a getcwd()-ish function is not implemented yet, I'd like to request it. :)

Kind regards, Ingwie.

Remove sha1 and base64 functions

Having sha1 requires dependency on OpenSSL when it is not necessary. A filesystem library should ONLY provide the basic functionality to traverse folders, and provide means to read/write to file streams. Nothing more.

Hash/base64 etc. can, and should, be provided outside the library.

Support for mingw on Windows

Hi!
Thanks for the great job you have done so far!
Can you please add support for mingw builds on Windows?
So far i'm getting this error when trying to build.

...\ThirdParty\cppfs\source\cppfs\source\windows\LocalFileHandle.cpp:341:10: error: 'CreateSymbolicLinkA' was not declared in this scope
     if (!CreateSymbolicLinkA(dst.c_str(), src.c_str(), 0))
          ^~~~~~~~~~~~~~~~~~~

Cheers :)

🍻

Build Error [-Werror-deprecated-copy]

I am getting a build error on the latest release: 1.3.0

Steps to reproduce:
mkdir build && cd build
cmake ..
make

Output:

Scanning dependencies of target gmock_main
[ 67%] Building CXX object source/tests/googletest/googlemock/CMakeFiles/gmock_main.dir/__/googletest/src/gtest-all.cc.o
[ 70%] Building CXX object source/tests/googletest/googlemock/CMakeFiles/gmock_main.dir/src/gmock-all.cc.o
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<char> >]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<char> >]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:3975:65:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<char> >::StrEqualityMatcher(const testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<char> >&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<char> >’ has user-provided ‘void testing::internal::StrEqualityMatcher<StringType>::operator=(const testing::internal::StrEqualityMatcher<StringType>&) [with StringType = std::__cxx11::basic_string<char>]’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1180:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1180 |   GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<char> >]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<char> >]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:4004:57:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<char> >::HasSubstrMatcher(const testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<char> >&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<char> >’ has user-provided ‘void testing::internal::HasSubstrMatcher<StringType>::operator=(const testing::internal::HasSubstrMatcher<StringType>&) [with StringType = std::__cxx11::basic_string<char>]’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1227:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1227 |   GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::StartsWithMatcher<std::__cxx11::basic_string<char> >]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::StartsWithMatcher<std::__cxx11::basic_string<char> >]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:4011:55:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::StartsWithMatcher<std::__cxx11::basic_string<char> >::StartsWithMatcher(const testing::internal::StartsWithMatcher<std::__cxx11::basic_string<char> >&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::StartsWithMatcher<std::__cxx11::basic_string<char> >’ has user-provided ‘void testing::internal::StartsWithMatcher<StringType>::operator=(const testing::internal::StartsWithMatcher<StringType>&) [with StringType = std::__cxx11::basic_string<char>]’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1274:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1274 |   GTEST_DISALLOW_ASSIGN_(StartsWithMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::EndsWithMatcher<std::__cxx11::basic_string<char> >]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::EndsWithMatcher<std::__cxx11::basic_string<char> >]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:4017:79:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::EndsWithMatcher<std::__cxx11::basic_string<char> >::EndsWithMatcher(const testing::internal::EndsWithMatcher<std::__cxx11::basic_string<char> >&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::EndsWithMatcher<std::__cxx11::basic_string<char> >’ has user-provided ‘void testing::internal::EndsWithMatcher<StringType>::operator=(const testing::internal::EndsWithMatcher<StringType>&) [with StringType = std::__cxx11::basic_string<char>]’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1320:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1320 |   GTEST_DISALLOW_ASSIGN_(EndsWithMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::MatchesRegexMatcher]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::MatchesRegexMatcher]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:4024:75:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::MatchesRegexMatcher::MatchesRegexMatcher(const testing::internal::MatchesRegexMatcher&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::MatchesRegexMatcher’ has user-provided ‘void testing::internal::MatchesRegexMatcher::operator=(const testing::internal::MatchesRegexMatcher&)’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1369:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1369 |   GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<wchar_t> >]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<wchar_t> >]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:4049:23:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<wchar_t> >::StrEqualityMatcher(const testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<wchar_t> >&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::StrEqualityMatcher<std::__cxx11::basic_string<wchar_t> >’ has user-provided ‘void testing::internal::StrEqualityMatcher<StringType>::operator=(const testing::internal::StrEqualityMatcher<StringType>&) [with StringType = std::__cxx11::basic_string<wchar_t>]’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1180:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1180 |   GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<wchar_t> >]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<wchar_t> >]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:4078:17:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<wchar_t> >::HasSubstrMatcher(const testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<wchar_t> >&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::HasSubstrMatcher<std::__cxx11::basic_string<wchar_t> >’ has user-provided ‘void testing::internal::HasSubstrMatcher<StringType>::operator=(const testing::internal::HasSubstrMatcher<StringType>&) [with StringType = std::__cxx11::basic_string<wchar_t>]’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1227:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1227 |   GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::StartsWithMatcher<std::__cxx11::basic_string<wchar_t> >]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::StartsWithMatcher<std::__cxx11::basic_string<wchar_t> >]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:4085:14:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::StartsWithMatcher<std::__cxx11::basic_string<wchar_t> >::StartsWithMatcher(const testing::internal::StartsWithMatcher<std::__cxx11::basic_string<wchar_t> >&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::StartsWithMatcher<std::__cxx11::basic_string<wchar_t> >’ has user-provided ‘void testing::internal::StartsWithMatcher<StringType>::operator=(const testing::internal::StartsWithMatcher<StringType>&) [with StringType = std::__cxx11::basic_string<wchar_t>]’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1274:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1274 |   GTEST_DISALLOW_ASSIGN_(StartsWithMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-spec-builders.h:75,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:61,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h: In instantiation of ‘testing::PolymorphicMatcher<Impl>::PolymorphicMatcher(const Impl&) [with Impl = testing::internal::EndsWithMatcher<std::__cxx11::basic_string<wchar_t> >]’:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:497:10:   required from ‘testing::PolymorphicMatcher<Impl> testing::MakePolymorphicMatcher(const Impl&) [with Impl = testing::internal::EndsWithMatcher<std::__cxx11::basic_string<wchar_t> >]’
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:4092:14:   required from here
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::EndsWithMatcher<std::__cxx11::basic_string<wchar_t> >::EndsWithMatcher(const testing::internal::EndsWithMatcher<std::__cxx11::basic_string<wchar_t> >&)’ is deprecated [-Werror=deprecated-copy]
  432 |   explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
      |                                                                   ^
In file included from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-linked_ptr.h:74,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-port.h:53,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h:44,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h:45,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-actions.h:46,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock.h:58,
                 from /home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/src/gmock-all.cc:40:
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googletest/include/gtest/internal/gtest-port.h:908:8: note: because ‘testing::internal::EndsWithMatcher<std::__cxx11::basic_string<wchar_t> >’ has user-provided ‘void testing::internal::EndsWithMatcher<StringType>::operator=(const testing::internal::EndsWithMatcher<StringType>&) [with StringType = std::__cxx11::basic_string<wchar_t>]’
  908 |   void operator=(type const &)
      |        ^~~~~~~~
/home/acxz/.cache/yay/cppfs/src/cppfs-1.3.0/source/tests/googletest/googlemock/include/gmock/gmock-matchers.h:1320:3: note: in expansion of macro ‘GTEST_DISALLOW_ASSIGN_’
 1320 |   GTEST_DISALLOW_ASSIGN_(EndsWithMatcher);
      |   ^~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
make[2]: *** [source/tests/googletest/googlemock/CMakeFiles/gmock_main.dir/build.make:76: source/tests/googletest/googlemock/CMakeFiles/gmock_main.dir/src/gmock-all.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:421: source/tests/googletest/googlemock/CMakeFiles/gmock_main.dir/all] Error 2
make: *** [Makefile:141: all] Error 2

OS: ArchLinux
GCC: 9.2.0

Can a new release be made with a working build? As it is right now, the ArchLinux package is breaking. Thank you. The fix also seems to be pretty quick. Either we pass the deprecated errors as warnings or we use the updated api.

No file cppfs_api.h

cppfs/source/cppfs/include/cppfs/AbstractFileSystem.h:8:10: fatal error: cppfs/cppfs_api.h:

Remove std templates from interface

I would remove std::string (and other templates) from the interface and would replace it with const char* when returning for example the file name, etc. I believe this might be problematic if one tries to link a debug library with the release version of the cppfs

provide release libs to use them directly instead of Build by users

provide release libs to use them directly instead of Build by users
so people can easily use them in their projects
c make is not such popular for most of the people coming from other languages so its hard to build the libraries so provide release build on releases page so we can use them

GoogleTest should be included as ExternalProject

Hi!

First off, thanks for providing and maintaining this library!

I noticed that GoogleTests is checked in as a part of the source and I'd like to suggest that CMake's ExternalProject feature could be used instead. It would allow cppfs to checkout and include it in the configure process. Additionally, this could become optional based on if find_package() cannot find an already installed GTest library on the host.
Please see GoogleTest readme for more information: Incorporating Into An Existing CMake Project (https://github.com/google/googletest/blob/4f4c01d8c86659f587ea0bc27c815ffa94fc9f72/googletest/README.md)

Main benefits include

  1. 3rd party code is not checked in
  2. cppfs no longer need to update GoogleTest them self.
  3. cppfs could easily point to specific git tag or branch of GoogleTest
  4. GoogleTests source is not included if OPTION_ for tests is ON
  5. If installed on host, Linking is easy as find_package(GTest WANTED_VERSION EXACT) and target_link_libraries with GTest::GTest and GTest::Main
  6. If GoogleTests is downloaded and added to the project like suggested, just call target_link_libraries with gtest and gtest_main

If this sounds reasonable I would be happy to help out by sending a PR or further instructions.

Best regards

Handling unicode paths

As far as I can see, it is not possible to use paths on Windows such as C:\Överkörd\Überförare\, maybe paths should be considered UTF-8, then convert to wchar_t* for use with std::ofstream/ifstream.

removeDirectoryRec recursively follows symlink directories and should not ?

Hi,

it looks like removeDirectoryRec follow/enter directories symlinks.. which I think should better not be by default.

the issue is that there is no option to not follow/enter directories symlink.

Could we foresee to have/add such an option flag/bool to the function signature ?

I would be happy to contribute if that would be agreed

-void removeDirectoryRec() {
+void removeDirectoryRec(bool followSymlinks=false) {

...

        if (fh.isDirectory())
        {
+          if(fh.isSymbolicLink() && !followSymlinks)
+             fh.remove();
+          else
                fh.removeDirectoryRec();
        }

Watching files doesn't work on windows?

class TestFileEventHandler : public FileEventHandler {
   public:
    virtual void onFileEvent(FileHandle& fh, FileEvent event) override { //
        LOG_DEBUG("File Event"); // Not getting called
    }
};

int main() {
    TestFileEventHandler eventHandler;
    FileWatcher watcher;
    FileHandle dir = Fs::OpenFileHandle(std::move(std::string("assets://shaders")));
    // Valid path. Expands to "C:/dev/opengl_game/out/build/x64-Debug/bin/assets/shaders"
    watcher.add(dir);
    watcher.addHandler(&eventHandler);

    while (true) {
        watcher.watch(-1);
        LOG_DEBUG("Loop");
    }

    return 0;
}

Error in testing (googletest)

...
[ 72%] Building CXX object source/tests/googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
In file included from /opt/Development/libs/cppfs/source/tests/googletest/googletest/src/gtest-all.cc:42:
/opt/Development/libs/cppfs/source/tests/googletest/googletest/src/gtest-death-test.cc: In function ‘bool testing::internal::StackGrowsDown()’:
/opt/Development/libs/cppfs/source/tests/googletest/googletest/src/gtest-death-test.cc:1301:24: error: ‘dummy’ may be used uninitialized [-Werror=maybe-uninitialized]
 1301 |   StackLowerThanAddress(&dummy, &result);
...

i've got this error in both of my linux devices [Arch/Debian].
The way I used to get around the problem was to stop all tests by typing cmake .. -DOPTION_BUILD_TESTS=OFF, and I was able to build and install the library

Incorrect path resolving for concatenated path separators.

FilePath::resolved() goes wrong when you have multiple concatenated path separators, combined with path traversal paths.

a/b//../c should be resolved to a/c. cppfs instead resolves it to a/b/c

Windows 10 and Ubuntu 20.04 both treat concatenated path separators as "one" path separator.
a/b//c////../../d is treated as a/b/c/../../d and thus is resolved to a/d.

Here is a small program to illustrate the behaviour:

#include <string>
#include <iostream>
#include <cppfs/FilePath.h>

int main(int argc, char* argv[])
{
    std::string p1 = "/usr/bin/bash";
    std::string p2 = "/usr/bin/../bin/bash";
    std::string p3 = "/usr/bin//../bin/bash";
    std::cout << "p1: " << p1 << " -> FilePath::resolved: " << cppfs::FilePath{p1}.resolved() << "\n";
    std::cout << "p2: " << p2 << " -> FilePath::resolved: " << cppfs::FilePath{p2}.resolved() << "\n";
    std::cout << "p3: " << p3 << " -> FilePath::resolved: " << cppfs::FilePath{p3}.resolved() << "\n";
    return 0;
}

Building the program against the current cppfs master results in the following output:

p1: /usr/bin/bash -> FilePath::resolved: /usr/bin/bash
p2: /usr/bin/../bin/bash -> FilePath::resolved: /usr/bin/bash
p3: /usr/bin//../bin/bash -> FilePath::resolved: /usr/bin/bin/bash

I then gave all of the paths to file:

$ file /usr/bin/bash /usr/bin/../bin/bash /usr/bin//../bin/bash /usr/bin/bin/bash
/usr/bin/bash:         ELF 64-bit LSB shared object, [...]
/usr/bin/../bin/bash:  ELF 64-bit LSB shared object, [...]
/usr/bin//../bin/bash: ELF 64-bit LSB shared object, [...]
/usr/bin/bin/bash: cannot open `/usr/bin/bin/bash' (No such file or directory)

As seen, the last path (p3 resolved by cppfs) results in a "file not found" when it should not.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.