mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'update-tokenizer' into 'develop'
ENH: adjust tokenizing See merge request Development/openfoam!452
This commit is contained in:
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDict;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDict;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDict;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDictCalc1;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDictEval1;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDictEval1;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDictEval1;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
121
applications/test/dictionary/testDictEval4
Normal file
121
applications/test/dictionary/testDictEval4
Normal file
@ -0,0 +1,121 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2012 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Test expansion with negative signs
|
||||
|
||||
value 0.5;
|
||||
|
||||
radius 3;
|
||||
|
||||
negValue -$value;
|
||||
|
||||
select1 10;
|
||||
|
||||
sqrt05 #eval{ sqrt(0.5) };
|
||||
|
||||
vector ( -10 ${{-$sqrt05}} $value );
|
||||
|
||||
corner ( ${{ -$radius*sqrt(0.5) }} 1 0 );
|
||||
|
||||
corner2 ${{
|
||||
vector(-${radius}*sqrt(0.5), ${radius}*sqrt(0.5), 2)
|
||||
}};
|
||||
|
||||
|
||||
// Just a future idea (2021-05-14) - does not yet work!
|
||||
#if 0
|
||||
corner3 #eval #{
|
||||
variables ( "outer = $radius*sqrt(0.5)" );
|
||||
vector(-outer, outer, 2)
|
||||
#};
|
||||
#endif
|
||||
|
||||
|
||||
// The brace-bracket #eval with multi-lines failed for v2012 and earlier
|
||||
|
||||
corner2b #eval
|
||||
{
|
||||
vector(-${radius}*sqrt(0.5), $radius*sqrt(0.5), 2)
|
||||
};
|
||||
|
||||
corner2c #eval
|
||||
${{
|
||||
vector(-${radius}*sqrt(0.5), $radius*sqrt(0.5), 2)
|
||||
}};
|
||||
|
||||
|
||||
longSlurp #eval
|
||||
{
|
||||
// This is actually a very simple expression
|
||||
1 + 2
|
||||
// With a long comment that is stripped out
|
||||
// during reading anyhow.
|
||||
};
|
||||
|
||||
|
||||
longVariable
|
||||
${{
|
||||
// This is actually a very simple expression in variable syntax
|
||||
1 + 2
|
||||
/*
|
||||
// With a long comment that is stripped out
|
||||
// during reading anyhow.
|
||||
*/
|
||||
}};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Geometric parameters
|
||||
rxo 2;
|
||||
ryo 3;
|
||||
rzo 4;
|
||||
|
||||
// Geometric parameters
|
||||
outerRadius 1;
|
||||
innerRatio 0.75;
|
||||
|
||||
geometry
|
||||
{
|
||||
sphere
|
||||
{
|
||||
type sphere;
|
||||
origin (0 0 0);
|
||||
radius ($rxo $ryo $rzo);
|
||||
}
|
||||
|
||||
innerSphere
|
||||
{
|
||||
$sphere
|
||||
|
||||
// Different solutions to the same problem
|
||||
radius_v1
|
||||
(
|
||||
${{ $innerRatio*$rxo }}
|
||||
${{ $innerRatio*$ryo }}
|
||||
${{ $innerRatio*$rzo }}
|
||||
);
|
||||
|
||||
radius_v2 #eval{ $innerRatio*vector($rxo, $ryo, $rzo) };
|
||||
radius_v3 ${{ $innerRatio*$[(vector) ../sphere/radius] }};
|
||||
|
||||
// Inplace overwrite the same value
|
||||
radius ${{ $innerRatio*$[(vector) radius] }};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDict;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Test some parsing
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDictRegex;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
#inputMode merge
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDict;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ FoamFile
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object testDict;
|
||||
object dictionary;
|
||||
note "test with foamDictionary -expand";
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
3
applications/test/dictionary3/Make/files
Normal file
3
applications/test/dictionary3/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-dictionary3.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-dictionary3
|
||||
2
applications/test/dictionary3/Make/options
Normal file
2
applications/test/dictionary3/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
78
applications/test/dictionary3/Test-dictionary3.C
Normal file
78
applications/test/dictionary3/Test-dictionary3.C
Normal file
@ -0,0 +1,78 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 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/>.
|
||||
|
||||
Application
|
||||
Test-dictionary3
|
||||
|
||||
Description
|
||||
Test expressions and re-expansions
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "dictionary.H"
|
||||
#include "vector.H"
|
||||
#include "StringStream.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
|
||||
{
|
||||
IStringStream is
|
||||
(
|
||||
"value 10;"
|
||||
"scalar1 $value;"
|
||||
"scalar2 -$value;"
|
||||
|
||||
// Use #eval expansion entirely
|
||||
"vector1 ${{vector($value, -$value, $value)}};"
|
||||
"vector2 ($value -$value $value);"
|
||||
);
|
||||
|
||||
dictionary dict(is);
|
||||
|
||||
Info<< "input dictionary:" << dict << nl;
|
||||
|
||||
Info<< "value: " << dict.get<scalar>("value") << nl;
|
||||
|
||||
Info<< "scalar1: " << dict.get<scalar>("scalar1") << nl;
|
||||
Info<< "scalar2: " << dict.get<scalar>("scalar2") << nl;
|
||||
|
||||
Info<< "vector1: " << dict.get<vector>("vector1") << nl;
|
||||
Info<< "vector2: " << dict.get<vector>("vector2") << nl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
3
applications/test/namedDictionary/Make/files
Normal file
3
applications/test/namedDictionary/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-namedDictionary.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-namedDictionary
|
||||
2
applications/test/namedDictionary/Make/options
Normal file
2
applications/test/namedDictionary/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
84
applications/test/namedDictionary/Test-namedDictionary.C
Normal file
84
applications/test/namedDictionary/Test-namedDictionary.C
Normal file
@ -0,0 +1,84 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 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/>.
|
||||
|
||||
Application
|
||||
Test-namedDictionary
|
||||
|
||||
Description
|
||||
Test handling of keyType/dictionary
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "IOobject.H"
|
||||
#include "IFstream.H"
|
||||
#include "namedDictionary.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noBanner();
|
||||
argList::noParallel();
|
||||
argList::addArgument("file1 .. fileN");
|
||||
argList args(argc, argv, false, true);
|
||||
|
||||
if (args.size() <= 1)
|
||||
{
|
||||
InfoErr<< "Provide a file or files to test" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (label argi=1; argi < args.size(); ++argi)
|
||||
{
|
||||
const auto dictFile = args.get<fileName>(argi);
|
||||
IFstream ifs(dictFile);
|
||||
|
||||
dictionary dict(ifs);
|
||||
|
||||
IOobject::writeDivider(Info) << nl;
|
||||
|
||||
for (const entry& dEntry : dict)
|
||||
{
|
||||
if (!dEntry.isStream())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Info<< "input: " << dEntry << nl;
|
||||
List<namedDictionary> list(dEntry.stream());
|
||||
Info<< "list: " << list << nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
83
applications/test/namedDictionary/testDict1
Normal file
83
applications/test/namedDictionary/testDict1
Normal file
@ -0,0 +1,83 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2012 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
entry1
|
||||
(
|
||||
value1
|
||||
value2 ; // spurious trailing ';' is removed
|
||||
this { correct true; }
|
||||
|
||||
{ } // Empty everything == ignore
|
||||
|
||||
{ anonymous true; }
|
||||
);
|
||||
|
||||
|
||||
actions1
|
||||
(
|
||||
starting
|
||||
{
|
||||
name self;
|
||||
type faceSet;
|
||||
action new;
|
||||
source something;
|
||||
}
|
||||
|
||||
{
|
||||
name self;
|
||||
type faceSet;
|
||||
action subset;
|
||||
source something;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
actions2
|
||||
(
|
||||
{
|
||||
name self;
|
||||
type faceSet;
|
||||
action new;
|
||||
source something;
|
||||
}
|
||||
|
||||
{
|
||||
name self;
|
||||
type faceSet;
|
||||
action subset;
|
||||
source something;
|
||||
}
|
||||
);
|
||||
|
||||
actions3
|
||||
(
|
||||
{
|
||||
name self;
|
||||
type faceSet;
|
||||
action new;
|
||||
source something;
|
||||
}
|
||||
|
||||
subset
|
||||
{
|
||||
name self;
|
||||
type faceSet;
|
||||
action subset;
|
||||
source something;
|
||||
}
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
3
applications/test/splitFunctionArgs/Make/files
Normal file
3
applications/test/splitFunctionArgs/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-splitFunctionArgs.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-splitFunctionArgs
|
||||
2
applications/test/splitFunctionArgs/Make/options
Normal file
2
applications/test/splitFunctionArgs/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
155
applications/test/splitFunctionArgs/Test-splitFunctionArgs.C
Normal file
155
applications/test/splitFunctionArgs/Test-splitFunctionArgs.C
Normal file
@ -0,0 +1,155 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 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/>.
|
||||
|
||||
Application
|
||||
Test-splitFunctionArgs
|
||||
|
||||
Description
|
||||
Test splitting of function name args
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "IOobject.H"
|
||||
#include "IFstream.H"
|
||||
#include "dictionary.H"
|
||||
#include "stringOps.H"
|
||||
#include "Tuple2.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// Split out function name and any arguments
|
||||
// - use as per functionObjectList
|
||||
void testFunctionNameAndArgsSplit(const std::string& line)
|
||||
{
|
||||
word funcName;
|
||||
wordRes args;
|
||||
List<Tuple2<word, string>> namedArgs;
|
||||
|
||||
const auto lbracket = line.find('(');
|
||||
if (lbracket == std::string::npos)
|
||||
{
|
||||
funcName = word::validate(line);
|
||||
// No args
|
||||
}
|
||||
else
|
||||
{
|
||||
funcName = word::validate(line.substr(0, lbracket));
|
||||
std::string params;
|
||||
|
||||
const auto rbracket = line.rfind(')');
|
||||
if (rbracket != std::string::npos && lbracket < rbracket)
|
||||
{
|
||||
params = line.substr(lbracket+1, (rbracket - lbracket - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
params = line.substr(lbracket+1);
|
||||
}
|
||||
|
||||
Info<<"parsing: " << params << nl;
|
||||
|
||||
stringOps::splitFunctionArgs(params, args, namedArgs);
|
||||
}
|
||||
|
||||
Info<< nl
|
||||
<< line << nl
|
||||
<< "function: <" << funcName << '>' << nl
|
||||
<< " args: " << args << nl
|
||||
<< " named: " << namedArgs << nl;
|
||||
}
|
||||
|
||||
|
||||
// Split out any arguments
|
||||
void testArgsSplit(const std::string& line)
|
||||
{
|
||||
wordRes args;
|
||||
List<Tuple2<word, string>> namedArgs;
|
||||
stringOps::splitFunctionArgs(line, args, namedArgs);
|
||||
|
||||
Info<< nl
|
||||
<< line << nl
|
||||
<< " args: " << args << nl
|
||||
<< " named: " << namedArgs << nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noBanner();
|
||||
argList::noParallel();
|
||||
argList::addArgument("file1 .. fileN");
|
||||
argList args(argc, argv, false, true);
|
||||
|
||||
if (args.size() <= 1)
|
||||
{
|
||||
InfoErr<< "Provide a file or files to test" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (label argi=1; argi < args.size(); ++argi)
|
||||
{
|
||||
IOobject::writeDivider(Info);
|
||||
|
||||
const auto inputFile = args.get<fileName>(argi);
|
||||
IFstream is(inputFile);
|
||||
|
||||
string line;
|
||||
while (is.getLine(line))
|
||||
{
|
||||
if (line.empty() || line[0] == '#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.starts_with("function:"))
|
||||
{
|
||||
auto trim = line.find(':');
|
||||
++trim;
|
||||
while (isspace(line[trim]))
|
||||
{
|
||||
++trim;
|
||||
}
|
||||
|
||||
line.erase(0, trim);
|
||||
testFunctionNameAndArgsSplit(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
testArgsSplit(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
47
applications/test/splitFunctionArgs/testNames1
Normal file
47
applications/test/splitFunctionArgs/testNames1
Normal file
@ -0,0 +1,47 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Test names for splitting. Comment character as per -*- sh -*- mode
|
||||
#
|
||||
# Prefix with "function: " to test with function name splitting
|
||||
|
||||
function: basic
|
||||
|
||||
function: func1( a , b );
|
||||
|
||||
function: func2(a, value=10);
|
||||
|
||||
# discard or flag bad/missing parameters?
|
||||
function: func3(a , , , value=10);
|
||||
|
||||
function: func4();
|
||||
|
||||
function: func5( abc );
|
||||
|
||||
start=1, end=2
|
||||
|
||||
start=1, end=2,
|
||||
|
||||
start=100, end= 200, abc
|
||||
|
||||
value=100
|
||||
|
||||
start=1, end=2
|
||||
|
||||
origin=(0 0 0), scale=2, normal=(0 0 1)
|
||||
|
||||
|
||||
# Canonical with named args
|
||||
function: patchAverage(patch=inlet, p)
|
||||
|
||||
# Canonical with unnamed and named args
|
||||
function: patchAverage(other, patch=inlet, pval)
|
||||
|
||||
|
||||
function: patchAverage(patch=(inlet|outlet), p)
|
||||
|
||||
# General
|
||||
(a, b)
|
||||
|
||||
allow=(inlet|outlet), deny=false, regular(value)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -47,6 +47,7 @@ Description
|
||||
#include "faceZoneSet.H"
|
||||
#include "pointZoneSet.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "namedDictionary.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -237,7 +238,7 @@ int main(int argc, char *argv[])
|
||||
IOdictionary topoSetDict(dictIO);
|
||||
|
||||
// Read set construct info from dictionary
|
||||
PtrList<dictionary> actions(topoSetDict.lookup("actions"));
|
||||
List<namedDictionary> actionEntries(topoSetDict.lookup("actions"));
|
||||
|
||||
forAll(timeDirs, timeI)
|
||||
{
|
||||
@ -248,8 +249,13 @@ int main(int argc, char *argv[])
|
||||
meshReadUpdate(mesh);
|
||||
|
||||
// Execute all actions
|
||||
for (const dictionary& dict : actions)
|
||||
for (const namedDictionary& actionEntry : actionEntries)
|
||||
{
|
||||
const dictionary& dict = actionEntry.dict();
|
||||
if (dict.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const word setName(dict.get<word>("name"));
|
||||
const word setType(dict.get<word>("type"));
|
||||
|
||||
|
||||
@ -145,6 +145,7 @@ $(strings)/parsing/genericRagelLemonDriver.C
|
||||
$(strings)/stringOps/stringOps.C
|
||||
$(strings)/stringOps/stringOpsEvaluate.C
|
||||
$(strings)/stringOps/stringOpsSort.C
|
||||
$(strings)/stringOps/stringOpsSplit.C
|
||||
|
||||
expr = expressions
|
||||
$(expr)/exprEntry/expressionEntry.C
|
||||
@ -275,7 +276,9 @@ $(dictionary)/dictionaryIO.C
|
||||
$(dictionary)/dictionarySearch.C
|
||||
$(dictionary)/dictionaryCompat.C
|
||||
|
||||
/* Additional helpers */
|
||||
$(dictionary)/dictionaryContent/dictionaryContent.C
|
||||
$(dictionary)/namedDictionary/namedDictionary.C
|
||||
|
||||
entry = $(dictionary)/entry
|
||||
$(entry)/entry.C
|
||||
|
||||
@ -218,8 +218,8 @@ Foam::Istream& Foam::UIPstream::read(token& t)
|
||||
case token::COLON :
|
||||
case token::COMMA :
|
||||
case token::ASSIGN :
|
||||
case token::ADD :
|
||||
case token::SUBTRACT :
|
||||
case token::PLUS :
|
||||
case token::MINUS :
|
||||
case token::MULTIPLY :
|
||||
case token::DIVIDE :
|
||||
{
|
||||
@ -227,12 +227,12 @@ Foam::Istream& Foam::UIPstream::read(token& t)
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Word/directive
|
||||
// The word-variants
|
||||
case token::tokenType::WORD :
|
||||
case token::tokenType::DIRECTIVE :
|
||||
{
|
||||
word val;
|
||||
if (read(val))
|
||||
if (readStringFromBuffer(val))
|
||||
{
|
||||
if (token::compound::isCompound(val))
|
||||
{
|
||||
@ -251,13 +251,14 @@ Foam::Istream& Foam::UIPstream::read(token& t)
|
||||
return *this;
|
||||
}
|
||||
|
||||
// String types
|
||||
// The string-variants
|
||||
case token::tokenType::STRING :
|
||||
case token::tokenType::EXPRESSION :
|
||||
case token::tokenType::VARIABLE :
|
||||
case token::tokenType::VERBATIM :
|
||||
{
|
||||
string val;
|
||||
if (read(val))
|
||||
if (readStringFromBuffer(val))
|
||||
{
|
||||
t = std::move(val);
|
||||
t.setType(token::tokenType(c));
|
||||
|
||||
@ -202,14 +202,19 @@ bool Foam::UOPstream::write(const token& tok)
|
||||
return true;
|
||||
}
|
||||
|
||||
// The word-variants
|
||||
case token::tokenType::WORD :
|
||||
case token::tokenType::DIRECTIVE :
|
||||
{
|
||||
writeToBuffer(char(token::tokenType::DIRECTIVE));
|
||||
writeToBuffer(char(tok.type()));
|
||||
writeStringToBuffer(tok.wordToken());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// The string-variants
|
||||
case token::tokenType::STRING :
|
||||
case token::tokenType::EXPRESSION :
|
||||
case token::tokenType::VARIABLE :
|
||||
case token::tokenType::VERBATIM :
|
||||
{
|
||||
|
||||
@ -30,6 +30,7 @@ License
|
||||
#include "int.H"
|
||||
#include "token.H"
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -42,14 +43,14 @@ namespace
|
||||
{
|
||||
|
||||
// Convert a single character to a word with length 1
|
||||
inline static Foam::word charToWord(char c)
|
||||
inline Foam::word charToWord(char c)
|
||||
{
|
||||
return Foam::word(std::string(1, c), false);
|
||||
}
|
||||
|
||||
|
||||
// Permit slash-scoping of entries
|
||||
static inline bool validVariableChar(char c)
|
||||
inline bool validVariableChar(char c)
|
||||
{
|
||||
return (Foam::word::valid(c) || c == '/');
|
||||
}
|
||||
@ -59,23 +60,51 @@ static inline bool validVariableChar(char c)
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::ISstream::seekCommentEnd_Cstyle()
|
||||
{
|
||||
// Search for end of C-style comment - "*/"
|
||||
|
||||
// Can use getLine(nullptr, '*') in the logic,
|
||||
// but written out looks less obscure
|
||||
|
||||
char c = 0;
|
||||
bool star = false;
|
||||
|
||||
while (get(c))
|
||||
{
|
||||
if (c == '*')
|
||||
{
|
||||
star = true;
|
||||
}
|
||||
else if (star)
|
||||
{
|
||||
star = false;
|
||||
if (c == '/')
|
||||
{
|
||||
// Matched "*/"
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exhausted stream without finding "*/" sequence
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
char Foam::ISstream::nextValid()
|
||||
{
|
||||
char c = 0;
|
||||
|
||||
while (true)
|
||||
// Get next non-whitespace character
|
||||
while (get(c))
|
||||
{
|
||||
// Get next non-whitespace character
|
||||
while (get(c) && isspace(c))
|
||||
{}
|
||||
|
||||
// Return if stream is bad - ie, previous get() failed
|
||||
if (bad() || isspace(c))
|
||||
if (isspace(c))
|
||||
{
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is this the start of a C/C++ comment?
|
||||
// Check if this starts a C/C++ comment
|
||||
if (c == '/')
|
||||
{
|
||||
if (!get(c))
|
||||
@ -86,37 +115,15 @@ char Foam::ISstream::nextValid()
|
||||
|
||||
if (c == '/')
|
||||
{
|
||||
// C++ style single-line comment - skip through past end-of-line
|
||||
while (get(c) && c != '\n')
|
||||
{}
|
||||
// C++ comment: discard through newline
|
||||
(void) getLine(nullptr, '\n');
|
||||
}
|
||||
else if (c == '*')
|
||||
{
|
||||
// Within a C-style comment
|
||||
while (true)
|
||||
// C-style comment: discard through to "*/" ending
|
||||
if (!seekCommentEnd_Cstyle())
|
||||
{
|
||||
// Search for end of C-style comment - '*/'
|
||||
if (get(c) && c == '*')
|
||||
{
|
||||
if (get(c))
|
||||
{
|
||||
if (c == '/')
|
||||
{
|
||||
// matched '*/'
|
||||
break;
|
||||
}
|
||||
else if (c == '*')
|
||||
{
|
||||
// check again
|
||||
putback(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!good())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -137,28 +144,261 @@ char Foam::ISstream::nextValid()
|
||||
}
|
||||
|
||||
|
||||
void Foam::ISstream::readWordToken(token& t)
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
word val;
|
||||
if (read(val).bad())
|
||||
|
||||
// Read a verbatim string (excluding block delimiters),
|
||||
// continuing until a closing "#}" has been found.
|
||||
//
|
||||
// The leading "#{" removed from stream prior to calling.
|
||||
static ISstream& readVerbatim
|
||||
(
|
||||
ISstream& is,
|
||||
std::string& str
|
||||
)
|
||||
{
|
||||
constexpr const unsigned bufLen = 8000;
|
||||
static char buf[bufLen];
|
||||
|
||||
unsigned nChar = 0;
|
||||
char c;
|
||||
|
||||
str.clear();
|
||||
while (is.get(c))
|
||||
{
|
||||
t.setBad();
|
||||
}
|
||||
else if (token::compound::isCompound(val))
|
||||
{
|
||||
t = token::compound::New(val, *this).ptr();
|
||||
}
|
||||
else
|
||||
{
|
||||
t = std::move(val); // Move contents to token
|
||||
if (c == token::HASH)
|
||||
{
|
||||
char nextC;
|
||||
is.get(nextC);
|
||||
if (nextC == token::END_BLOCK)
|
||||
{
|
||||
// Found closing "#}" sequence
|
||||
str.append(buf, nChar);
|
||||
return is;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Re-analyze the character
|
||||
is.putback(nextC);
|
||||
}
|
||||
}
|
||||
|
||||
buf[nChar++] = c;
|
||||
if (nChar == bufLen) // Flush full buffer
|
||||
{
|
||||
str.append(buf, nChar);
|
||||
nChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Abnormal exit of the loop
|
||||
str.append(buf, nChar); // Finalize pending content
|
||||
strncpy(buf, str.c_str(), errLen);
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Problem while reading verbatim \"" << buf
|
||||
<< "...\" [after " << str.length() << " chars]\n"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
// Read a variable or expression.
|
||||
// Handles "$var" and "${var}" forms, permits '/' scoping character.
|
||||
// Also handles "${{expr}}".
|
||||
//
|
||||
// Return the token type or ERROR
|
||||
//
|
||||
// The leading "${" or "$c" removed from stream prior to calling.
|
||||
static token::tokenType readVariable
|
||||
(
|
||||
ISstream& is,
|
||||
std::string& str,
|
||||
char c // Next character after '$'
|
||||
)
|
||||
{
|
||||
constexpr const unsigned bufLen = 1024;
|
||||
static char buf[bufLen];
|
||||
|
||||
token::tokenType tokType(token::tokenType::VARIABLE);
|
||||
|
||||
// The first two characters are known:
|
||||
buf[0] = token::DOLLAR;
|
||||
buf[1] = c;
|
||||
|
||||
unsigned nChar = 2; // Starts with two characters
|
||||
unsigned depth = 0; // Depth of {..} nesting
|
||||
|
||||
str.clear();
|
||||
if (c == token::BEGIN_BLOCK)
|
||||
{
|
||||
// Processing '${variable}' or '${{expr}}'
|
||||
++depth;
|
||||
|
||||
int lookahead = is.peek();
|
||||
if (lookahead == token::BEGIN_BLOCK)
|
||||
{
|
||||
// Looks like '${{expr...'
|
||||
tokType = token::tokenType::EXPRESSION;
|
||||
}
|
||||
else if (lookahead == token::END_BLOCK)
|
||||
{
|
||||
// Looks like '${}'
|
||||
IOWarningInFunction(is)
|
||||
<< "Ignoring empty ${}" << endl;
|
||||
return token::tokenType::ERROR;
|
||||
}
|
||||
|
||||
while (is.get(c))
|
||||
{
|
||||
buf[nChar++] = c;
|
||||
|
||||
if (c == token::BEGIN_BLOCK)
|
||||
{
|
||||
++depth;
|
||||
}
|
||||
else if (c == token::END_BLOCK)
|
||||
{
|
||||
--depth;
|
||||
if (!depth)
|
||||
{
|
||||
// Found closing '}' character
|
||||
str.append(buf, nChar);
|
||||
return tokType;
|
||||
}
|
||||
}
|
||||
else if (c == '/' && tokType == token::tokenType::EXPRESSION)
|
||||
{
|
||||
// Strip C/C++ comments from expressions
|
||||
// Note: could also peek instead of get/putback
|
||||
|
||||
if (!is.get(c))
|
||||
{
|
||||
break; // Premature end of stream
|
||||
}
|
||||
else if (c == '/')
|
||||
{
|
||||
--nChar; // Remove initial '/' from buffer
|
||||
|
||||
// C++ comment: discard through newline
|
||||
(void) is.getLine(nullptr, '\n');
|
||||
}
|
||||
else if (c == '*')
|
||||
{
|
||||
--nChar; // Remove initial '/' from buffer
|
||||
|
||||
// C-style comment: seek "*/" ending
|
||||
if (!is.seekCommentEnd_Cstyle())
|
||||
{
|
||||
break; // Premature end of stream
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Re-analyze the character
|
||||
is.putback(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (nChar == bufLen) // Flush full buffer
|
||||
{
|
||||
str.append(buf, nChar);
|
||||
nChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Abnormal exit of the loop
|
||||
|
||||
str.append(buf, nChar); // Finalize pending content
|
||||
strncpy(buf, str.c_str(), errLen);
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "stream terminated while reading variable '" << buf
|
||||
<< "...' [after " << str.length() << " chars]\n"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return token::tokenType::ERROR;
|
||||
}
|
||||
else if (validVariableChar(c))
|
||||
{
|
||||
// Processing '$variable'
|
||||
|
||||
while (is.get(c))
|
||||
{
|
||||
if (!validVariableChar(c))
|
||||
{
|
||||
is.putback(c);
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == token::BEGIN_LIST)
|
||||
{
|
||||
++depth;
|
||||
}
|
||||
else if (c == token::END_LIST)
|
||||
{
|
||||
if (!depth)
|
||||
{
|
||||
// Closed ')' without opening '(':
|
||||
// - don't consider it part of our input
|
||||
is.putback(c);
|
||||
break;
|
||||
}
|
||||
--depth;
|
||||
}
|
||||
|
||||
buf[nChar++] = c;
|
||||
if (nChar == bufLen) // Flush full buffer
|
||||
{
|
||||
str.append(buf, nChar);
|
||||
nChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
str.append(buf, nChar); // Finalize pending content
|
||||
|
||||
if (depth)
|
||||
{
|
||||
strncpy(buf, str.c_str(), errLen);
|
||||
buf[errLen] = '\0';
|
||||
|
||||
IOWarningInFunction(is)
|
||||
<< "Missing " << depth
|
||||
<< " closing ')' while parsing" << nl << nl
|
||||
<< buf << endl;
|
||||
}
|
||||
|
||||
return tokType;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid character. Terminate string (for message)
|
||||
|
||||
buf[nChar--] = '\0';
|
||||
|
||||
IOWarningInFunction(is)
|
||||
<< "Ignoring bad variable name: " << buf << nl << endl;
|
||||
}
|
||||
|
||||
return token::tokenType::ERROR;
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::ISstream::read(token& t)
|
||||
{
|
||||
constexpr const unsigned maxLen = 128; // Max length for labels/scalars
|
||||
static char buf[maxLen];
|
||||
constexpr const unsigned bufLen = 128; // Max length for labels/scalars
|
||||
static char buf[bufLen];
|
||||
|
||||
// Return the put back token if it exists
|
||||
if (Istream::getBack(t))
|
||||
@ -199,8 +439,8 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
case token::COLON :
|
||||
case token::COMMA :
|
||||
case token::ASSIGN :
|
||||
case token::ADD :
|
||||
// NB: token::SUBTRACT handled later as the possible start of a Number
|
||||
case token::PLUS :
|
||||
// NB: token::MINUS handled later as the possible start of a Number
|
||||
case token::MULTIPLY :
|
||||
case token::DIVIDE :
|
||||
{
|
||||
@ -209,7 +449,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
}
|
||||
|
||||
// String: enclosed by double quotes.
|
||||
case token::BEGIN_STRING :
|
||||
case token::DQUOTE :
|
||||
{
|
||||
putback(c);
|
||||
|
||||
@ -226,21 +466,21 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Possible verbatim string or dictionary functionEntry
|
||||
// Verbatim string '#{ .. #}' or dictionary '#directive'
|
||||
case token::HASH :
|
||||
{
|
||||
char nextC;
|
||||
if (read(nextC).bad())
|
||||
{
|
||||
// Return lone '#' as word
|
||||
t = charToWord(c);
|
||||
}
|
||||
else if (nextC == token::BEGIN_BLOCK)
|
||||
int lookahead = peek();
|
||||
|
||||
if (lookahead == token::BEGIN_BLOCK)
|
||||
{
|
||||
// Verbatim string: #{ ... #}
|
||||
// Token stored without the surrounding delimiters
|
||||
|
||||
(void) get(nextC); // Discard '{' lookahead
|
||||
|
||||
string val;
|
||||
if (readVerbatim(val).bad())
|
||||
if (readVerbatim(*this, val).bad())
|
||||
{
|
||||
t.setBad();
|
||||
}
|
||||
@ -250,9 +490,14 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
t.setType(token::tokenType::VERBATIM);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (read(nextC).bad())
|
||||
{
|
||||
// Word beginning with '#'. Eg, "#include"
|
||||
// Return lone '#' as word
|
||||
t = charToWord(c);
|
||||
}
|
||||
else if (word::valid(nextC))
|
||||
{
|
||||
// Directive (wordToken) beginning with '#'. Eg, "#include"
|
||||
// Put back both so that '#...' is included in the directive
|
||||
|
||||
putback(nextC);
|
||||
@ -269,34 +514,44 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
t.setType(token::tokenType::DIRECTIVE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// '#' followed by non-word. Just ignore leading '#'?
|
||||
putback(nextC);
|
||||
|
||||
IOWarningInFunction(*this)
|
||||
<< "Invalid sequence #" << char(nextC)
|
||||
<< " ... ignoring the leading '#'" << nl << endl;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Dictionary variable (as rvalue)
|
||||
// Dictionary variable or ${{ expression }}
|
||||
case token::DOLLAR :
|
||||
{
|
||||
char nextC;
|
||||
if (read(nextC).bad())
|
||||
{
|
||||
// Return lone '$' as word
|
||||
// Return lone '$' as word. Could also ignore
|
||||
t = charToWord(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Put back both so that '$...' is included in the variable
|
||||
putback(nextC);
|
||||
putback(c);
|
||||
// NB: the parser is slightly generous here.
|
||||
// It will also accept '$ {' as input.
|
||||
// - to be revisited (2021-05-17)
|
||||
|
||||
string val;
|
||||
if (readVariable(val).bad())
|
||||
token::tokenType tokType = readVariable(*this, val, nextC);
|
||||
if (tokType == token::tokenType::ERROR)
|
||||
{
|
||||
t.setBad();
|
||||
}
|
||||
else
|
||||
{
|
||||
t = std::move(val); // Move contents to token
|
||||
t.setType(token::tokenType::VARIABLE);
|
||||
t.setType(tokType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,14 +595,14 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
}
|
||||
|
||||
buf[nChar++] = c;
|
||||
if (nChar == maxLen)
|
||||
if (nChar == bufLen)
|
||||
{
|
||||
// Runaway argument - avoid buffer overflow
|
||||
buf[maxLen-1] = '\0';
|
||||
buf[bufLen-1] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "number '" << buf << "...'\n"
|
||||
<< " is too long (max. " << maxLen << " characters)"
|
||||
<< "Number '" << buf << "...'\n"
|
||||
<< " is too long (max. " << bufLen << " characters)"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
t.setBad();
|
||||
@ -368,7 +623,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
if (nChar == 1 && buf[0] == '-')
|
||||
{
|
||||
// A single '-' is punctuation
|
||||
t = token::punctuationToken(token::SUBTRACT);
|
||||
t = token::punctuationToken(token::MINUS);
|
||||
}
|
||||
else if (labelVal && Foam::read(buf, labelVal))
|
||||
{
|
||||
@ -397,7 +652,20 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
default:
|
||||
{
|
||||
putback(c);
|
||||
readWordToken(t);
|
||||
|
||||
word val;
|
||||
if (read(val).bad())
|
||||
{
|
||||
t.setBad();
|
||||
}
|
||||
else if (token::compound::isCompound(val))
|
||||
{
|
||||
t = token::compound::New(val, *this).ptr();
|
||||
}
|
||||
else
|
||||
{
|
||||
t = std::move(val); // Move contents to token
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -414,20 +682,22 @@ Foam::Istream& Foam::ISstream::read(char& c)
|
||||
|
||||
Foam::Istream& Foam::ISstream::read(word& str)
|
||||
{
|
||||
constexpr const unsigned maxLen = 1024;
|
||||
static char buf[maxLen];
|
||||
constexpr const unsigned bufLen = 1024;
|
||||
static char buf[bufLen];
|
||||
|
||||
unsigned nChar = 0;
|
||||
unsigned depth = 0; // Track depth of (..) nesting
|
||||
unsigned depth = 0; // Depth of (..) nesting
|
||||
char c;
|
||||
|
||||
while
|
||||
(
|
||||
(nChar < maxLen)
|
||||
&& get(c)
|
||||
&& word::valid(c)
|
||||
)
|
||||
str.clear();
|
||||
while (get(c))
|
||||
{
|
||||
if (!word::valid(c))
|
||||
{
|
||||
putback(c);
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == token::BEGIN_LIST)
|
||||
{
|
||||
++depth;
|
||||
@ -436,42 +706,40 @@ Foam::Istream& Foam::ISstream::read(word& str)
|
||||
{
|
||||
if (!depth)
|
||||
{
|
||||
break; // Closed ')' without an opening '(' ? ... stop
|
||||
// Closed ')' without opening '(':
|
||||
// - don't consider it part of our input
|
||||
putback(c);
|
||||
break;
|
||||
}
|
||||
--depth;
|
||||
}
|
||||
|
||||
buf[nChar++] = c;
|
||||
if (nChar == bufLen) // Flush full buffer
|
||||
{
|
||||
str.append(buf, nChar);
|
||||
nChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (nChar >= maxLen)
|
||||
{
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "word '" << buf << "...'\n"
|
||||
<< " is too long (max. " << maxLen << " characters)"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
buf[nChar] = '\0'; // Terminate string
|
||||
str.append(buf, nChar); // Finalize pending content
|
||||
|
||||
if (bad())
|
||||
{
|
||||
// Could probably skip this check
|
||||
|
||||
strncpy(buf, str.c_str(), errLen);
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "Problem while reading word '" << buf << "...' after "
|
||||
<< nChar << " characters\n"
|
||||
<< "Problem while reading word '" << buf
|
||||
<< "...' [after " << str.length() << " chars]\n"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (nChar == 0)
|
||||
if (str.empty())
|
||||
{
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "Invalid first character found : " << c
|
||||
@ -479,25 +747,25 @@ Foam::Istream& Foam::ISstream::read(word& str)
|
||||
}
|
||||
else if (depth)
|
||||
{
|
||||
strncpy(buf, str.c_str(), errLen);
|
||||
buf[errLen] = '\0';
|
||||
|
||||
IOWarningInFunction(*this)
|
||||
<< "Missing " << depth
|
||||
<< " closing ')' while parsing" << nl << nl
|
||||
<< buf << nl << endl;
|
||||
}
|
||||
|
||||
// Finalize: content already validated, assign without additional checks.
|
||||
str.assign(buf, nChar);
|
||||
putback(c);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Foam::Istream& Foam::ISstream::read(string& str)
|
||||
{
|
||||
constexpr const unsigned maxLen = 1024;
|
||||
static char buf[maxLen];
|
||||
constexpr const unsigned bufLen = 1024;
|
||||
static char buf[bufLen];
|
||||
|
||||
unsigned nChar = 0;
|
||||
char c;
|
||||
|
||||
if (!get(c))
|
||||
@ -510,7 +778,7 @@ Foam::Istream& Foam::ISstream::read(string& str)
|
||||
}
|
||||
|
||||
// Note, we could also handle single-quoted strings here (if desired)
|
||||
if (c != token::BEGIN_STRING)
|
||||
if (c != token::DQUOTE)
|
||||
{
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "Incorrect start of string character found : " << c
|
||||
@ -519,26 +787,25 @@ Foam::Istream& Foam::ISstream::read(string& str)
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned nChar = 0;
|
||||
str.clear();
|
||||
bool escaped = false;
|
||||
|
||||
while
|
||||
(
|
||||
(nChar < maxLen)
|
||||
&& get(c)
|
||||
)
|
||||
while (get(c))
|
||||
{
|
||||
if (c == token::END_STRING)
|
||||
if (c == '\\')
|
||||
{
|
||||
escaped = !escaped; // Toggle state (retains backslashes)
|
||||
}
|
||||
else if (c == token::DQUOTE)
|
||||
{
|
||||
if (escaped)
|
||||
{
|
||||
escaped = false;
|
||||
--nChar; // Overwrite backslash
|
||||
--nChar; // Overwrite backslash
|
||||
}
|
||||
else
|
||||
{
|
||||
// Done reading
|
||||
str.assign(buf, nChar);
|
||||
str.append(buf, nChar);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
@ -547,253 +814,44 @@ Foam::Istream& Foam::ISstream::read(string& str)
|
||||
if (escaped)
|
||||
{
|
||||
escaped = false;
|
||||
--nChar; // Overwrite backslash
|
||||
--nChar; // Overwrite backslash
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[errLen] = buf[nChar] = '\0';
|
||||
str.append(buf, nChar); // Finalize pending content
|
||||
strncpy(buf, str.c_str(), errLen);
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "found '\\n' while reading string \""
|
||||
<< buf << "...\""
|
||||
<< "Unescaped '\\n' while reading string \"" << buf
|
||||
<< "...\" [after " << str.length() << " chars]\n"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
else if (c == '\\')
|
||||
{
|
||||
escaped = !escaped; // toggle state (retains backslashes)
|
||||
}
|
||||
else
|
||||
{
|
||||
escaped = false;
|
||||
}
|
||||
|
||||
buf[nChar++] = c;
|
||||
if (nChar == bufLen) // Flush full buffer
|
||||
{
|
||||
// Keep lookback character (eg, for backslash escaping)
|
||||
str.append(buf, nChar-1);
|
||||
nChar = 1;
|
||||
buf[0] = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (nChar >= maxLen)
|
||||
{
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "string \"" << buf << "...\"\n"
|
||||
<< " is too long (max. " << maxLen << " characters)"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Abnormal exit of the loop
|
||||
// Don't worry about a dangling backslash if string terminated prematurely
|
||||
buf[errLen] = buf[nChar] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "Problem while reading string \"" << buf << "...\""
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Foam::Istream& Foam::ISstream::readVariable(std::string& str)
|
||||
{
|
||||
constexpr const unsigned maxLen = 1024;
|
||||
static char buf[maxLen];
|
||||
|
||||
unsigned nChar = 0;
|
||||
unsigned depth = 0; // Track depth of (..) or {..} nesting
|
||||
char c;
|
||||
|
||||
// First character must be '$'
|
||||
if (!get(c) || c != token::DOLLAR)
|
||||
{
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "Invalid first character found : " << c << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
buf[nChar++] = c;
|
||||
|
||||
// Next character should also exist.
|
||||
// This should never fail, since it was checked before calling.
|
||||
if (!get(c))
|
||||
{
|
||||
str.assign(buf, nChar);
|
||||
|
||||
IOWarningInFunction(*this)
|
||||
<< "Truncated variable name : " << str << nl;
|
||||
|
||||
return *this;
|
||||
}
|
||||
buf[nChar++] = c;
|
||||
|
||||
str.clear();
|
||||
if (c == token::BEGIN_BLOCK)
|
||||
{
|
||||
// Processing ${...} style.
|
||||
++depth;
|
||||
|
||||
// Could check that the next char is good and not one of '{}'
|
||||
// since this would indicate "${}", "${{..." or truncated "${"
|
||||
|
||||
while (get(c))
|
||||
{
|
||||
buf[nChar++] = c;
|
||||
if (nChar == maxLen)
|
||||
{
|
||||
str.append(buf, nChar);
|
||||
nChar = 0;
|
||||
}
|
||||
if (c == token::BEGIN_BLOCK)
|
||||
{
|
||||
++depth;
|
||||
}
|
||||
else if (c == token::END_BLOCK)
|
||||
{
|
||||
--depth;
|
||||
if (!depth)
|
||||
{
|
||||
// Found closing '}' character
|
||||
str.append(buf, nChar);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Should never reach here on normal input
|
||||
|
||||
str.append(buf, nChar); // Finalize pending buffer input
|
||||
|
||||
nChar = str.length();
|
||||
if (str.length() > errLen)
|
||||
{
|
||||
str.erase(errLen);
|
||||
}
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "stream terminated while reading variable '"
|
||||
<< str.c_str() << "...' [" << nChar << "]\n"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return *this;
|
||||
}
|
||||
else if (validVariableChar(c))
|
||||
{
|
||||
// Processing $var style
|
||||
|
||||
while
|
||||
(
|
||||
(nChar < maxLen) && get(c)
|
||||
&& (validVariableChar(c))
|
||||
)
|
||||
{
|
||||
if (c == token::BEGIN_LIST)
|
||||
{
|
||||
++depth;
|
||||
}
|
||||
else if (c == token::END_LIST)
|
||||
{
|
||||
if (!depth)
|
||||
{
|
||||
break; // Closed ')' without an opening '(' ? ... stop
|
||||
}
|
||||
--depth;
|
||||
}
|
||||
|
||||
buf[nChar++] = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid character. Terminate string (for message) without
|
||||
// including the invalid character in the count.
|
||||
|
||||
buf[nChar--] = '\0';
|
||||
|
||||
IOWarningInFunction(*this)
|
||||
<< "Bad variable name: " << buf << nl << endl;
|
||||
}
|
||||
|
||||
if (nChar >= maxLen)
|
||||
{
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "variable '" << buf << "...'\n"
|
||||
<< " is too long (max. " << maxLen << " characters)"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
buf[nChar] = '\0'; // Terminate string
|
||||
|
||||
if (bad())
|
||||
{
|
||||
// Could probably skip this check
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "Problem while reading variable '" << buf << "...' after "
|
||||
<< nChar << " characters\n"
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (depth)
|
||||
{
|
||||
IOWarningInFunction(*this)
|
||||
<< "Missing " << depth
|
||||
<< " closing ')' while parsing" << nl << nl
|
||||
<< buf << nl << endl;
|
||||
}
|
||||
|
||||
// Finalize
|
||||
str.assign(buf, nChar);
|
||||
putback(c);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Foam::Istream& Foam::ISstream::readVerbatim(std::string& str)
|
||||
{
|
||||
constexpr const unsigned maxLen = 8000;
|
||||
static char buf[maxLen];
|
||||
|
||||
unsigned nChar = 0;
|
||||
char c;
|
||||
|
||||
str.clear();
|
||||
while (get(c))
|
||||
{
|
||||
if (c == token::HASH)
|
||||
{
|
||||
char nextC;
|
||||
get(nextC);
|
||||
if (nextC == token::END_BLOCK)
|
||||
{
|
||||
// Found closing "#}" sequence
|
||||
str.append(buf, nChar);
|
||||
return *this;
|
||||
}
|
||||
else
|
||||
{
|
||||
putback(nextC);
|
||||
}
|
||||
}
|
||||
|
||||
buf[nChar++] = c;
|
||||
if (nChar == maxLen)
|
||||
{
|
||||
str.append(buf, nChar);
|
||||
nChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Truncated terminated prematurely
|
||||
buf[errLen] = buf[nChar] = '\0';
|
||||
str.append(buf, nChar); // Finalize pending content
|
||||
strncpy(buf, str.c_str(), errLen);
|
||||
buf[errLen] = '\0';
|
||||
|
||||
FatalIOErrorInFunction(*this)
|
||||
<< "Problem while reading string \"" << buf << "...\""
|
||||
|
||||
@ -69,18 +69,6 @@ class ISstream
|
||||
//- Get the next valid character
|
||||
char nextValid();
|
||||
|
||||
//- Read a word token
|
||||
void readWordToken(token& t);
|
||||
|
||||
//- Read a verbatim string (excluding block delimiters).
|
||||
// The leading "#{" has been removed prior to calling,
|
||||
// continues until the closing "#}" has been found.
|
||||
Istream& readVerbatim(std::string& str);
|
||||
|
||||
//- Read a variable name starting with '$'.
|
||||
// Handles "$var" and "${var}" forms, permits '/' scoping character.
|
||||
Istream& readVariable(std::string& str);
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const ISstream&) = delete;
|
||||
|
||||
@ -137,6 +125,13 @@ public:
|
||||
virtual ios_base::fmtflags flags() const;
|
||||
|
||||
|
||||
// Special-purpose Functions
|
||||
|
||||
//- Discard until end of C-style comment '*/'
|
||||
// \return False if stream exhausted before finding the comment end
|
||||
bool seekCommentEnd_Cstyle();
|
||||
|
||||
|
||||
// Read Functions
|
||||
|
||||
//- Raw, low-level get character function.
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -47,27 +47,33 @@ bool Foam::OSstream::write(const token& tok)
|
||||
|
||||
case token::tokenType::DIRECTIVE :
|
||||
{
|
||||
// The '#' sigil is already part of the wordToken
|
||||
// Token stored with leading '#' sigil - output directly
|
||||
write(tok.wordToken());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case token::tokenType::VERBATIM :
|
||||
case token::tokenType::EXPRESSION :
|
||||
{
|
||||
// Surrounding '#{ .. #}' to be recognized as verbatim
|
||||
write(char(token::HASH));
|
||||
write(char(token::BEGIN_BLOCK));
|
||||
// Token stored with surrounding '${{ .. }}' - output directly
|
||||
writeQuoted(tok.stringToken(), false);
|
||||
write(char(token::HASH));
|
||||
write(char(token::END_BLOCK));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case token::tokenType::VARIABLE :
|
||||
{
|
||||
// Token stored with leading '$' sigil - output directly
|
||||
writeQuoted(tok.stringToken(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
case token::tokenType::VERBATIM :
|
||||
{
|
||||
// Token stored without surrounding '#{ .. #}'. Add on output
|
||||
write(char(token::HASH));
|
||||
write(char(token::BEGIN_BLOCK));
|
||||
writeQuoted(tok.stringToken(), false);
|
||||
write(char(token::HASH));
|
||||
write(char(token::END_BLOCK));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -127,7 +133,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
||||
|
||||
|
||||
// Output with surrounding quotes and backslash escaping
|
||||
os_ << token::BEGIN_STRING;
|
||||
os_ << token::DQUOTE;
|
||||
|
||||
unsigned backslash = 0;
|
||||
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
|
||||
@ -144,7 +150,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
||||
++lineNumber_;
|
||||
++backslash; // backslash escape for newline
|
||||
}
|
||||
else if (c == token::END_STRING)
|
||||
else if (c == token::DQUOTE)
|
||||
{
|
||||
++backslash; // backslash escape for quote
|
||||
}
|
||||
@ -161,7 +167,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
||||
|
||||
// silently drop any trailing backslashes
|
||||
// they would otherwise appear like an escaped end-quote
|
||||
os_ << token::END_STRING;
|
||||
os_ << token::DQUOTE;
|
||||
|
||||
setState(os_.rdstate());
|
||||
return *this;
|
||||
|
||||
@ -71,11 +71,13 @@ class token
|
||||
public:
|
||||
|
||||
//- Enumeration defining the types of token.
|
||||
// Since these values are also used to tag content in Pstream,
|
||||
// the maximum number of types is limited to 30.
|
||||
enum tokenType
|
||||
// Since the enumeration is used to tag content in Pstream, it is of
|
||||
// type \c char and shall have values that do not overlap with regular
|
||||
// punctuation characters.
|
||||
enum tokenType : char
|
||||
{
|
||||
UNDEFINED = 0, //!< An undefined token-type
|
||||
UNDEFINED = '\0', //!< An undefined token-type
|
||||
ERROR = '\x80', //!< Token error encountered
|
||||
|
||||
// Fundamental types
|
||||
FLAG, //!< stream flag (1-byte bitmask)
|
||||
@ -86,14 +88,18 @@ public:
|
||||
DOUBLE, //!< double (double-precision) type
|
||||
|
||||
// Pointer types
|
||||
WORD, //!< A Foam::word
|
||||
STRING, //!< A string (usually double-quoted)
|
||||
DIRECTIVE, //!< A dictionary \c \#directive (word variant)
|
||||
VARIABLE, //!< A dictionary \c \$variable (string variant)
|
||||
VERBATIM, //!< Verbatim string content
|
||||
WORD, //!< Foam::word
|
||||
STRING, //!< Foam::string (usually double-quoted)
|
||||
COMPOUND, //!< Compound type such as \c List\<label\> etc.
|
||||
|
||||
ERROR, //!< A token error encountered
|
||||
DIRECTIVE, //!< Word-variant: dictionary \c \#directive
|
||||
//!< stored with sigil
|
||||
EXPRESSION, //!< String-variant: math expression for evaluation
|
||||
//!< stored with delimiters
|
||||
VARIABLE, //!< String-variant: dictionary \c \$variable
|
||||
//!< stored with sigil
|
||||
VERBATIM, //!< String-variant: verbatim string content
|
||||
//!< stored without delimiters
|
||||
|
||||
// Aliases
|
||||
FLOAT_SCALAR = FLOAT,
|
||||
@ -122,16 +128,16 @@ public:
|
||||
COLON = ':', //!< Colon [#isseparator]
|
||||
SEMICOLON = ';', //!< Semicolon [#isseparator]
|
||||
COMMA = ',', //!< Comma [#isseparator]
|
||||
HASH = '#', //!< Hash - directive or verbatim string
|
||||
DOLLAR = '$', //!< Dollar - start variable
|
||||
HASH = '#', //!< Hash - directive or start verbatim string
|
||||
DOLLAR = '$', //!< Dollar - start variable or expression
|
||||
QUESTION = '?', //!< Question mark (eg, ternary)
|
||||
ATSYM = '@', //!< The 'at' symbol
|
||||
SQUOTE = '\'', //!< Single quote
|
||||
DQUOTE = '"', //!< Double quote
|
||||
|
||||
ASSIGN = '=', //!< Assignment/equals [#isseparator]
|
||||
ADD = '+', //!< Addition [#isseparator]
|
||||
SUBTRACT = '-', //!< Subtract or start of negative number
|
||||
PLUS = '+', //!< Addition [#isseparator]
|
||||
MINUS = '-', //!< Subtract or start of negative number
|
||||
MULTIPLY = '*', //!< Multiply [#isseparator]
|
||||
DIVIDE = '/', //!< Divide [#isseparator]
|
||||
|
||||
@ -144,6 +150,8 @@ public:
|
||||
|
||||
// With semantically meaning
|
||||
|
||||
ADD = PLUS, //!< Addition [#isseparator]
|
||||
SUBTRACT = MINUS, //!< Subtract or start of negative number
|
||||
END_STATEMENT = SEMICOLON, //!< End entry [#isseparator]
|
||||
BEGIN_LIST = LPAREN, //!< Begin list [#isseparator]
|
||||
END_LIST = RPAREN, //!< End list [#isseparator]
|
||||
@ -471,10 +479,10 @@ public:
|
||||
//- Token is LABEL, FLOAT or DOUBLE
|
||||
inline bool isNumber() const noexcept;
|
||||
|
||||
//- Token is WORD or DIRECTIVE word
|
||||
//- Token is word-variant (WORD, DIRECTIVE)
|
||||
inline bool isWord() const noexcept;
|
||||
|
||||
//- Token is WORD or DIRECTIVE word and equal to parameter
|
||||
//- Token is word-variant and equal to parameter
|
||||
inline bool isWord(const std::string& s) const;
|
||||
|
||||
//- Token is DIRECTIVE (word variant)
|
||||
@ -483,16 +491,20 @@ public:
|
||||
//- Token is (quoted) STRING (string variant)
|
||||
inline bool isQuotedString() const noexcept;
|
||||
|
||||
//- Token is STRING, VARIABLE or VERBATIM (string variant)
|
||||
//- Token is string-variant (STRING, EXPRESSION, VARIABLE, VERBATIM)
|
||||
inline bool isString() const noexcept;
|
||||
|
||||
//- Token is EXPRESSION (string variant)
|
||||
inline bool isExpression() const noexcept;
|
||||
|
||||
//- Token is VARIABLE (string variant)
|
||||
inline bool isVariable() const noexcept;
|
||||
|
||||
//- Token is VERBATIM string (string variant)
|
||||
inline bool isVerbatim() const noexcept;
|
||||
|
||||
//- Token is WORD, DIRECTIVE, STRING, VARIABLE or VERBATIM
|
||||
//- Token is word-variant or string-variant
|
||||
//- (WORD, DIRECTIVE, STRING, EXPRESSION, VARIABLE, VERBATIM)
|
||||
inline bool isStringType() const noexcept;
|
||||
|
||||
//- Token is COMPOUND
|
||||
@ -542,7 +554,8 @@ public:
|
||||
|
||||
//- Return const reference to the string contents.
|
||||
// Report FatalIOError and return \b "" if token is not a
|
||||
// STRING, VARIABLE, VERBATIM or an upcast WORD or DIRECTIVE
|
||||
// STRING, EXPRESSION, VARIABLE, VERBATIM
|
||||
// or an upcast WORD or DIRECTIVE
|
||||
inline const string& stringToken() const;
|
||||
|
||||
//- Read access for compound token
|
||||
@ -599,16 +612,16 @@ public:
|
||||
//- Copy assign from double
|
||||
inline void operator=(const doubleScalar val);
|
||||
|
||||
//- Copy assign from word
|
||||
//- Copy assign from word content
|
||||
inline void operator=(const word& w);
|
||||
|
||||
//- Copy assign from string
|
||||
//- Copy assign from string content
|
||||
inline void operator=(const string& str);
|
||||
|
||||
//- Move assign from word
|
||||
//- Move assign from word content
|
||||
inline void operator=(word&& w);
|
||||
|
||||
//- Move assign from string
|
||||
//- Move assign from string content
|
||||
inline void operator=(string&& str);
|
||||
|
||||
//- Assign compound with reference counting to token
|
||||
|
||||
@ -66,8 +66,8 @@ inline bool Foam::token::isseparator(int c) noexcept
|
||||
case token::COLON :
|
||||
case token::COMMA :
|
||||
case token::ASSIGN :
|
||||
case token::ADD :
|
||||
// Excluded token::SUBTRACT since it could start a number
|
||||
case token::PLUS :
|
||||
// Excluded token::MINUS since it could start a number
|
||||
case token::MULTIPLY :
|
||||
case token::DIVIDE :
|
||||
{
|
||||
@ -121,6 +121,7 @@ inline Foam::token::token(const token& tok)
|
||||
}
|
||||
|
||||
case tokenType::STRING:
|
||||
case tokenType::EXPRESSION:
|
||||
case tokenType::VARIABLE:
|
||||
case tokenType::VERBATIM:
|
||||
{
|
||||
@ -265,6 +266,7 @@ inline void Foam::token::reset()
|
||||
}
|
||||
|
||||
case tokenType::STRING:
|
||||
case tokenType::EXPRESSION:
|
||||
case tokenType::VARIABLE:
|
||||
case tokenType::VERBATIM:
|
||||
{
|
||||
@ -357,6 +359,7 @@ inline bool Foam::token::setType(token::tokenType tokType) noexcept
|
||||
break;
|
||||
|
||||
case tokenType::STRING:
|
||||
case tokenType::EXPRESSION:
|
||||
case tokenType::VARIABLE:
|
||||
case tokenType::VERBATIM:
|
||||
{
|
||||
@ -364,6 +367,7 @@ inline bool Foam::token::setType(token::tokenType tokType) noexcept
|
||||
{
|
||||
// could also go from WORD to STRING etc - to be decided
|
||||
case tokenType::STRING:
|
||||
case tokenType::EXPRESSION:
|
||||
case tokenType::VARIABLE:
|
||||
case tokenType::VERBATIM:
|
||||
type_ = tokType;
|
||||
@ -651,12 +655,19 @@ inline bool Foam::token::isString() const noexcept
|
||||
return
|
||||
(
|
||||
type_ == tokenType::STRING
|
||||
|| type_ == tokenType::EXPRESSION
|
||||
|| type_ == tokenType::VARIABLE
|
||||
|| type_ == tokenType::VERBATIM
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::token::isExpression() const noexcept
|
||||
{
|
||||
return (type_ == tokenType::EXPRESSION);
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::token::isVariable() const noexcept
|
||||
{
|
||||
return (type_ == tokenType::VARIABLE);
|
||||
@ -680,6 +691,7 @@ inline const Foam::string& Foam::token::stringToken() const
|
||||
if
|
||||
(
|
||||
type_ == tokenType::STRING
|
||||
|| type_ == tokenType::EXPRESSION
|
||||
|| type_ == tokenType::VARIABLE
|
||||
|| type_ == tokenType::VERBATIM
|
||||
)
|
||||
@ -754,6 +766,7 @@ inline void Foam::token::operator=(const token& tok)
|
||||
break;
|
||||
|
||||
case tokenType::STRING:
|
||||
case tokenType::EXPRESSION:
|
||||
case tokenType::VARIABLE:
|
||||
case tokenType::VERBATIM:
|
||||
{
|
||||
@ -903,6 +916,7 @@ inline bool Foam::token::operator==(const token& tok) const
|
||||
return *data_.wordPtr == *tok.data_.wordPtr;
|
||||
|
||||
case tokenType::STRING:
|
||||
case tokenType::EXPRESSION:
|
||||
case tokenType::VARIABLE:
|
||||
case tokenType::VERBATIM:
|
||||
return *data_.stringPtr == *tok.data_.stringPtr;
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -82,6 +82,10 @@ static OS& printTokenInfo(OS& os, const token& tok)
|
||||
os << "string " << tok.stringToken();
|
||||
break;
|
||||
|
||||
case token::tokenType::EXPRESSION:
|
||||
os << "expression " << tok.stringToken();
|
||||
break;
|
||||
|
||||
case token::tokenType::VARIABLE:
|
||||
os << "variable " << tok.stringToken();
|
||||
break;
|
||||
@ -141,6 +145,7 @@ Foam::word Foam::token::name() const
|
||||
case token::tokenType::WORD: return "word";
|
||||
case token::tokenType::DIRECTIVE: return "directive";
|
||||
case token::tokenType::STRING: return "string";
|
||||
case token::tokenType::EXPRESSION: return "expression";
|
||||
case token::tokenType::VERBATIM: return "verbatim";
|
||||
case token::tokenType::VARIABLE: return "variable";
|
||||
case token::tokenType::COMPOUND: return "compound";
|
||||
@ -194,8 +199,10 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const token& tok)
|
||||
os << tok.data_.doubleVal;
|
||||
break;
|
||||
|
||||
// Different behaviour for (serial/parallel) streams: preserve types
|
||||
// Possibly different behaviour for serial/parallel streams:
|
||||
// preserve types
|
||||
case token::tokenType::DIRECTIVE:
|
||||
case token::tokenType::EXPRESSION:
|
||||
case token::tokenType::VARIABLE:
|
||||
case token::tokenType::VERBATIMSTRING:
|
||||
os.write(tok);
|
||||
|
||||
@ -56,60 +56,163 @@ namespace functionEntries
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is akin to a SafeIOWarning, which does not yet exist
|
||||
inline void safeIOWarning
|
||||
(
|
||||
const Foam::IOstream& is,
|
||||
const std::string& msg
|
||||
)
|
||||
{
|
||||
std::cerr
|
||||
<< "--> FOAM Warning :\n"
|
||||
<< " Reading \"" << is.name() << "\" at line "
|
||||
<< is.lineNumber() << '\n'
|
||||
<< " " << msg << std::endl;
|
||||
}
|
||||
|
||||
} // End anonymous namespace
|
||||
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Slurp a string until a closing '}' is found.
|
||||
// Track balanced bracket/brace pairs, with max stack depth of 60.
|
||||
static bool slurpUntilBalancedBrace(ISstream& is, std::string& str)
|
||||
{
|
||||
constexpr const unsigned bufLen = 1024;
|
||||
static char buf[bufLen];
|
||||
|
||||
is.fatalCheck(FUNCTION_NAME);
|
||||
|
||||
unsigned nChar = 0;
|
||||
unsigned depth = 1; // Initial '{' already seen by caller
|
||||
char c;
|
||||
|
||||
str.clear();
|
||||
while (is.get(c))
|
||||
{
|
||||
buf[nChar++] = c;
|
||||
|
||||
if (c == token::BEGIN_BLOCK)
|
||||
{
|
||||
++depth;
|
||||
}
|
||||
else if (c == token::END_BLOCK)
|
||||
{
|
||||
--depth;
|
||||
if (!depth)
|
||||
{
|
||||
// Closing '}' character - do not include in output
|
||||
--nChar;
|
||||
str.append(buf, nChar);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (c == '/')
|
||||
{
|
||||
// Strip C/C++ comments from expressions
|
||||
// Note: could also peek instead of get/putback
|
||||
|
||||
if (!is.get(c))
|
||||
{
|
||||
break; // Premature end of stream
|
||||
}
|
||||
else if (c == '/')
|
||||
{
|
||||
--nChar; // Remove initial '/' from buffer
|
||||
|
||||
// C++ comment: discard through newline
|
||||
(void) is.getLine(nullptr, '\n');
|
||||
}
|
||||
else if (c == '*')
|
||||
{
|
||||
--nChar; // Remove initial '/' from buffer
|
||||
|
||||
// C-style comment: discard through to "*/" ending
|
||||
if (!is.seekCommentEnd_Cstyle())
|
||||
{
|
||||
break; // Premature end of stream
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reanalyze the char
|
||||
is.putback(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (nChar == bufLen)
|
||||
{
|
||||
str.append(buf, nChar); // Flush full buffer
|
||||
nChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Abnormal exit of the loop
|
||||
|
||||
str.append(buf, nChar); // Finalize pending content
|
||||
|
||||
safeIOWarning(is, "Premature end while reading expression - missing '}'?");
|
||||
|
||||
is.fatalCheck(FUNCTION_NAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
Foam::tokenList Foam::functionEntries::evalEntry::evaluate
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
Istream& is
|
||||
const string& inputExpr,
|
||||
label fieldWidth,
|
||||
const Istream& is
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
DetailInfo
|
||||
<< "Using #eval - line "
|
||||
<< is.lineNumber() << " in file " << parentDict.name() << nl;
|
||||
#endif
|
||||
|
||||
token tok(is);
|
||||
label fieldWidth(1); // Field width for the result
|
||||
if (tok.isLabel())
|
||||
{
|
||||
// - #eval INT "expr"
|
||||
// - #eval INT { expr }
|
||||
// - #eval INT #{ expr #}
|
||||
fieldWidth = max(1, tok.labelToken());
|
||||
is >> tok;
|
||||
}
|
||||
|
||||
string s; // String to evaluate
|
||||
if (tok.isString())
|
||||
{
|
||||
// - #eval "expr"
|
||||
// - #eval #{ expr #}
|
||||
s = tok.stringToken();
|
||||
}
|
||||
else if (tok.isPunctuation(token::BEGIN_BLOCK))
|
||||
{
|
||||
// - #eval { expr }
|
||||
dynamic_cast<ISstream&>(is).getLine(s, token::END_BLOCK);
|
||||
}
|
||||
else
|
||||
// Field width for the result
|
||||
if (fieldWidth < 1)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Invalid input for #eval."
|
||||
" Expecting a string or block to evaluate, but found" << nl
|
||||
<< tok.info() << endl
|
||||
<< "Invalid field width: " << fieldWidth << nl << endl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
DetailInfo
|
||||
<< "input: " << s << endl;
|
||||
<< "input: " << inputExpr << endl;
|
||||
#endif
|
||||
|
||||
// Expand with env=true, empty=true, subDict=false
|
||||
// with comments stripped.
|
||||
// Special handling of $[...] syntax enabled.
|
||||
|
||||
string s;
|
||||
|
||||
// Passed '${{ expr }}' by accident, or on purpuse
|
||||
if
|
||||
(
|
||||
inputExpr[0] == token::DOLLAR
|
||||
&& inputExpr[1] == token::BEGIN_BLOCK
|
||||
&& inputExpr[2] == token::BEGIN_BLOCK
|
||||
&& inputExpr[inputExpr.length()-1] == token::END_BLOCK
|
||||
&& inputExpr[inputExpr.length()-2] == token::END_BLOCK
|
||||
)
|
||||
{
|
||||
s.assign(inputExpr, 3, inputExpr.length()-5);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.assign(inputExpr);
|
||||
}
|
||||
|
||||
expressions::exprString::inplaceExpand(s, parentDict, true);
|
||||
stringOps::inplaceTrim(s);
|
||||
|
||||
@ -184,6 +287,60 @@ Foam::tokenList Foam::functionEntries::evalEntry::evaluate
|
||||
}
|
||||
|
||||
|
||||
Foam::tokenList Foam::functionEntries::evalEntry::evaluate
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
DetailInfo
|
||||
<< "Using #eval - line "
|
||||
<< is.lineNumber() << " in file " << parentDict.name() << nl;
|
||||
#endif
|
||||
|
||||
token tok(is);
|
||||
label fieldWidth(1); // Field width for the result
|
||||
if (tok.isLabel())
|
||||
{
|
||||
// - #eval INT "expr"
|
||||
// - #eval INT { expr }
|
||||
// - #eval INT #{ expr #}
|
||||
fieldWidth = max(1, tok.labelToken());
|
||||
is >> tok;
|
||||
}
|
||||
|
||||
string str; // The string to evaluate
|
||||
if (tok.isString())
|
||||
{
|
||||
// - #eval "expr"
|
||||
// - #eval #{ expr #}
|
||||
// - #eval ${{ expr }} - wierd but handled
|
||||
str = tok.stringToken();
|
||||
}
|
||||
else if (tok.isPunctuation(token::BEGIN_BLOCK))
|
||||
{
|
||||
// - #eval { expr }
|
||||
slurpUntilBalancedBrace(dynamic_cast<ISstream&>(is), str);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Invalid input for #eval."
|
||||
" Expecting a string or block to evaluate, but found" << nl
|
||||
<< tok.info() << endl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
tokenList toks
|
||||
(
|
||||
evalEntry::evaluate(parentDict, str, fieldWidth, is)
|
||||
);
|
||||
|
||||
return toks;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::functionEntries::evalEntry::execute
|
||||
@ -201,4 +358,21 @@ bool Foam::functionEntries::evalEntry::execute
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionEntries::evalEntry::execute
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
primitiveEntry& entry,
|
||||
const string& inputExpr,
|
||||
label fieldWidth,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
tokenList toks(evaluate(parentDict, inputExpr, fieldWidth, is));
|
||||
|
||||
entry.append(std::move(toks), true); // Lazy resizing
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -87,18 +87,36 @@ class evalEntry
|
||||
{
|
||||
|
||||
//- Evaluate and return a token list
|
||||
static tokenList evaluate(const dictionary& parentDict, Istream& is);
|
||||
static tokenList evaluate
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
const string& inputExpr, //!< String to expand and evaluate
|
||||
label fieldWidth, //!< Field width for the result
|
||||
const Istream& is //!< For reporting errors
|
||||
);
|
||||
|
||||
//- Evaluate and return a token list
|
||||
static tokenList evaluate(const dictionary& parentDict, Istream& is);
|
||||
|
||||
public:
|
||||
|
||||
//- Execute in a primitiveEntry context
|
||||
//- Execute in a primitiveEntry context, extracts token or line
|
||||
static bool execute
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
primitiveEntry& thisEntry,
|
||||
Istream& is
|
||||
);
|
||||
|
||||
//- Execute in a primitiveEntry context, evaluating the given content
|
||||
static bool execute
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
primitiveEntry& entry,
|
||||
const string& inputExpr,
|
||||
label fieldWidth,
|
||||
Istream& is
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -90,7 +90,8 @@ bool Foam::functionEntry::execute
|
||||
|
||||
if (!executedictionaryIstreamMemberFunctionTablePtr_)
|
||||
{
|
||||
cerr<< FUNCTION_NAME << nl
|
||||
std::cerr
|
||||
<< FUNCTION_NAME << nl
|
||||
<< "Not yet initialized, function = "
|
||||
<< functionName.c_str() << std::endl;
|
||||
|
||||
@ -128,7 +129,8 @@ bool Foam::functionEntry::execute
|
||||
|
||||
if (!executeprimitiveEntryIstreamMemberFunctionTablePtr_)
|
||||
{
|
||||
cerr<< FUNCTION_NAME << nl
|
||||
std::cerr
|
||||
<< FUNCTION_NAME << nl
|
||||
<< "Not yet initialized, function = "
|
||||
<< functionName.c_str() << std::endl;
|
||||
|
||||
|
||||
@ -58,12 +58,7 @@ void Foam::functionEntries::ifeqEntry::readToken(token& t, Istream& is)
|
||||
// Skip dummy tokens - avoids entry::getKeyword consuming #else, #endif
|
||||
do
|
||||
{
|
||||
if
|
||||
(
|
||||
is.read(t).bad()
|
||||
|| is.eof()
|
||||
|| !t.good()
|
||||
)
|
||||
if (is.read(t).bad() || is.eof() || !t.good())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -72,7 +67,7 @@ void Foam::functionEntries::ifeqEntry::readToken(token& t, Istream& is)
|
||||
}
|
||||
|
||||
|
||||
Foam::token Foam::functionEntries::ifeqEntry::expand
|
||||
Foam::token Foam::functionEntries::ifeqEntry::expandToken
|
||||
(
|
||||
const dictionary& dict,
|
||||
const string& keyword,
|
||||
@ -109,7 +104,7 @@ Foam::token Foam::functionEntries::ifeqEntry::expand
|
||||
}
|
||||
|
||||
|
||||
Foam::token Foam::functionEntries::ifeqEntry::expand
|
||||
Foam::token Foam::functionEntries::ifeqEntry::expandToken
|
||||
(
|
||||
const dictionary& dict,
|
||||
const token& t
|
||||
@ -117,15 +112,15 @@ Foam::token Foam::functionEntries::ifeqEntry::expand
|
||||
{
|
||||
if (t.isWord())
|
||||
{
|
||||
return expand(dict, t.wordToken(), t);
|
||||
return expandToken(dict, t.wordToken(), t);
|
||||
}
|
||||
else if (t.isVariable())
|
||||
{
|
||||
return expand(dict, t.stringToken(), t);
|
||||
return expandToken(dict, t.stringToken(), t);
|
||||
}
|
||||
else if (t.isString())
|
||||
{
|
||||
return expand(dict, t.stringToken(), t);
|
||||
return expandToken(dict, t.stringToken(), t);
|
||||
}
|
||||
|
||||
return t;
|
||||
@ -230,6 +225,9 @@ bool Foam::functionEntries::ifeqEntry::equalToken
|
||||
}
|
||||
return false;
|
||||
|
||||
case token::EXPRESSION:
|
||||
return false;
|
||||
|
||||
case token::COMPOUND:
|
||||
return false;
|
||||
|
||||
@ -245,7 +243,7 @@ void Foam::functionEntries::ifeqEntry::skipUntil
|
||||
(
|
||||
DynamicList<filePos>& stack,
|
||||
const dictionary& parentDict,
|
||||
const word& endWord,
|
||||
const word& endDirective,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
@ -258,28 +256,26 @@ void Foam::functionEntries::ifeqEntry::skipUntil
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if
|
||||
(
|
||||
t.wordToken() == "#if"
|
||||
|| t.wordToken() == "#ifeq"
|
||||
)
|
||||
else if (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
|
||||
{
|
||||
stack.append(filePos(is.name(), is.lineNumber()));
|
||||
skipUntil(stack, parentDict, "#endif", is);
|
||||
stack.remove();
|
||||
}
|
||||
else if (t.wordToken() == endWord)
|
||||
else if (t.wordToken() == endDirective)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FatalIOErrorInFunction(parentDict)
|
||||
<< "Did not find matching " << endWord << nl
|
||||
<< "Did not find matching " << endDirective << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::functionEntries::ifeqEntry::evaluate
|
||||
(
|
||||
const bool doIf,
|
||||
@ -292,35 +288,47 @@ bool Foam::functionEntries::ifeqEntry::evaluate
|
||||
{
|
||||
token t;
|
||||
readToken(t, is);
|
||||
bool pending = false;
|
||||
|
||||
if (t.isWord() && t.wordToken() == "#ifeq")
|
||||
if (t.isDirective())
|
||||
{
|
||||
// Recurse to evaluate
|
||||
execute(stack, parentDict, is);
|
||||
}
|
||||
else if (t.isWord() && t.wordToken() == "#if")
|
||||
{
|
||||
// Recurse to evaluate
|
||||
ifEntry::execute(stack, parentDict, is);
|
||||
}
|
||||
else if
|
||||
(
|
||||
doIf
|
||||
&& t.isWord()
|
||||
&& (t.wordToken() == "#else" || t.wordToken() == "#elif")
|
||||
)
|
||||
{
|
||||
// Now skip until #endif
|
||||
skipUntil(stack, parentDict, "#endif", is);
|
||||
stack.remove();
|
||||
break;
|
||||
}
|
||||
else if (t.isWord() && t.wordToken() == "#endif")
|
||||
{
|
||||
stack.remove();
|
||||
break;
|
||||
if (t.wordToken() == "#ifeq")
|
||||
{
|
||||
// Recurse to evaluate
|
||||
execute(stack, parentDict, is);
|
||||
}
|
||||
else if (t.wordToken() == "#if")
|
||||
{
|
||||
// Recurse to evaluate
|
||||
ifEntry::execute(stack, parentDict, is);
|
||||
}
|
||||
else if
|
||||
(
|
||||
doIf
|
||||
&& (t.wordToken() == "#else" || t.wordToken() == "#elif")
|
||||
)
|
||||
{
|
||||
// Now skip until #endif
|
||||
skipUntil(stack, parentDict, "#endif", is);
|
||||
stack.remove();
|
||||
break;
|
||||
}
|
||||
else if (t.wordToken() == "#endif")
|
||||
{
|
||||
stack.remove();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pending = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pending = true;
|
||||
}
|
||||
|
||||
if (pending)
|
||||
{
|
||||
is.putBack(t);
|
||||
bool ok = entry::New(parentDict, is);
|
||||
@ -354,21 +362,23 @@ bool Foam::functionEntries::ifeqEntry::execute
|
||||
{
|
||||
readToken(t, is);
|
||||
|
||||
if
|
||||
(
|
||||
t.isWord()
|
||||
&& (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
|
||||
)
|
||||
// Only consider directives
|
||||
if (!t.isDirective())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
|
||||
{
|
||||
stack.append(filePos(is.name(), is.lineNumber()));
|
||||
skipUntil(stack, parentDict, "#endif", is);
|
||||
stack.remove();
|
||||
}
|
||||
else if (t.isWord() && t.wordToken() == "#else")
|
||||
else if (t.wordToken() == "#else")
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (t.isWord() && t.wordToken() == "#elif")
|
||||
else if (t.wordToken() == "#elif")
|
||||
{
|
||||
// const label lineNo = is.lineNumber();
|
||||
|
||||
@ -386,7 +396,7 @@ bool Foam::functionEntries::ifeqEntry::execute
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (t.isWord() && t.wordToken() == "#endif")
|
||||
else if (t.wordToken() == "#endif")
|
||||
{
|
||||
stack.remove();
|
||||
break;
|
||||
@ -421,11 +431,11 @@ bool Foam::functionEntries::ifeqEntry::execute
|
||||
|
||||
// Read first token and expand any string
|
||||
token cond1(is);
|
||||
cond1 = expand(parentDict, cond1);
|
||||
cond1 = expandToken(parentDict, cond1);
|
||||
|
||||
// Read second token and expand any string
|
||||
token cond2(is);
|
||||
cond2 = expand(parentDict, cond2);
|
||||
cond2 = expandToken(parentDict, cond2);
|
||||
|
||||
const bool equal = equalToken(cond1, cond2);
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018 OpenFOAM Foundation
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,7 +32,7 @@ Description
|
||||
|
||||
E.g.
|
||||
\verbatim
|
||||
a #calc "0.123";
|
||||
a #eval "0.123";
|
||||
b 1.23e-1;
|
||||
|
||||
#ifeq $a $b
|
||||
@ -90,46 +91,15 @@ class ifeqEntry
|
||||
:
|
||||
public functionEntry
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
// Data Types
|
||||
|
||||
typedef Tuple2<fileName, label> filePos;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Read tokens. Skip dummy tokens
|
||||
static void readToken(token& t, Istream& is);
|
||||
|
||||
//- Expand a variable (string/word/var starting with '$')
|
||||
static token expand
|
||||
(
|
||||
const dictionary& dict,
|
||||
const string& keyword,
|
||||
const token& t
|
||||
);
|
||||
|
||||
//- Expand a string/word/var token
|
||||
static token expand
|
||||
(
|
||||
const dictionary& dict,
|
||||
const token& t
|
||||
);
|
||||
|
||||
static bool equalToken
|
||||
(
|
||||
const token& t1,
|
||||
const token& t2
|
||||
);
|
||||
|
||||
//- Consume tokens until reached a specific word
|
||||
static void skipUntil
|
||||
(
|
||||
DynamicList<filePos>& stack,
|
||||
const dictionary& parentDict,
|
||||
const word& endWord,
|
||||
Istream& is
|
||||
);
|
||||
|
||||
static bool evaluate
|
||||
(
|
||||
const bool doIf,
|
||||
@ -158,6 +128,41 @@ protected:
|
||||
);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Read tokens. Skip dummy tokens
|
||||
static void readToken(token& t, Istream& is);
|
||||
|
||||
//- Expand a variable (string/word/var starting with '$')
|
||||
static token expandToken
|
||||
(
|
||||
const dictionary& dict,
|
||||
const string& keyword,
|
||||
const token& t
|
||||
);
|
||||
|
||||
//- Expand a string/word/var token
|
||||
static token expandToken
|
||||
(
|
||||
const dictionary& dict,
|
||||
const token& t
|
||||
);
|
||||
|
||||
//- Test for equality
|
||||
static bool equalToken(const token& t1, const token& t2);
|
||||
|
||||
//- Consume tokens until reached a specific directive
|
||||
static void skipUntil
|
||||
(
|
||||
DynamicList<filePos>& stack,
|
||||
const dictionary& parentDict,
|
||||
const word& endDirective, //!< end directive (without '#')
|
||||
Istream& is
|
||||
);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
|
||||
122
src/OpenFOAM/db/dictionary/namedDictionary/namedDictionary.C
Normal file
122
src/OpenFOAM/db/dictionary/namedDictionary/namedDictionary.C
Normal file
@ -0,0 +1,122 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenFOAM Foundation
|
||||
Copyright (C) 2021 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "namedDictionary.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::namedDictionary::namedDictionary()
|
||||
:
|
||||
Tuple2<keyType, dictionary>()
|
||||
{}
|
||||
|
||||
|
||||
Foam::namedDictionary::namedDictionary(Istream& is)
|
||||
{
|
||||
is >> *this;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::namedDictionary::clear()
|
||||
{
|
||||
first().clear();
|
||||
second().clear();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::namedDictionary::empty() const noexcept
|
||||
{
|
||||
return (first().empty() && second().empty());
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, namedDictionary& obj)
|
||||
{
|
||||
obj.clear();
|
||||
|
||||
// Three possible inputs:
|
||||
// - key
|
||||
// - key { ... }
|
||||
// - { ... }
|
||||
|
||||
// Minor consistency with primitiveEntry, also accept the following:
|
||||
// - key ;
|
||||
|
||||
token tok(is);
|
||||
is.putBack(tok);
|
||||
|
||||
if (!tok.isPunctuation(token::BEGIN_BLOCK))
|
||||
{
|
||||
is >> obj.keyword();
|
||||
is >> tok;
|
||||
|
||||
// Discards possible trailing ';'
|
||||
if (!tok.isPunctuation(token::END_STATEMENT))
|
||||
{
|
||||
is.putBack(tok);
|
||||
}
|
||||
}
|
||||
|
||||
if (tok.isPunctuation(token::BEGIN_BLOCK))
|
||||
{
|
||||
obj.dict().read(is);
|
||||
}
|
||||
|
||||
is.check(FUNCTION_NAME);
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const namedDictionary& obj)
|
||||
{
|
||||
// Three possible outputs:
|
||||
// - key
|
||||
// - key { ... }
|
||||
// - { ... }
|
||||
// No distinction between a missing and an empty dictionary
|
||||
|
||||
if (obj.keyword().empty() || !obj.dict().empty())
|
||||
{
|
||||
// Never allow empty output.
|
||||
// Otherwise cannot re-read for streaming
|
||||
obj.dict().writeEntry(obj.keyword(), os);
|
||||
}
|
||||
else
|
||||
{
|
||||
os << obj.keyword();
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
154
src/OpenFOAM/db/dictionary/namedDictionary/namedDictionary.H
Normal file
154
src/OpenFOAM/db/dictionary/namedDictionary/namedDictionary.H
Normal file
@ -0,0 +1,154 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenFOAM Foundation
|
||||
Copyright (C) 2021 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/>.
|
||||
|
||||
Class
|
||||
Foam::namedDictionary
|
||||
|
||||
Description
|
||||
A tuple of keyType and dictionary, which can be used when reading
|
||||
named or unnamed dictionary entries or simply a name.
|
||||
|
||||
For example,
|
||||
\verbatim
|
||||
fields
|
||||
(
|
||||
U
|
||||
T { relax false; }
|
||||
);
|
||||
\endverbatim
|
||||
|
||||
In can also be used in situations where an individual dictionary entry
|
||||
should be read.
|
||||
\verbatim
|
||||
actions
|
||||
(
|
||||
testing { action new; ... } // An action with a name
|
||||
{ action subset; } // Unnamed action
|
||||
);
|
||||
\endverbatim
|
||||
Normal dictionary reading would fail for this type of input since the
|
||||
leading 'testing' keyword would cause the entire content to be considered
|
||||
a single dictionary.
|
||||
|
||||
Note
|
||||
No distinction currently made between a missing and an empty dictionary.
|
||||
|
||||
SourceFiles
|
||||
namedDictionary.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef namedDictionary_H
|
||||
#define namedDictionary_H
|
||||
|
||||
#include "dictionary.H"
|
||||
#include "Tuple2.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class namedDictionary;
|
||||
Istream& operator>>(Istream&, namedDictionary&);
|
||||
Ostream& operator<<(Ostream&, const namedDictionary&);
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class namedDictionary Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class namedDictionary
|
||||
:
|
||||
public Tuple2<keyType, dictionary>
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Inherit constructors
|
||||
using Tuple2<keyType, dictionary>::Tuple2;
|
||||
|
||||
//- Default construct
|
||||
namedDictionary();
|
||||
|
||||
//- Construct from Istream
|
||||
explicit namedDictionary(Istream& is);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~namedDictionary() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Clear keyword and dictionary
|
||||
void clear();
|
||||
|
||||
//- Empty if both keyword and dictionary are empty
|
||||
bool empty() const noexcept;
|
||||
|
||||
//- Return keyword
|
||||
const keyType& keyword() const noexcept
|
||||
{
|
||||
return first();
|
||||
}
|
||||
|
||||
//- Return non-const access to keyword
|
||||
keyType& keyword() noexcept
|
||||
{
|
||||
return first();
|
||||
}
|
||||
|
||||
//- Read-access to the dictionay
|
||||
const dictionary& dict() const noexcept
|
||||
{
|
||||
return second();
|
||||
}
|
||||
|
||||
//- Write access to the dictionay
|
||||
dictionary& dict() noexcept
|
||||
{
|
||||
return second();
|
||||
}
|
||||
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
friend Istream& operator>>(Istream&, namedDictionary&);
|
||||
friend Ostream& operator<<(Ostream&, const namedDictionary&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -35,7 +35,7 @@ License
|
||||
|
||||
// Find the type/position of the ":-" or ":+" alternative values
|
||||
// Returns 0, '-', '+' corresponding to not-found or ':-' or ':+'
|
||||
static inline int findParameterAlternative
|
||||
static inline char findParameterAlternative
|
||||
(
|
||||
const std::string& s,
|
||||
std::string::size_type& pos,
|
||||
@ -50,7 +50,7 @@ static inline int findParameterAlternative
|
||||
if (pos < endPos)
|
||||
{
|
||||
// in-range: check for '+' or '-' following the ':'
|
||||
const int altType = s[pos+1];
|
||||
const char altType = s[pos+1];
|
||||
if (altType == '+' || altType == '-')
|
||||
{
|
||||
return altType;
|
||||
@ -78,11 +78,13 @@ bool Foam::primitiveEntry::expandVariable
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
int altType = 0; // Type ('-' or '+') for ":-" or ":+" alternatives
|
||||
char altType = 0; // Type ('-' or '+') for ":-" or ":+" alternatives
|
||||
word expanded;
|
||||
string altValue;
|
||||
|
||||
if (varName.size() > 1 && varName[0] == token::BEGIN_BLOCK)
|
||||
// Any ${{ expr }} entries have been trapped and processed elsewhere
|
||||
|
||||
if (varName[0] == token::BEGIN_BLOCK && varName.size() > 1)
|
||||
{
|
||||
// Replace content between {} with string expansion and
|
||||
// handle ${parameter:-word} or ${parameter:+word}
|
||||
|
||||
@ -28,6 +28,7 @@ License
|
||||
|
||||
#include "primitiveEntry.H"
|
||||
#include "functionEntry.H"
|
||||
#include "evalEntry.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
@ -63,25 +64,51 @@ bool Foam::primitiveEntry::acceptToken
|
||||
|
||||
if (tok.isDirective())
|
||||
{
|
||||
// Directive: wordToken starts with '#'
|
||||
// Directive (wordToken) begins with '#'. Eg, "#include"
|
||||
// Remove leading '#' sigil before dispatching
|
||||
|
||||
const word& key = tok.wordToken();
|
||||
|
||||
// Min-size is 2: sigil '#' with any content
|
||||
accept =
|
||||
(
|
||||
disableFunctionEntries
|
||||
|| key.size() == 1
|
||||
(disableFunctionEntries || key.size() < 2)
|
||||
|| !expandFunction(key.substr(1), dict, is)
|
||||
);
|
||||
}
|
||||
else if (tok.isExpression())
|
||||
{
|
||||
// Expression (stringToken): ${{ expr }}
|
||||
// Surrounding delimiters are stripped as required in evalEntry
|
||||
|
||||
const string& key = tok.stringToken();
|
||||
|
||||
// Min-size is 6: decorators '${{}}' with any content
|
||||
accept =
|
||||
(
|
||||
(disableFunctionEntries || key.size() < 6)
|
||||
|| !functionEntries::evalEntry::execute
|
||||
(
|
||||
dict,
|
||||
*this,
|
||||
key,
|
||||
1, // Field width is 1
|
||||
is // For error messages
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (tok.isVariable())
|
||||
{
|
||||
// Variable: stringToken starts with '$'
|
||||
// Variable (stringToken): starts with '$'
|
||||
// Eg, "$varName" or "${varName}"
|
||||
// Remove leading '$' sigil before dispatching
|
||||
|
||||
const string& key = tok.stringToken();
|
||||
|
||||
// Min-size is 2: sigil '$' with any content
|
||||
accept =
|
||||
(
|
||||
disableFunctionEntries
|
||||
|| key.size() == 1
|
||||
(disableFunctionEntries || key.size() < 2)
|
||||
|| !expandVariable(key.substr(1), dict)
|
||||
);
|
||||
}
|
||||
@ -116,7 +143,7 @@ bool Foam::primitiveEntry::read(const dictionary& dict, Istream& is)
|
||||
// - similarly, the bitmask is tested *after* decreasing depth
|
||||
|
||||
uint64_t balanced = 0u;
|
||||
label depth = 0;
|
||||
int depth = 0;
|
||||
token tok;
|
||||
|
||||
while
|
||||
@ -274,19 +301,18 @@ void Foam::primitiveEntry::write(Ostream& os, const bool contentsOnly) const
|
||||
os.writeKeyword(keyword());
|
||||
}
|
||||
|
||||
bool addSpace = false; // Separate from previous tokens with a space
|
||||
bool addSpace = false; // Separate from previous token with a space
|
||||
for (const token& tok : *this)
|
||||
{
|
||||
if (addSpace) os << token::SPACE;
|
||||
addSpace = true;
|
||||
|
||||
// Try to output token directly, with special handling in Ostreams.
|
||||
|
||||
// Output token with direct handling in Ostream(s),
|
||||
// or use normal '<<' output operator
|
||||
if (!os.write(tok))
|
||||
{
|
||||
os << tok; // Revert to normal '<<' output operator
|
||||
os << tok;
|
||||
}
|
||||
|
||||
addSpace = true; // Separate from following tokens
|
||||
}
|
||||
|
||||
if (!contentsOnly)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -243,91 +243,42 @@ bool Foam::functionObjectList::readFunctionObject
|
||||
// 'patchAverage(patch=inlet, p)' -> funcName = patchAverage;
|
||||
// args = (patch=inlet, p); field = p
|
||||
|
||||
word funcName(funcNameArgs);
|
||||
|
||||
int argLevel = 0;
|
||||
word funcName;
|
||||
wordRes args;
|
||||
|
||||
List<Tuple2<word, string>> namedArgs;
|
||||
bool hasNamedArg = false;
|
||||
word argName;
|
||||
|
||||
word::size_type start = 0;
|
||||
word::size_type i = 0;
|
||||
|
||||
for
|
||||
(
|
||||
word::const_iterator iter = funcNameArgs.begin();
|
||||
iter != funcNameArgs.end();
|
||||
++iter
|
||||
)
|
||||
{
|
||||
char c = *iter;
|
||||
|
||||
if (c == '(')
|
||||
const auto argsBeg = funcNameArgs.find('(');
|
||||
if (argsBeg == std::string::npos)
|
||||
{
|
||||
if (argLevel == 0)
|
||||
{
|
||||
funcName = funcNameArgs.substr(start, i - start);
|
||||
start = i+1;
|
||||
}
|
||||
++argLevel;
|
||||
// Function name only, no args
|
||||
funcName = word::validate(funcNameArgs);
|
||||
}
|
||||
else if (c == ',' || c == ')')
|
||||
else
|
||||
{
|
||||
if (argLevel == 1)
|
||||
{
|
||||
if (hasNamedArg)
|
||||
{
|
||||
namedArgs.append
|
||||
(
|
||||
Tuple2<word, string>
|
||||
(
|
||||
argName,
|
||||
funcNameArgs.substr(start, i - start)
|
||||
)
|
||||
);
|
||||
hasNamedArg = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.append
|
||||
(
|
||||
wordRe
|
||||
(
|
||||
word::validate
|
||||
(
|
||||
funcNameArgs.substr(start, i - start)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
start = i+1;
|
||||
}
|
||||
// Leading function name
|
||||
funcName = word::validate(funcNameArgs.substr(0, argsBeg));
|
||||
|
||||
if (c == ')')
|
||||
{
|
||||
if (argLevel == 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
--argLevel;
|
||||
}
|
||||
}
|
||||
else if (c == '=')
|
||||
{
|
||||
argName = word::validate
|
||||
const auto argsEnd = funcNameArgs.rfind(')');
|
||||
|
||||
stringOps::splitFunctionArgs
|
||||
(
|
||||
funcNameArgs.substr(start, i - start)
|
||||
funcNameArgs.substr
|
||||
(
|
||||
(argsBeg + 1),
|
||||
(
|
||||
(argsEnd != std::string::npos && argsBeg < argsEnd)
|
||||
? (argsEnd - argsBeg - 1)
|
||||
: std::string::npos
|
||||
)
|
||||
),
|
||||
args,
|
||||
namedArgs
|
||||
);
|
||||
|
||||
start = i+1;
|
||||
hasNamedArg = true;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
// Search for the functionObject dictionary
|
||||
fileName path = functionObjectList::findDict(funcName);
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -145,16 +145,37 @@ Istream& operator>>(Istream& is, Scalar& val)
|
||||
return is;
|
||||
}
|
||||
|
||||
// Accept separated '-' (or '+') while expecting a number.
|
||||
// This can arise during dictionary expansions (Eg, -$value)
|
||||
|
||||
char prefix = 0;
|
||||
if (t.isPunctuation())
|
||||
{
|
||||
prefix = t.pToken();
|
||||
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||
{
|
||||
is >> t;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isNumber())
|
||||
{
|
||||
val = t.number();
|
||||
val =
|
||||
(
|
||||
(prefix == token::MINUS)
|
||||
? (0 - t.number())
|
||||
: t.number()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Wrong token type - expected scalar value, found "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
<< "Wrong token type - expected scalar value, found ";
|
||||
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||
{
|
||||
FatalIOError << '\'' << prefix << "' followed by ";
|
||||
}
|
||||
FatalIOError << t.info() << exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2014-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -100,13 +100,36 @@ Foam::Istream& Foam::operator>>(Istream& is, int32_t& val)
|
||||
return is;
|
||||
}
|
||||
|
||||
// Accept separated '-' (or '+') while expecting a number.
|
||||
// This can arise during dictionary expansions (Eg, -$value)
|
||||
|
||||
char prefix = 0;
|
||||
if (t.isPunctuation())
|
||||
{
|
||||
prefix = t.pToken();
|
||||
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||
{
|
||||
is >> t;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isLabel())
|
||||
{
|
||||
val = int32_t(t.labelToken());
|
||||
val = int32_t
|
||||
(
|
||||
(prefix == token::MINUS)
|
||||
? (0 - t.labelToken())
|
||||
: t.labelToken()
|
||||
);
|
||||
}
|
||||
else if (t.isScalar())
|
||||
{
|
||||
const scalar sval(t.scalarToken());
|
||||
const scalar sval
|
||||
(
|
||||
(prefix == token::MINUS)
|
||||
? (0 - t.scalarToken())
|
||||
: t.scalarToken()
|
||||
);
|
||||
const intmax_t parsed = intmax_t(std::round(sval));
|
||||
val = 0 + int32_t(parsed);
|
||||
|
||||
@ -135,9 +158,12 @@ Foam::Istream& Foam::operator>>(Istream& is, int32_t& val)
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Wrong token type - expected label (int32), found "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
<< "Wrong token type - expected label (int32), found ";
|
||||
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||
{
|
||||
FatalIOError << '\'' << prefix << "' followed by ";
|
||||
}
|
||||
FatalIOError << t.info() << exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2014-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -100,13 +100,37 @@ Foam::Istream& Foam::operator>>(Istream& is, int64_t& val)
|
||||
return is;
|
||||
}
|
||||
|
||||
// Accept separated '-' (or '+') while expecting a number.
|
||||
// This can arise during dictionary expansions (Eg, -$value)
|
||||
|
||||
char prefix = 0;
|
||||
if (t.isPunctuation())
|
||||
{
|
||||
prefix = t.pToken();
|
||||
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||
{
|
||||
is >> t;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isLabel())
|
||||
{
|
||||
val = int64_t(t.labelToken());
|
||||
val = int64_t
|
||||
(
|
||||
(prefix == token::MINUS)
|
||||
? (0 - t.labelToken())
|
||||
: t.labelToken()
|
||||
);
|
||||
}
|
||||
else if (t.isScalar())
|
||||
{
|
||||
const scalar sval(t.scalarToken());
|
||||
const scalar sval
|
||||
(
|
||||
(prefix == token::MINUS)
|
||||
? (0 - t.scalarToken())
|
||||
: t.scalarToken()
|
||||
);
|
||||
|
||||
const intmax_t parsed = intmax_t(std::round(sval));
|
||||
val = 0 + int64_t(parsed);
|
||||
|
||||
@ -135,9 +159,12 @@ Foam::Istream& Foam::operator>>(Istream& is, int64_t& val)
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Wrong token type - expected label (int64), found "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
<< "Wrong token type - expected label (int64), found ";
|
||||
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||
{
|
||||
FatalIOError << '\'' << prefix << "' followed by ";
|
||||
}
|
||||
FatalIOError << t.info() << exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
|
||||
@ -693,7 +693,7 @@ static void expandString
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
std::string::size_type Foam::stringOps::count
|
||||
(
|
||||
|
||||
@ -57,6 +57,7 @@ namespace Foam
|
||||
|
||||
// Forward Declarations
|
||||
class OSstream;
|
||||
template<class T1, class T2> class Tuple2;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Namespace stringOps Declaration
|
||||
@ -282,6 +283,14 @@ namespace stringOps
|
||||
// Return true if a replacement was successful.
|
||||
bool inplaceReplaceVar(std::string& s, const word& varName);
|
||||
|
||||
//- Return a copy of the input string with validated characters
|
||||
template<class StringType, class UnaryPredicate>
|
||||
StringType validate
|
||||
(
|
||||
const std::string& str,
|
||||
const UnaryPredicate& accept,
|
||||
const bool invert=false //!< Invert the test logic
|
||||
);
|
||||
|
||||
//- Find (first, last) non-space locations in string or sub-string.
|
||||
// This may change to std::string_view in the future.
|
||||
@ -334,6 +343,30 @@ namespace stringOps
|
||||
//- Inplace transform string with std::toupper on each character
|
||||
void inplaceUpper(std::string& s);
|
||||
|
||||
//- Split out arguments (named or unnamed) from an input string.
|
||||
//
|
||||
// For example,
|
||||
// \verbatim
|
||||
// (U)
|
||||
// -> named = ()
|
||||
// -> unnamed = (U)
|
||||
//
|
||||
// (patch=inlet, p)
|
||||
// -> named = ((patch inlet))
|
||||
// -> unnamed = (p)
|
||||
//
|
||||
// testing, start=100, stop=200
|
||||
// -> named = ((start 100)(stop 200))
|
||||
// -> unnamed = (testing)
|
||||
// \endverbatim
|
||||
//
|
||||
// \return total number of arguments
|
||||
label splitFunctionArgs
|
||||
(
|
||||
const std::string& str,
|
||||
wordRes& args,
|
||||
List<Tuple2<word, string>>& namedArgs
|
||||
);
|
||||
|
||||
//- Split string into sub-strings at the delimiter character.
|
||||
// Empty sub-strings are normally suppressed.
|
||||
|
||||
221
src/OpenFOAM/primitives/strings/stringOps/stringOpsSplit.C
Normal file
221
src/OpenFOAM/primitives/strings/stringOps/stringOpsSplit.C
Normal file
@ -0,0 +1,221 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016 OpenFOAM Foundation
|
||||
Copyright (C) 2021 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stringOps.H"
|
||||
#include "Pair.H"
|
||||
#include "Tuple2.H"
|
||||
#include <vector>
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
inline Foam::word validateVariableName(const std::string& str)
|
||||
{
|
||||
return Foam::stringOps::validate<Foam::word>
|
||||
(
|
||||
str,
|
||||
[](char c)
|
||||
{
|
||||
return (Foam::word::valid(c) || c == '/' || c == '{' || c == '}');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
} // End anonymous namespace
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::stringOps::splitFunctionArgs
|
||||
(
|
||||
const std::string& str,
|
||||
wordRes& args,
|
||||
List<Tuple2<word, string>>& namedArgs
|
||||
)
|
||||
{
|
||||
args.clear();
|
||||
namedArgs.clear();
|
||||
|
||||
// Similar to code originally in functionObjectList (v2012 and earlier)
|
||||
// except that the function-name handling is now done prior to calling
|
||||
|
||||
// (U)
|
||||
// -> named = ()
|
||||
// -> unnamed = (U)
|
||||
//
|
||||
// (patch=inlet, p)
|
||||
// -> named = ((patch inlet))
|
||||
// -> unnamed = (p)
|
||||
//
|
||||
// start=100, stop=200
|
||||
// -> named = ((start 100) (stop 200) )
|
||||
// -> unnamed = ()
|
||||
//
|
||||
// origin=(0 0 0) , scale=2 , normal=(0 0 1)
|
||||
|
||||
|
||||
// Use begin/end parse positions
|
||||
typedef Pair<std::string::size_type> rangeType;
|
||||
|
||||
// For unnamed: beg/end range of each arg
|
||||
std::vector<rangeType> unnamed;
|
||||
|
||||
// For named: list of beg/end ranges for (name, arg)
|
||||
std::vector<rangeType> named;
|
||||
|
||||
// The beg/end range of the argument name
|
||||
rangeType argName(0, 0);
|
||||
|
||||
// If argName is valid
|
||||
bool isNamed = false;
|
||||
|
||||
// The depth of the argument parsing
|
||||
int argLevel = 0;
|
||||
|
||||
const auto strLen = str.length();
|
||||
|
||||
// Pass 1: parsing begin/end parse positions.
|
||||
|
||||
for (std::string::size_type pos = 0, beg = 0; pos < strLen; ++pos)
|
||||
{
|
||||
const bool penultimate = ((pos + 1) == strLen);
|
||||
const char c = str[pos];
|
||||
|
||||
if (c == ')')
|
||||
{
|
||||
--argLevel;
|
||||
}
|
||||
|
||||
if (c == '=')
|
||||
{
|
||||
// Introducer for named argument
|
||||
argName = rangeType(beg, pos);
|
||||
isNamed = true;
|
||||
beg = pos + 1;
|
||||
}
|
||||
else if (c == '(')
|
||||
{
|
||||
++argLevel;
|
||||
}
|
||||
else if (penultimate || (c == ',')) // OR: (c == ',' || c == ';')
|
||||
{
|
||||
if (penultimate && (c != ',')) // OR: (c != ',' && c != ';')
|
||||
{
|
||||
++pos; // Until the end, but do not include comma
|
||||
}
|
||||
|
||||
if (argLevel == 0)
|
||||
{
|
||||
if (isNamed)
|
||||
{
|
||||
named.push_back(argName);
|
||||
named.push_back(rangeType(beg, pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
unnamed.push_back(rangeType(beg, pos));
|
||||
}
|
||||
isNamed = false;
|
||||
beg = pos + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Stage 2: Convert to concrete string and store
|
||||
|
||||
|
||||
// unnamed
|
||||
{
|
||||
const label nInputArgs = static_cast<label>(unnamed.size());
|
||||
args.resize(nInputArgs);
|
||||
|
||||
label ngood = 0;
|
||||
for (label i = 0; i < nInputArgs; ++i)
|
||||
{
|
||||
const auto& arg = unnamed[i];
|
||||
|
||||
args[ngood] = wordRe
|
||||
(
|
||||
word::validate
|
||||
(
|
||||
str.substr(arg.first(), (arg.second()-arg.first()))
|
||||
)
|
||||
);
|
||||
|
||||
// Only retain if non-empty
|
||||
if (!args[ngood].empty())
|
||||
{
|
||||
++ngood;
|
||||
}
|
||||
}
|
||||
|
||||
args.resize(ngood);
|
||||
}
|
||||
|
||||
// named
|
||||
{
|
||||
const label nInputArgs = static_cast<label>(named.size());
|
||||
namedArgs.resize(nInputArgs/2);
|
||||
|
||||
label ngood = 0;
|
||||
for (label i = 0; i < nInputArgs; i += 2)
|
||||
{
|
||||
const auto& name = named[i];
|
||||
const auto& arg = named[i+1];
|
||||
|
||||
namedArgs[ngood].first() =
|
||||
validateVariableName
|
||||
(
|
||||
str.substr(name.first(), (name.second()-name.first()))
|
||||
);
|
||||
|
||||
namedArgs[ngood].second() =
|
||||
stringOps::trim
|
||||
(
|
||||
str.substr(arg.first(), (arg.second()-arg.first()))
|
||||
);
|
||||
|
||||
// Only retain if name is non-empty
|
||||
if (!namedArgs[ngood].first().empty())
|
||||
{
|
||||
++ngood;
|
||||
}
|
||||
}
|
||||
|
||||
namedArgs.resize(ngood);
|
||||
}
|
||||
|
||||
// Return total number of arguments
|
||||
return (args.size() + namedArgs.size());
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -66,6 +66,33 @@ StringType Foam::stringOps::quotemeta
|
||||
}
|
||||
|
||||
|
||||
template<class StringType, class UnaryPredicate>
|
||||
StringType Foam::stringOps::validate
|
||||
(
|
||||
const std::string& str,
|
||||
const UnaryPredicate& accept,
|
||||
const bool invert
|
||||
)
|
||||
{
|
||||
StringType out;
|
||||
out.resize(str.length());
|
||||
|
||||
std::string::size_type len = 0;
|
||||
|
||||
for (std::string::size_type i = 0; i < str.length(); ++i)
|
||||
{
|
||||
const char c = str[i];
|
||||
if (accept(c) ? !invert : invert)
|
||||
{
|
||||
out[len++] += c;
|
||||
}
|
||||
}
|
||||
|
||||
out.erase(len);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
template<class StringType>
|
||||
Foam::SubStrings<StringType> Foam::stringOps::split
|
||||
(
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2012-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -120,8 +120,8 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
OFstream::write(static_cast<char>(token::BEGIN_STRING));
|
||||
// Output with surrounding quotes and backslash escaping
|
||||
OFstream::write(static_cast<char>(token::DQUOTE));
|
||||
|
||||
unsigned backslash = 0;
|
||||
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
|
||||
@ -138,7 +138,7 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
|
||||
++lineNumber_;
|
||||
++backslash; // backslash escape for newline
|
||||
}
|
||||
else if (c == token::END_STRING)
|
||||
else if (c == token::DQUOTE)
|
||||
{
|
||||
++backslash; // backslash escape for quote
|
||||
}
|
||||
@ -155,7 +155,7 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
|
||||
|
||||
// silently drop any trailing backslashes
|
||||
// they would otherwise appear like an escaped end-quote
|
||||
OFstream::write(static_cast<char>(token::END_STRING));
|
||||
OFstream::write(static_cast<char>(token::DQUOTE));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -16,9 +16,27 @@ FoamFile
|
||||
|
||||
scale 1;
|
||||
|
||||
// Front/back locations
|
||||
zmin -0.5;
|
||||
zmax 0.5;
|
||||
// Geometric parameters
|
||||
rInner 0.5;
|
||||
rOuter 1;
|
||||
xmax 2;
|
||||
ymax 2;
|
||||
|
||||
zmin -0.5; // Back/front locations
|
||||
zmax 0.5;
|
||||
|
||||
// Divisions: Radial, quarter circumference, outer region and z-directions.
|
||||
nRadial 10;
|
||||
nQuarter 10;
|
||||
nxOuter 20;
|
||||
nyOuter 20;
|
||||
nz 1;
|
||||
|
||||
// ----------------
|
||||
|
||||
// Derived quantities
|
||||
rInner45 ${{ $rInner * sqrt(0.5) }};
|
||||
rOuter45 ${{ $rOuter * sqrt(0.5) }};
|
||||
|
||||
vertices #codeStream
|
||||
{
|
||||
@ -29,30 +47,27 @@ vertices #codeStream
|
||||
|
||||
code
|
||||
#{
|
||||
// sin(45), cos(45)
|
||||
const scalar sqrt05 = sqrt(0.5);
|
||||
|
||||
pointField points
|
||||
({
|
||||
/* 0*/ {0.5, 0, $zmin},
|
||||
/* 1*/ {1, 0, $zmin},
|
||||
/* 2*/ {2, 0, $zmin},
|
||||
/* 3*/ {2, sqrt05, $zmin},
|
||||
/* 4*/ {sqrt05, sqrt05, $zmin},
|
||||
/* 5*/ {sqrt05/2, sqrt05/2, $zmin},
|
||||
/* 6*/ {2, 2, $zmin},
|
||||
/* 7*/ {sqrt05, 2, $zmin},
|
||||
/* 8*/ {0, 2, $zmin},
|
||||
/* 9*/ {0, 1, $zmin},
|
||||
/*10*/ {0, 0.5, $zmin},
|
||||
/*11*/ {-0.5, 0, $zmin},
|
||||
/*12*/ {-1, 0, $zmin},
|
||||
/*13*/ {-2, 0, $zmin},
|
||||
/*14*/ {-2, sqrt05, $zmin},
|
||||
/*15*/ {-sqrt05, sqrt05, $zmin},
|
||||
/*16*/ {-sqrt05/2, sqrt05/2, $zmin},
|
||||
/*17*/ {-2, 2, $zmin},
|
||||
/*18*/ {-sqrt05, 2, $zmin}
|
||||
/* 0*/ { $rInner, 0, $zmin },
|
||||
/* 1*/ { $rOuter, 0, $zmin },
|
||||
/* 2*/ { $xmax, 0, $zmin },
|
||||
/* 3*/ { $xmax, $rOuter45, $zmin },
|
||||
/* 4*/ { $rOuter45, $rOuter45, $zmin },
|
||||
/* 5*/ { $rInner45, $rInner45, $zmin },
|
||||
/* 6*/ { $xmax, $ymax, $zmin },
|
||||
/* 7*/ { $rOuter45, $ymax, $zmin },
|
||||
/* 8*/ { 0, $ymax, $zmin },
|
||||
/* 9*/ { 0, $rOuter, $zmin },
|
||||
/*10*/ { 0, $rInner, $zmin },
|
||||
/*11*/ { -$rInner, 0, $zmin },
|
||||
/*12*/ { -$rOuter, 0, $zmin },
|
||||
/*13*/ { -$xmax, 0, $zmin },
|
||||
/*14*/ { -$xmax, $rOuter45, $zmin },
|
||||
/*15*/ { -$rOuter45, $rOuter45, $zmin },
|
||||
/*16*/ { -$rInner45, $rInner45, $zmin },
|
||||
/*17*/ { -$xmax, $ymax, $zmin },
|
||||
/*18*/ { -$rOuter45, $ymax, $zmin }
|
||||
});
|
||||
|
||||
// Duplicate z points for zmax
|
||||
@ -68,19 +83,21 @@ vertices #codeStream
|
||||
#};
|
||||
};
|
||||
|
||||
// Can remove unneeded variables
|
||||
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
|
||||
|
||||
blocks
|
||||
(
|
||||
hex (5 4 9 10 24 23 28 29) (10 10 1) simpleGrading (1 1 1)
|
||||
hex (0 1 4 5 19 20 23 24) (10 10 1) simpleGrading (1 1 1)
|
||||
hex (1 2 3 4 20 21 22 23) (20 10 1) simpleGrading (1 1 1)
|
||||
hex (4 3 6 7 23 22 25 26) (20 20 1) simpleGrading (1 1 1)
|
||||
hex (9 4 7 8 28 23 26 27) (10 20 1) simpleGrading (1 1 1)
|
||||
hex (15 16 10 9 34 35 29 28) (10 10 1) simpleGrading (1 1 1)
|
||||
hex (12 11 16 15 31 30 35 34) (10 10 1) simpleGrading (1 1 1)
|
||||
hex (13 12 15 14 32 31 34 33) (20 10 1) simpleGrading (1 1 1)
|
||||
hex (14 15 18 17 33 34 37 36) (20 20 1) simpleGrading (1 1 1)
|
||||
hex (15 9 8 18 34 28 27 37) (10 20 1) simpleGrading (1 1 1)
|
||||
hex (5 4 9 10 24 23 28 29) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (0 1 4 5 19 20 23 24) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (1 2 3 4 20 21 22 23) ($nxOuter $nQuarter $nz) grading (1 1 1)
|
||||
hex (4 3 6 7 23 22 25 26) ($nxOuter $nyOuter $nz) grading (1 1 1)
|
||||
hex (9 4 7 8 28 23 26 27) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||
hex (15 16 10 9 34 35 29 28) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (12 11 16 15 31 30 35 34) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (13 12 15 14 32 31 34 33) ($nxOuter $nQuarter $nz) grading (1 1 1)
|
||||
hex (14 15 18 17 33 34 37 36) ($nxOuter $nyOuter $nz) grading (1 1 1)
|
||||
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||
);
|
||||
|
||||
edges
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2012 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object decomposeParDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
numberOfSubdomains 4;
|
||||
|
||||
method simple;
|
||||
|
||||
coeffs
|
||||
{
|
||||
n ( 2 2 1 );
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -40,22 +40,20 @@ nz #eval{ round($nz / 5) };
|
||||
#endif
|
||||
|
||||
zmin #eval{ -$zmax };
|
||||
mrad0 #eval{ -$rad0 };
|
||||
mrad1 #eval{ -$rad1 };
|
||||
|
||||
vertices
|
||||
(
|
||||
// back-plane:
|
||||
// inlet region
|
||||
( $xin $rad0 $zmin) // pt 0
|
||||
( 0 $rad0 $zmin) // pt 1
|
||||
( 0 $rad1 $zmin) // pt 2
|
||||
( $xin $rad1 $zmin) // pt 3
|
||||
( $xin $rad0 $zmin) // pt 0
|
||||
( 0 $rad0 $zmin) // pt 1
|
||||
( 0 $rad1 $zmin) // pt 2
|
||||
( $xin $rad1 $zmin) // pt 3
|
||||
// outlet region
|
||||
( $xout $mrad1 $zmin) // pt 4
|
||||
( 0 $mrad1 $zmin) // pt 5
|
||||
( 0 $mrad0 $zmin) // pt 6
|
||||
( $xout $mrad0 $zmin) // pt 7
|
||||
( $xout -$rad1 $zmin) // pt 4
|
||||
( 0 -$rad1 $zmin) // pt 5
|
||||
( 0 -$rad0 $zmin) // pt 6
|
||||
( $xout -$rad0 $zmin) // pt 7
|
||||
// bend mid-points
|
||||
( $rad0 0 $zmin) // pt 8
|
||||
( $rad1 0 $zmin) // pt 9
|
||||
@ -66,13 +64,13 @@ vertices
|
||||
( 0 $rad1 $zmax) // pt 2 + 10
|
||||
( $xin $rad1 $zmax) // pt 3 + 10
|
||||
// outlet region
|
||||
( $xout $mrad1 $zmax) // pt 4 + 10
|
||||
( 0 $mrad1 $zmax) // pt 5 + 10
|
||||
( 0 $mrad0 $zmax) // pt 6 + 10
|
||||
( $xout $mrad0 $zmax) // pt 7 + 10
|
||||
( $xout -$rad1 $zmax) // pt 4 + 10
|
||||
( 0 -$rad1 $zmax) // pt 5 + 10
|
||||
( 0 -$rad0 $zmax) // pt 6 + 10
|
||||
( $xout -$rad0 $zmax) // pt 7 + 10
|
||||
// bend mid-points
|
||||
( $rad0 0 $zmax) // pt 8 + 10
|
||||
( $rad1 0 $zmax) // pt 9 + 10
|
||||
( $rad0 0 $zmax) // pt 8 + 10
|
||||
( $rad1 0 $zmax) // pt 9 + 10
|
||||
);
|
||||
|
||||
blocks
|
||||
|
||||
@ -40,22 +40,20 @@ nz #eval{ round($nz / 5) };
|
||||
#endif
|
||||
|
||||
zmin #eval{ -$zmax };
|
||||
mrad0 #eval{ -$rad0 };
|
||||
mrad1 #eval{ -$rad1 };
|
||||
|
||||
vertices
|
||||
(
|
||||
// back-plane:
|
||||
// inlet region
|
||||
( $xin $rad0 $zmin) // pt 0
|
||||
( 0 $rad0 $zmin) // pt 1
|
||||
( 0 $rad1 $zmin) // pt 2
|
||||
( $xin $rad1 $zmin) // pt 3
|
||||
( $xin $rad0 $zmin) // pt 0
|
||||
( 0 $rad0 $zmin) // pt 1
|
||||
( 0 $rad1 $zmin) // pt 2
|
||||
( $xin $rad1 $zmin) // pt 3
|
||||
// outlet region
|
||||
( $xout $mrad1 $zmin) // pt 4
|
||||
( 0 $mrad1 $zmin) // pt 5
|
||||
( 0 $mrad0 $zmin) // pt 6
|
||||
( $xout $mrad0 $zmin) // pt 7
|
||||
( $xout -$rad1 $zmin) // pt 4
|
||||
( 0 -$rad1 $zmin) // pt 5
|
||||
( 0 -$rad0 $zmin) // pt 6
|
||||
( $xout -$rad0 $zmin) // pt 7
|
||||
// bend mid-points
|
||||
( $rad0 0 $zmin) // pt 8
|
||||
( $rad1 0 $zmin) // pt 9
|
||||
@ -66,13 +64,13 @@ vertices
|
||||
( 0 $rad1 $zmax) // pt 2 + 10
|
||||
( $xin $rad1 $zmax) // pt 3 + 10
|
||||
// outlet region
|
||||
( $xout $mrad1 $zmax) // pt 4 + 10
|
||||
( 0 $mrad1 $zmax) // pt 5 + 10
|
||||
( 0 $mrad0 $zmax) // pt 6 + 10
|
||||
( $xout $mrad0 $zmax) // pt 7 + 10
|
||||
( $xout -$rad1 $zmax) // pt 4 + 10
|
||||
( 0 -$rad1 $zmax) // pt 5 + 10
|
||||
( 0 -$rad0 $zmax) // pt 6 + 10
|
||||
( $xout -$rad0 $zmax) // pt 7 + 10
|
||||
// bend mid-points
|
||||
( $rad0 0 $zmax) // pt 8 + 10
|
||||
( $rad1 0 $zmax) // pt 9 + 10
|
||||
( $rad0 0 $zmax) // pt 8 + 10
|
||||
( $rad1 0 $zmax) // pt 9 + 10
|
||||
);
|
||||
|
||||
blocks
|
||||
|
||||
@ -40,8 +40,6 @@ nz #eval{ round($nz / 5) };
|
||||
#endif
|
||||
|
||||
zmin #eval{ -$zmax };
|
||||
mrad0 #eval{ -$rad0 };
|
||||
mrad1 #eval{ -$rad1 };
|
||||
|
||||
vertices
|
||||
(
|
||||
@ -52,13 +50,13 @@ vertices
|
||||
( 0 $rad1 $zmin) // pt 2
|
||||
( $xin $rad1 $zmin) // pt 3
|
||||
// outlet region
|
||||
( $xout $mrad1 $zmin) // pt 4
|
||||
( 0 $mrad1 $zmin) // pt 5
|
||||
( 0 $mrad0 $zmin) // pt 6
|
||||
( $xout $mrad0 $zmin) // pt 7
|
||||
( $xout -$rad1 $zmin) // pt 4
|
||||
( 0 -$rad1 $zmin) // pt 5
|
||||
( 0 -$rad0 $zmin) // pt 6
|
||||
( $xout -$rad0 $zmin) // pt 7
|
||||
// bend mid-points
|
||||
( $rad0 0 $zmin) // pt 8
|
||||
( $rad1 0 $zmin) // pt 9
|
||||
( $rad0 0 $zmin) // pt 8
|
||||
( $rad1 0 $zmin) // pt 9
|
||||
// front-plane:
|
||||
// inlet region
|
||||
( $xin $rad0 $zmax) // pt 0 + 10
|
||||
@ -66,10 +64,10 @@ vertices
|
||||
( 0 $rad1 $zmax) // pt 2 + 10
|
||||
( $xin $rad1 $zmax) // pt 3 + 10
|
||||
// outlet region
|
||||
( $xout $mrad1 $zmax) // pt 4 + 10
|
||||
( 0 $mrad1 $zmax) // pt 5 + 10
|
||||
( 0 $mrad0 $zmax) // pt 6 + 10
|
||||
( $xout $mrad0 $zmax) // pt 7 + 10
|
||||
( $xout -$rad1 $zmax) // pt 4 + 10
|
||||
( 0 -$rad1 $zmax) // pt 5 + 10
|
||||
( 0 -$rad0 $zmax) // pt 6 + 10
|
||||
( $xout -$rad0 $zmax) // pt 7 + 10
|
||||
// bend mid-points
|
||||
( $rad0 0 $zmax) // pt 8 + 10
|
||||
( $rad1 0 $zmax) // pt 9 + 10
|
||||
|
||||
@ -18,66 +18,91 @@ FoamFile
|
||||
|
||||
scale 0.016;
|
||||
|
||||
// Front/back locations
|
||||
zmin 0;
|
||||
zmax 0.5;
|
||||
// Geometric parameters
|
||||
rInner 0.5;
|
||||
rOuter 1;
|
||||
xmax 2;
|
||||
ymax 2;
|
||||
|
||||
zmin 0; // Back/front locations
|
||||
zmax 0.5;
|
||||
|
||||
// Divisions: Radial, quarter circumference, outer region and z-directions.
|
||||
nRadial 10;
|
||||
nQuarter 10;
|
||||
nxOuter 20;
|
||||
nyOuter 20;
|
||||
nz 1;
|
||||
|
||||
// ----------------
|
||||
|
||||
// Derived quantities
|
||||
rInner45 ${{ $rInner * sqrt(0.5) }};
|
||||
rOuter45 ${{ $rOuter * sqrt(0.5) }};
|
||||
xmin ${{ -$xmax }};
|
||||
|
||||
vertices
|
||||
(
|
||||
(0.5 0 $zmin)
|
||||
(1 0 $zmin)
|
||||
(2 0 $zmin)
|
||||
(2 0.707107 $zmin)
|
||||
(0.707107 0.707107 $zmin)
|
||||
(0.353553 0.353553 $zmin)
|
||||
(2 2 $zmin)
|
||||
(0.707107 2 $zmin)
|
||||
(0 2 $zmin)
|
||||
(0 1 $zmin)
|
||||
(0 0.5 $zmin)
|
||||
(-0.5 0 $zmin)
|
||||
(-1 0 $zmin)
|
||||
(-2 0 $zmin)
|
||||
(-2 0.707107 $zmin)
|
||||
(-0.707107 0.707107 $zmin)
|
||||
(-0.353553 0.353553 $zmin)
|
||||
(-2 2 $zmin)
|
||||
(-0.707107 2 $zmin)
|
||||
(0.5 0 $zmax)
|
||||
(1 0 $zmax)
|
||||
(2 0 $zmax)
|
||||
(2 0.707107 $zmax)
|
||||
(0.707107 0.707107 $zmax)
|
||||
(0.353553 0.353553 $zmax)
|
||||
(2 2 $zmax)
|
||||
(0.707107 2 $zmax)
|
||||
(0 2 $zmax)
|
||||
(0 1 $zmax)
|
||||
(0 0.5 $zmax)
|
||||
(-0.5 0 $zmax)
|
||||
(-1 0 $zmax)
|
||||
(-2 0 $zmax)
|
||||
(-2 0.707107 $zmax)
|
||||
(-0.707107 0.707107 $zmax)
|
||||
(-0.353553 0.353553 $zmax)
|
||||
(-2 2 $zmax)
|
||||
(-0.707107 2 $zmax)
|
||||
/* 0*/ ( $rInner 0 $zmin )
|
||||
/* 1*/ ( $rOuter 0 $zmin )
|
||||
/* 2*/ ( $xmax 0 $zmin )
|
||||
/* 3*/ ( $xmax $rOuter45 $zmin )
|
||||
/* 4*/ ( $rOuter45 $rOuter45 $zmin )
|
||||
/* 5*/ ( $rInner45 $rInner45 $zmin )
|
||||
/* 6*/ ( $xmax $ymax $zmin )
|
||||
/* 7*/ ( $rOuter45 $ymax $zmin )
|
||||
/* 8*/ ( 0 $ymax $zmin )
|
||||
/* 9*/ ( 0 $rOuter $zmin )
|
||||
/*10*/ ( 0 $rInner $zmin )
|
||||
/*11*/ ( -$rInner 0 $zmin )
|
||||
/*12*/ ( -$rOuter 0 $zmin )
|
||||
/*13*/ ( -$xmax 0 $zmin )
|
||||
/*14*/ ( -$xmax $rOuter45 $zmin )
|
||||
/*15*/ ( -$rOuter45 $rOuter45 $zmin )
|
||||
/*16*/ ( -$rInner45 $rInner45 $zmin )
|
||||
/*17*/ ( -$xmax $ymax $zmin )
|
||||
/*18*/ ( -$rOuter45 $ymax $zmin )
|
||||
|
||||
/*19*/ ( $rInner 0 $zmax )
|
||||
/*20*/ ( $rOuter 0 $zmax )
|
||||
/*21*/ ( $xmax 0 $zmax )
|
||||
/*22*/ ( $xmax $rOuter45 $zmax )
|
||||
/*23*/ ( $rOuter45 $rOuter45 $zmax )
|
||||
/*24*/ ( $rInner45 $rInner45 $zmax )
|
||||
/*25*/ ( $xmax $ymax $zmax )
|
||||
/*26*/ ( $rOuter45 $ymax $zmax )
|
||||
/*27*/ ( 0 $ymax $zmax )
|
||||
/*28*/ ( 0 $rOuter $zmax )
|
||||
/*29*/ ( 0 $rInner $zmax )
|
||||
/*30*/ ( -$rInner 0 $zmax )
|
||||
/*31*/ ( -$rOuter 0 $zmax )
|
||||
/*32*/ ( -$xmax 0 $zmax )
|
||||
/*33*/ ( -$xmax $rOuter45 $zmax )
|
||||
/*34*/ ( -$rOuter45 $rOuter45 $zmax )
|
||||
/*35*/ ( -$rInner45 $rInner45 $zmax )
|
||||
/*36*/ ( -$xmax $ymax $zmax )
|
||||
/*37*/ ( -$rOuter45 $ymax $zmax )
|
||||
);
|
||||
|
||||
// Can remove some unneeded variables
|
||||
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
|
||||
|
||||
|
||||
blocks
|
||||
(
|
||||
hex (5 4 9 10 24 23 28 29) (10 10 1) simpleGrading (1 1 1)
|
||||
hex (0 1 4 5 19 20 23 24) (10 10 1) simpleGrading (1 1 1)
|
||||
hex (1 2 3 4 20 21 22 23) (20 10 1) simpleGrading (1 1 1)
|
||||
hex (4 3 6 7 23 22 25 26) (20 20 1) simpleGrading (1 1 1)
|
||||
hex (9 4 7 8 28 23 26 27) (10 20 1) simpleGrading (1 1 1)
|
||||
hex (15 16 10 9 34 35 29 28) (10 10 1) simpleGrading (1 1 1)
|
||||
hex (12 11 16 15 31 30 35 34) (10 10 1) simpleGrading (1 1 1)
|
||||
hex (13 12 15 14 32 31 34 33) (20 10 1) simpleGrading (1 1 1)
|
||||
hex (14 15 18 17 33 34 37 36) (20 20 1) simpleGrading (1 1 1)
|
||||
hex (15 9 8 18 34 28 27 37) (10 20 1) simpleGrading (1 1 1)
|
||||
hex (5 4 9 10 24 23 28 29) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (0 1 4 5 19 20 23 24) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (1 2 3 4 20 21 22 23) ($nxOuter $nQuarter $nz) grading (1 1 1)
|
||||
hex (4 3 6 7 23 22 25 26) ($nxOuter $nyOuter $nz) grading (1 1 1)
|
||||
hex (9 4 7 8 28 23 26 27) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||
hex (15 16 10 9 34 35 29 28) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (12 11 16 15 31 30 35 34) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (13 12 15 14 32 31 34 33) ($nxOuter $nQuarter $nz) grading (1 1 1)
|
||||
hex (14 15 18 17 33 34 37 36) ($nxOuter $nyOuter $nz) grading (1 1 1)
|
||||
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||
);
|
||||
|
||||
|
||||
edges
|
||||
(
|
||||
// Inner cylinder
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2012 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object decomposeParDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
numberOfSubdomains 4;
|
||||
|
||||
method simple;
|
||||
|
||||
coeffs
|
||||
{
|
||||
n ( 2 2 1 );
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -17,16 +17,13 @@ FoamFile
|
||||
|
||||
actions
|
||||
(
|
||||
// Heater
|
||||
heater
|
||||
{
|
||||
name heaterCellSet;
|
||||
type cellSet;
|
||||
action new;
|
||||
source boxToCell;
|
||||
sourceInfo
|
||||
{
|
||||
box (-0.01 29e-3 -1 )(4.77e-3 70e-3 1);
|
||||
}
|
||||
box (-0.01 29e-3 -1) (4.77e-3 70e-3 1);
|
||||
}
|
||||
|
||||
{
|
||||
@ -34,10 +31,7 @@ actions
|
||||
type cellZoneSet;
|
||||
action new;
|
||||
source setToCellZone;
|
||||
sourceInfo
|
||||
{
|
||||
set heaterCellSet;
|
||||
}
|
||||
set heaterCellSet;
|
||||
}
|
||||
|
||||
{
|
||||
@ -45,10 +39,7 @@ actions
|
||||
type cellSet;
|
||||
action new;
|
||||
source cellToCell;
|
||||
sourceInfo
|
||||
{
|
||||
set heaterCellSet;
|
||||
}
|
||||
set heaterCellSet;
|
||||
}
|
||||
|
||||
{
|
||||
@ -62,10 +53,7 @@ actions
|
||||
type cellZoneSet;
|
||||
action new;
|
||||
source setToCellZone;
|
||||
sourceInfo
|
||||
{
|
||||
set bottomWaterCellSet;
|
||||
}
|
||||
set bottomWaterCellSet;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ timePrecision 6;
|
||||
runTimeModifiable true;
|
||||
|
||||
// Allow 10% run-up before calculating mean
|
||||
timeStart #eval #{ 0.1 * ${/endTime} #};
|
||||
timeStart #eval{ 0.1 * ${/endTime} };
|
||||
|
||||
|
||||
functions
|
||||
|
||||
@ -40,22 +40,20 @@ nz #eval{ round($nz / 5) };
|
||||
#endif
|
||||
|
||||
zmin #eval{ -$zmax };
|
||||
mrad0 #eval{ -$rad0 };
|
||||
mrad1 #eval{ -$rad1 };
|
||||
|
||||
vertices
|
||||
(
|
||||
// back-plane:
|
||||
// inlet region
|
||||
( $xin $rad0 $zmin) // pt 0
|
||||
( 0 $rad0 $zmin) // pt 1
|
||||
( 0 $rad1 $zmin) // pt 2
|
||||
( $xin $rad1 $zmin) // pt 3
|
||||
( $xin $rad0 $zmin) // pt 0
|
||||
( 0 $rad0 $zmin) // pt 1
|
||||
( 0 $rad1 $zmin) // pt 2
|
||||
( $xin $rad1 $zmin) // pt 3
|
||||
// outlet region
|
||||
( $xout $mrad1 $zmin) // pt 4
|
||||
( 0 $mrad1 $zmin) // pt 5
|
||||
( 0 $mrad0 $zmin) // pt 6
|
||||
( $xout $mrad0 $zmin) // pt 7
|
||||
( $xout -$rad1 $zmin) // pt 4
|
||||
( 0 -$rad1 $zmin) // pt 5
|
||||
( 0 -$rad0 $zmin) // pt 6
|
||||
( $xout -$rad0 $zmin) // pt 7
|
||||
// bend mid-points
|
||||
( $rad0 0 $zmin) // pt 8
|
||||
( $rad1 0 $zmin) // pt 9
|
||||
@ -66,13 +64,13 @@ vertices
|
||||
( 0 $rad1 $zmax) // pt 2 + 10
|
||||
( $xin $rad1 $zmax) // pt 3 + 10
|
||||
// outlet region
|
||||
( $xout $mrad1 $zmax) // pt 4 + 10
|
||||
( 0 $mrad1 $zmax) // pt 5 + 10
|
||||
( 0 $mrad0 $zmax) // pt 6 + 10
|
||||
( $xout $mrad0 $zmax) // pt 7 + 10
|
||||
( $xout -$rad1 $zmax) // pt 4 + 10
|
||||
( 0 -$rad1 $zmax) // pt 5 + 10
|
||||
( 0 -$rad0 $zmax) // pt 6 + 10
|
||||
( $xout -$rad0 $zmax) // pt 7 + 10
|
||||
// bend mid-points
|
||||
( $rad0 0 $zmax) // pt 8 + 10
|
||||
( $rad1 0 $zmax) // pt 9 + 10
|
||||
( $rad0 0 $zmax) // pt 8 + 10
|
||||
( $rad1 0 $zmax) // pt 9 + 10
|
||||
);
|
||||
|
||||
blocks
|
||||
|
||||
@ -18,64 +18,87 @@ FoamFile
|
||||
|
||||
scale 1;
|
||||
|
||||
// Front/back locations
|
||||
zmin -0.5;
|
||||
zmax 0.5;
|
||||
// Geometric parameters
|
||||
rInner 0.5;
|
||||
rOuter 1;
|
||||
xmax 2;
|
||||
ymax 2;
|
||||
|
||||
zmin -0.5; // Back/front locations
|
||||
zmax 0.5;
|
||||
|
||||
// Divisions: Radial, quarter circumference, outer region and z-directions.
|
||||
nRadial 10;
|
||||
nQuarter 10;
|
||||
nxOuter 20;
|
||||
nyOuter 20;
|
||||
nz 11;
|
||||
|
||||
// ----------------
|
||||
|
||||
// Derived quantities
|
||||
rInner45 ${{ $rInner * sqrt(0.5) }};
|
||||
rOuter45 ${{ $rOuter * sqrt(0.5) }};
|
||||
|
||||
vertices
|
||||
(
|
||||
(0.5 0 $zmin)
|
||||
(1 0 $zmin)
|
||||
(2 0 $zmin)
|
||||
(2 0.707107 $zmin)
|
||||
(0.707107 0.707107 $zmin)
|
||||
(0.353553 0.353553 $zmin)
|
||||
(2 2 $zmin)
|
||||
(0.707107 2 $zmin)
|
||||
(0 2 $zmin)
|
||||
(0 1 $zmin)
|
||||
(0 0.5 $zmin)
|
||||
(-0.5 0 $zmin)
|
||||
(-1 0 $zmin)
|
||||
(-2 0 $zmin)
|
||||
(-2 0.707107 $zmin)
|
||||
(-0.707107 0.707107 $zmin)
|
||||
(-0.353553 0.353553 $zmin)
|
||||
(-2 2 $zmin)
|
||||
(-0.707107 2 $zmin)
|
||||
(0.5 0 $zmax)
|
||||
(1 0 $zmax)
|
||||
(2 0 $zmax)
|
||||
(2 0.707107 $zmax)
|
||||
(0.707107 0.707107 $zmax)
|
||||
(0.353553 0.353553 $zmax)
|
||||
(2 2 $zmax)
|
||||
(0.707107 2 $zmax)
|
||||
(0 2 $zmax)
|
||||
(0 1 $zmax)
|
||||
(0 0.5 $zmax)
|
||||
(-0.5 0 $zmax)
|
||||
(-1 0 $zmax)
|
||||
(-2 0 $zmax)
|
||||
(-2 0.707107 $zmax)
|
||||
(-0.707107 0.707107 $zmax)
|
||||
(-0.353553 0.353553 $zmax)
|
||||
(-2 2 $zmax)
|
||||
(-0.707107 2 $zmax)
|
||||
/* 0*/ ( $rInner 0 $zmin )
|
||||
/* 1*/ ( $rOuter 0 $zmin )
|
||||
/* 2*/ ( $xmax 0 $zmin )
|
||||
/* 3*/ ( $xmax $rOuter45 $zmin )
|
||||
/* 4*/ ( $rOuter45 $rOuter45 $zmin )
|
||||
/* 5*/ ( $rInner45 $rInner45 $zmin )
|
||||
/* 6*/ ( $xmax $ymax $zmin )
|
||||
/* 7*/ ( $rOuter45 $ymax $zmin )
|
||||
/* 8*/ ( 0 $ymax $zmin )
|
||||
/* 9*/ ( 0 $rOuter $zmin )
|
||||
/*10*/ ( 0 $rInner $zmin )
|
||||
/*11*/ ( -$rInner 0 $zmin )
|
||||
/*12*/ ( -$rOuter 0 $zmin )
|
||||
/*13*/ ( -$xmax 0 $zmin )
|
||||
/*14*/ ( -$xmax $rOuter45 $zmin )
|
||||
/*15*/ ( -$rOuter45 $rOuter45 $zmin )
|
||||
/*16*/ ( -$rInner45 $rInner45 $zmin )
|
||||
/*17*/ ( -$xmax $ymax $zmin )
|
||||
/*18*/ ( -$rOuter45 $ymax $zmin )
|
||||
|
||||
/*19*/ ( $rInner 0 $zmax )
|
||||
/*20*/ ( $rOuter 0 $zmax )
|
||||
/*21*/ ( $xmax 0 $zmax )
|
||||
/*22*/ ( $xmax $rOuter45 $zmax )
|
||||
/*23*/ ( $rOuter45 $rOuter45 $zmax )
|
||||
/*24*/ ( $rInner45 $rInner45 $zmax )
|
||||
/*25*/ ( $xmax $ymax $zmax )
|
||||
/*26*/ ( $rOuter45 $ymax $zmax )
|
||||
/*27*/ ( 0 $ymax $zmax )
|
||||
/*28*/ ( 0 $rOuter $zmax )
|
||||
/*29*/ ( 0 $rInner $zmax )
|
||||
/*30*/ ( -$rInner 0 $zmax )
|
||||
/*31*/ ( -$rOuter 0 $zmax )
|
||||
/*32*/ ( -$xmax 0 $zmax )
|
||||
/*33*/ ( -$xmax $rOuter45 $zmax )
|
||||
/*34*/ ( -$rOuter45 $rOuter45 $zmax )
|
||||
/*35*/ ( -$rInner45 $rInner45 $zmax )
|
||||
/*36*/ ( -$xmax $ymax $zmax )
|
||||
/*37*/ ( -$rOuter45 $ymax $zmax )
|
||||
);
|
||||
|
||||
// Can remove some unneeded variables
|
||||
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
|
||||
|
||||
|
||||
blocks
|
||||
(
|
||||
hex (5 4 9 10 24 23 28 29) (10 10 11) simpleGrading (1 1 1)
|
||||
hex (0 1 4 5 19 20 23 24) (10 10 11) simpleGrading (1 1 1)
|
||||
hex (1 2 3 4 20 21 22 23) (20 10 11) simpleGrading (1 1 1)
|
||||
hex (4 3 6 7 23 22 25 26) (20 20 11) simpleGrading (1 1 1)
|
||||
hex (9 4 7 8 28 23 26 27) (10 20 11) simpleGrading (1 1 1)
|
||||
hex (15 16 10 9 34 35 29 28) (10 10 11) simpleGrading (1 1 1)
|
||||
hex (12 11 16 15 31 30 35 34) (10 10 11) simpleGrading (1 1 1)
|
||||
hex (13 12 15 14 32 31 34 33) (20 10 11) simpleGrading (1 1 1)
|
||||
hex (14 15 18 17 33 34 37 36) (20 20 11) simpleGrading (1 1 1)
|
||||
hex (15 9 8 18 34 28 27 37) (10 20 11) simpleGrading (1 1 1)
|
||||
hex (5 4 9 10 24 23 28 29) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (0 1 4 5 19 20 23 24) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (1 2 3 4 20 21 22 23) ($nxOuter $nQuarter $nz) grading (1 1 1)
|
||||
hex (4 3 6 7 23 22 25 26) ($nxOuter $nyOuter $nz) grading (1 1 1)
|
||||
hex (9 4 7 8 28 23 26 27) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||
hex (15 16 10 9 34 35 29 28) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (12 11 16 15 31 30 35 34) ($nRadial $nQuarter $nz) grading (1 1 1)
|
||||
hex (13 12 15 14 32 31 34 33) ($nxOuter $nQuarter $nz) grading (1 1 1)
|
||||
hex (14 15 18 17 33 34 37 36) ($nxOuter $nyOuter $nz) grading (1 1 1)
|
||||
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||
);
|
||||
|
||||
edges
|
||||
|
||||
@ -34,20 +34,19 @@ geometry
|
||||
}
|
||||
}
|
||||
|
||||
// Box sizes
|
||||
// Box size
|
||||
vo #eval{ sqrt($outerRadius/3) };
|
||||
mvo #eval{ -$vo };
|
||||
|
||||
vertices
|
||||
(
|
||||
($mvo $mvo $mvo)
|
||||
( $vo $mvo $mvo)
|
||||
( $vo $vo $mvo)
|
||||
($mvo $vo $mvo)
|
||||
($mvo $mvo $vo)
|
||||
( $vo $mvo $vo)
|
||||
(-$vo -$vo -$vo)
|
||||
( $vo -$vo -$vo)
|
||||
( $vo $vo -$vo)
|
||||
(-$vo $vo -$vo)
|
||||
(-$vo -$vo $vo)
|
||||
( $vo -$vo $vo)
|
||||
( $vo $vo $vo)
|
||||
($mvo $vo $vo)
|
||||
(-$vo $vo $vo)
|
||||
);
|
||||
|
||||
blocks
|
||||
|
||||
@ -37,35 +37,33 @@ geometry
|
||||
}
|
||||
}
|
||||
|
||||
// Outer box sizes
|
||||
// Outer box size
|
||||
vo #eval{ sqrt($outerRadius/3) };
|
||||
mvo #eval{ -$vo };
|
||||
|
||||
// Inner box sizes - % of overall dimension
|
||||
// Inner box size - % of overall dimension
|
||||
vi #eval{ $vo * $innerRatio };
|
||||
mvi #eval{ -$vi };
|
||||
|
||||
vertices
|
||||
(
|
||||
// Inner block
|
||||
($mvi $mvi $mvi)
|
||||
( $vi $mvi $mvi)
|
||||
( $vi $vi $mvi)
|
||||
($mvi $vi $mvi)
|
||||
($mvi $mvi $vi)
|
||||
( $vi $mvi $vi)
|
||||
(-$vi -$vi -$vi)
|
||||
( $vi -$vi -$vi)
|
||||
( $vi $vi -$vi)
|
||||
(-$vi $vi -$vi)
|
||||
(-$vi -$vi $vi)
|
||||
( $vi -$vi $vi)
|
||||
( $vi $vi $vi)
|
||||
($mvi $vi $vi)
|
||||
(-$vi $vi $vi)
|
||||
|
||||
// Outer blocks
|
||||
($mvo $mvo $mvo)
|
||||
( $vo $mvo $mvo)
|
||||
( $vo $vo $mvo)
|
||||
($mvo $vo $mvo)
|
||||
($mvo $mvo $vo)
|
||||
( $vo $mvo $vo)
|
||||
(-$vo -$vo -$vo)
|
||||
( $vo -$vo -$vo)
|
||||
( $vo $vo -$vo)
|
||||
(-$vo $vo -$vo)
|
||||
(-$vo -$vo $vo)
|
||||
( $vo -$vo $vo)
|
||||
( $vo $vo $vo)
|
||||
($mvo $vo $vo)
|
||||
(-$vo $vo $vo)
|
||||
);
|
||||
|
||||
blocks
|
||||
|
||||
@ -44,35 +44,33 @@ geometry
|
||||
}
|
||||
|
||||
|
||||
// Outer box sizes (approximate)
|
||||
// Outer box size (approximate)
|
||||
vo #eval{ sqrt($outerRadius/3) };
|
||||
mvo #eval{ -$vo };
|
||||
|
||||
// Inner box sizes - % of overall dimension
|
||||
// Inner box size - % of overall dimension
|
||||
vi #eval{ $vo * $innerRatio };
|
||||
mvi #eval{ -$vi };
|
||||
|
||||
vertices
|
||||
(
|
||||
// Inner block points
|
||||
project ($mvi $mvi $mvi) (innerSphere)
|
||||
project ( $vi $mvi $mvi) (innerSphere)
|
||||
project ( $vi $vi $mvi) (innerSphere)
|
||||
project ($mvi $vi $mvi) (innerSphere)
|
||||
project ($mvi $mvi $vi) (innerSphere)
|
||||
project ( $vi $mvi $vi) (innerSphere)
|
||||
project (-$vi -$vi -$vi) (innerSphere)
|
||||
project ( $vi -$vi -$vi) (innerSphere)
|
||||
project ( $vi $vi -$vi) (innerSphere)
|
||||
project (-$vi $vi -$vi) (innerSphere)
|
||||
project (-$vi -$vi $vi) (innerSphere)
|
||||
project ( $vi -$vi $vi) (innerSphere)
|
||||
project ( $vi $vi $vi) (innerSphere)
|
||||
project ($mvi $vi $vi) (innerSphere)
|
||||
project (-$vi $vi $vi) (innerSphere)
|
||||
|
||||
// Outer block points
|
||||
project ($mvo $mvo $mvo) (sphere)
|
||||
project ( $vo $mvo $mvo) (sphere)
|
||||
project ( $vo $vo $mvo) (sphere)
|
||||
project ($mvo $vo $mvo) (sphere)
|
||||
project ($mvo $mvo $vo) (sphere)
|
||||
project ( $vo $mvo $vo) (sphere)
|
||||
project (-$vo -$vo -$vo) (sphere)
|
||||
project ( $vo -$vo -$vo) (sphere)
|
||||
project ( $vo $vo -$vo) (sphere)
|
||||
project (-$vo $vo -$vo) (sphere)
|
||||
project (-$vo -$vo $vo) (sphere)
|
||||
project ( $vo -$vo $vo) (sphere)
|
||||
project ( $vo $vo $vo) (sphere)
|
||||
project ($mvo $vo $vo) (sphere)
|
||||
project (-$vo $vo $vo) (sphere)
|
||||
);
|
||||
|
||||
blocks
|
||||
|
||||
@ -44,47 +44,42 @@ geometry
|
||||
innerSphere
|
||||
{
|
||||
$sphere
|
||||
radius
|
||||
(
|
||||
#eval{ $rxo * $innerRatio }
|
||||
#eval{ $ryo * $innerRatio }
|
||||
#eval{ $rzo * $innerRatio }
|
||||
);
|
||||
radius #eval{ $innerRatio*$[(vector) ../sphere/radius] };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Outer box sizes (approximate)
|
||||
vxo #eval{ sqrt(1.0/3.0) * $rxo }; mvxo #eval{ -$vxo };
|
||||
vyo #eval{ sqrt(1.0/3.0) * $ryo }; mvyo #eval{ -$vyo };
|
||||
vzo #eval{ sqrt(1.0/3.0) * $rzo }; mvzo #eval{ -$vzo };
|
||||
vxo #eval{ sqrt(1.0/3.0) * $rxo };
|
||||
vyo #eval{ sqrt(1.0/3.0) * $ryo };
|
||||
vzo #eval{ sqrt(1.0/3.0) * $rzo };
|
||||
|
||||
// Inner box sizes - % of overall dimension
|
||||
vxi #eval{ $vxo * $innerRatio }; mvxi #eval{ -$vxi };
|
||||
vyi #eval{ $vyo * $innerRatio }; mvyi #eval{ -$vyi };
|
||||
vzi #eval{ $vzo * $innerRatio }; mvzi #eval{ -$vzi };
|
||||
vxi #eval{ $vxo * $innerRatio };
|
||||
vyi #eval{ $vyo * $innerRatio };
|
||||
vzi #eval{ $vzo * $innerRatio };
|
||||
|
||||
vertices
|
||||
(
|
||||
// Inner block points
|
||||
project ($mvxi $mvyi $mvzi) (innerSphere)
|
||||
project ( $vxi $mvyi $mvzi) (innerSphere)
|
||||
project ( $vxi $vyi $mvzi) (innerSphere)
|
||||
project ($mvxi $vyi $mvzi) (innerSphere)
|
||||
project ($mvxi $mvyi $vzi) (innerSphere)
|
||||
project ( $vxi $mvyi $vzi) (innerSphere)
|
||||
project (-$vxi -$vyi -$vzi) (innerSphere)
|
||||
project ( $vxi -$vyi -$vzi) (innerSphere)
|
||||
project ( $vxi $vyi -$vzi) (innerSphere)
|
||||
project (-$vxi $vyi -$vzi) (innerSphere)
|
||||
project (-$vxi -$vyi $vzi) (innerSphere)
|
||||
project ( $vxi -$vyi $vzi) (innerSphere)
|
||||
project ( $vxi $vyi $vzi) (innerSphere)
|
||||
project ($mvxi $vyi $vzi) (innerSphere)
|
||||
project (-$vxi $vyi $vzi) (innerSphere)
|
||||
|
||||
// Outer block points
|
||||
project ($mvxo $mvyo $mvzo) (sphere)
|
||||
project ( $vxo $mvyo $mvzo) (sphere)
|
||||
project ( $vxo $vyo $mvzo) (sphere)
|
||||
project ($mvxo $vyo $mvzo) (sphere)
|
||||
project ($mvxo $mvyo $vzo) (sphere)
|
||||
project ( $vxo $mvyo $vzo) (sphere)
|
||||
project (-$vxo -$vyo -$vzo) (sphere)
|
||||
project ( $vxo -$vyo -$vzo) (sphere)
|
||||
project ( $vxo $vyo -$vzo) (sphere)
|
||||
project (-$vxo $vyo -$vzo) (sphere)
|
||||
project (-$vxo -$vyo $vzo) (sphere)
|
||||
project ( $vxo -$vyo $vzo) (sphere)
|
||||
project ( $vxo $vyo $vzo) (sphere)
|
||||
project ($mvxo $vyo $vzo) (sphere)
|
||||
project (-$vxo $vyo $vzo) (sphere)
|
||||
);
|
||||
|
||||
blocks
|
||||
|
||||
@ -37,21 +37,21 @@ geometry
|
||||
}
|
||||
|
||||
// Box sizes
|
||||
vxo #eval{sqrt(1.0/3.0) * $rxo}; mvxo #eval{-$vxo};
|
||||
vyo #eval{sqrt(1.0/3.0) * $ryo}; mvyo #eval{-$vyo};
|
||||
vzo #eval{sqrt(1.0/3.0) * $rzo}; mvzo #eval{-$vzo};
|
||||
vxo ${{sqrt(1.0/3.0) * $rxo}};
|
||||
vyo ${{sqrt(1.0/3.0) * $ryo}};
|
||||
vzo ${{sqrt(1.0/3.0) * $rzo}};
|
||||
|
||||
vertices
|
||||
(
|
||||
// Outer block points
|
||||
project ($mvxo $mvyo $mvzo) (sphere)
|
||||
project ( $vxo $mvyo $mvzo) (sphere)
|
||||
project ( $vxo $vyo $mvzo) (sphere)
|
||||
project ($mvxo $vyo $mvzo) (sphere)
|
||||
project ($mvxo $mvyo $vzo) (sphere)
|
||||
project ( $vxo $mvyo $vzo) (sphere)
|
||||
project (-$vxo -$vyo -$vzo) (sphere)
|
||||
project ( $vxo -$vyo -$vzo) (sphere)
|
||||
project ( $vxo $vyo -$vzo) (sphere)
|
||||
project (-$vxo $vyo -$vzo) (sphere)
|
||||
project (-$vxo -$vyo $vzo) (sphere)
|
||||
project ( $vxo -$vyo $vzo) (sphere)
|
||||
project ( $vxo $vyo $vzo) (sphere)
|
||||
project ($mvxo $vyo $vzo) (sphere)
|
||||
project (-$vxo $vyo $vzo) (sphere)
|
||||
);
|
||||
|
||||
blocks
|
||||
|
||||
@ -25,7 +25,7 @@ boundaryField
|
||||
type rotatingWallVelocity;
|
||||
axis (0 1 0);
|
||||
origin (0 0 0);
|
||||
omega constant #eval{ 2.1 * (2*pi()) }; // rev/s -> rads/s
|
||||
omega constant ${{ 2.1 * (2*pi()) }}; // rev/s -> rads/s
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ boundaryField
|
||||
type rotatingWallVelocity;
|
||||
axis (0 1 0);
|
||||
origin (0 0 0);
|
||||
omega constant #eval{ 2.1 * (2*pi()) }; // rev/s -> rads/s
|
||||
omega constant ${{ 2.1 * (2*pi()) }}; // rev/s -> rads/s
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
vessel
|
||||
|
||||
@ -42,7 +42,7 @@ solvers
|
||||
|
||||
centreOfMass (0.5 0.5 0.4);
|
||||
cOfGdisplacement CofG;
|
||||
|
||||
|
||||
// Cuboid dimensions
|
||||
Lx 0.24;
|
||||
Ly 0.24;
|
||||
|
||||
@ -16,29 +16,25 @@ FoamFile
|
||||
|
||||
actions
|
||||
(
|
||||
pickCells
|
||||
{
|
||||
name zone;
|
||||
type cellSet;
|
||||
action new;
|
||||
source boxToCell;
|
||||
sourceInfo
|
||||
{
|
||||
boxes
|
||||
(
|
||||
(0 0.4 0) (0.15 0.5 0.1)
|
||||
);
|
||||
}
|
||||
boxes
|
||||
(
|
||||
(0 0.4 0) (0.15 0.5 0.1)
|
||||
);
|
||||
}
|
||||
|
||||
convertToZone
|
||||
{
|
||||
name zone;
|
||||
type cellZoneSet;
|
||||
action new;
|
||||
source setToCellZone;
|
||||
sourceInfo
|
||||
{
|
||||
set zone;
|
||||
}
|
||||
set zone;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ adjustTimeStep false;
|
||||
|
||||
|
||||
// Allow 10% of time for initialisation before sampling
|
||||
timeStart #eval #{ 0.1 * ${/endTime} #};
|
||||
timeStart #eval{ 0.1 * ${/endTime} };
|
||||
|
||||
functions
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user