/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2011-2018, The GROMACS development team.
+ * Copyright (c) 2019, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <sys/stat.h>
#if GMX_NATIVE_WINDOWS
-#include <Windows.h>
-#include <direct.h>
+# include <Windows.h>
+# include <direct.h>
#else
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
#endif
#include "gromacs/utility/dir_separator.h"
* Path
*/
-bool Path::containsDirectory(const std::string &path)
+bool Path::containsDirectory(const std::string& path)
{
return path.find_first_of(cDirSeparators) != std::string::npos;
}
* with "\" or "X:\" on windows. If not, the program name
* is relative to the current directory.
*/
-bool Path::isAbsolute(const char *path)
+bool Path::isAbsolute(const char* path)
{
#if GMX_NATIVE_WINDOWS
return path[0] != '\0' && path[1] == ':' && isDirSeparator(path[2]);
#endif
}
-bool Path::isAbsolute(const std::string &path)
+bool Path::isAbsolute(const std::string& path)
{
return isAbsolute(path.c_str());
}
struct handle_wrapper
{
HANDLE handle;
- handle_wrapper(HANDLE h)
- : handle(h){}
+ handle_wrapper(HANDLE h) : handle(h) {}
~handle_wrapper()
{
if (handle != INVALID_HANDLE_VALUE)
}
}
};
-}
+} // namespace
#endif
-bool Path::isEquivalent(const std::string &path1, const std::string &path2)
+bool Path::isEquivalent(const std::string& path1, const std::string& path2)
{
- //based on boost_1_56_0/libs/filesystem/src/operations.cpp under BSL
+ // based on boost_1_56_0/libs/filesystem/src/operations.cpp under BSL
#if GMX_NATIVE_WINDOWS
// Note well: Physical location on external media is part of the
// equivalence criteria. If there are no open handles, physical location
// p2 is done first, so any error reported is for p1
// FixME: #1635
- handle_wrapper h2(
- CreateFile(
- path2.c_str(),
- 0,
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- 0,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- 0));
-
- handle_wrapper h1(
- CreateFile(
- path1.c_str(),
- 0,
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- 0,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- 0));
-
- if (h1.handle == INVALID_HANDLE_VALUE
- || h2.handle == INVALID_HANDLE_VALUE)
+ handle_wrapper h2(CreateFile(path2.c_str(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
+
+ handle_wrapper h1(CreateFile(path1.c_str(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
+
+ if (h1.handle == INVALID_HANDLE_VALUE || h2.handle == INVALID_HANDLE_VALUE)
{
// if one is invalid and the other isn't, then they aren't equivalent,
// but if both are invalid then it is an error
- if (h1.handle == INVALID_HANDLE_VALUE
- && h2.handle == INVALID_HANDLE_VALUE)
+ if (h1.handle == INVALID_HANDLE_VALUE && h2.handle == INVALID_HANDLE_VALUE)
{
GMX_THROW(FileIOError("Path::isEquivalent called with two invalid files"));
}
// In theory, volume serial numbers are sufficient to distinguish between
// devices, but in practice VSN's are sometimes duplicated, so last write
// time and file size are also checked.
- return
- info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
- && info1.nFileIndexHigh == info2.nFileIndexHigh
- && info1.nFileIndexLow == info2.nFileIndexLow
- && info1.nFileSizeHigh == info2.nFileSizeHigh
- && info1.nFileSizeLow == info2.nFileSizeLow
- && info1.ftLastWriteTime.dwLowDateTime
- == info2.ftLastWriteTime.dwLowDateTime
- && info1.ftLastWriteTime.dwHighDateTime
- == info2.ftLastWriteTime.dwHighDateTime;
+ return info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
+ && info1.nFileIndexHigh == info2.nFileIndexHigh && info1.nFileIndexLow == info2.nFileIndexLow
+ && info1.nFileSizeHigh == info2.nFileSizeHigh && info1.nFileSizeLow == info2.nFileSizeLow
+ && info1.ftLastWriteTime.dwLowDateTime == info2.ftLastWriteTime.dwLowDateTime
+ && info1.ftLastWriteTime.dwHighDateTime == info2.ftLastWriteTime.dwHighDateTime;
#else
struct stat s1, s2;
int e2 = stat(path2.c_str(), &s2);
// but if both are invalid then it is an error.
if (e1 != 0 && e2 != 0)
{
- GMX_THROW_WITH_ERRNO(
- FileIOError("Path::isEquivalent called with two invalid files"),
- "stat", errno);
+ GMX_THROW_WITH_ERRNO(FileIOError("Path::isEquivalent called with two invalid files"),
+ "stat", errno);
}
return false;
}
// both stats now known to be valid
- return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino
+ return s1.st_dev == s2.st_dev
+ && s1.st_ino == s2.st_ino
// According to the POSIX stat specs, "The st_ino and st_dev fields
// taken together uniquely identify the file within the system."
// Just to be sure, size and mod time are also checked.
#endif
}
-std::string Path::join(const std::string &path1,
- const std::string &path2)
+std::string Path::join(const std::string& path1, const std::string& path2)
{
// TODO: Remove extra separators if they are present in the input paths.
return path1 + cDirSeparator + path2;
}
-std::string Path::join(const std::string &path1,
- const std::string &path2,
- const std::string &path3)
+std::string Path::join(const std::string& path1, const std::string& path2, const std::string& path3)
{
// TODO: Remove extra separators if they are present in the input paths.
return path1 + cDirSeparator + path2 + cDirSeparator + path3;
*
* \returns A view of the parent-path components, or empty if no
* directory separator exists. */
-compat::string_view getParentPathView(const std::string &input)
+compat::string_view getParentPathView(const std::string& input)
{
auto inputView = compat::to_string_view(input);
size_t pos = inputView.find_last_of(cDirSeparators);
{
return input;
}
- return input.substr(pos+1);
+ return input.substr(pos + 1);
}
/*! \brief Returns a view of the stem of the filename in \c input.
* filename component, ie. omitting any leading directories.
*
* \returns The view of the filename stem, or empty if none exists. */
-compat::string_view getStemView(const std::string &input)
+compat::string_view getStemView(const std::string& input)
{
auto filenameView = getFilenameView(input);
size_t extensionSeparatorPosition = filenameView.find_last_of('.');
return filenameView.substr(extensionSeparatorPosition);
}
-} // namespace
+} // namespace
-std::string Path::getParentPath(const std::string &input)
+std::string Path::getParentPath(const std::string& input)
{
return compat::to_string(getParentPathView(input));
}
-std::string Path::getFilename(const std::string &input)
+std::string Path::getFilename(const std::string& input)
{
return to_string(getFilenameView(input));
}
-bool Path::hasExtension(const std::string &input)
+bool Path::hasExtension(const std::string& input)
{
// This could be implemented with getStemView, but that search is
// less efficient than just finding the first of possibly multiple
return getFilenameView(input).find('.') != std::string::npos;
}
-bool Path::extensionMatches(const compat::string_view input,
- const compat::string_view extension)
+bool Path::extensionMatches(const compat::string_view input, const compat::string_view extension)
{
auto extensionWithSeparator = getExtensionView(input);
- return (!extensionWithSeparator.empty() &&
- extensionWithSeparator.substr(1) == extension);
+ return (!extensionWithSeparator.empty() && extensionWithSeparator.substr(1) == extension);
}
-std::string Path::stripExtension(const std::string &input)
+std::string Path::stripExtension(const std::string& input)
{
- auto pathView = getParentPathView(input);
+ auto pathView = getParentPathView(input);
// Make sure the returned string will have room for the directory
// separator between the parent path and the stem, but only where
// it is needed.
size_t pathLength = pathView.empty() ? 0 : pathView.length() + 1;
auto stemView = getStemView(input);
- return std::string(std::begin(input),
- std::begin(input) + pathLength + stemView.length());
+ return std::string(std::begin(input), std::begin(input) + pathLength + stemView.length());
}
-std::string Path::concatenateBeforeExtension(const std::string &input, const std::string &stringToAdd)
+std::string Path::concatenateBeforeExtension(const std::string& input, const std::string& stringToAdd)
{
std::string output = stripExtension(input);
output += stringToAdd;
- auto extensionView = getExtensionView(input);
+ auto extensionView = getExtensionView(input);
output.append(std::begin(extensionView), std::end(extensionView));
return output;
}
-std::string Path::normalize(const std::string &path)
+std::string Path::normalize(const std::string& path)
{
std::string result(path);
#if DIR_SEPARATOR != '/'
return result;
}
-const char *Path::stripSourcePrefix(const char *path)
+const char* Path::stripSourcePrefix(const char* path)
{
- const char *fallback = path;
- const char *sep = path + std::strlen(path);
+ const char* fallback = path;
+ const char* sep = path + std::strlen(path);
bool gromacsSubdirFound = false;
while (sep > path)
{
- const char *prevSep = sep - 1;
+ const char* prevSep = sep - 1;
while (prevSep >= path && !isDirSeparator(*prevSep))
{
--prevSep;
return fallback;
}
-bool Path::exists(const char *path)
+bool Path::exists(const char* path)
{
return gmx_fexist(path);
}
-bool Path::exists(const std::string &path)
+bool Path::exists(const std::string& path)
{
return exists(path.c_str());
}
return cwd;
}
-void Path::splitPathEnvironment(const std::string &pathEnv,
- std::vector<std::string> *result)
+void Path::splitPathEnvironment(const std::string& pathEnv, std::vector<std::string>* result)
{
size_t prevPos = 0;
size_t separator;
separator = pathEnv.find(cPathSeparator, prevPos);
result->push_back(pathEnv.substr(prevPos, separator - prevPos));
prevPos = separator + 1;
- }
- while (separator != std::string::npos);
+ } while (separator != std::string::npos);
}
std::vector<std::string> Path::getExecutablePaths()
// Add the local dir since it is not in the path on Windows.
result.push_back("");
#endif
- const char *path = std::getenv("PATH");
+ const char* path = std::getenv("PATH");
if (path != nullptr)
{
splitPathEnvironment(path, &result);
return result;
}
-std::string Path::resolveSymlinks(const std::string &path)
+std::string Path::resolveSymlinks(const std::string& path)
{
/* Does not fully resolve the path like realpath/boost::canonical would.
* It doesn't resolve path elements (including "." or ".."), but only
* resolves the entire path (it does that recursively). */
std::string result(path);
#if !GMX_NATIVE_WINDOWS
- char buf[GMX_PATH_MAX];
- int length;
- while ((length = readlink(result.c_str(), buf, sizeof(buf)-1)) > 0)
+ char buf[GMX_PATH_MAX];
+ int length;
+ while ((length = readlink(result.c_str(), buf, sizeof(buf) - 1)) > 0)
{
buf[length] = '\0';
if (isAbsolute(buf))
* File
*/
-void File::returnFalseOnError(const NotFoundInfo & /*info*/)
-{
-}
+void File::returnFalseOnError(const NotFoundInfo& /*info*/) {}
-void File::throwOnError(const NotFoundInfo &info)
+void File::throwOnError(const NotFoundInfo& info)
{
if (info.wasError)
{
- const std::string message
- = formatString("Failed to access file '%s'.\n%s",
- info.filename, info.message);
+ const std::string message =
+ formatString("Failed to access file '%s'.\n%s", info.filename, info.message);
GMX_THROW_WITH_ERRNO(FileIOError(message), info.call, info.err);
}
}
-void File::throwOnNotFound(const NotFoundInfo &info)
+void File::throwOnNotFound(const NotFoundInfo& info)
{
throwOnError(info);
- const std::string message
- = formatString("File '%s' does not exist or is not accessible.\n%s",
- info.filename, info.message);
+ const std::string message = formatString("File '%s' does not exist or is not accessible.\n%s",
+ info.filename, info.message);
GMX_THROW_WITH_ERRNO(InvalidInputError(message), info.call, info.err);
}
// static
-bool File::exists(const char *filename, NotFoundHandler onNotFound)
+bool File::exists(const char* filename, NotFoundHandler onNotFound)
{
if (filename == nullptr)
{
return false;
}
- FILE *test = std::fopen(filename, "r");
+ FILE* test = std::fopen(filename, "r");
if (test == nullptr)
{
const bool wasError = (errno != ENOENT && errno != ENOTDIR);
- NotFoundInfo info(filename, "The file could not be opened.",
- "fopen", wasError, errno);
+ NotFoundInfo info(filename, "The file could not be opened.", "fopen", wasError, errno);
onNotFound(info);
return false;
}
int status = stat(filename, &st_buf);
if (status != 0)
{
- NotFoundInfo info(filename, "File information could not be read.",
- "stat", true, errno);
+ NotFoundInfo info(filename, "File information could not be read.", "stat", true, errno);
onNotFound(info);
return false;
}
if (!S_ISREG(st_buf.st_mode))
{
- NotFoundInfo info(filename, "The file is not a regular file.",
- nullptr, true, 0);
+ NotFoundInfo info(filename, "The file is not a regular file.", nullptr, true, 0);
onNotFound(info);
return false;
}
}
// static
-bool File::exists(const std::string &filename, NotFoundHandler onNotFound)
+bool File::exists(const std::string& filename, NotFoundHandler onNotFound)
{
return exists(filename.c_str(), onNotFound);
}
* Directory
*/
-int Directory::create(const char *path)
+int Directory::create(const char* path)
{
if (Directory::exists(path))
{
}
-int Directory::create(const std::string &path)
+int Directory::create(const std::string& path)
{
return create(path.c_str());
}
-bool Directory::exists(const char *path)
+bool Directory::exists(const char* path)
{
struct stat info;
if (stat(path, &info) != 0)
}
-bool Directory::exists(const std::string &path)
+bool Directory::exists(const std::string& path)
{
return exists(path.c_str());
}