common/FileUtil.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 47 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 3 deletions(-)
New commits: commit 07d5f8cf2aa2495bf803e04afff42a5da911f5b5 Author: Jan Holesovsky <[email protected]> AuthorDate: Fri Nov 8 13:42:59 2019 +0100 Commit: Jan Holesovsky <[email protected]> CommitDate: Fri Nov 8 13:56:09 2019 +0100 killpoco: Remove POCO usage from FileUtil.cpp when C++17 is available. This introduces basic C++17 support, because the functionality needed here is easy to implement using std::filesystem. Adds also the necessary checks to ./configure. The code still uses POCO when C++17 is not available in the compiler. Change-Id: I03353834d10201bf0a13ea72715560b9b9b16265 Reviewed-on: https://gerrit.libreoffice.org/82294 Reviewed-by: Jan Holesovsky <[email protected]> Tested-by: Jan Holesovsky <[email protected]> diff --git a/common/FileUtil.cpp b/common/FileUtil.cpp index fbad5f3de..1c37a7afc 100644 --- a/common/FileUtil.cpp +++ b/common/FileUtil.cpp @@ -27,7 +27,17 @@ #include <mutex> #include <string> -#include <Poco/TemporaryFile.h> +#if HAVE_STD_FILESYSTEM +# if HAVE_STD_FILESYSTEM_EXPERIMENTAL +# include <experimental/filesystem> +namespace filesystem = ::std::experimental::filesystem; +# else +# include <filesystem> +namespace filesystem = ::std::filesystem; +# endif +#else +# include <Poco/TemporaryFile.h> +#endif #include "Log.hpp" #include "Util.hpp" @@ -40,6 +50,26 @@ namespace LOG_ERR(message); Util::alertAllUsers(cmd, kind); } + +#if HAVE_STD_FILESYSTEM +/// Class to delete files when the process ends. +class FileDeleter +{ + std::vector<std::string> _filesToDelete; +public: + FileDeleter() {} + ~FileDeleter() + { + for (auto& file: _filesToDelete) + filesystem::remove(file); + } + + void registerForDeletion(const std::string& file) + { + _filesToDelete.push_back(file); + } +}; +#endif } namespace FileUtil @@ -47,7 +77,11 @@ namespace FileUtil std::string createRandomDir(const std::string& path) { const std::string name = Util::rng::getFilename(64); +#if HAVE_STD_FILESYSTEM + filesystem::create_directory(path + '/' + name); +#else Poco::File(Poco::Path(path, name)).createDirectories(); +#endif return name; } @@ -55,9 +89,18 @@ namespace FileUtil { const std::string srcPath = srcDir + '/' + srcFilename; const std::string dstFilename = dstFilenamePrefix + Util::encodeId(Util::rng::getNext()) + '_' + srcFilename; +#if HAVE_STD_FILESYSTEM + const std::string dstPath = filesystem::temp_directory_path() / dstFilename; + filesystem::copy(srcPath, dstPath); + + static FileDeleter fileDeleter; + fileDeleter.registerForDeletion(dstPath); +#else const std::string dstPath = Poco::Path(Poco::Path::temp(), dstFilename).toString(); Poco::File(srcPath).copyTo(dstPath); Poco::TemporaryFile::registerForDeletion(dstPath); +#endif + return dstPath; } @@ -121,6 +164,7 @@ namespace FileUtil } } +#if !HAVE_STD_FILESYSTEM static int nftw_cb(const char *fpath, const struct stat*, int type, struct FTW*) { if (type == FTW_DP) @@ -135,9 +179,20 @@ namespace FileUtil // Always continue even when things go wrong. return 0; } +#endif void removeFile(const std::string& path, const bool recursive) { +#if HAVE_STD_FILESYSTEM + std::error_code ec; + if (recursive) + filesystem::remove_all(path, ec); + else + filesystem::remove(path, ec); + + // Already removed or we don't care about failures. + (void) ec; +#else try { struct stat sb; @@ -156,6 +211,7 @@ namespace FileUtil { // Already removed or we don't care about failures. } +#endif } diff --git a/configure.ac b/configure.ac index 159204888..401738c67 100644 --- a/configure.ac +++ b/configure.ac @@ -506,8 +506,8 @@ fi # check for C++11 support HAVE_CXX11= -AC_MSG_CHECKING([whether $CXX supports C++14 or C++11]) -for flag in -std=gnu++14 -std=gnu++1y -std=c++14 -std=c++1y -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x ; do +AC_MSG_CHECKING([whether $CXX supports C++17, C++14 or C++11]) +for flag in -std=c++17 -std=gnu++14 -std=gnu++1y -std=c++14 -std=c++1y -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x ; do save_CXXFLAGS=$CXXFLAGS CXXFLAGS="$CXXFLAGS $flag -Werror" AC_LANG_PUSH([C++]) @@ -532,6 +532,49 @@ else AC_MSG_ERROR(no) fi +STD_FILESYSTEM= +if test "$CXXFLAGS_CXX11" = "-std=c++17" ; then + save_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS -Werror" + save_LIBS=$LIBS + LIBS="$save_LIBS -lstdc++fs" + AC_LANG_PUSH([C++]) + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + #include <experimental/filesystem> + int main() + { + if (!std::experimental::filesystem::temp_directory_path().empty()) + return 0; + return 1; + } + ]])],[STD_FILESYSTEM=experimental]) + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + #include <filesystem> + int main() + { + if (!std::filesystem::temp_directory_path().empty()) + return 0; + return 1; + } + ]])],[STD_FILESYSTEM=TRUE]) + AC_LANG_POP([C++]) + CXXFLAGS=$save_CXXFLAGS + LIBS=$save_LIBS +fi + +if test -n "$STD_FILESYSTEM" ; then + LIBS="$LIBS -lstdc++fs" + AC_DEFINE([HAVE_STD_FILESYSTEM],1,[Whether the used C++ has support for std::filesystem.]) + if test "$STD_FILESYSTEM" = "experimental" ; then + AC_DEFINE([HAVE_STD_FILESYSTEM_EXPERIMENTAL],1,[Whether the std::filesystem is in the experimental header.]) + else + AC_DEFINE([HAVE_STD_FILESYSTEM_EXPERIMENTAL],0,[Whether the std::filesystem is in the experimental header.]) + fi +else + AC_DEFINE([HAVE_STD_FILESYSTEM],0,[Whether the used C++ has support for std::filesystem.]) + AC_DEFINE([HAVE_STD_FILESYSTEM_EXPERIMENTAL],0,[Whether the std::filesystem is in the experimental header.]) +fi + AS_IF([test -n "$LOKIT_PATH"], [CPPFLAGS="$CPPFLAGS -I${LOKIT_PATH}"]) lokit_msg="$LOKIT_PATH" _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
