diff --git a/src/OpenFOAM/db/IOobject/IOobject.C b/src/OpenFOAM/db/IOobject/IOobject.C index 9fa9499c63..60734683a4 100644 --- a/src/OpenFOAM/db/IOobject/IOobject.C +++ b/src/OpenFOAM/db/IOobject/IOobject.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -95,6 +95,17 @@ namespace Foam } +// file-scope +// +// A file is 'outside' of the case if it has been specified using an +// absolute path (starts with '/') +// +static inline bool isOutsideOfCase(const std::string& file) +{ + return !file.empty() && file[0] == '/'; +} + + // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * // // Return components following the IOobject requirements @@ -104,10 +115,10 @@ namespace Foam // ----- ------ // "foo" ("", "", "foo") // "foo/bar" ("foo", "", "bar") -// "/XXX/bar" ("/XXX", "", "bar") // "foo/bar/" ERROR - no name // "foo/xxx/bar" ("foo", "xxx", "bar") // "foo/xxx/yyy/bar" ("foo", "xxx/yyy", "bar") +// "/xxx/yyy/bar" ("/xxx/yyy", "", "bar") bool Foam::IOobject::fileNameComponents ( const fileName& path, @@ -120,7 +131,7 @@ bool Foam::IOobject::fileNameComponents local.clear(); name.clear(); - // called with directory + // Called with directory if (isDir(path)) { WarningInFunction @@ -129,44 +140,49 @@ bool Foam::IOobject::fileNameComponents return false; } - if (path.isAbsolute()) + const auto first = path.find('/'); + const auto last = path.rfind('/'); + + // The raw length of name (without validating for word chars) + auto nameLen = path.size(); + + if (first == std::string::npos) { - string::size_type last = path.rfind('/'); + // No '/' found (or empty entirely) + // => no instance or local + + name = word::validated(path, false); + } + else if (first == 0) + { + // Absolute path (starts with '/') + // => no local + instance = path.substr(0, last); - // Check afterwards - name.string::operator=(path.substr(last+1)); + const std::string ending = path.substr(last+1); + nameLen = ending.size(); // The raw length of name + name = word::validated(ending, false); } else { - string::size_type first = path.find('/'); + // Normal case. + // First part is instance, remainder is local + instance = path.substr(0, first); - if (first == string::npos) + if (last > first) { - // no '/' found - no instance or local - - // check afterwards - name.string::operator=(path); + // With local + local = path.substr(first+1, last-first-1); } - else - { - instance = path.substr(0, first); - string::size_type last = path.rfind('/'); - if (last > first) - { - // with local - local = path.substr(first+1, last-first-1); - } - - // check afterwards - name.string::operator=(path.substr(last+1)); - } + const std::string ending = path.substr(last+1); + nameLen = ending.size(); // The raw length of name + name = word::validated(ending, false); } - // Check for valid (and stripped) name, regardless of the debug level - if (name.empty() || string::stripInvalid(name)) + if (!nameLen || nameLen != name.size()) { WarningInFunction << "has invalid word for name: \"" << name @@ -360,24 +376,24 @@ const Foam::fileName& Foam::IOobject::caseName() const Foam::word Foam::IOobject::group() const { - word::size_type i = name_.find_last_of('.'); + const auto i = name_.rfind('.'); - if (i == word::npos || i == 0) + if (i == std::string::npos || i == 0) { return word::null; } else { - return name_.substr(i+1, word::npos); + return name_.substr(i+1); } } Foam::word Foam::IOobject::member() const { - word::size_type i = name_.find_last_of('.'); + const auto i = name_.rfind('.'); - if (i == word::npos || i == 0) + if (i == std::string::npos || i == 0) { return name_; } @@ -390,7 +406,7 @@ Foam::word Foam::IOobject::member() const Foam::fileName Foam::IOobject::path() const { - if (instance().isAbsolute()) + if (isOutsideOfCase(instance())) { return instance(); } @@ -414,9 +430,9 @@ Foam::fileName Foam::IOobject::path Foam::fileName Foam::IOobject::localFilePath(const bool search) const { - if (instance().isAbsolute()) + if (isOutsideOfCase(instance())) { - fileName objectPath = instance()/name(); + const fileName objectPath = instance()/name(); if (isFile(objectPath)) { @@ -429,8 +445,8 @@ Foam::fileName Foam::IOobject::localFilePath(const bool search) const } else { - fileName path = this->path(); - fileName objectPath = path/name(); + const fileName path = this->path(); + const fileName objectPath = path/name(); if (isFile(objectPath)) { @@ -440,14 +456,14 @@ Foam::fileName Foam::IOobject::localFilePath(const bool search) const { if (!isDir(path) && search) { - word newInstancePath = time().findInstancePath + const word newInstancePath = time().findInstancePath ( instant(instance()) ); if (newInstancePath.size()) { - fileName fName + const fileName fName ( rootPath()/caseName() /newInstancePath/db_.dbDir()/local()/name() @@ -468,9 +484,9 @@ Foam::fileName Foam::IOobject::localFilePath(const bool search) const Foam::fileName Foam::IOobject::globalFilePath(const bool search) const { - if (instance().isAbsolute()) + if (isOutsideOfCase(instance())) { - fileName objectPath = instance()/name(); + const fileName objectPath = instance()/name(); if (isFile(objectPath)) { if (objectRegistry::debug) @@ -492,8 +508,8 @@ Foam::fileName Foam::IOobject::globalFilePath(const bool search) const } else { - fileName path = this->path(); - fileName objectPath = path/name(); + const fileName path = this->path(); + const fileName objectPath = path/name(); if (isFile(objectPath)) { @@ -516,7 +532,7 @@ Foam::fileName Foam::IOobject::globalFilePath(const bool search) const { // Constant & system can come from global case - fileName parentObjectPath = + const fileName parentObjectPath = rootPath()/time().globalCaseName() /instance()/db().dbDir()/local()/name(); @@ -534,14 +550,14 @@ Foam::fileName Foam::IOobject::globalFilePath(const bool search) const // Check for approximately same (local) time if (!isDir(path) && search) { - word newInstancePath = time().findInstancePath + const word newInstancePath = time().findInstancePath ( instant(instance()) ); if (newInstancePath.size()) { - fileName fName + const fileName fName ( rootPath()/caseName() /newInstancePath/db().dbDir()/local()/name() @@ -586,10 +602,8 @@ Foam::Istream* Foam::IOobject::objectStream(const fileName& fName) return nullptr; } } - else - { - return nullptr; - } + + return nullptr; }