[Libreoffice-commits] online.git: common/FileUtil.cpp configure.ac

Jan Holesovsky (via logerrit) logerrit at kemper.freedesktop.org
Fri Nov 8 12:56:28 UTC 2019


 common/FileUtil.cpp |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 configure.ac        |   47 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 102 insertions(+), 3 deletions(-)

New commits:
commit 07d5f8cf2aa2495bf803e04afff42a5da911f5b5
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Fri Nov 8 13:42:59 2019 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
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 <kendy at collabora.com>
    Tested-by: Jan Holesovsky <kendy at collabora.com>

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"


More information about the Libreoffice-commits mailing list