Skip to content

Commit

Permalink
Move filesystem namespace alias to os/fs.h, which now includes either…
Browse files Browse the repository at this point in the history
… boost/filesystem.hpp or the standard one. For now, we only switch on that in VC++ 2017 which ships the std::experimental::filesystem::v1 namespace.

Add a few adapter methods for the few routines that are called differently in boost and in std::experimental.
  • Loading branch information
codereader committed Jul 15, 2017
1 parent d08b67a commit 44ac0a4
Show file tree
Hide file tree
Showing 17 changed files with 97 additions and 71 deletions.
13 changes: 10 additions & 3 deletions libs/os/dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

/// \file
/// \brief OS directory-listing object.
#include <boost/filesystem.hpp>
#include "fs.h"
#include "itextstream.h"

#include <string>
#include <stdexcept>
#include <functional>

namespace fs = boost::filesystem;

namespace os
{

Expand Down Expand Up @@ -62,11 +61,19 @@ inline bool makeDirectory(const std::string& name)
// Directory has been created, set permissions
rConsole() << "Directory " << dirPath << " created succesfully." << std::endl;

#ifdef DR_USE_STD_FILESYSTEM
// Set permissions to rwxrwxr_x
fs::permissions(dirPath, fs::perms::add_perms |
fs::perms::owner_exec | fs::perms::owner_write | fs::perms::owner_read |
fs::perms::group_exec | fs::perms::group_write | fs::perms::group_read |
fs::perms::others_exec | fs::perms::others_read);
#else
// Set permissions to rwxrwxr_x
fs::permissions(dirPath, fs::add_perms |
fs::owner_exe | fs::owner_write | fs::owner_read |
fs::group_exe | fs::group_write | fs::group_read |
fs::others_exe | fs::others_read);
#endif
}

// Directory already exists or has been created successfully
Expand Down
14 changes: 7 additions & 7 deletions libs/os/file.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "itextstream.h"
#include <boost/filesystem/operations.hpp>
#include "fs.h"
#include "debugging/debugging.h"

/// \file
Expand Down Expand Up @@ -56,7 +56,7 @@ inline bool fileIsReadable(const std::string& path)
}

/// \brief Returns true if the file or directory identified by \p path exists and may be opened for reading.
inline bool fileIsReadable(const boost::filesystem::path& path)
inline bool fileIsReadable(const fs::path& path)
{
return detail::checkFileAccess(path.string(), detail::FileAccess::Read);
}
Expand All @@ -68,7 +68,7 @@ inline bool fileIsWritable(const std::string& path)
}

/// \brief Returns true if the file or directory identified by \p path exists and may be opened for writing.
inline bool fileIsWritable(const boost::filesystem::path& path)
inline bool fileIsWritable(const fs::path& path)
{
return detail::checkFileAccess(path.string(), detail::FileAccess::Write);
}
Expand All @@ -78,9 +78,9 @@ inline bool fileOrDirExists(const std::string& path)
{
try
{
return boost::filesystem::exists(path);
return fs::exists(path);
}
catch (boost::filesystem::filesystem_error&)
catch (fs::filesystem_error&)
{
return false;
}
Expand All @@ -91,9 +91,9 @@ inline std::size_t getFileSize(const std::string& path)
{
try
{
return static_cast<std::size_t>(boost::filesystem::file_size(path));
return static_cast<std::size_t>(fs::file_size(path));
}
catch (boost::filesystem::filesystem_error& err)
catch (fs::filesystem_error& err)
{
rError() << "Error checking filesize: " << err.what() << std::endl;
return static_cast<std::size_t>(-1);
Expand Down
79 changes: 55 additions & 24 deletions libs/os/fs.h
Original file line number Diff line number Diff line change
@@ -1,50 +1,81 @@
/**
* \file
* Helper header for boost::filesystem. Includes the relevant Boost headers,
* defines the common "fs" namespace alias, and includes some helper functions
* to deal with the transition from Filesystem V2 to V3.
* Helper header for std::filesystem feature set. Includes the relevant headers
* and defines the common "fs" namespace alias.
* If the compiler library supports the C++17 feature std::filesystem, it will
* include the corresponding headers. All other compilers will refer to the
* headers provided by boost::filesystem.
*/
#pragma once

// At the time of writing C++17 is still in draft state, but compilers
// provide the features through the std::experimental namespace.
#if _MSC_VER >= 1900

// Visual Studio 2015 onwards supplies the experimental/filesystem header
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem::v1;
#define DR_USE_STD_FILESYSTEM

#else

// All other compilers will use the boost headers
#include <boost/version.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/predicate.hpp>
#define DR_USE_BOOST_FILESYSTEM

namespace fs = boost::filesystem;

namespace os
{
/// Return the string filename of a path object
inline std::string filename_from_path(const fs::path& p)
{
#if BOOST_VERSION < 104600
return p.filename();
#else
return p.filename().string();
#endif
}

/// Return a string for the given path in platform-independent format
inline std::string string_from_path(const fs::path& p)
{
#if BOOST_VERSION < 104600
return p.string(); // in contrast to file_string() (native format)
#else
return p.generic_string(); // in this case string() is native format
#endif
}
#include <boost/algorithm/string/predicate.hpp>

namespace os
{
/// Overload of standardPathWithSlash that accepts a fs::path
inline std::string standardPathWithSlash(const fs::path& p)
{
std::string genString = string_from_path(p);
std::string genString = p.generic_string();

// Just add slash if needed, we don't need to convert intermediate
// slashes since string_from_path will already have done that.
if (!boost::algorithm::ends_with(genString, "/"))
{
genString += "/";
}

return genString;
}

// Wrapper method to return the depth of a recursive iterator,
// supporting std::experimental::filesystem as well as boost::filesystem
inline int getDepth(fs::recursive_directory_iterator& it)
{
#ifdef DR_USE_STD_FILESYSTEM
return it.depth();
#else
return it.level();
#endif
}

// Wrapper method to call no_push / disable_recursion_pending on iterators
// Since the C++17 call has been named differently than the boost one, here we go
inline void disableRecursionPending(fs::recursive_directory_iterator& it)
{
#ifdef DR_USE_STD_FILESYSTEM
it.disable_recursion_pending();
#else
it.no_push();
#endif
}

// Replaces the extension of the given filename with newExt
inline std::string replaceExtension(const std::string& input, const std::string& newExt)
{
#ifdef DR_USE_STD_FILESYSTEM
return fs::path(input).replace_extension(newExt).string();
#else
return fs::change_extension(input, newExt).string();
#endif
}
}
4 changes: 1 addition & 3 deletions plugins/particles/ParticlesManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
#include <regex>
#include <boost/algorithm/string/predicate.hpp>

namespace fs = boost::filesystem;

namespace particles
{

Expand Down Expand Up @@ -343,7 +341,7 @@ void ParticlesManager::saveParticleDef(const std::string& particleName)
fs::path tempFile = targetFile;

tempFile.remove_filename();
tempFile /= "_" + os::filename_from_path(targetFile);
tempFile /= "_" + targetFile.filename().string();

std::ofstream tempStream(tempFile.string().c_str());

Expand Down
6 changes: 2 additions & 4 deletions plugins/script/ScriptingSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@

#include <wx/frame.h>

#include "os/fs.h"
#include "os/file.h"
#include "os/path.h"
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

namespace fs = boost::filesystem;

namespace script {

ScriptingSystem::ScriptingSystem() :
Expand Down Expand Up @@ -339,7 +337,7 @@ void ScriptingSystem::reloadScripts()
if (extension != "py") continue;

// Script file found, construct a new command
loadCommandScript(os::getRelativePath(candidate.string(), _scriptPath));
loadCommandScript(os::getRelativePath(candidate.generic_string(), _scriptPath));
}

rMessage() << "ScriptModule: Found " << _commands.size() << " commands." << std::endl;
Expand Down
8 changes: 3 additions & 5 deletions plugins/vfspk3/DirectoryArchive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
#include "os/fs.h"
#include <vector>

namespace fs = boost::filesystem;

DirectoryArchive::DirectoryArchive(const std::string& root) :
_root(root)
{}
Expand Down Expand Up @@ -63,15 +61,15 @@ void DirectoryArchive::forEachFile(VisitorFunc visitor, const std::string& root)
{
// Get the candidate
const fs::path& candidate = *it;
std::string candidateStr = os::string_from_path(candidate);
std::string candidateStr = candidate.generic_string();

if (fs::is_directory(candidate))
{
// Check if we should traverse further
if (visitor.directory(candidateStr.substr(rootLen), it.level()+1))
if (visitor.directory(candidateStr.substr(rootLen), os::getDepth(it)+1))
{
// Visitor returned true, prevent going deeper into it
it.no_push();
os::disableRecursionPending(it);
}
}
else
Expand Down
2 changes: 1 addition & 1 deletion plugins/vfspk3/Doom3FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void Doom3FileSystem::initDirectory(const std::string& inputPath)
// Traverse the directory using the filename list as functor
try
{
os::foreachItemInDirectory(path, [&] (const boost::filesystem::path& file)
os::foreachItemInDirectory(path, [&] (const fs::path& file)
{
// Just insert the name, it will get sorted correctly.
filenameList.insert(file.filename().string());
Expand Down
2 changes: 1 addition & 1 deletion radiant/map/AutoSaver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void AutoMapSaver::saveSnapshot()
snapshotPath /= GlobalRegistry().get(RKEY_AUTOSAVE_SNAPSHOTS_FOLDER);

// Retrieve the mapname
std::string mapName = os::filename_from_path(fullPath.filename());
std::string mapName = fullPath.filename().string();

// Check if the folder exists and create it if necessary
if (os::fileOrDirExists(snapshotPath.string()) || os::makeDirectory(snapshotPath.string()))
Expand Down
5 changes: 2 additions & 3 deletions radiant/map/MapResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "debugging/debugging.h"
#include "os/path.h"
#include "os/file.h"
#include "os/fs.h"
#include "map/algorithm/Traverse.h"
#include "stream/textfilestream.h"
#include "scenelib.h"
Expand All @@ -37,8 +38,6 @@
#include "infofile/InfoFileExporter.h"
#include "algorithm/ChildPrimitives.h"

namespace fs = boost::filesystem;

namespace map
{

Expand Down Expand Up @@ -517,7 +516,7 @@ void MapResource::openFileStream(const std::string& path, const std::function<vo
}
}

bool MapResource::checkIsWriteable(const boost::filesystem::path& path)
bool MapResource::checkIsWriteable(const fs::path& path)
{
// Check writeability of the given file
if (os::fileOrDirExists(path.string()) && !os::fileIsWritable(path))
Expand Down
4 changes: 2 additions & 2 deletions radiant/map/MapResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "imap.h"
#include <set>
#include "RootNode.h"
#include <boost/filesystem.hpp>
#include "os/fs.h"

namespace map
{
Expand Down Expand Up @@ -72,7 +72,7 @@ class MapResource :
// function is then called with the opened stream. Throws std::runtime_error on stream open failure.
void openFileStream(const std::string& path, const std::function<void(std::istream&)>& streamProcessor);

static bool checkIsWriteable(const boost::filesystem::path& path);
static bool checkIsWriteable(const fs::path& path);
};
// Resource pointer types
typedef std::shared_ptr<MapResource> MapResourcePtr;
Expand Down
9 changes: 4 additions & 5 deletions radiant/model/ScaledModelExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
#include "igame.h"
#include "ientity.h"
#include "iscenegraph.h"
#include "os/fs.h"
#include "os/path.h"
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <regex>

namespace fs = boost::filesystem;

namespace map
{

Expand Down Expand Up @@ -181,13 +180,13 @@ void ScaledModelExporter::exportModel(const model::IModelExporterPtr& exporter,
std::string ScaledModelExporter::generateUniqueModelFilename(
const fs::path& outputPath, const fs::path& modelPath, const std::string& outputExtension)
{
std::string modelFilename = os::getFilename(modelPath.string());
std::string modelFilename = modelPath.filename().string();

// Remove any previously existing "_scaledN" suffix
std::regex expr("_scaled\\d+\\.");
modelFilename = std::regex_replace(modelFilename, expr, ".");

std::string filenameNoExt = fs::change_extension(modelFilename, "").string();
std::string filenameNoExt = os::replaceExtension(modelFilename, "");

int i = 0;

Expand All @@ -205,7 +204,7 @@ std::string ScaledModelExporter::generateUniqueModelFilename(
throw new std::runtime_error("Could not generate a unique model filename.");
}

boost::filesystem::path ScaledModelExporter::getWritableGamePath()
fs::path ScaledModelExporter::getWritableGamePath()
{
fs::path targetPath = GlobalGameManager().getModPath();

Expand Down
4 changes: 1 addition & 3 deletions radiant/model/ScaledModelExporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
#include "imodel.h"
#include "imap.h"
#include <sigc++/connection.h>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;
#include "os/fs.h"

namespace map
{
Expand Down
4 changes: 2 additions & 2 deletions radiant/modulesystem/ModuleLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace
}

// Functor operator, gets invoked on directory traversal
void ModuleLoader::processModuleFile(const boost::filesystem::path& file)
void ModuleLoader::processModuleFile(const fs::path& file)
{
// Check for the correct extension of the visited file
if (boost::algorithm::to_lower_copy(file.extension().string()) != MODULE_FILE_EXTENSION) return;
Expand Down Expand Up @@ -120,7 +120,7 @@ void ModuleLoader::loadModulesFromPath(const std::string& path)
// In case the folder is non-existent, catch the exception
try
{
os::foreachItemInDirectory(path, [&](const boost::filesystem::path& file)
os::foreachItemInDirectory(path, [&](const fs::path& file)
{
processModuleFile(file);
});
Expand Down

0 comments on commit 44ac0a4

Please sign in to comment.