openfoam/applications/test/string/Test-string.C
Mark Olesen e623e6a865 STYLE: favour include word.H instead of string.H
- in many places the string.H include is redundant anyhow.
  May wish to change to foamString.H (or equiv) in the future
2023-02-27 15:41:25 +01:00

444 lines
13 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Test some string functionality
\*---------------------------------------------------------------------------*/
#include "fieldExprFwd.H"
#include "int.H"
#include "uint.H"
#include "scalar.H"
#include "Switch.H"
#include "fileName.H"
#include "stringList.H"
#include "stringOps.H"
#include "dictionary.H"
#include "IOstreams.H"
#include "OSspecific.H"
using namespace Foam;
void testCommentStripping(const std::string& s)
{
Info<< "input" << nl
<< "========" << nl
<< s << nl
<< "========" << nl;
Info<< "output" << nl
<< "========" << nl
<< stringOps::removeComments(s) << nl
<< "========" << nl << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
string test
(
" $HOME kjhkjhkjh \" \\$HOME/tyetyery $; ${FOAM_RUN} \n $; hkjh;"
" $(DONOTSUBST) some other <${USER}> with '${__UNKNOWN:-some default}'"
" value "
" or with '${HOME:+Home was set}' via :+ alternative"
" or with '${__UNKNOWN:+unknown}' empty "
);
setEnv("FOAM_CASE", cwd(), true);
dictionary dict;
dict.add("HOME", "myHome");
dictionary subDict;
subDict.add("value1", "test1");
subDict.add("value2", "test2");
dict.add("FOAM_RUN", subDict);
if (false)
{
typedef std::string inputType;
typedef string outputType;
inputType in1("move-construct-from");
Info<<"move construct from " << in1.length() << nl;
outputType out1(std::move(in1));
Info<<"after move construct "
<< out1.size() << ", " << in1.size() << nl;
in1 = "move-assign-from";
out1 = "some-text-rubbish";
out1.resize(10);
Info<<"move assign from " << in1.length() << nl;
out1 = std::move(in1);
Info<<"after move assign "
<< out1.size() << ", " << in1.size() << nl;
return 0;
}
// basic expansions
{
for
(
const auto& cstr
:
{
"~OpenFOAM/controlDict", "<etc>/controlDict",
"<etc:ugo>/controlDict",
"<etc:u>/controlDict",
"<etc:ug>/controlDict",
"<etc:go>/controlDict",
"<etc:o>/controlDict",
"<etc:JUNK>/controlDict", // rubbish input
"<etc:>/controlDict", // rubbish input
"$FOAM_CASE/xyz", "<case>/xyz",
"$FOAM_CASE/constant/xyz", "<constant>/xyz",
"$FOAM_CASE/system/xyz", "<system>/xyz",
// corner cases
"~OpenFOAM", "<etc>",
"~OpenFOAM/", "<etc>/",
"$FOAM_CASE", "<case>",
"$FOAM_CASE/constant", "<constant>",
"$FOAM_CASE/system", "<system>",
"$FOAM_CASE/", "<case>/",
"$FOAM_CASE/constant/", "<constant>/",
"$FOAM_CASE/system/", "<system>/",
}
)
{
string input(cstr);
string output(stringOps::expand(input));
Info<< "input: " << input << nl
<< "expand: " << output << nl
<< "split: " << stringOps::split(output, "/") << nl << nl;
}
}
// Test Foam::name with formatting string
{
word formatted = word::printf("formatted=<%X>", 0xdeadbeef);
Info<<"formatted: " << formatted << nl;
}
Info<<"formatted: "
<< word::printf("formatted not checked for validity=<%X>", 0xdeadbeef)
<< nl
<< endl;
Info<< "string:" << test << nl << "hash:"
<< unsigned(string::hasher()(test)) << endl;
Info<<"trimLeft: " << stringOps::trimLeft(test) << endl;
Info<<"trimRight: " << stringOps::trimRight(test) << endl;
Info<<"trim: " << stringOps::trim(test) << endl;
// With replace, replaceAll
{
string test2(test);
Info<<"replaceAny: (\"abcj\", '?')" << nl
<< test2.replaceAny("abcj", '?') << endl;
Info<<"replaceAll: (\"k\", \"?\")" << nl
<< test2.replaceAll("k", "?") << endl;
Info<<"replaceAll: (\"h\", null) - ie, remove them" << nl
<< test2.replaceAll("h", "") << endl;
Info<<"replaceAny: (\"it${}?\", null) - ie, remove them" << nl
<< test2.replaceAny("it${}?", '\0') << endl;
}
if (false)
{
Info<<"test move construct - string size:" << test.size() << nl;
string test2(std::move(test));
Info<<"input size:" << test.size() << nl;
Info<<"moved size:" << test2.size() << nl;
Info<<"test move assign - string sizes:"
<< test.size() << "/" << test2.size() << nl;
test = std::move(test2);
Info<<"input size:" << test.size() << nl;
Info<<"moved size:" << test2.size() << nl;
}
if (false)
{
std::string str("some text");
Info<<"test move construct to string:" << str.size() << nl;
Foam::string test2(std::move(str));
Info<<"input/moved sizes:" << str.size() << "/" << test2.size() << nl;
str = std::move(test2);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
}
if (false)
{
Foam::string str("thisIsAWord");
Info<<"test move construct to word:" << str.size() << nl;
word test2(std::move(str));
Info<<"input/moved sizes:" << str.size() << "/" << test2.size() << nl;
str = std::move(test2);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
// move back
test2.swap(str);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
string str2(std::move(test2));
Info<<"input/moved sizes:" << test2.size() << "/" << str2.size() << nl;
}
{
fileName test1("libFooBar.so");
Info<< nl;
Info<< "trim filename: " << test1 << nl;
test1.removeStart("lib");
Info<<"without leading 'lib': " << test1 << nl;
}
Info<< nl;
Info<<"camel-case => " << (word("camel") & "case") << nl;
for (const auto& s : { " text with \"spaces'", "08/15 value" })
{
// Character sequence
Info<<"validated 5 chars from \" => "
<< word::validate(s, s+5, true) << nl;
Info<<"validated (via string convert) \"" << s << "\" => "
<< word::validate(s, true) << nl;
}
Info<< nl;
// test sub-strings via iterators
string::const_iterator iter = test.end();
string::const_iterator iter2 = test.end();
string::size_type fnd = test.find('\\');
if (fnd != string::npos)
{
iter = test.begin() + fnd;
iter2 = iter + 6;
}
Info<< "sub-string via iterators : >";
while (iter != iter2)
{
Info<< *iter;
++iter;
}
Info<< "<\n";
Info<< string(test).replace("kj", "zzz") << endl;
Info<< string(test).replace("kj", "") << endl;
Info<< string(test).replaceAll("kj", "zzz") << endl;
Info<< string(test).replaceAll("kj", "z") << endl;
Info<< "expanded: " << string(test).expand() << endl;
Info<<"dictionary-based substitution: " << dict << endl;
Info<< "expand dict: " << stringOps::expand(test, dict) << endl;
string test2("~OpenFOAM/controlDict");
Info<< test2 << " => " << test2.expand() << endl;
// replace controlDict with "newName"
{
string::size_type i = test2.rfind('/');
if (i == string::npos)
{
test2 = "newName";
}
else
{
// this uses the std::string::replace
test2.replace(i+1, string::npos, "newName");
}
Info<< "after replace: " << test2 << endl;
// do another replace
// this uses the Foam::string::replace
test2.replace("OpenFOAM", "openfoam");
Info<< "after replace: " << test2 << endl;
}
cout<< "\nEnter some string to test:\n";
string s;
Sin.getLine(s);
string s2(s.expand());
cout<< "output string with " << s2.length() << " characters\n";
cout<< "ostream<< >" << s2 << "<\n";
Info<< "Ostream<< >" << s2 << "<\n";
Info<< "hash:" << hex << string::hasher()(s2) << dec << endl;
cout<< "\ntest Foam::name()\n";
Info<< "hash: = " << word::printf("0x%012X", string::hasher()(s2)) << endl;
// Test formatting on int
{
label val = 25;
Info<< "int " << val << " nameOp='"
<< nameOp<label>()(val) << "', name='"
<< Foam::name(val) << "' or "
<< word::printf("formatted '%08d'", val) << "\n";
}
// Test formatting on scalar
{
scalar val = 3.1415926535897931;
Info<< "scalar " << val << " nameOp='"
<< nameOp<scalar>()(val) << "', name='"
<< Foam::name(val) << "' or "
<< word::printf("formatted '%.9f'", val) << "\n";
}
// Test formatting on uint
{
uint64_t val = 25000000ul;
Info<< "uint64 " << val << " nameOp='"
<< nameOp<uint64_t>()(val) << "', name='"
<< Foam::name(val) << "' or "
<< word::printf("formatted '%08d'", val) << "\n";
}
// test starts_with, ends_with methods
{
string empty; //;
string input1 = "shorter input";
string input2 = "longer input text";
stringList checks{"match", "long", "", "short", "text", "s", "l", "t"};
Info<< nl;
Info<< "check starts_with:" << nl
<< "~~~~~~~~~~~~~~~~~" << nl;
Info<<"input: " << empty << nl;
for (const string& test : checks)
{
Info<< " starts_with(" << test << ") = "
<< Switch(empty.starts_with(test)) << nl;
}
Info<<"input: " << input1 << nl;
for (const string& test : checks)
{
Info<< " starts_with(" << test << ") = "
<< Switch(input1.starts_with(test)) << nl;
}
Info<<"input: " << input2 << nl;
for (const string& test : checks)
{
Info<< " starts_with(" << test << ") = "
<< Switch(input2.starts_with(test)) << nl;
}
Info<< nl;
Info<< "check ends_with:" << nl
<< "~~~~~~~~~~~~~~~~~" << nl;
Info<<"input: " << empty << nl;
for (const string& test : checks)
{
Info<< " ends_with(" << test << ") = "
<< Switch(empty.ends_with(test)) << nl;
}
Info<<"input: " << input1 << nl;
for (const string& test : checks)
{
Info<< " ends_with(" << test << ") = "
<< Switch(input1.ends_with(test)) << nl;
}
Info<<"input: " << input2 << nl;
for (const string& test : checks)
{
Info<< " ends_with(" << test << ") = "
<< Switch(input2.ends_with(test)) << nl;
}
Info<< nl;
Info<< "check ends_with as applied to field names:" << nl
<< "~~~~~~~~~~~~~~~~~" << nl;
string input3 = "field_0";
string input4 = "_0";
Info<<input3 << " ends_with(\"_0\") = "
<< Switch(input3.ends_with("_0")) << nl;
Info<<input4 << " ends_with(\"_0\") = "
<< Switch(input4.ends_with("_0")) << nl;
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //