diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/poco/Foundation/src/Glob.cpp | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/poco/Foundation/src/Glob.cpp')
-rw-r--r-- | contrib/libs/poco/Foundation/src/Glob.cpp | 568 |
1 files changed, 284 insertions, 284 deletions
diff --git a/contrib/libs/poco/Foundation/src/Glob.cpp b/contrib/libs/poco/Foundation/src/Glob.cpp index 4ca64debc9..14d24e0649 100644 --- a/contrib/libs/poco/Foundation/src/Glob.cpp +++ b/contrib/libs/poco/Foundation/src/Glob.cpp @@ -1,285 +1,285 @@ -// -// Glob.cpp -// -// Library: Foundation -// Package: Filesystem -// Module: Glob -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// SPDX-License-Identifier: BSL-1.0 -// - - -#include "Poco/Glob.h" -#include "Poco/Path.h" -#include "Poco/Exception.h" -#include "Poco/DirectoryIterator.h" -#include "Poco/File.h" -#include "Poco/UTF8Encoding.h" -#include "Poco/Unicode.h" - - -namespace Poco { - - -Glob::Glob(const std::string& pattern, int options) - : _pattern(pattern), _options(options) -{ -} - - -Glob::~Glob() -{ -} - - -bool Glob::match(const std::string& subject) -{ - UTF8Encoding utf8; - TextIterator itp(_pattern, utf8); - TextIterator endp(_pattern); - TextIterator its(subject, utf8); - TextIterator ends(subject); - - if ((_options & GLOB_DOT_SPECIAL) && its != ends && *its == '.' && (*itp == '?' || *itp == '*')) - return false; - else - return match(itp, endp, its, ends); -} - - -void Glob::glob(const std::string& pathPattern, std::set<std::string>& files, int options) -{ - glob(Path(Path::expand(pathPattern), Path::PATH_GUESS), files, options); -} - - -void Glob::glob(const char* pathPattern, std::set<std::string>& files, int options) -{ - glob(Path(Path::expand(pathPattern), Path::PATH_GUESS), files, options); -} - - -void Glob::glob(const Path& pathPattern, std::set<std::string>& files, int options) -{ - Path pattern(pathPattern); - pattern.makeDirectory(); // to simplify pattern handling later on - Path base(pattern); - Path absBase(base); - absBase.makeAbsolute(); - // In case of UNC paths we must not pop the topmost directory - // (which must not contain wildcards), otherwise collect() will fail - // as one cannot create a DirectoryIterator with only a node name ("\\srv\"). - int minDepth = base.getNode().empty() ? 0 : 1; - while (base.depth() > minDepth && base[base.depth() - 1] != "..") - { - base.popDirectory(); - absBase.popDirectory(); - } - if (pathPattern.isDirectory()) - options |= GLOB_DIRS_ONLY; - collect(pattern, absBase, base, pathPattern[base.depth()], files, options); -} - - -void Glob::glob(const Path& pathPattern, const Path& basePath, std::set<std::string>& files, int options) -{ - Path pattern(pathPattern); - pattern.makeDirectory(); // to simplify pattern handling later on - Path absBase(basePath); - absBase.makeAbsolute(); - if (pathPattern.isDirectory()) - options |= GLOB_DIRS_ONLY; - collect(pattern, absBase, basePath, pathPattern[basePath.depth()], files, options); -} - - -bool Glob::match(TextIterator& itp, const TextIterator& endp, TextIterator& its, const TextIterator& ends) -{ - while (itp != endp) - { - if (its == ends) - { - while (itp != endp && *itp == '*') ++itp; - break; - } - switch (*itp) - { - case '?': - ++itp; ++its; - break; - case '*': - if (++itp != endp) - { - while (its != ends && !matchAfterAsterisk(itp, endp, its, ends)) ++its; - return its != ends; - } - return true; - case '[': +// +// Glob.cpp +// +// Library: Foundation +// Package: Filesystem +// Module: Glob +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Glob.h" +#include "Poco/Path.h" +#include "Poco/Exception.h" +#include "Poco/DirectoryIterator.h" +#include "Poco/File.h" +#include "Poco/UTF8Encoding.h" +#include "Poco/Unicode.h" + + +namespace Poco { + + +Glob::Glob(const std::string& pattern, int options) + : _pattern(pattern), _options(options) +{ +} + + +Glob::~Glob() +{ +} + + +bool Glob::match(const std::string& subject) +{ + UTF8Encoding utf8; + TextIterator itp(_pattern, utf8); + TextIterator endp(_pattern); + TextIterator its(subject, utf8); + TextIterator ends(subject); + + if ((_options & GLOB_DOT_SPECIAL) && its != ends && *its == '.' && (*itp == '?' || *itp == '*')) + return false; + else + return match(itp, endp, its, ends); +} + + +void Glob::glob(const std::string& pathPattern, std::set<std::string>& files, int options) +{ + glob(Path(Path::expand(pathPattern), Path::PATH_GUESS), files, options); +} + + +void Glob::glob(const char* pathPattern, std::set<std::string>& files, int options) +{ + glob(Path(Path::expand(pathPattern), Path::PATH_GUESS), files, options); +} + + +void Glob::glob(const Path& pathPattern, std::set<std::string>& files, int options) +{ + Path pattern(pathPattern); + pattern.makeDirectory(); // to simplify pattern handling later on + Path base(pattern); + Path absBase(base); + absBase.makeAbsolute(); + // In case of UNC paths we must not pop the topmost directory + // (which must not contain wildcards), otherwise collect() will fail + // as one cannot create a DirectoryIterator with only a node name ("\\srv\"). + int minDepth = base.getNode().empty() ? 0 : 1; + while (base.depth() > minDepth && base[base.depth() - 1] != "..") + { + base.popDirectory(); + absBase.popDirectory(); + } + if (pathPattern.isDirectory()) + options |= GLOB_DIRS_ONLY; + collect(pattern, absBase, base, pathPattern[base.depth()], files, options); +} + + +void Glob::glob(const Path& pathPattern, const Path& basePath, std::set<std::string>& files, int options) +{ + Path pattern(pathPattern); + pattern.makeDirectory(); // to simplify pattern handling later on + Path absBase(basePath); + absBase.makeAbsolute(); + if (pathPattern.isDirectory()) + options |= GLOB_DIRS_ONLY; + collect(pattern, absBase, basePath, pathPattern[basePath.depth()], files, options); +} + + +bool Glob::match(TextIterator& itp, const TextIterator& endp, TextIterator& its, const TextIterator& ends) +{ + while (itp != endp) + { + if (its == ends) + { + while (itp != endp && *itp == '*') ++itp; + break; + } + switch (*itp) + { + case '?': + ++itp; ++its; + break; + case '*': if (++itp != endp) - { - bool invert = *itp == '!'; - if (invert) ++itp; - if (itp != endp) - { - bool mtch = matchSet(itp, endp, *its++); - if ((invert && mtch) || (!invert && !mtch)) return false; - break; - } - } - throw SyntaxException("bad range syntax in glob pattern"); - case '\\': - if (++itp == endp) throw SyntaxException("backslash must be followed by character in glob pattern"); - // fallthrough - default: - if (_options & GLOB_CASELESS) - { - if (Unicode::toLower(*itp) != Unicode::toLower(*its)) return false; - } - else - { - if (*itp != *its) return false; - } - ++itp; ++its; - } - } - return itp == endp && its == ends; -} - - -bool Glob::matchAfterAsterisk(TextIterator itp, const TextIterator& endp, TextIterator its, const TextIterator& ends) -{ - return match(itp, endp, its, ends); -} - - -bool Glob::matchSet(TextIterator& itp, const TextIterator& endp, int c) -{ - if (_options & GLOB_CASELESS) - c = Unicode::toLower(c); - - while (itp != endp) - { - switch (*itp) - { - case ']': - ++itp; - return false; - case '\\': - if (++itp == endp) throw SyntaxException("backslash must be followed by character in glob pattern"); - } - int first = *itp; - int last = first; - if (++itp != endp && *itp == '-') - { - if (++itp != endp) - last = *itp++; - else - throw SyntaxException("bad range syntax in glob pattern"); - } - if (_options & GLOB_CASELESS) - { - first = Unicode::toLower(first); - last = Unicode::toLower(last); - } - if (first <= c && c <= last) - { - while (itp != endp) - { - switch (*itp) - { - case ']': - ++itp; - return true; - case '\\': - if (++itp == endp) break; - default: - ++itp; - } - } - throw SyntaxException("range must be terminated by closing bracket in glob pattern"); - } - } - return false; -} - - -void Glob::collect(const Path& pathPattern, const Path& base, const Path& current, const std::string& pattern, std::set<std::string>& files, int options) -{ - try - { - std::string pp = pathPattern.toString(); - std::string basep = base.toString(); - std::string curp = current.toString(); - Glob g(pattern, options); - DirectoryIterator it(base); - DirectoryIterator end; - while (it != end) - { - const std::string& name = it.name(); - if (g.match(name)) - { - Path p(current); - if (p.depth() < pathPattern.depth() - 1) - { - p.pushDirectory(name); - collect(pathPattern, it.path(), p, pathPattern[p.depth()], files, options); - } - else - { - p.setFileName(name); - if (isDirectory(p, (options & GLOB_FOLLOW_SYMLINKS) != 0)) - { - p.makeDirectory(); - files.insert(p.toString()); - } - else if (!(options & GLOB_DIRS_ONLY)) - { - files.insert(p.toString()); - } - } - } - ++it; - } - } - catch (Exception&) - { - } -} - - -bool Glob::isDirectory(const Path& path, bool followSymlink) -{ - File f(path); - bool isDir = false; - try - { - isDir = f.isDirectory(); - } - catch (Poco::Exception&) - { - return false; - } - if (isDir) - { - return true; - } - else if (followSymlink && f.isLink()) - { - try - { - // Test if link resolves to a directory. - DirectoryIterator it(f); - return true; - } - catch (Exception&) - { - } - } - return false; -} - - -} // namespace Poco + { + while (its != ends && !matchAfterAsterisk(itp, endp, its, ends)) ++its; + return its != ends; + } + return true; + case '[': + if (++itp != endp) + { + bool invert = *itp == '!'; + if (invert) ++itp; + if (itp != endp) + { + bool mtch = matchSet(itp, endp, *its++); + if ((invert && mtch) || (!invert && !mtch)) return false; + break; + } + } + throw SyntaxException("bad range syntax in glob pattern"); + case '\\': + if (++itp == endp) throw SyntaxException("backslash must be followed by character in glob pattern"); + // fallthrough + default: + if (_options & GLOB_CASELESS) + { + if (Unicode::toLower(*itp) != Unicode::toLower(*its)) return false; + } + else + { + if (*itp != *its) return false; + } + ++itp; ++its; + } + } + return itp == endp && its == ends; +} + + +bool Glob::matchAfterAsterisk(TextIterator itp, const TextIterator& endp, TextIterator its, const TextIterator& ends) +{ + return match(itp, endp, its, ends); +} + + +bool Glob::matchSet(TextIterator& itp, const TextIterator& endp, int c) +{ + if (_options & GLOB_CASELESS) + c = Unicode::toLower(c); + + while (itp != endp) + { + switch (*itp) + { + case ']': + ++itp; + return false; + case '\\': + if (++itp == endp) throw SyntaxException("backslash must be followed by character in glob pattern"); + } + int first = *itp; + int last = first; + if (++itp != endp && *itp == '-') + { + if (++itp != endp) + last = *itp++; + else + throw SyntaxException("bad range syntax in glob pattern"); + } + if (_options & GLOB_CASELESS) + { + first = Unicode::toLower(first); + last = Unicode::toLower(last); + } + if (first <= c && c <= last) + { + while (itp != endp) + { + switch (*itp) + { + case ']': + ++itp; + return true; + case '\\': + if (++itp == endp) break; + default: + ++itp; + } + } + throw SyntaxException("range must be terminated by closing bracket in glob pattern"); + } + } + return false; +} + + +void Glob::collect(const Path& pathPattern, const Path& base, const Path& current, const std::string& pattern, std::set<std::string>& files, int options) +{ + try + { + std::string pp = pathPattern.toString(); + std::string basep = base.toString(); + std::string curp = current.toString(); + Glob g(pattern, options); + DirectoryIterator it(base); + DirectoryIterator end; + while (it != end) + { + const std::string& name = it.name(); + if (g.match(name)) + { + Path p(current); + if (p.depth() < pathPattern.depth() - 1) + { + p.pushDirectory(name); + collect(pathPattern, it.path(), p, pathPattern[p.depth()], files, options); + } + else + { + p.setFileName(name); + if (isDirectory(p, (options & GLOB_FOLLOW_SYMLINKS) != 0)) + { + p.makeDirectory(); + files.insert(p.toString()); + } + else if (!(options & GLOB_DIRS_ONLY)) + { + files.insert(p.toString()); + } + } + } + ++it; + } + } + catch (Exception&) + { + } +} + + +bool Glob::isDirectory(const Path& path, bool followSymlink) +{ + File f(path); + bool isDir = false; + try + { + isDir = f.isDirectory(); + } + catch (Poco::Exception&) + { + return false; + } + if (isDir) + { + return true; + } + else if (followSymlink && f.isLink()) + { + try + { + // Test if link resolves to a directory. + DirectoryIterator it(f); + return true; + } + catch (Exception&) + { + } + } + return false; +} + + +} // namespace Poco |