From 3b77493abcdc6d954faab4ab3311a936d5105b20 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Sun, 7 Oct 2018 18:30:33 +0200 Subject: [PATCH] ENH: wordRes matcher method that distinguishes literal vs. regex - useful for customizing the behaviour of white/black lists depending on the type of the match. --- applications/test/wordRe/Test-wordRe.C | 113 ++++++++++-------- .../primitives/strings/wordRes/wordRes.H | 34 ++++-- .../primitives/strings/wordRes/wordResI.H | 37 ++++++ 3 files changed, 129 insertions(+), 55 deletions(-) diff --git a/applications/test/wordRe/Test-wordRe.C b/applications/test/wordRe/Test-wordRe.C index 98c4b6ebc63..e420d4bd034 100644 --- a/applications/test/wordRe/Test-wordRe.C +++ b/applications/test/wordRe/Test-wordRe.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) 2017 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -22,6 +22,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Description + Test word/regex \*---------------------------------------------------------------------------*/ @@ -36,6 +37,16 @@ Description using namespace Foam; + +word typeOf(wordRe::compOption retval) +{ + if (wordRe::LITERAL == retval) return "(literal)"; + if (wordRe::UNKNOWN == retval) return "(unknown)"; + if (wordRe::REGEX == retval) return "(regex)"; + return ""; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: @@ -53,28 +64,30 @@ int main(int argc, char *argv[]) {"this", wordRe::LITERAL}, {"x.*", wordRe::REGEX}, {"file[a-b]", wordRe::REGEX}, + {"xvalues", wordRe::LITERAL}, + {"xv.*", wordRe::REGEX}, }; - if (true) + if (false) { - Info<<"keyType: " << keyre << endl; + Info<<"keyType: " << keyre << nl; keyType key2(std::move(keyre)); - Info<<"move construct: <" << keyre << "> <" << key2 << ">" << endl; + Info<<"move construct: <" << keyre << "> <" << key2 << ">" << nl; keyre = std::move(key2); - Info<<"move assign: <" << keyre << "> <" << key2 << ">" << endl; + Info<<"move assign: <" << keyre << "> <" << key2 << ">" << nl; keyType key3; keyre.swap(key3); - Info<<"swap: <" << keyre << "> <" << key3 << ">" << endl; + Info<<"swap: <" << keyre << "> <" << key3 << ">" << nl; keyre = std::move(key3); - Info<<"move assign: <" << keyre << "> <" << key3 << ">" << endl; + Info<<"move assign: <" << keyre << "> <" << key3 << ">" << nl; return 0; } @@ -83,86 +96,92 @@ int main(int argc, char *argv[]) { wordRe keyre("y.*", wordRe::REGEX); - Info<<"wordRe: " << keyre << endl; + Info<<"wordRe: " << keyre << nl; wordRe key2(std::move(keyre)); - Info<<"keyTypes: " << keyre << " " << key2 << endl; + Info<<"keyTypes: " << keyre << " " << key2 << nl; keyre = std::move(key2); - Info<<"keyTypes: " << keyre << " " << key2 << endl; + Info<<"keyTypes: " << keyre << " " << key2 << nl; wordRe key3; keyre.swap(key3); - Info<<"keyTypes: <" << keyre << "> <" << key3 << ">" << endl; + Info<<"keyTypes: <" << keyre << "> <" << key3 << ">" << nl; keyre = std::move(key3); - Info<<"keyTypes: <" << keyre << "> <" << key3 << ">" << endl; + Info<<"keyTypes: <" << keyre << "> <" << key3 << ">" << nl; return 0; } - wordRes wrelist(wordrelist); + wordRes wres1(wordrelist); + + Info<< "re-list:" << wres1 << nl; + Info<< "match this: " << wres1("this") << nl; + Info<< "match xyz: " << wres1("xyz") << nl; + Info<< "match zyx: " << wres1("zyx") << nl; + Info<< "match xyz: " << wres1.match("xyz") << nl; + Info<< "match any: " << predicates::always()("any junk") << nl; + + Info<< "match xvalues: " << wres1.match("xvalues") << nl; + Info<< "matched xvalues = " << typeOf(wres1.matched("xvalues")) << nl; + Info<< "matched xval = " << typeOf(wres1.matched("xval")) << nl; + Info<< "matched zyx = " << typeOf(wres1.matched("zyx")) << nl; - Info<< "re-list:" << wrelist << endl; - Info<< "match this: " << wrelist("this") << endl; - Info<< "match xyz: " << wrelist("xyz") << endl; - Info<< "match zyx: " << wrelist("zyx") << endl; - Info<< "match xyz: " << wrelist.match("xyz") << endl; - Info<< "match any: " << predicates::always()("any junk") << endl; - Info<< "keyre match: " << keyre("xyz") << endl; - Info<< "string match: " << string("this").match("xyz") << endl; - Info<< "string match: " << string("x.*")("xyz") << endl; - Info<< "string match: " << string("x.*")(keyre) << endl; + Info<< "keyre match: " << keyre("xyz") << nl; + Info<< "string match: " << string("this").match("xyz") << nl; + Info<< "string match: " << string("x.*")("xyz") << nl; + Info<< "string match: " << string("x.*")(keyre) << nl; - wordRe(s1, wordRe::DETECT).info(Info) << endl; - wordRe(s2).info(Info) << endl; - wordRe(s2, wordRe::DETECT).info(Info) << endl; - wordRe(s3, wordRe::REGEX).info(Info) << endl; + wordRe(s1, wordRe::DETECT).info(Info) << nl; + wordRe(s2).info(Info) << nl; + wordRe(s2, wordRe::DETECT).info(Info) << nl; + wordRe(s3, wordRe::REGEX).info(Info) << nl; wre = "this .* file"; - Info<<"substring: " << wre.substr(4) << endl; + Info<<"substring: " << wre.substr(4) << nl; - wre.info(Info) << endl; + wre.info(Info) << nl; wre = s1; - wre.info(Info) << endl; + wre.info(Info) << nl; wre.uncompile(); - wre.info(Info) << endl; + wre.info(Info) << nl; wre = "something"; - wre.info(Info) << " before" << endl; + wre.info(Info) << " before" << nl; wre.uncompile(); - wre.info(Info) << " uncompiled" << endl; + wre.info(Info) << " uncompiled" << nl; wre.compile(wordRe::DETECT); - wre.info(Info) << " after DETECT" << endl; + wre.info(Info) << " after DETECT" << nl; wre.compile(wordRe::ICASE); - wre.info(Info) << " after ICASE" << endl; + wre.info(Info) << " after ICASE" << nl; wre.compile(wordRe::DETECT_ICASE); - wre.info(Info) << " after DETECT_ICASE" << endl; + wre.info(Info) << " after DETECT_ICASE" << nl; wre = "something .* value"; - wre.info(Info) << " before" << endl; + wre.info(Info) << " before" << nl; wre.uncompile(); - wre.info(Info) << " uncompiled" << endl; + wre.info(Info) << " uncompiled" << nl; wre.compile(wordRe::DETECT); - wre.info(Info) << " after DETECT" << endl; + wre.info(Info) << " after DETECT" << nl; wre.uncompile(); - wre.info(Info) << " uncompiled" << endl; + wre.info(Info) << " uncompiled" << nl; wre.compile(); - wre.info(Info) << " re-compiled" << endl; + wre.info(Info) << " re-compiled" << nl; wre.set("something .* value", wordRe::LITERAL); - wre.info(Info) << " set as LITERAL" << endl; + wre.info(Info) << " set as LITERAL" << nl; IOobject::writeDivider(Info); List<Tuple2<wordRe, string>> rawList(IFstream("testRegexps")()); - Info<< "input list:" << rawList << endl; - IOobject::writeDivider(Info) << endl; + Info<< "input list:" << rawList << nl; + IOobject::writeDivider(Info) << nl; forAll(rawList, elemI) { @@ -174,7 +193,7 @@ int main(int argc, char *argv[]) << "(" << wre.match(str, true) << ")" << " match:" << wre.match(str) << " str=" << str - << endl; + << nl; wordRe wre2; wre2.set(wre, wordRe::ICASE); @@ -182,11 +201,11 @@ int main(int argc, char *argv[]) wre2.info(Info) << " match:" << wre2.match(str) << " str=" << str - << endl; + << nl; } - Info<< endl; + Info<< "\nEnd\n" << endl; return 0; } diff --git a/src/OpenFOAM/primitives/strings/wordRes/wordRes.H b/src/OpenFOAM/primitives/strings/wordRes/wordRes.H index 28cf35b9727..197823682c7 100644 --- a/src/OpenFOAM/primitives/strings/wordRes/wordRes.H +++ b/src/OpenFOAM/primitives/strings/wordRes/wordRes.H @@ -53,7 +53,7 @@ class wordRes { // Private Methods - //- Check for any match of text in list of matchers + //- Smart match as literal or regex, stopping on the first match. inline static bool found_match ( const UList<wordRe>& patterns, @@ -61,6 +61,17 @@ class wordRes bool literal=false ); + //- Smart match across entire list, returning the match type. + // Stops on the first literal match, or continues to examine + // if a regex match occurs. + // \return wordRe::LITERAL, wordRe::REGEX on match and + // wordRe::UNKNOWN otherwise. + inline static wordRe::compOption found_matched + ( + const UList<wordRe>& patterns, + const std::string& text + ); + public: @@ -111,16 +122,23 @@ public: // No filtering attempted on regular expressions. void uniq(); - //- Return true if string matches ANY of the regular expressions - // Smart match as regular expression or as a string. - // Optionally force a literal match only - inline bool match(const std::string& text, bool literal=false) const; + //- Smart match as literal or regex, stopping on the first match. + // + // \param literal Force literal match only. + // \return True if text matches ANY of the entries. + inline bool match(const std::string& text, bool literal = false) const; + + //- Smart match in the list of matchers, returning the match type. + // It stops if there is a literal match, or continues to examine + // other regexs. + // \return LITERAL if a lteral match was found, REGEX if a regex + // match was found and UNKNOWN otherwise. + inline wordRe::compOption matched(const std::string& text) const; - // Member operators + // Member Operators - //- Perform smart match on text, as per match() - // Allows use as a predicate. + //- Identical to match(), for use as a predicate. inline bool operator()(const std::string& text) const; }; diff --git a/src/OpenFOAM/primitives/strings/wordRes/wordResI.H b/src/OpenFOAM/primitives/strings/wordRes/wordResI.H index ab602ee1f8e..65cbe2fe465 100644 --- a/src/OpenFOAM/primitives/strings/wordRes/wordResI.H +++ b/src/OpenFOAM/primitives/strings/wordRes/wordResI.H @@ -50,6 +50,36 @@ inline bool Foam::wordRes::found_match } +inline Foam::wordRe::compOption Foam::wordRes::found_matched +( + const UList<wordRe>& patterns, + const std::string& text +) +{ + auto retval(wordRe::compOption::UNKNOWN); + + for (const wordRe& select : patterns) + { + if (select.isLiteral()) + { + if (select.match(text, true)) + { + return wordRe::compOption::LITERAL; + } + } + else if (wordRe::compOption::UNKNOWN == retval) + { + if (select.match(text, false)) + { + retval = wordRe::compOption::REGEX; + } + } + } + + return retval; +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // inline bool Foam::wordRes::match(const std::string& text, bool literal) const @@ -58,6 +88,13 @@ inline bool Foam::wordRes::match(const std::string& text, bool literal) const } +inline Foam::wordRe::compOption +Foam::wordRes::matched(const std::string& text) const +{ + return found_matched(*this, text); +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::wordRes::operator()(const std::string& text) const -- GitLab