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;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDict;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDict;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDict;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDictCalc1;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDictEval1;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDictEval1;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
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;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDict;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
// Test some parsing
|
// Test some parsing
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDictRegex;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
#inputMode merge
|
#inputMode merge
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDict;
|
object dictionary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object testDict;
|
object dictionary;
|
||||||
note "test with foamDictionary -expand";
|
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 |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2018-2020 OpenCFD Ltd.
|
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -47,6 +47,7 @@ Description
|
|||||||
#include "faceZoneSet.H"
|
#include "faceZoneSet.H"
|
||||||
#include "pointZoneSet.H"
|
#include "pointZoneSet.H"
|
||||||
#include "IOdictionary.H"
|
#include "IOdictionary.H"
|
||||||
|
#include "namedDictionary.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -237,7 +238,7 @@ int main(int argc, char *argv[])
|
|||||||
IOdictionary topoSetDict(dictIO);
|
IOdictionary topoSetDict(dictIO);
|
||||||
|
|
||||||
// Read set construct info from dictionary
|
// Read set construct info from dictionary
|
||||||
PtrList<dictionary> actions(topoSetDict.lookup("actions"));
|
List<namedDictionary> actionEntries(topoSetDict.lookup("actions"));
|
||||||
|
|
||||||
forAll(timeDirs, timeI)
|
forAll(timeDirs, timeI)
|
||||||
{
|
{
|
||||||
@ -248,8 +249,13 @@ int main(int argc, char *argv[])
|
|||||||
meshReadUpdate(mesh);
|
meshReadUpdate(mesh);
|
||||||
|
|
||||||
// Execute all actions
|
// 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 setName(dict.get<word>("name"));
|
||||||
const word setType(dict.get<word>("type"));
|
const word setType(dict.get<word>("type"));
|
||||||
|
|
||||||
|
|||||||
@ -145,6 +145,7 @@ $(strings)/parsing/genericRagelLemonDriver.C
|
|||||||
$(strings)/stringOps/stringOps.C
|
$(strings)/stringOps/stringOps.C
|
||||||
$(strings)/stringOps/stringOpsEvaluate.C
|
$(strings)/stringOps/stringOpsEvaluate.C
|
||||||
$(strings)/stringOps/stringOpsSort.C
|
$(strings)/stringOps/stringOpsSort.C
|
||||||
|
$(strings)/stringOps/stringOpsSplit.C
|
||||||
|
|
||||||
expr = expressions
|
expr = expressions
|
||||||
$(expr)/exprEntry/expressionEntry.C
|
$(expr)/exprEntry/expressionEntry.C
|
||||||
@ -275,7 +276,9 @@ $(dictionary)/dictionaryIO.C
|
|||||||
$(dictionary)/dictionarySearch.C
|
$(dictionary)/dictionarySearch.C
|
||||||
$(dictionary)/dictionaryCompat.C
|
$(dictionary)/dictionaryCompat.C
|
||||||
|
|
||||||
|
/* Additional helpers */
|
||||||
$(dictionary)/dictionaryContent/dictionaryContent.C
|
$(dictionary)/dictionaryContent/dictionaryContent.C
|
||||||
|
$(dictionary)/namedDictionary/namedDictionary.C
|
||||||
|
|
||||||
entry = $(dictionary)/entry
|
entry = $(dictionary)/entry
|
||||||
$(entry)/entry.C
|
$(entry)/entry.C
|
||||||
|
|||||||
@ -218,8 +218,8 @@ Foam::Istream& Foam::UIPstream::read(token& t)
|
|||||||
case token::COLON :
|
case token::COLON :
|
||||||
case token::COMMA :
|
case token::COMMA :
|
||||||
case token::ASSIGN :
|
case token::ASSIGN :
|
||||||
case token::ADD :
|
case token::PLUS :
|
||||||
case token::SUBTRACT :
|
case token::MINUS :
|
||||||
case token::MULTIPLY :
|
case token::MULTIPLY :
|
||||||
case token::DIVIDE :
|
case token::DIVIDE :
|
||||||
{
|
{
|
||||||
@ -227,12 +227,12 @@ Foam::Istream& Foam::UIPstream::read(token& t)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Word/directive
|
// The word-variants
|
||||||
case token::tokenType::WORD :
|
case token::tokenType::WORD :
|
||||||
case token::tokenType::DIRECTIVE :
|
case token::tokenType::DIRECTIVE :
|
||||||
{
|
{
|
||||||
word val;
|
word val;
|
||||||
if (read(val))
|
if (readStringFromBuffer(val))
|
||||||
{
|
{
|
||||||
if (token::compound::isCompound(val))
|
if (token::compound::isCompound(val))
|
||||||
{
|
{
|
||||||
@ -251,13 +251,14 @@ Foam::Istream& Foam::UIPstream::read(token& t)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// String types
|
// The string-variants
|
||||||
case token::tokenType::STRING :
|
case token::tokenType::STRING :
|
||||||
|
case token::tokenType::EXPRESSION :
|
||||||
case token::tokenType::VARIABLE :
|
case token::tokenType::VARIABLE :
|
||||||
case token::tokenType::VERBATIM :
|
case token::tokenType::VERBATIM :
|
||||||
{
|
{
|
||||||
string val;
|
string val;
|
||||||
if (read(val))
|
if (readStringFromBuffer(val))
|
||||||
{
|
{
|
||||||
t = std::move(val);
|
t = std::move(val);
|
||||||
t.setType(token::tokenType(c));
|
t.setType(token::tokenType(c));
|
||||||
|
|||||||
@ -202,14 +202,19 @@ bool Foam::UOPstream::write(const token& tok)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The word-variants
|
||||||
|
case token::tokenType::WORD :
|
||||||
case token::tokenType::DIRECTIVE :
|
case token::tokenType::DIRECTIVE :
|
||||||
{
|
{
|
||||||
writeToBuffer(char(token::tokenType::DIRECTIVE));
|
writeToBuffer(char(tok.type()));
|
||||||
writeStringToBuffer(tok.wordToken());
|
writeStringToBuffer(tok.wordToken());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The string-variants
|
||||||
|
case token::tokenType::STRING :
|
||||||
|
case token::tokenType::EXPRESSION :
|
||||||
case token::tokenType::VARIABLE :
|
case token::tokenType::VARIABLE :
|
||||||
case token::tokenType::VERBATIM :
|
case token::tokenType::VERBATIM :
|
||||||
{
|
{
|
||||||
|
|||||||
@ -30,6 +30,7 @@ License
|
|||||||
#include "int.H"
|
#include "int.H"
|
||||||
#include "token.H"
|
#include "token.H"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -42,14 +43,14 @@ namespace
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Convert a single character to a word with length 1
|
// 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);
|
return Foam::word(std::string(1, c), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Permit slash-scoping of entries
|
// Permit slash-scoping of entries
|
||||||
static inline bool validVariableChar(char c)
|
inline bool validVariableChar(char c)
|
||||||
{
|
{
|
||||||
return (Foam::word::valid(c) || c == '/');
|
return (Foam::word::valid(c) || c == '/');
|
||||||
}
|
}
|
||||||
@ -59,23 +60,51 @@ static inline bool validVariableChar(char c)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * 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 Foam::ISstream::nextValid()
|
||||||
{
|
{
|
||||||
char c = 0;
|
char c = 0;
|
||||||
|
|
||||||
while (true)
|
// Get next non-whitespace character
|
||||||
|
while (get(c))
|
||||||
{
|
{
|
||||||
// Get next non-whitespace character
|
if (isspace(c))
|
||||||
while (get(c) && isspace(c))
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Return if stream is bad - ie, previous get() failed
|
|
||||||
if (bad() || 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 (c == '/')
|
||||||
{
|
{
|
||||||
if (!get(c))
|
if (!get(c))
|
||||||
@ -86,37 +115,15 @@ char Foam::ISstream::nextValid()
|
|||||||
|
|
||||||
if (c == '/')
|
if (c == '/')
|
||||||
{
|
{
|
||||||
// C++ style single-line comment - skip through past end-of-line
|
// C++ comment: discard through newline
|
||||||
while (get(c) && c != '\n')
|
(void) getLine(nullptr, '\n');
|
||||||
{}
|
|
||||||
}
|
}
|
||||||
else if (c == '*')
|
else if (c == '*')
|
||||||
{
|
{
|
||||||
// Within a C-style comment
|
// C-style comment: discard through to "*/" ending
|
||||||
while (true)
|
if (!seekCommentEnd_Cstyle())
|
||||||
{
|
{
|
||||||
// Search for end of C-style comment - '*/'
|
return 0;
|
||||||
if (get(c) && c == '*')
|
|
||||||
{
|
|
||||||
if (get(c))
|
|
||||||
{
|
|
||||||
if (c == '/')
|
|
||||||
{
|
|
||||||
// matched '*/'
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (c == '*')
|
|
||||||
{
|
|
||||||
// check again
|
|
||||||
putback(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!good())
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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();
|
if (c == token::HASH)
|
||||||
}
|
{
|
||||||
else if (token::compound::isCompound(val))
|
char nextC;
|
||||||
{
|
is.get(nextC);
|
||||||
t = token::compound::New(val, *this).ptr();
|
if (nextC == token::END_BLOCK)
|
||||||
}
|
{
|
||||||
else
|
// Found closing "#}" sequence
|
||||||
{
|
str.append(buf, nChar);
|
||||||
t = std::move(val); // Move contents to token
|
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)
|
Foam::Istream& Foam::ISstream::read(token& t)
|
||||||
{
|
{
|
||||||
constexpr const unsigned maxLen = 128; // Max length for labels/scalars
|
constexpr const unsigned bufLen = 128; // Max length for labels/scalars
|
||||||
static char buf[maxLen];
|
static char buf[bufLen];
|
||||||
|
|
||||||
// Return the put back token if it exists
|
// Return the put back token if it exists
|
||||||
if (Istream::getBack(t))
|
if (Istream::getBack(t))
|
||||||
@ -199,8 +439,8 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
|||||||
case token::COLON :
|
case token::COLON :
|
||||||
case token::COMMA :
|
case token::COMMA :
|
||||||
case token::ASSIGN :
|
case token::ASSIGN :
|
||||||
case token::ADD :
|
case token::PLUS :
|
||||||
// NB: token::SUBTRACT handled later as the possible start of a Number
|
// NB: token::MINUS handled later as the possible start of a Number
|
||||||
case token::MULTIPLY :
|
case token::MULTIPLY :
|
||||||
case token::DIVIDE :
|
case token::DIVIDE :
|
||||||
{
|
{
|
||||||
@ -209,7 +449,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String: enclosed by double quotes.
|
// String: enclosed by double quotes.
|
||||||
case token::BEGIN_STRING :
|
case token::DQUOTE :
|
||||||
{
|
{
|
||||||
putback(c);
|
putback(c);
|
||||||
|
|
||||||
@ -226,21 +466,21 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Possible verbatim string or dictionary functionEntry
|
// Verbatim string '#{ .. #}' or dictionary '#directive'
|
||||||
case token::HASH :
|
case token::HASH :
|
||||||
{
|
{
|
||||||
char nextC;
|
char nextC;
|
||||||
if (read(nextC).bad())
|
int lookahead = peek();
|
||||||
{
|
|
||||||
// Return lone '#' as word
|
if (lookahead == token::BEGIN_BLOCK)
|
||||||
t = charToWord(c);
|
|
||||||
}
|
|
||||||
else if (nextC == token::BEGIN_BLOCK)
|
|
||||||
{
|
{
|
||||||
// Verbatim string: #{ ... #}
|
// Verbatim string: #{ ... #}
|
||||||
|
// Token stored without the surrounding delimiters
|
||||||
|
|
||||||
|
(void) get(nextC); // Discard '{' lookahead
|
||||||
|
|
||||||
string val;
|
string val;
|
||||||
if (readVerbatim(val).bad())
|
if (readVerbatim(*this, val).bad())
|
||||||
{
|
{
|
||||||
t.setBad();
|
t.setBad();
|
||||||
}
|
}
|
||||||
@ -250,9 +490,14 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
|||||||
t.setType(token::tokenType::VERBATIM);
|
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
|
// Put back both so that '#...' is included in the directive
|
||||||
|
|
||||||
putback(nextC);
|
putback(nextC);
|
||||||
@ -269,34 +514,44 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
|||||||
t.setType(token::tokenType::DIRECTIVE);
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dictionary variable (as rvalue)
|
// Dictionary variable or ${{ expression }}
|
||||||
case token::DOLLAR :
|
case token::DOLLAR :
|
||||||
{
|
{
|
||||||
char nextC;
|
char nextC;
|
||||||
if (read(nextC).bad())
|
if (read(nextC).bad())
|
||||||
{
|
{
|
||||||
// Return lone '$' as word
|
// Return lone '$' as word. Could also ignore
|
||||||
t = charToWord(c);
|
t = charToWord(c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Put back both so that '$...' is included in the variable
|
// NB: the parser is slightly generous here.
|
||||||
putback(nextC);
|
// It will also accept '$ {' as input.
|
||||||
putback(c);
|
// - to be revisited (2021-05-17)
|
||||||
|
|
||||||
string val;
|
string val;
|
||||||
if (readVariable(val).bad())
|
token::tokenType tokType = readVariable(*this, val, nextC);
|
||||||
|
if (tokType == token::tokenType::ERROR)
|
||||||
{
|
{
|
||||||
t.setBad();
|
t.setBad();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t = std::move(val); // Move contents to token
|
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;
|
buf[nChar++] = c;
|
||||||
if (nChar == maxLen)
|
if (nChar == bufLen)
|
||||||
{
|
{
|
||||||
// Runaway argument - avoid buffer overflow
|
// Runaway argument - avoid buffer overflow
|
||||||
buf[maxLen-1] = '\0';
|
buf[bufLen-1] = '\0';
|
||||||
|
|
||||||
FatalIOErrorInFunction(*this)
|
FatalIOErrorInFunction(*this)
|
||||||
<< "number '" << buf << "...'\n"
|
<< "Number '" << buf << "...'\n"
|
||||||
<< " is too long (max. " << maxLen << " characters)"
|
<< " is too long (max. " << bufLen << " characters)"
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
|
|
||||||
t.setBad();
|
t.setBad();
|
||||||
@ -368,7 +623,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
|||||||
if (nChar == 1 && buf[0] == '-')
|
if (nChar == 1 && buf[0] == '-')
|
||||||
{
|
{
|
||||||
// A single '-' is punctuation
|
// A single '-' is punctuation
|
||||||
t = token::punctuationToken(token::SUBTRACT);
|
t = token::punctuationToken(token::MINUS);
|
||||||
}
|
}
|
||||||
else if (labelVal && Foam::read(buf, labelVal))
|
else if (labelVal && Foam::read(buf, labelVal))
|
||||||
{
|
{
|
||||||
@ -397,7 +652,20 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
putback(c);
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -414,20 +682,22 @@ Foam::Istream& Foam::ISstream::read(char& c)
|
|||||||
|
|
||||||
Foam::Istream& Foam::ISstream::read(word& str)
|
Foam::Istream& Foam::ISstream::read(word& str)
|
||||||
{
|
{
|
||||||
constexpr const unsigned maxLen = 1024;
|
constexpr const unsigned bufLen = 1024;
|
||||||
static char buf[maxLen];
|
static char buf[bufLen];
|
||||||
|
|
||||||
unsigned nChar = 0;
|
unsigned nChar = 0;
|
||||||
unsigned depth = 0; // Track depth of (..) nesting
|
unsigned depth = 0; // Depth of (..) nesting
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
while
|
str.clear();
|
||||||
(
|
while (get(c))
|
||||||
(nChar < maxLen)
|
|
||||||
&& get(c)
|
|
||||||
&& word::valid(c)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
if (!word::valid(c))
|
||||||
|
{
|
||||||
|
putback(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == token::BEGIN_LIST)
|
if (c == token::BEGIN_LIST)
|
||||||
{
|
{
|
||||||
++depth;
|
++depth;
|
||||||
@ -436,42 +706,40 @@ Foam::Istream& Foam::ISstream::read(word& str)
|
|||||||
{
|
{
|
||||||
if (!depth)
|
if (!depth)
|
||||||
{
|
{
|
||||||
break; // Closed ')' without an opening '(' ? ... stop
|
// Closed ')' without opening '(':
|
||||||
|
// - don't consider it part of our input
|
||||||
|
putback(c);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
--depth;
|
--depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[nChar++] = c;
|
buf[nChar++] = c;
|
||||||
|
if (nChar == bufLen) // Flush full buffer
|
||||||
|
{
|
||||||
|
str.append(buf, nChar);
|
||||||
|
nChar = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nChar >= maxLen)
|
str.append(buf, nChar); // Finalize pending content
|
||||||
{
|
|
||||||
buf[errLen] = '\0';
|
|
||||||
|
|
||||||
FatalIOErrorInFunction(*this)
|
|
||||||
<< "word '" << buf << "...'\n"
|
|
||||||
<< " is too long (max. " << maxLen << " characters)"
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[nChar] = '\0'; // Terminate string
|
|
||||||
|
|
||||||
if (bad())
|
if (bad())
|
||||||
{
|
{
|
||||||
// Could probably skip this check
|
// Could probably skip this check
|
||||||
|
|
||||||
|
strncpy(buf, str.c_str(), errLen);
|
||||||
buf[errLen] = '\0';
|
buf[errLen] = '\0';
|
||||||
|
|
||||||
FatalIOErrorInFunction(*this)
|
FatalIOErrorInFunction(*this)
|
||||||
<< "Problem while reading word '" << buf << "...' after "
|
<< "Problem while reading word '" << buf
|
||||||
<< nChar << " characters\n"
|
<< "...' [after " << str.length() << " chars]\n"
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nChar == 0)
|
if (str.empty())
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(*this)
|
FatalIOErrorInFunction(*this)
|
||||||
<< "Invalid first character found : " << c
|
<< "Invalid first character found : " << c
|
||||||
@ -479,25 +747,25 @@ Foam::Istream& Foam::ISstream::read(word& str)
|
|||||||
}
|
}
|
||||||
else if (depth)
|
else if (depth)
|
||||||
{
|
{
|
||||||
|
strncpy(buf, str.c_str(), errLen);
|
||||||
|
buf[errLen] = '\0';
|
||||||
|
|
||||||
IOWarningInFunction(*this)
|
IOWarningInFunction(*this)
|
||||||
<< "Missing " << depth
|
<< "Missing " << depth
|
||||||
<< " closing ')' while parsing" << nl << nl
|
<< " closing ')' while parsing" << nl << nl
|
||||||
<< buf << nl << endl;
|
<< buf << nl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize: content already validated, assign without additional checks.
|
|
||||||
str.assign(buf, nChar);
|
|
||||||
putback(c);
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::ISstream::read(string& str)
|
Foam::Istream& Foam::ISstream::read(string& str)
|
||||||
{
|
{
|
||||||
constexpr const unsigned maxLen = 1024;
|
constexpr const unsigned bufLen = 1024;
|
||||||
static char buf[maxLen];
|
static char buf[bufLen];
|
||||||
|
|
||||||
|
unsigned nChar = 0;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
if (!get(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)
|
// Note, we could also handle single-quoted strings here (if desired)
|
||||||
if (c != token::BEGIN_STRING)
|
if (c != token::DQUOTE)
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(*this)
|
FatalIOErrorInFunction(*this)
|
||||||
<< "Incorrect start of string character found : " << c
|
<< "Incorrect start of string character found : " << c
|
||||||
@ -519,26 +787,25 @@ Foam::Istream& Foam::ISstream::read(string& str)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned nChar = 0;
|
str.clear();
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
|
while (get(c))
|
||||||
while
|
|
||||||
(
|
|
||||||
(nChar < maxLen)
|
|
||||||
&& get(c)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (c == token::END_STRING)
|
if (c == '\\')
|
||||||
|
{
|
||||||
|
escaped = !escaped; // Toggle state (retains backslashes)
|
||||||
|
}
|
||||||
|
else if (c == token::DQUOTE)
|
||||||
{
|
{
|
||||||
if (escaped)
|
if (escaped)
|
||||||
{
|
{
|
||||||
escaped = false;
|
escaped = false;
|
||||||
--nChar; // Overwrite backslash
|
--nChar; // Overwrite backslash
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Done reading
|
// Done reading
|
||||||
str.assign(buf, nChar);
|
str.append(buf, nChar);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,253 +814,44 @@ Foam::Istream& Foam::ISstream::read(string& str)
|
|||||||
if (escaped)
|
if (escaped)
|
||||||
{
|
{
|
||||||
escaped = false;
|
escaped = false;
|
||||||
--nChar; // Overwrite backslash
|
--nChar; // Overwrite backslash
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf[errLen] = buf[nChar] = '\0';
|
str.append(buf, nChar); // Finalize pending content
|
||||||
|
strncpy(buf, str.c_str(), errLen);
|
||||||
|
buf[errLen] = '\0';
|
||||||
|
|
||||||
FatalIOErrorInFunction(*this)
|
FatalIOErrorInFunction(*this)
|
||||||
<< "found '\\n' while reading string \""
|
<< "Unescaped '\\n' while reading string \"" << buf
|
||||||
<< buf << "...\""
|
<< "...\" [after " << str.length() << " chars]\n"
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (c == '\\')
|
|
||||||
{
|
|
||||||
escaped = !escaped; // toggle state (retains backslashes)
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
escaped = false;
|
escaped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[nChar++] = c;
|
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
|
// Don't worry about a dangling backslash if string terminated prematurely
|
||||||
buf[errLen] = buf[nChar] = '\0';
|
|
||||||
|
|
||||||
FatalIOErrorInFunction(*this)
|
str.append(buf, nChar); // Finalize pending content
|
||||||
<< "Problem while reading string \"" << buf << "...\""
|
strncpy(buf, str.c_str(), errLen);
|
||||||
<< exit(FatalIOError);
|
buf[errLen] = '\0';
|
||||||
|
|
||||||
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';
|
|
||||||
|
|
||||||
FatalIOErrorInFunction(*this)
|
FatalIOErrorInFunction(*this)
|
||||||
<< "Problem while reading string \"" << buf << "...\""
|
<< "Problem while reading string \"" << buf << "...\""
|
||||||
|
|||||||
@ -69,18 +69,6 @@ class ISstream
|
|||||||
//- Get the next valid character
|
//- Get the next valid character
|
||||||
char nextValid();
|
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
|
//- No copy assignment
|
||||||
void operator=(const ISstream&) = delete;
|
void operator=(const ISstream&) = delete;
|
||||||
|
|
||||||
@ -137,6 +125,13 @@ public:
|
|||||||
virtual ios_base::fmtflags flags() const;
|
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
|
// Read Functions
|
||||||
|
|
||||||
//- Raw, low-level get character function.
|
//- Raw, low-level get character function.
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -47,27 +47,33 @@ bool Foam::OSstream::write(const token& tok)
|
|||||||
|
|
||||||
case token::tokenType::DIRECTIVE :
|
case token::tokenType::DIRECTIVE :
|
||||||
{
|
{
|
||||||
// The '#' sigil is already part of the wordToken
|
// Token stored with leading '#' sigil - output directly
|
||||||
write(tok.wordToken());
|
write(tok.wordToken());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case token::tokenType::VERBATIM :
|
case token::tokenType::EXPRESSION :
|
||||||
{
|
{
|
||||||
// Surrounding '#{ .. #}' to be recognized as verbatim
|
// Token stored with surrounding '${{ .. }}' - output directly
|
||||||
write(char(token::HASH));
|
|
||||||
write(char(token::BEGIN_BLOCK));
|
|
||||||
writeQuoted(tok.stringToken(), false);
|
writeQuoted(tok.stringToken(), false);
|
||||||
write(char(token::HASH));
|
|
||||||
write(char(token::END_BLOCK));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case token::tokenType::VARIABLE :
|
case token::tokenType::VARIABLE :
|
||||||
{
|
{
|
||||||
|
// Token stored with leading '$' sigil - output directly
|
||||||
writeQuoted(tok.stringToken(), false);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -127,7 +133,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
|||||||
|
|
||||||
|
|
||||||
// Output with surrounding quotes and backslash escaping
|
// Output with surrounding quotes and backslash escaping
|
||||||
os_ << token::BEGIN_STRING;
|
os_ << token::DQUOTE;
|
||||||
|
|
||||||
unsigned backslash = 0;
|
unsigned backslash = 0;
|
||||||
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
|
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
|
||||||
@ -144,7 +150,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
|||||||
++lineNumber_;
|
++lineNumber_;
|
||||||
++backslash; // backslash escape for newline
|
++backslash; // backslash escape for newline
|
||||||
}
|
}
|
||||||
else if (c == token::END_STRING)
|
else if (c == token::DQUOTE)
|
||||||
{
|
{
|
||||||
++backslash; // backslash escape for quote
|
++backslash; // backslash escape for quote
|
||||||
}
|
}
|
||||||
@ -161,7 +167,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
|||||||
|
|
||||||
// silently drop any trailing backslashes
|
// silently drop any trailing backslashes
|
||||||
// they would otherwise appear like an escaped end-quote
|
// they would otherwise appear like an escaped end-quote
|
||||||
os_ << token::END_STRING;
|
os_ << token::DQUOTE;
|
||||||
|
|
||||||
setState(os_.rdstate());
|
setState(os_.rdstate());
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@ -71,11 +71,13 @@ class token
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
//- Enumeration defining the types of token.
|
//- Enumeration defining the types of token.
|
||||||
// Since these values are also used to tag content in Pstream,
|
// Since the enumeration is used to tag content in Pstream, it is of
|
||||||
// the maximum number of types is limited to 30.
|
// type \c char and shall have values that do not overlap with regular
|
||||||
enum tokenType
|
// punctuation characters.
|
||||||
|
enum tokenType : char
|
||||||
{
|
{
|
||||||
UNDEFINED = 0, //!< An undefined token-type
|
UNDEFINED = '\0', //!< An undefined token-type
|
||||||
|
ERROR = '\x80', //!< Token error encountered
|
||||||
|
|
||||||
// Fundamental types
|
// Fundamental types
|
||||||
FLAG, //!< stream flag (1-byte bitmask)
|
FLAG, //!< stream flag (1-byte bitmask)
|
||||||
@ -86,14 +88,18 @@ public:
|
|||||||
DOUBLE, //!< double (double-precision) type
|
DOUBLE, //!< double (double-precision) type
|
||||||
|
|
||||||
// Pointer types
|
// Pointer types
|
||||||
WORD, //!< A Foam::word
|
WORD, //!< Foam::word
|
||||||
STRING, //!< A string (usually double-quoted)
|
STRING, //!< Foam::string (usually double-quoted)
|
||||||
DIRECTIVE, //!< A dictionary \c \#directive (word variant)
|
|
||||||
VARIABLE, //!< A dictionary \c \$variable (string variant)
|
|
||||||
VERBATIM, //!< Verbatim string content
|
|
||||||
COMPOUND, //!< Compound type such as \c List\<label\> etc.
|
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
|
// Aliases
|
||||||
FLOAT_SCALAR = FLOAT,
|
FLOAT_SCALAR = FLOAT,
|
||||||
@ -122,16 +128,16 @@ public:
|
|||||||
COLON = ':', //!< Colon [#isseparator]
|
COLON = ':', //!< Colon [#isseparator]
|
||||||
SEMICOLON = ';', //!< Semicolon [#isseparator]
|
SEMICOLON = ';', //!< Semicolon [#isseparator]
|
||||||
COMMA = ',', //!< Comma [#isseparator]
|
COMMA = ',', //!< Comma [#isseparator]
|
||||||
HASH = '#', //!< Hash - directive or verbatim string
|
HASH = '#', //!< Hash - directive or start verbatim string
|
||||||
DOLLAR = '$', //!< Dollar - start variable
|
DOLLAR = '$', //!< Dollar - start variable or expression
|
||||||
QUESTION = '?', //!< Question mark (eg, ternary)
|
QUESTION = '?', //!< Question mark (eg, ternary)
|
||||||
ATSYM = '@', //!< The 'at' symbol
|
ATSYM = '@', //!< The 'at' symbol
|
||||||
SQUOTE = '\'', //!< Single quote
|
SQUOTE = '\'', //!< Single quote
|
||||||
DQUOTE = '"', //!< Double quote
|
DQUOTE = '"', //!< Double quote
|
||||||
|
|
||||||
ASSIGN = '=', //!< Assignment/equals [#isseparator]
|
ASSIGN = '=', //!< Assignment/equals [#isseparator]
|
||||||
ADD = '+', //!< Addition [#isseparator]
|
PLUS = '+', //!< Addition [#isseparator]
|
||||||
SUBTRACT = '-', //!< Subtract or start of negative number
|
MINUS = '-', //!< Subtract or start of negative number
|
||||||
MULTIPLY = '*', //!< Multiply [#isseparator]
|
MULTIPLY = '*', //!< Multiply [#isseparator]
|
||||||
DIVIDE = '/', //!< Divide [#isseparator]
|
DIVIDE = '/', //!< Divide [#isseparator]
|
||||||
|
|
||||||
@ -144,6 +150,8 @@ public:
|
|||||||
|
|
||||||
// With semantically meaning
|
// With semantically meaning
|
||||||
|
|
||||||
|
ADD = PLUS, //!< Addition [#isseparator]
|
||||||
|
SUBTRACT = MINUS, //!< Subtract or start of negative number
|
||||||
END_STATEMENT = SEMICOLON, //!< End entry [#isseparator]
|
END_STATEMENT = SEMICOLON, //!< End entry [#isseparator]
|
||||||
BEGIN_LIST = LPAREN, //!< Begin list [#isseparator]
|
BEGIN_LIST = LPAREN, //!< Begin list [#isseparator]
|
||||||
END_LIST = RPAREN, //!< End list [#isseparator]
|
END_LIST = RPAREN, //!< End list [#isseparator]
|
||||||
@ -471,10 +479,10 @@ public:
|
|||||||
//- Token is LABEL, FLOAT or DOUBLE
|
//- Token is LABEL, FLOAT or DOUBLE
|
||||||
inline bool isNumber() const noexcept;
|
inline bool isNumber() const noexcept;
|
||||||
|
|
||||||
//- Token is WORD or DIRECTIVE word
|
//- Token is word-variant (WORD, DIRECTIVE)
|
||||||
inline bool isWord() const noexcept;
|
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;
|
inline bool isWord(const std::string& s) const;
|
||||||
|
|
||||||
//- Token is DIRECTIVE (word variant)
|
//- Token is DIRECTIVE (word variant)
|
||||||
@ -483,16 +491,20 @@ public:
|
|||||||
//- Token is (quoted) STRING (string variant)
|
//- Token is (quoted) STRING (string variant)
|
||||||
inline bool isQuotedString() const noexcept;
|
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;
|
inline bool isString() const noexcept;
|
||||||
|
|
||||||
|
//- Token is EXPRESSION (string variant)
|
||||||
|
inline bool isExpression() const noexcept;
|
||||||
|
|
||||||
//- Token is VARIABLE (string variant)
|
//- Token is VARIABLE (string variant)
|
||||||
inline bool isVariable() const noexcept;
|
inline bool isVariable() const noexcept;
|
||||||
|
|
||||||
//- Token is VERBATIM string (string variant)
|
//- Token is VERBATIM string (string variant)
|
||||||
inline bool isVerbatim() const noexcept;
|
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;
|
inline bool isStringType() const noexcept;
|
||||||
|
|
||||||
//- Token is COMPOUND
|
//- Token is COMPOUND
|
||||||
@ -542,7 +554,8 @@ public:
|
|||||||
|
|
||||||
//- Return const reference to the string contents.
|
//- Return const reference to the string contents.
|
||||||
// Report FatalIOError and return \b "" if token is not a
|
// 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;
|
inline const string& stringToken() const;
|
||||||
|
|
||||||
//- Read access for compound token
|
//- Read access for compound token
|
||||||
@ -599,16 +612,16 @@ public:
|
|||||||
//- Copy assign from double
|
//- Copy assign from double
|
||||||
inline void operator=(const doubleScalar val);
|
inline void operator=(const doubleScalar val);
|
||||||
|
|
||||||
//- Copy assign from word
|
//- Copy assign from word content
|
||||||
inline void operator=(const word& w);
|
inline void operator=(const word& w);
|
||||||
|
|
||||||
//- Copy assign from string
|
//- Copy assign from string content
|
||||||
inline void operator=(const string& str);
|
inline void operator=(const string& str);
|
||||||
|
|
||||||
//- Move assign from word
|
//- Move assign from word content
|
||||||
inline void operator=(word&& w);
|
inline void operator=(word&& w);
|
||||||
|
|
||||||
//- Move assign from string
|
//- Move assign from string content
|
||||||
inline void operator=(string&& str);
|
inline void operator=(string&& str);
|
||||||
|
|
||||||
//- Assign compound with reference counting to token
|
//- Assign compound with reference counting to token
|
||||||
|
|||||||
@ -66,8 +66,8 @@ inline bool Foam::token::isseparator(int c) noexcept
|
|||||||
case token::COLON :
|
case token::COLON :
|
||||||
case token::COMMA :
|
case token::COMMA :
|
||||||
case token::ASSIGN :
|
case token::ASSIGN :
|
||||||
case token::ADD :
|
case token::PLUS :
|
||||||
// Excluded token::SUBTRACT since it could start a number
|
// Excluded token::MINUS since it could start a number
|
||||||
case token::MULTIPLY :
|
case token::MULTIPLY :
|
||||||
case token::DIVIDE :
|
case token::DIVIDE :
|
||||||
{
|
{
|
||||||
@ -121,6 +121,7 @@ inline Foam::token::token(const token& tok)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case tokenType::STRING:
|
case tokenType::STRING:
|
||||||
|
case tokenType::EXPRESSION:
|
||||||
case tokenType::VARIABLE:
|
case tokenType::VARIABLE:
|
||||||
case tokenType::VERBATIM:
|
case tokenType::VERBATIM:
|
||||||
{
|
{
|
||||||
@ -265,6 +266,7 @@ inline void Foam::token::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
case tokenType::STRING:
|
case tokenType::STRING:
|
||||||
|
case tokenType::EXPRESSION:
|
||||||
case tokenType::VARIABLE:
|
case tokenType::VARIABLE:
|
||||||
case tokenType::VERBATIM:
|
case tokenType::VERBATIM:
|
||||||
{
|
{
|
||||||
@ -357,6 +359,7 @@ inline bool Foam::token::setType(token::tokenType tokType) noexcept
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case tokenType::STRING:
|
case tokenType::STRING:
|
||||||
|
case tokenType::EXPRESSION:
|
||||||
case tokenType::VARIABLE:
|
case tokenType::VARIABLE:
|
||||||
case tokenType::VERBATIM:
|
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
|
// could also go from WORD to STRING etc - to be decided
|
||||||
case tokenType::STRING:
|
case tokenType::STRING:
|
||||||
|
case tokenType::EXPRESSION:
|
||||||
case tokenType::VARIABLE:
|
case tokenType::VARIABLE:
|
||||||
case tokenType::VERBATIM:
|
case tokenType::VERBATIM:
|
||||||
type_ = tokType;
|
type_ = tokType;
|
||||||
@ -651,12 +655,19 @@ inline bool Foam::token::isString() const noexcept
|
|||||||
return
|
return
|
||||||
(
|
(
|
||||||
type_ == tokenType::STRING
|
type_ == tokenType::STRING
|
||||||
|
|| type_ == tokenType::EXPRESSION
|
||||||
|| type_ == tokenType::VARIABLE
|
|| type_ == tokenType::VARIABLE
|
||||||
|| type_ == tokenType::VERBATIM
|
|| type_ == tokenType::VERBATIM
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::token::isExpression() const noexcept
|
||||||
|
{
|
||||||
|
return (type_ == tokenType::EXPRESSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Foam::token::isVariable() const noexcept
|
inline bool Foam::token::isVariable() const noexcept
|
||||||
{
|
{
|
||||||
return (type_ == tokenType::VARIABLE);
|
return (type_ == tokenType::VARIABLE);
|
||||||
@ -680,6 +691,7 @@ inline const Foam::string& Foam::token::stringToken() const
|
|||||||
if
|
if
|
||||||
(
|
(
|
||||||
type_ == tokenType::STRING
|
type_ == tokenType::STRING
|
||||||
|
|| type_ == tokenType::EXPRESSION
|
||||||
|| type_ == tokenType::VARIABLE
|
|| type_ == tokenType::VARIABLE
|
||||||
|| type_ == tokenType::VERBATIM
|
|| type_ == tokenType::VERBATIM
|
||||||
)
|
)
|
||||||
@ -754,6 +766,7 @@ inline void Foam::token::operator=(const token& tok)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case tokenType::STRING:
|
case tokenType::STRING:
|
||||||
|
case tokenType::EXPRESSION:
|
||||||
case tokenType::VARIABLE:
|
case tokenType::VARIABLE:
|
||||||
case tokenType::VERBATIM:
|
case tokenType::VERBATIM:
|
||||||
{
|
{
|
||||||
@ -903,6 +916,7 @@ inline bool Foam::token::operator==(const token& tok) const
|
|||||||
return *data_.wordPtr == *tok.data_.wordPtr;
|
return *data_.wordPtr == *tok.data_.wordPtr;
|
||||||
|
|
||||||
case tokenType::STRING:
|
case tokenType::STRING:
|
||||||
|
case tokenType::EXPRESSION:
|
||||||
case tokenType::VARIABLE:
|
case tokenType::VARIABLE:
|
||||||
case tokenType::VERBATIM:
|
case tokenType::VERBATIM:
|
||||||
return *data_.stringPtr == *tok.data_.stringPtr;
|
return *data_.stringPtr == *tok.data_.stringPtr;
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -82,6 +82,10 @@ static OS& printTokenInfo(OS& os, const token& tok)
|
|||||||
os << "string " << tok.stringToken();
|
os << "string " << tok.stringToken();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case token::tokenType::EXPRESSION:
|
||||||
|
os << "expression " << tok.stringToken();
|
||||||
|
break;
|
||||||
|
|
||||||
case token::tokenType::VARIABLE:
|
case token::tokenType::VARIABLE:
|
||||||
os << "variable " << tok.stringToken();
|
os << "variable " << tok.stringToken();
|
||||||
break;
|
break;
|
||||||
@ -141,6 +145,7 @@ Foam::word Foam::token::name() const
|
|||||||
case token::tokenType::WORD: return "word";
|
case token::tokenType::WORD: return "word";
|
||||||
case token::tokenType::DIRECTIVE: return "directive";
|
case token::tokenType::DIRECTIVE: return "directive";
|
||||||
case token::tokenType::STRING: return "string";
|
case token::tokenType::STRING: return "string";
|
||||||
|
case token::tokenType::EXPRESSION: return "expression";
|
||||||
case token::tokenType::VERBATIM: return "verbatim";
|
case token::tokenType::VERBATIM: return "verbatim";
|
||||||
case token::tokenType::VARIABLE: return "variable";
|
case token::tokenType::VARIABLE: return "variable";
|
||||||
case token::tokenType::COMPOUND: return "compound";
|
case token::tokenType::COMPOUND: return "compound";
|
||||||
@ -194,8 +199,10 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const token& tok)
|
|||||||
os << tok.data_.doubleVal;
|
os << tok.data_.doubleVal;
|
||||||
break;
|
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::DIRECTIVE:
|
||||||
|
case token::tokenType::EXPRESSION:
|
||||||
case token::tokenType::VARIABLE:
|
case token::tokenType::VARIABLE:
|
||||||
case token::tokenType::VERBATIMSTRING:
|
case token::tokenType::VERBATIMSTRING:
|
||||||
os.write(tok);
|
os.write(tok);
|
||||||
|
|||||||
@ -56,60 +56,163 @@ namespace functionEntries
|
|||||||
} // End namespace Foam
|
} // 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
|
Foam::tokenList Foam::functionEntries::evalEntry::evaluate
|
||||||
(
|
(
|
||||||
const dictionary& parentDict,
|
const dictionary& parentDict,
|
||||||
Istream& is
|
const string& inputExpr,
|
||||||
|
label fieldWidth,
|
||||||
|
const Istream& is
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#ifdef FULLDEBUG
|
// Field width for the result
|
||||||
DetailInfo
|
if (fieldWidth < 1)
|
||||||
<< "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
|
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(is)
|
FatalIOErrorInFunction(is)
|
||||||
<< "Invalid input for #eval."
|
<< "Invalid field width: " << fieldWidth << nl << endl
|
||||||
" Expecting a string or block to evaluate, but found" << nl
|
|
||||||
<< tok.info() << endl
|
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FULLDEBUG
|
#ifdef FULLDEBUG
|
||||||
DetailInfo
|
DetailInfo
|
||||||
<< "input: " << s << endl;
|
<< "input: " << inputExpr << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Expand with env=true, empty=true, subDict=false
|
// Expand with env=true, empty=true, subDict=false
|
||||||
// with comments stripped.
|
// with comments stripped.
|
||||||
// Special handling of $[...] syntax enabled.
|
// 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);
|
expressions::exprString::inplaceExpand(s, parentDict, true);
|
||||||
stringOps::inplaceTrim(s);
|
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 * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::functionEntries::evalEntry::execute
|
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
|
//- 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:
|
public:
|
||||||
|
|
||||||
//- Execute in a primitiveEntry context
|
//- Execute in a primitiveEntry context, extracts token or line
|
||||||
static bool execute
|
static bool execute
|
||||||
(
|
(
|
||||||
const dictionary& parentDict,
|
const dictionary& parentDict,
|
||||||
primitiveEntry& thisEntry,
|
primitiveEntry& thisEntry,
|
||||||
Istream& is
|
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_)
|
if (!executedictionaryIstreamMemberFunctionTablePtr_)
|
||||||
{
|
{
|
||||||
cerr<< FUNCTION_NAME << nl
|
std::cerr
|
||||||
|
<< FUNCTION_NAME << nl
|
||||||
<< "Not yet initialized, function = "
|
<< "Not yet initialized, function = "
|
||||||
<< functionName.c_str() << std::endl;
|
<< functionName.c_str() << std::endl;
|
||||||
|
|
||||||
@ -128,7 +129,8 @@ bool Foam::functionEntry::execute
|
|||||||
|
|
||||||
if (!executeprimitiveEntryIstreamMemberFunctionTablePtr_)
|
if (!executeprimitiveEntryIstreamMemberFunctionTablePtr_)
|
||||||
{
|
{
|
||||||
cerr<< FUNCTION_NAME << nl
|
std::cerr
|
||||||
|
<< FUNCTION_NAME << nl
|
||||||
<< "Not yet initialized, function = "
|
<< "Not yet initialized, function = "
|
||||||
<< functionName.c_str() << std::endl;
|
<< 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
|
// Skip dummy tokens - avoids entry::getKeyword consuming #else, #endif
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if
|
if (is.read(t).bad() || is.eof() || !t.good())
|
||||||
(
|
|
||||||
is.read(t).bad()
|
|
||||||
|| is.eof()
|
|
||||||
|| !t.good()
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return;
|
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 dictionary& dict,
|
||||||
const string& keyword,
|
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 dictionary& dict,
|
||||||
const token& t
|
const token& t
|
||||||
@ -117,15 +112,15 @@ Foam::token Foam::functionEntries::ifeqEntry::expand
|
|||||||
{
|
{
|
||||||
if (t.isWord())
|
if (t.isWord())
|
||||||
{
|
{
|
||||||
return expand(dict, t.wordToken(), t);
|
return expandToken(dict, t.wordToken(), t);
|
||||||
}
|
}
|
||||||
else if (t.isVariable())
|
else if (t.isVariable())
|
||||||
{
|
{
|
||||||
return expand(dict, t.stringToken(), t);
|
return expandToken(dict, t.stringToken(), t);
|
||||||
}
|
}
|
||||||
else if (t.isString())
|
else if (t.isString())
|
||||||
{
|
{
|
||||||
return expand(dict, t.stringToken(), t);
|
return expandToken(dict, t.stringToken(), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
@ -230,6 +225,9 @@ bool Foam::functionEntries::ifeqEntry::equalToken
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case token::EXPRESSION:
|
||||||
|
return false;
|
||||||
|
|
||||||
case token::COMPOUND:
|
case token::COMPOUND:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -245,7 +243,7 @@ void Foam::functionEntries::ifeqEntry::skipUntil
|
|||||||
(
|
(
|
||||||
DynamicList<filePos>& stack,
|
DynamicList<filePos>& stack,
|
||||||
const dictionary& parentDict,
|
const dictionary& parentDict,
|
||||||
const word& endWord,
|
const word& endDirective,
|
||||||
Istream& is
|
Istream& is
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -258,28 +256,26 @@ void Foam::functionEntries::ifeqEntry::skipUntil
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if
|
else if (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
|
||||||
(
|
|
||||||
t.wordToken() == "#if"
|
|
||||||
|| t.wordToken() == "#ifeq"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
stack.append(filePos(is.name(), is.lineNumber()));
|
stack.append(filePos(is.name(), is.lineNumber()));
|
||||||
skipUntil(stack, parentDict, "#endif", is);
|
skipUntil(stack, parentDict, "#endif", is);
|
||||||
stack.remove();
|
stack.remove();
|
||||||
}
|
}
|
||||||
else if (t.wordToken() == endWord)
|
else if (t.wordToken() == endDirective)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FatalIOErrorInFunction(parentDict)
|
FatalIOErrorInFunction(parentDict)
|
||||||
<< "Did not find matching " << endWord << nl
|
<< "Did not find matching " << endDirective << nl
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::functionEntries::ifeqEntry::evaluate
|
bool Foam::functionEntries::ifeqEntry::evaluate
|
||||||
(
|
(
|
||||||
const bool doIf,
|
const bool doIf,
|
||||||
@ -292,35 +288,47 @@ bool Foam::functionEntries::ifeqEntry::evaluate
|
|||||||
{
|
{
|
||||||
token t;
|
token t;
|
||||||
readToken(t, is);
|
readToken(t, is);
|
||||||
|
bool pending = false;
|
||||||
|
|
||||||
if (t.isWord() && t.wordToken() == "#ifeq")
|
if (t.isDirective())
|
||||||
{
|
{
|
||||||
// Recurse to evaluate
|
if (t.wordToken() == "#ifeq")
|
||||||
execute(stack, parentDict, is);
|
{
|
||||||
}
|
// Recurse to evaluate
|
||||||
else if (t.isWord() && t.wordToken() == "#if")
|
execute(stack, parentDict, is);
|
||||||
{
|
}
|
||||||
// Recurse to evaluate
|
else if (t.wordToken() == "#if")
|
||||||
ifEntry::execute(stack, parentDict, is);
|
{
|
||||||
}
|
// Recurse to evaluate
|
||||||
else if
|
ifEntry::execute(stack, parentDict, is);
|
||||||
(
|
}
|
||||||
doIf
|
else if
|
||||||
&& t.isWord()
|
(
|
||||||
&& (t.wordToken() == "#else" || t.wordToken() == "#elif")
|
doIf
|
||||||
)
|
&& (t.wordToken() == "#else" || t.wordToken() == "#elif")
|
||||||
{
|
)
|
||||||
// Now skip until #endif
|
{
|
||||||
skipUntil(stack, parentDict, "#endif", is);
|
// Now skip until #endif
|
||||||
stack.remove();
|
skipUntil(stack, parentDict, "#endif", is);
|
||||||
break;
|
stack.remove();
|
||||||
}
|
break;
|
||||||
else if (t.isWord() && t.wordToken() == "#endif")
|
}
|
||||||
{
|
else if (t.wordToken() == "#endif")
|
||||||
stack.remove();
|
{
|
||||||
break;
|
stack.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pending = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
pending = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending)
|
||||||
{
|
{
|
||||||
is.putBack(t);
|
is.putBack(t);
|
||||||
bool ok = entry::New(parentDict, is);
|
bool ok = entry::New(parentDict, is);
|
||||||
@ -354,21 +362,23 @@ bool Foam::functionEntries::ifeqEntry::execute
|
|||||||
{
|
{
|
||||||
readToken(t, is);
|
readToken(t, is);
|
||||||
|
|
||||||
if
|
// Only consider directives
|
||||||
(
|
if (!t.isDirective())
|
||||||
t.isWord()
|
{
|
||||||
&& (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
|
continue;
|
||||||
)
|
}
|
||||||
|
|
||||||
|
if (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
|
||||||
{
|
{
|
||||||
stack.append(filePos(is.name(), is.lineNumber()));
|
stack.append(filePos(is.name(), is.lineNumber()));
|
||||||
skipUntil(stack, parentDict, "#endif", is);
|
skipUntil(stack, parentDict, "#endif", is);
|
||||||
stack.remove();
|
stack.remove();
|
||||||
}
|
}
|
||||||
else if (t.isWord() && t.wordToken() == "#else")
|
else if (t.wordToken() == "#else")
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (t.isWord() && t.wordToken() == "#elif")
|
else if (t.wordToken() == "#elif")
|
||||||
{
|
{
|
||||||
// const label lineNo = is.lineNumber();
|
// const label lineNo = is.lineNumber();
|
||||||
|
|
||||||
@ -386,7 +396,7 @@ bool Foam::functionEntries::ifeqEntry::execute
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (t.isWord() && t.wordToken() == "#endif")
|
else if (t.wordToken() == "#endif")
|
||||||
{
|
{
|
||||||
stack.remove();
|
stack.remove();
|
||||||
break;
|
break;
|
||||||
@ -421,11 +431,11 @@ bool Foam::functionEntries::ifeqEntry::execute
|
|||||||
|
|
||||||
// Read first token and expand any string
|
// Read first token and expand any string
|
||||||
token cond1(is);
|
token cond1(is);
|
||||||
cond1 = expand(parentDict, cond1);
|
cond1 = expandToken(parentDict, cond1);
|
||||||
|
|
||||||
// Read second token and expand any string
|
// Read second token and expand any string
|
||||||
token cond2(is);
|
token cond2(is);
|
||||||
cond2 = expand(parentDict, cond2);
|
cond2 = expandToken(parentDict, cond2);
|
||||||
|
|
||||||
const bool equal = equalToken(cond1, cond2);
|
const bool equal = equalToken(cond1, cond2);
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018 OpenFOAM Foundation
|
Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -31,7 +32,7 @@ Description
|
|||||||
|
|
||||||
E.g.
|
E.g.
|
||||||
\verbatim
|
\verbatim
|
||||||
a #calc "0.123";
|
a #eval "0.123";
|
||||||
b 1.23e-1;
|
b 1.23e-1;
|
||||||
|
|
||||||
#ifeq $a $b
|
#ifeq $a $b
|
||||||
@ -90,46 +91,15 @@ class ifeqEntry
|
|||||||
:
|
:
|
||||||
public functionEntry
|
public functionEntry
|
||||||
{
|
{
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
// Data Types
|
||||||
|
|
||||||
typedef Tuple2<fileName, label> filePos;
|
typedef Tuple2<fileName, label> filePos;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// 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
|
static bool evaluate
|
||||||
(
|
(
|
||||||
const bool doIf,
|
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:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- 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
|
// Find the type/position of the ":-" or ":+" alternative values
|
||||||
// Returns 0, '-', '+' corresponding to not-found or ':-' or ':+'
|
// Returns 0, '-', '+' corresponding to not-found or ':-' or ':+'
|
||||||
static inline int findParameterAlternative
|
static inline char findParameterAlternative
|
||||||
(
|
(
|
||||||
const std::string& s,
|
const std::string& s,
|
||||||
std::string::size_type& pos,
|
std::string::size_type& pos,
|
||||||
@ -50,7 +50,7 @@ static inline int findParameterAlternative
|
|||||||
if (pos < endPos)
|
if (pos < endPos)
|
||||||
{
|
{
|
||||||
// in-range: check for '+' or '-' following the ':'
|
// in-range: check for '+' or '-' following the ':'
|
||||||
const int altType = s[pos+1];
|
const char altType = s[pos+1];
|
||||||
if (altType == '+' || altType == '-')
|
if (altType == '+' || altType == '-')
|
||||||
{
|
{
|
||||||
return altType;
|
return altType;
|
||||||
@ -78,11 +78,13 @@ bool Foam::primitiveEntry::expandVariable
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int altType = 0; // Type ('-' or '+') for ":-" or ":+" alternatives
|
char altType = 0; // Type ('-' or '+') for ":-" or ":+" alternatives
|
||||||
word expanded;
|
word expanded;
|
||||||
string altValue;
|
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
|
// Replace content between {} with string expansion and
|
||||||
// handle ${parameter:-word} or ${parameter:+word}
|
// handle ${parameter:-word} or ${parameter:+word}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ License
|
|||||||
|
|
||||||
#include "primitiveEntry.H"
|
#include "primitiveEntry.H"
|
||||||
#include "functionEntry.H"
|
#include "functionEntry.H"
|
||||||
|
#include "evalEntry.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -63,25 +64,51 @@ bool Foam::primitiveEntry::acceptToken
|
|||||||
|
|
||||||
if (tok.isDirective())
|
if (tok.isDirective())
|
||||||
{
|
{
|
||||||
// Directive: wordToken starts with '#'
|
// Directive (wordToken) begins with '#'. Eg, "#include"
|
||||||
|
// Remove leading '#' sigil before dispatching
|
||||||
|
|
||||||
const word& key = tok.wordToken();
|
const word& key = tok.wordToken();
|
||||||
|
|
||||||
|
// Min-size is 2: sigil '#' with any content
|
||||||
accept =
|
accept =
|
||||||
(
|
(
|
||||||
disableFunctionEntries
|
(disableFunctionEntries || key.size() < 2)
|
||||||
|| key.size() == 1
|
|
||||||
|| !expandFunction(key.substr(1), dict, is)
|
|| !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())
|
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();
|
const string& key = tok.stringToken();
|
||||||
|
|
||||||
|
// Min-size is 2: sigil '$' with any content
|
||||||
accept =
|
accept =
|
||||||
(
|
(
|
||||||
disableFunctionEntries
|
(disableFunctionEntries || key.size() < 2)
|
||||||
|| key.size() == 1
|
|
||||||
|| !expandVariable(key.substr(1), dict)
|
|| !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
|
// - similarly, the bitmask is tested *after* decreasing depth
|
||||||
|
|
||||||
uint64_t balanced = 0u;
|
uint64_t balanced = 0u;
|
||||||
label depth = 0;
|
int depth = 0;
|
||||||
token tok;
|
token tok;
|
||||||
|
|
||||||
while
|
while
|
||||||
@ -274,19 +301,18 @@ void Foam::primitiveEntry::write(Ostream& os, const bool contentsOnly) const
|
|||||||
os.writeKeyword(keyword());
|
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)
|
for (const token& tok : *this)
|
||||||
{
|
{
|
||||||
if (addSpace) os << token::SPACE;
|
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))
|
if (!os.write(tok))
|
||||||
{
|
{
|
||||||
os << tok; // Revert to normal '<<' output operator
|
os << tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
addSpace = true; // Separate from following tokens
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contentsOnly)
|
if (!contentsOnly)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2020 OpenCFD Ltd.
|
Copyright (C) 2015-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -243,91 +243,42 @@ bool Foam::functionObjectList::readFunctionObject
|
|||||||
// 'patchAverage(patch=inlet, p)' -> funcName = patchAverage;
|
// 'patchAverage(patch=inlet, p)' -> funcName = patchAverage;
|
||||||
// args = (patch=inlet, p); field = p
|
// args = (patch=inlet, p); field = p
|
||||||
|
|
||||||
word funcName(funcNameArgs);
|
word funcName;
|
||||||
|
|
||||||
int argLevel = 0;
|
|
||||||
wordRes args;
|
wordRes args;
|
||||||
|
|
||||||
List<Tuple2<word, string>> namedArgs;
|
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;
|
const auto argsBeg = funcNameArgs.find('(');
|
||||||
|
if (argsBeg == std::string::npos)
|
||||||
if (c == '(')
|
|
||||||
{
|
{
|
||||||
if (argLevel == 0)
|
// Function name only, no args
|
||||||
{
|
funcName = word::validate(funcNameArgs);
|
||||||
funcName = funcNameArgs.substr(start, i - start);
|
|
||||||
start = i+1;
|
|
||||||
}
|
|
||||||
++argLevel;
|
|
||||||
}
|
}
|
||||||
else if (c == ',' || c == ')')
|
else
|
||||||
{
|
{
|
||||||
if (argLevel == 1)
|
// Leading function name
|
||||||
{
|
funcName = word::validate(funcNameArgs.substr(0, argsBeg));
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == ')')
|
const auto argsEnd = funcNameArgs.rfind(')');
|
||||||
{
|
|
||||||
if (argLevel == 1)
|
stringOps::splitFunctionArgs
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
--argLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (c == '=')
|
|
||||||
{
|
|
||||||
argName = word::validate
|
|
||||||
(
|
(
|
||||||
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
|
// Search for the functionObject dictionary
|
||||||
fileName path = functionObjectList::findDict(funcName);
|
fileName path = functionObjectList::findDict(funcName);
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2019 OpenCFD Ltd.
|
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -145,16 +145,37 @@ Istream& operator>>(Istream& is, Scalar& val)
|
|||||||
return is;
|
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())
|
if (t.isNumber())
|
||||||
{
|
{
|
||||||
val = t.number();
|
val =
|
||||||
|
(
|
||||||
|
(prefix == token::MINUS)
|
||||||
|
? (0 - t.number())
|
||||||
|
: t.number()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(is)
|
FatalIOErrorInFunction(is)
|
||||||
<< "Wrong token type - expected scalar value, found "
|
<< "Wrong token type - expected scalar value, found ";
|
||||||
<< t.info()
|
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||||
<< exit(FatalIOError);
|
{
|
||||||
|
FatalIOError << '\'' << prefix << "' followed by ";
|
||||||
|
}
|
||||||
|
FatalIOError << t.info() << exit(FatalIOError);
|
||||||
is.setBad();
|
is.setBad();
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2014-2016 OpenFOAM Foundation
|
Copyright (C) 2014-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -100,13 +100,36 @@ Foam::Istream& Foam::operator>>(Istream& is, int32_t& val)
|
|||||||
return is;
|
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())
|
if (t.isLabel())
|
||||||
{
|
{
|
||||||
val = int32_t(t.labelToken());
|
val = int32_t
|
||||||
|
(
|
||||||
|
(prefix == token::MINUS)
|
||||||
|
? (0 - t.labelToken())
|
||||||
|
: t.labelToken()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (t.isScalar())
|
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));
|
const intmax_t parsed = intmax_t(std::round(sval));
|
||||||
val = 0 + int32_t(parsed);
|
val = 0 + int32_t(parsed);
|
||||||
|
|
||||||
@ -135,9 +158,12 @@ Foam::Istream& Foam::operator>>(Istream& is, int32_t& val)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(is)
|
FatalIOErrorInFunction(is)
|
||||||
<< "Wrong token type - expected label (int32), found "
|
<< "Wrong token type - expected label (int32), found ";
|
||||||
<< t.info()
|
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||||
<< exit(FatalIOError);
|
{
|
||||||
|
FatalIOError << '\'' << prefix << "' followed by ";
|
||||||
|
}
|
||||||
|
FatalIOError << t.info() << exit(FatalIOError);
|
||||||
is.setBad();
|
is.setBad();
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2014-2016 OpenFOAM Foundation
|
Copyright (C) 2014-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -100,13 +100,37 @@ Foam::Istream& Foam::operator>>(Istream& is, int64_t& val)
|
|||||||
return is;
|
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())
|
if (t.isLabel())
|
||||||
{
|
{
|
||||||
val = int64_t(t.labelToken());
|
val = int64_t
|
||||||
|
(
|
||||||
|
(prefix == token::MINUS)
|
||||||
|
? (0 - t.labelToken())
|
||||||
|
: t.labelToken()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (t.isScalar())
|
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));
|
const intmax_t parsed = intmax_t(std::round(sval));
|
||||||
val = 0 + int64_t(parsed);
|
val = 0 + int64_t(parsed);
|
||||||
|
|
||||||
@ -135,9 +159,12 @@ Foam::Istream& Foam::operator>>(Istream& is, int64_t& val)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(is)
|
FatalIOErrorInFunction(is)
|
||||||
<< "Wrong token type - expected label (int64), found "
|
<< "Wrong token type - expected label (int64), found ";
|
||||||
<< t.info()
|
if (prefix == token::PLUS || prefix == token::MINUS)
|
||||||
<< exit(FatalIOError);
|
{
|
||||||
|
FatalIOError << '\'' << prefix << "' followed by ";
|
||||||
|
}
|
||||||
|
FatalIOError << t.info() << exit(FatalIOError);
|
||||||
is.setBad();
|
is.setBad();
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -693,7 +693,7 @@ static void expandString
|
|||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
std::string::size_type Foam::stringOps::count
|
std::string::size_type Foam::stringOps::count
|
||||||
(
|
(
|
||||||
|
|||||||
@ -57,6 +57,7 @@ namespace Foam
|
|||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
class OSstream;
|
class OSstream;
|
||||||
|
template<class T1, class T2> class Tuple2;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Namespace stringOps Declaration
|
Namespace stringOps Declaration
|
||||||
@ -282,6 +283,14 @@ namespace stringOps
|
|||||||
// Return true if a replacement was successful.
|
// Return true if a replacement was successful.
|
||||||
bool inplaceReplaceVar(std::string& s, const word& varName);
|
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.
|
//- Find (first, last) non-space locations in string or sub-string.
|
||||||
// This may change to std::string_view in the future.
|
// 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
|
//- Inplace transform string with std::toupper on each character
|
||||||
void inplaceUpper(std::string& s);
|
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.
|
//- Split string into sub-strings at the delimiter character.
|
||||||
// Empty sub-strings are normally suppressed.
|
// 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>
|
template<class StringType>
|
||||||
Foam::SubStrings<StringType> Foam::stringOps::split
|
Foam::SubStrings<StringType> Foam::stringOps::split
|
||||||
(
|
(
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2012-2016 OpenFOAM Foundation
|
Copyright (C) 2012-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2020 OpenCFD Ltd.
|
Copyright (C) 2020-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -120,8 +120,8 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Output with surrounding quotes and backslash escaping
|
||||||
OFstream::write(static_cast<char>(token::BEGIN_STRING));
|
OFstream::write(static_cast<char>(token::DQUOTE));
|
||||||
|
|
||||||
unsigned backslash = 0;
|
unsigned backslash = 0;
|
||||||
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
|
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
|
||||||
@ -138,7 +138,7 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
|
|||||||
++lineNumber_;
|
++lineNumber_;
|
||||||
++backslash; // backslash escape for newline
|
++backslash; // backslash escape for newline
|
||||||
}
|
}
|
||||||
else if (c == token::END_STRING)
|
else if (c == token::DQUOTE)
|
||||||
{
|
{
|
||||||
++backslash; // backslash escape for quote
|
++backslash; // backslash escape for quote
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
|
|||||||
|
|
||||||
// silently drop any trailing backslashes
|
// silently drop any trailing backslashes
|
||||||
// they would otherwise appear like an escaped end-quote
|
// 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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,9 +16,27 @@ FoamFile
|
|||||||
|
|
||||||
scale 1;
|
scale 1;
|
||||||
|
|
||||||
// Front/back locations
|
// Geometric parameters
|
||||||
zmin -0.5;
|
rInner 0.5;
|
||||||
zmax 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
|
vertices #codeStream
|
||||||
{
|
{
|
||||||
@ -29,30 +47,27 @@ vertices #codeStream
|
|||||||
|
|
||||||
code
|
code
|
||||||
#{
|
#{
|
||||||
// sin(45), cos(45)
|
|
||||||
const scalar sqrt05 = sqrt(0.5);
|
|
||||||
|
|
||||||
pointField points
|
pointField points
|
||||||
({
|
({
|
||||||
/* 0*/ {0.5, 0, $zmin},
|
/* 0*/ { $rInner, 0, $zmin },
|
||||||
/* 1*/ {1, 0, $zmin},
|
/* 1*/ { $rOuter, 0, $zmin },
|
||||||
/* 2*/ {2, 0, $zmin},
|
/* 2*/ { $xmax, 0, $zmin },
|
||||||
/* 3*/ {2, sqrt05, $zmin},
|
/* 3*/ { $xmax, $rOuter45, $zmin },
|
||||||
/* 4*/ {sqrt05, sqrt05, $zmin},
|
/* 4*/ { $rOuter45, $rOuter45, $zmin },
|
||||||
/* 5*/ {sqrt05/2, sqrt05/2, $zmin},
|
/* 5*/ { $rInner45, $rInner45, $zmin },
|
||||||
/* 6*/ {2, 2, $zmin},
|
/* 6*/ { $xmax, $ymax, $zmin },
|
||||||
/* 7*/ {sqrt05, 2, $zmin},
|
/* 7*/ { $rOuter45, $ymax, $zmin },
|
||||||
/* 8*/ {0, 2, $zmin},
|
/* 8*/ { 0, $ymax, $zmin },
|
||||||
/* 9*/ {0, 1, $zmin},
|
/* 9*/ { 0, $rOuter, $zmin },
|
||||||
/*10*/ {0, 0.5, $zmin},
|
/*10*/ { 0, $rInner, $zmin },
|
||||||
/*11*/ {-0.5, 0, $zmin},
|
/*11*/ { -$rInner, 0, $zmin },
|
||||||
/*12*/ {-1, 0, $zmin},
|
/*12*/ { -$rOuter, 0, $zmin },
|
||||||
/*13*/ {-2, 0, $zmin},
|
/*13*/ { -$xmax, 0, $zmin },
|
||||||
/*14*/ {-2, sqrt05, $zmin},
|
/*14*/ { -$xmax, $rOuter45, $zmin },
|
||||||
/*15*/ {-sqrt05, sqrt05, $zmin},
|
/*15*/ { -$rOuter45, $rOuter45, $zmin },
|
||||||
/*16*/ {-sqrt05/2, sqrt05/2, $zmin},
|
/*16*/ { -$rInner45, $rInner45, $zmin },
|
||||||
/*17*/ {-2, 2, $zmin},
|
/*17*/ { -$xmax, $ymax, $zmin },
|
||||||
/*18*/ {-sqrt05, 2, $zmin}
|
/*18*/ { -$rOuter45, $ymax, $zmin }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Duplicate z points for zmax
|
// Duplicate z points for zmax
|
||||||
@ -68,19 +83,21 @@ vertices #codeStream
|
|||||||
#};
|
#};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Can remove unneeded variables
|
||||||
|
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
(
|
(
|
||||||
hex (5 4 9 10 24 23 28 29) (10 10 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) (10 10 1) simpleGrading (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) (20 10 1) simpleGrading (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) (20 20 1) simpleGrading (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) (10 20 1) simpleGrading (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) (10 10 1) simpleGrading (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) (10 10 1) simpleGrading (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) (20 10 1) simpleGrading (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) (20 20 1) simpleGrading (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) (10 20 1) simpleGrading (1 1 1)
|
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
edges
|
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
|
#endif
|
||||||
|
|
||||||
zmin #eval{ -$zmax };
|
zmin #eval{ -$zmax };
|
||||||
mrad0 #eval{ -$rad0 };
|
|
||||||
mrad1 #eval{ -$rad1 };
|
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
// back-plane:
|
// back-plane:
|
||||||
// inlet region
|
// inlet region
|
||||||
( $xin $rad0 $zmin) // pt 0
|
( $xin $rad0 $zmin) // pt 0
|
||||||
( 0 $rad0 $zmin) // pt 1
|
( 0 $rad0 $zmin) // pt 1
|
||||||
( 0 $rad1 $zmin) // pt 2
|
( 0 $rad1 $zmin) // pt 2
|
||||||
( $xin $rad1 $zmin) // pt 3
|
( $xin $rad1 $zmin) // pt 3
|
||||||
// outlet region
|
// outlet region
|
||||||
( $xout $mrad1 $zmin) // pt 4
|
( $xout -$rad1 $zmin) // pt 4
|
||||||
( 0 $mrad1 $zmin) // pt 5
|
( 0 -$rad1 $zmin) // pt 5
|
||||||
( 0 $mrad0 $zmin) // pt 6
|
( 0 -$rad0 $zmin) // pt 6
|
||||||
( $xout $mrad0 $zmin) // pt 7
|
( $xout -$rad0 $zmin) // pt 7
|
||||||
// bend mid-points
|
// bend mid-points
|
||||||
( $rad0 0 $zmin) // pt 8
|
( $rad0 0 $zmin) // pt 8
|
||||||
( $rad1 0 $zmin) // pt 9
|
( $rad1 0 $zmin) // pt 9
|
||||||
@ -66,13 +64,13 @@ vertices
|
|||||||
( 0 $rad1 $zmax) // pt 2 + 10
|
( 0 $rad1 $zmax) // pt 2 + 10
|
||||||
( $xin $rad1 $zmax) // pt 3 + 10
|
( $xin $rad1 $zmax) // pt 3 + 10
|
||||||
// outlet region
|
// outlet region
|
||||||
( $xout $mrad1 $zmax) // pt 4 + 10
|
( $xout -$rad1 $zmax) // pt 4 + 10
|
||||||
( 0 $mrad1 $zmax) // pt 5 + 10
|
( 0 -$rad1 $zmax) // pt 5 + 10
|
||||||
( 0 $mrad0 $zmax) // pt 6 + 10
|
( 0 -$rad0 $zmax) // pt 6 + 10
|
||||||
( $xout $mrad0 $zmax) // pt 7 + 10
|
( $xout -$rad0 $zmax) // pt 7 + 10
|
||||||
// bend mid-points
|
// bend mid-points
|
||||||
( $rad0 0 $zmax) // pt 8 + 10
|
( $rad0 0 $zmax) // pt 8 + 10
|
||||||
( $rad1 0 $zmax) // pt 9 + 10
|
( $rad1 0 $zmax) // pt 9 + 10
|
||||||
);
|
);
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
|
|||||||
@ -40,22 +40,20 @@ nz #eval{ round($nz / 5) };
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
zmin #eval{ -$zmax };
|
zmin #eval{ -$zmax };
|
||||||
mrad0 #eval{ -$rad0 };
|
|
||||||
mrad1 #eval{ -$rad1 };
|
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
// back-plane:
|
// back-plane:
|
||||||
// inlet region
|
// inlet region
|
||||||
( $xin $rad0 $zmin) // pt 0
|
( $xin $rad0 $zmin) // pt 0
|
||||||
( 0 $rad0 $zmin) // pt 1
|
( 0 $rad0 $zmin) // pt 1
|
||||||
( 0 $rad1 $zmin) // pt 2
|
( 0 $rad1 $zmin) // pt 2
|
||||||
( $xin $rad1 $zmin) // pt 3
|
( $xin $rad1 $zmin) // pt 3
|
||||||
// outlet region
|
// outlet region
|
||||||
( $xout $mrad1 $zmin) // pt 4
|
( $xout -$rad1 $zmin) // pt 4
|
||||||
( 0 $mrad1 $zmin) // pt 5
|
( 0 -$rad1 $zmin) // pt 5
|
||||||
( 0 $mrad0 $zmin) // pt 6
|
( 0 -$rad0 $zmin) // pt 6
|
||||||
( $xout $mrad0 $zmin) // pt 7
|
( $xout -$rad0 $zmin) // pt 7
|
||||||
// bend mid-points
|
// bend mid-points
|
||||||
( $rad0 0 $zmin) // pt 8
|
( $rad0 0 $zmin) // pt 8
|
||||||
( $rad1 0 $zmin) // pt 9
|
( $rad1 0 $zmin) // pt 9
|
||||||
@ -66,13 +64,13 @@ vertices
|
|||||||
( 0 $rad1 $zmax) // pt 2 + 10
|
( 0 $rad1 $zmax) // pt 2 + 10
|
||||||
( $xin $rad1 $zmax) // pt 3 + 10
|
( $xin $rad1 $zmax) // pt 3 + 10
|
||||||
// outlet region
|
// outlet region
|
||||||
( $xout $mrad1 $zmax) // pt 4 + 10
|
( $xout -$rad1 $zmax) // pt 4 + 10
|
||||||
( 0 $mrad1 $zmax) // pt 5 + 10
|
( 0 -$rad1 $zmax) // pt 5 + 10
|
||||||
( 0 $mrad0 $zmax) // pt 6 + 10
|
( 0 -$rad0 $zmax) // pt 6 + 10
|
||||||
( $xout $mrad0 $zmax) // pt 7 + 10
|
( $xout -$rad0 $zmax) // pt 7 + 10
|
||||||
// bend mid-points
|
// bend mid-points
|
||||||
( $rad0 0 $zmax) // pt 8 + 10
|
( $rad0 0 $zmax) // pt 8 + 10
|
||||||
( $rad1 0 $zmax) // pt 9 + 10
|
( $rad1 0 $zmax) // pt 9 + 10
|
||||||
);
|
);
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
|
|||||||
@ -40,8 +40,6 @@ nz #eval{ round($nz / 5) };
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
zmin #eval{ -$zmax };
|
zmin #eval{ -$zmax };
|
||||||
mrad0 #eval{ -$rad0 };
|
|
||||||
mrad1 #eval{ -$rad1 };
|
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
@ -52,13 +50,13 @@ vertices
|
|||||||
( 0 $rad1 $zmin) // pt 2
|
( 0 $rad1 $zmin) // pt 2
|
||||||
( $xin $rad1 $zmin) // pt 3
|
( $xin $rad1 $zmin) // pt 3
|
||||||
// outlet region
|
// outlet region
|
||||||
( $xout $mrad1 $zmin) // pt 4
|
( $xout -$rad1 $zmin) // pt 4
|
||||||
( 0 $mrad1 $zmin) // pt 5
|
( 0 -$rad1 $zmin) // pt 5
|
||||||
( 0 $mrad0 $zmin) // pt 6
|
( 0 -$rad0 $zmin) // pt 6
|
||||||
( $xout $mrad0 $zmin) // pt 7
|
( $xout -$rad0 $zmin) // pt 7
|
||||||
// bend mid-points
|
// bend mid-points
|
||||||
( $rad0 0 $zmin) // pt 8
|
( $rad0 0 $zmin) // pt 8
|
||||||
( $rad1 0 $zmin) // pt 9
|
( $rad1 0 $zmin) // pt 9
|
||||||
// front-plane:
|
// front-plane:
|
||||||
// inlet region
|
// inlet region
|
||||||
( $xin $rad0 $zmax) // pt 0 + 10
|
( $xin $rad0 $zmax) // pt 0 + 10
|
||||||
@ -66,10 +64,10 @@ vertices
|
|||||||
( 0 $rad1 $zmax) // pt 2 + 10
|
( 0 $rad1 $zmax) // pt 2 + 10
|
||||||
( $xin $rad1 $zmax) // pt 3 + 10
|
( $xin $rad1 $zmax) // pt 3 + 10
|
||||||
// outlet region
|
// outlet region
|
||||||
( $xout $mrad1 $zmax) // pt 4 + 10
|
( $xout -$rad1 $zmax) // pt 4 + 10
|
||||||
( 0 $mrad1 $zmax) // pt 5 + 10
|
( 0 -$rad1 $zmax) // pt 5 + 10
|
||||||
( 0 $mrad0 $zmax) // pt 6 + 10
|
( 0 -$rad0 $zmax) // pt 6 + 10
|
||||||
( $xout $mrad0 $zmax) // pt 7 + 10
|
( $xout -$rad0 $zmax) // pt 7 + 10
|
||||||
// bend mid-points
|
// bend mid-points
|
||||||
( $rad0 0 $zmax) // pt 8 + 10
|
( $rad0 0 $zmax) // pt 8 + 10
|
||||||
( $rad1 0 $zmax) // pt 9 + 10
|
( $rad1 0 $zmax) // pt 9 + 10
|
||||||
|
|||||||
@ -18,66 +18,91 @@ FoamFile
|
|||||||
|
|
||||||
scale 0.016;
|
scale 0.016;
|
||||||
|
|
||||||
// Front/back locations
|
// Geometric parameters
|
||||||
zmin 0;
|
rInner 0.5;
|
||||||
zmax 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
|
vertices
|
||||||
(
|
(
|
||||||
(0.5 0 $zmin)
|
/* 0*/ ( $rInner 0 $zmin )
|
||||||
(1 0 $zmin)
|
/* 1*/ ( $rOuter 0 $zmin )
|
||||||
(2 0 $zmin)
|
/* 2*/ ( $xmax 0 $zmin )
|
||||||
(2 0.707107 $zmin)
|
/* 3*/ ( $xmax $rOuter45 $zmin )
|
||||||
(0.707107 0.707107 $zmin)
|
/* 4*/ ( $rOuter45 $rOuter45 $zmin )
|
||||||
(0.353553 0.353553 $zmin)
|
/* 5*/ ( $rInner45 $rInner45 $zmin )
|
||||||
(2 2 $zmin)
|
/* 6*/ ( $xmax $ymax $zmin )
|
||||||
(0.707107 2 $zmin)
|
/* 7*/ ( $rOuter45 $ymax $zmin )
|
||||||
(0 2 $zmin)
|
/* 8*/ ( 0 $ymax $zmin )
|
||||||
(0 1 $zmin)
|
/* 9*/ ( 0 $rOuter $zmin )
|
||||||
(0 0.5 $zmin)
|
/*10*/ ( 0 $rInner $zmin )
|
||||||
(-0.5 0 $zmin)
|
/*11*/ ( -$rInner 0 $zmin )
|
||||||
(-1 0 $zmin)
|
/*12*/ ( -$rOuter 0 $zmin )
|
||||||
(-2 0 $zmin)
|
/*13*/ ( -$xmax 0 $zmin )
|
||||||
(-2 0.707107 $zmin)
|
/*14*/ ( -$xmax $rOuter45 $zmin )
|
||||||
(-0.707107 0.707107 $zmin)
|
/*15*/ ( -$rOuter45 $rOuter45 $zmin )
|
||||||
(-0.353553 0.353553 $zmin)
|
/*16*/ ( -$rInner45 $rInner45 $zmin )
|
||||||
(-2 2 $zmin)
|
/*17*/ ( -$xmax $ymax $zmin )
|
||||||
(-0.707107 2 $zmin)
|
/*18*/ ( -$rOuter45 $ymax $zmin )
|
||||||
(0.5 0 $zmax)
|
|
||||||
(1 0 $zmax)
|
/*19*/ ( $rInner 0 $zmax )
|
||||||
(2 0 $zmax)
|
/*20*/ ( $rOuter 0 $zmax )
|
||||||
(2 0.707107 $zmax)
|
/*21*/ ( $xmax 0 $zmax )
|
||||||
(0.707107 0.707107 $zmax)
|
/*22*/ ( $xmax $rOuter45 $zmax )
|
||||||
(0.353553 0.353553 $zmax)
|
/*23*/ ( $rOuter45 $rOuter45 $zmax )
|
||||||
(2 2 $zmax)
|
/*24*/ ( $rInner45 $rInner45 $zmax )
|
||||||
(0.707107 2 $zmax)
|
/*25*/ ( $xmax $ymax $zmax )
|
||||||
(0 2 $zmax)
|
/*26*/ ( $rOuter45 $ymax $zmax )
|
||||||
(0 1 $zmax)
|
/*27*/ ( 0 $ymax $zmax )
|
||||||
(0 0.5 $zmax)
|
/*28*/ ( 0 $rOuter $zmax )
|
||||||
(-0.5 0 $zmax)
|
/*29*/ ( 0 $rInner $zmax )
|
||||||
(-1 0 $zmax)
|
/*30*/ ( -$rInner 0 $zmax )
|
||||||
(-2 0 $zmax)
|
/*31*/ ( -$rOuter 0 $zmax )
|
||||||
(-2 0.707107 $zmax)
|
/*32*/ ( -$xmax 0 $zmax )
|
||||||
(-0.707107 0.707107 $zmax)
|
/*33*/ ( -$xmax $rOuter45 $zmax )
|
||||||
(-0.353553 0.353553 $zmax)
|
/*34*/ ( -$rOuter45 $rOuter45 $zmax )
|
||||||
(-2 2 $zmax)
|
/*35*/ ( -$rInner45 $rInner45 $zmax )
|
||||||
(-0.707107 2 $zmax)
|
/*36*/ ( -$xmax $ymax $zmax )
|
||||||
|
/*37*/ ( -$rOuter45 $ymax $zmax )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Can remove some unneeded variables
|
||||||
|
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
|
||||||
|
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
(
|
(
|
||||||
hex (5 4 9 10 24 23 28 29) (10 10 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) (10 10 1) simpleGrading (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) (20 10 1) simpleGrading (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) (20 20 1) simpleGrading (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) (10 20 1) simpleGrading (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) (10 10 1) simpleGrading (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) (10 10 1) simpleGrading (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) (20 10 1) simpleGrading (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) (20 20 1) simpleGrading (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) (10 20 1) simpleGrading (1 1 1)
|
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
edges
|
edges
|
||||||
(
|
(
|
||||||
// Inner cylinder
|
// 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
|
actions
|
||||||
(
|
(
|
||||||
// Heater
|
heater
|
||||||
{
|
{
|
||||||
name heaterCellSet;
|
name heaterCellSet;
|
||||||
type cellSet;
|
type cellSet;
|
||||||
action new;
|
action new;
|
||||||
source boxToCell;
|
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;
|
type cellZoneSet;
|
||||||
action new;
|
action new;
|
||||||
source setToCellZone;
|
source setToCellZone;
|
||||||
sourceInfo
|
set heaterCellSet;
|
||||||
{
|
|
||||||
set heaterCellSet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -45,10 +39,7 @@ actions
|
|||||||
type cellSet;
|
type cellSet;
|
||||||
action new;
|
action new;
|
||||||
source cellToCell;
|
source cellToCell;
|
||||||
sourceInfo
|
set heaterCellSet;
|
||||||
{
|
|
||||||
set heaterCellSet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -62,10 +53,7 @@ actions
|
|||||||
type cellZoneSet;
|
type cellZoneSet;
|
||||||
action new;
|
action new;
|
||||||
source setToCellZone;
|
source setToCellZone;
|
||||||
sourceInfo
|
set bottomWaterCellSet;
|
||||||
{
|
|
||||||
set bottomWaterCellSet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ timePrecision 6;
|
|||||||
runTimeModifiable true;
|
runTimeModifiable true;
|
||||||
|
|
||||||
// Allow 10% run-up before calculating mean
|
// Allow 10% run-up before calculating mean
|
||||||
timeStart #eval #{ 0.1 * ${/endTime} #};
|
timeStart #eval{ 0.1 * ${/endTime} };
|
||||||
|
|
||||||
|
|
||||||
functions
|
functions
|
||||||
|
|||||||
@ -40,22 +40,20 @@ nz #eval{ round($nz / 5) };
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
zmin #eval{ -$zmax };
|
zmin #eval{ -$zmax };
|
||||||
mrad0 #eval{ -$rad0 };
|
|
||||||
mrad1 #eval{ -$rad1 };
|
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
// back-plane:
|
// back-plane:
|
||||||
// inlet region
|
// inlet region
|
||||||
( $xin $rad0 $zmin) // pt 0
|
( $xin $rad0 $zmin) // pt 0
|
||||||
( 0 $rad0 $zmin) // pt 1
|
( 0 $rad0 $zmin) // pt 1
|
||||||
( 0 $rad1 $zmin) // pt 2
|
( 0 $rad1 $zmin) // pt 2
|
||||||
( $xin $rad1 $zmin) // pt 3
|
( $xin $rad1 $zmin) // pt 3
|
||||||
// outlet region
|
// outlet region
|
||||||
( $xout $mrad1 $zmin) // pt 4
|
( $xout -$rad1 $zmin) // pt 4
|
||||||
( 0 $mrad1 $zmin) // pt 5
|
( 0 -$rad1 $zmin) // pt 5
|
||||||
( 0 $mrad0 $zmin) // pt 6
|
( 0 -$rad0 $zmin) // pt 6
|
||||||
( $xout $mrad0 $zmin) // pt 7
|
( $xout -$rad0 $zmin) // pt 7
|
||||||
// bend mid-points
|
// bend mid-points
|
||||||
( $rad0 0 $zmin) // pt 8
|
( $rad0 0 $zmin) // pt 8
|
||||||
( $rad1 0 $zmin) // pt 9
|
( $rad1 0 $zmin) // pt 9
|
||||||
@ -66,13 +64,13 @@ vertices
|
|||||||
( 0 $rad1 $zmax) // pt 2 + 10
|
( 0 $rad1 $zmax) // pt 2 + 10
|
||||||
( $xin $rad1 $zmax) // pt 3 + 10
|
( $xin $rad1 $zmax) // pt 3 + 10
|
||||||
// outlet region
|
// outlet region
|
||||||
( $xout $mrad1 $zmax) // pt 4 + 10
|
( $xout -$rad1 $zmax) // pt 4 + 10
|
||||||
( 0 $mrad1 $zmax) // pt 5 + 10
|
( 0 -$rad1 $zmax) // pt 5 + 10
|
||||||
( 0 $mrad0 $zmax) // pt 6 + 10
|
( 0 -$rad0 $zmax) // pt 6 + 10
|
||||||
( $xout $mrad0 $zmax) // pt 7 + 10
|
( $xout -$rad0 $zmax) // pt 7 + 10
|
||||||
// bend mid-points
|
// bend mid-points
|
||||||
( $rad0 0 $zmax) // pt 8 + 10
|
( $rad0 0 $zmax) // pt 8 + 10
|
||||||
( $rad1 0 $zmax) // pt 9 + 10
|
( $rad1 0 $zmax) // pt 9 + 10
|
||||||
);
|
);
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
|
|||||||
@ -18,64 +18,87 @@ FoamFile
|
|||||||
|
|
||||||
scale 1;
|
scale 1;
|
||||||
|
|
||||||
// Front/back locations
|
// Geometric parameters
|
||||||
zmin -0.5;
|
rInner 0.5;
|
||||||
zmax 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
|
vertices
|
||||||
(
|
(
|
||||||
(0.5 0 $zmin)
|
/* 0*/ ( $rInner 0 $zmin )
|
||||||
(1 0 $zmin)
|
/* 1*/ ( $rOuter 0 $zmin )
|
||||||
(2 0 $zmin)
|
/* 2*/ ( $xmax 0 $zmin )
|
||||||
(2 0.707107 $zmin)
|
/* 3*/ ( $xmax $rOuter45 $zmin )
|
||||||
(0.707107 0.707107 $zmin)
|
/* 4*/ ( $rOuter45 $rOuter45 $zmin )
|
||||||
(0.353553 0.353553 $zmin)
|
/* 5*/ ( $rInner45 $rInner45 $zmin )
|
||||||
(2 2 $zmin)
|
/* 6*/ ( $xmax $ymax $zmin )
|
||||||
(0.707107 2 $zmin)
|
/* 7*/ ( $rOuter45 $ymax $zmin )
|
||||||
(0 2 $zmin)
|
/* 8*/ ( 0 $ymax $zmin )
|
||||||
(0 1 $zmin)
|
/* 9*/ ( 0 $rOuter $zmin )
|
||||||
(0 0.5 $zmin)
|
/*10*/ ( 0 $rInner $zmin )
|
||||||
(-0.5 0 $zmin)
|
/*11*/ ( -$rInner 0 $zmin )
|
||||||
(-1 0 $zmin)
|
/*12*/ ( -$rOuter 0 $zmin )
|
||||||
(-2 0 $zmin)
|
/*13*/ ( -$xmax 0 $zmin )
|
||||||
(-2 0.707107 $zmin)
|
/*14*/ ( -$xmax $rOuter45 $zmin )
|
||||||
(-0.707107 0.707107 $zmin)
|
/*15*/ ( -$rOuter45 $rOuter45 $zmin )
|
||||||
(-0.353553 0.353553 $zmin)
|
/*16*/ ( -$rInner45 $rInner45 $zmin )
|
||||||
(-2 2 $zmin)
|
/*17*/ ( -$xmax $ymax $zmin )
|
||||||
(-0.707107 2 $zmin)
|
/*18*/ ( -$rOuter45 $ymax $zmin )
|
||||||
(0.5 0 $zmax)
|
|
||||||
(1 0 $zmax)
|
/*19*/ ( $rInner 0 $zmax )
|
||||||
(2 0 $zmax)
|
/*20*/ ( $rOuter 0 $zmax )
|
||||||
(2 0.707107 $zmax)
|
/*21*/ ( $xmax 0 $zmax )
|
||||||
(0.707107 0.707107 $zmax)
|
/*22*/ ( $xmax $rOuter45 $zmax )
|
||||||
(0.353553 0.353553 $zmax)
|
/*23*/ ( $rOuter45 $rOuter45 $zmax )
|
||||||
(2 2 $zmax)
|
/*24*/ ( $rInner45 $rInner45 $zmax )
|
||||||
(0.707107 2 $zmax)
|
/*25*/ ( $xmax $ymax $zmax )
|
||||||
(0 2 $zmax)
|
/*26*/ ( $rOuter45 $ymax $zmax )
|
||||||
(0 1 $zmax)
|
/*27*/ ( 0 $ymax $zmax )
|
||||||
(0 0.5 $zmax)
|
/*28*/ ( 0 $rOuter $zmax )
|
||||||
(-0.5 0 $zmax)
|
/*29*/ ( 0 $rInner $zmax )
|
||||||
(-1 0 $zmax)
|
/*30*/ ( -$rInner 0 $zmax )
|
||||||
(-2 0 $zmax)
|
/*31*/ ( -$rOuter 0 $zmax )
|
||||||
(-2 0.707107 $zmax)
|
/*32*/ ( -$xmax 0 $zmax )
|
||||||
(-0.707107 0.707107 $zmax)
|
/*33*/ ( -$xmax $rOuter45 $zmax )
|
||||||
(-0.353553 0.353553 $zmax)
|
/*34*/ ( -$rOuter45 $rOuter45 $zmax )
|
||||||
(-2 2 $zmax)
|
/*35*/ ( -$rInner45 $rInner45 $zmax )
|
||||||
(-0.707107 2 $zmax)
|
/*36*/ ( -$xmax $ymax $zmax )
|
||||||
|
/*37*/ ( -$rOuter45 $ymax $zmax )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Can remove some unneeded variables
|
||||||
|
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
|
||||||
|
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
(
|
(
|
||||||
hex (5 4 9 10 24 23 28 29) (10 10 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) (10 10 11) simpleGrading (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) (20 10 11) simpleGrading (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) (20 20 11) simpleGrading (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) (10 20 11) simpleGrading (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) (10 10 11) simpleGrading (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) (10 10 11) simpleGrading (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) (20 10 11) simpleGrading (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) (20 20 11) simpleGrading (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) (10 20 11) simpleGrading (1 1 1)
|
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
edges
|
edges
|
||||||
|
|||||||
@ -34,20 +34,19 @@ geometry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Box sizes
|
// Box size
|
||||||
vo #eval{ sqrt($outerRadius/3) };
|
vo #eval{ sqrt($outerRadius/3) };
|
||||||
mvo #eval{ -$vo };
|
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
($mvo $mvo $mvo)
|
(-$vo -$vo -$vo)
|
||||||
( $vo $mvo $mvo)
|
( $vo -$vo -$vo)
|
||||||
( $vo $vo $mvo)
|
( $vo $vo -$vo)
|
||||||
($mvo $vo $mvo)
|
(-$vo $vo -$vo)
|
||||||
($mvo $mvo $vo)
|
(-$vo -$vo $vo)
|
||||||
( $vo $mvo $vo)
|
( $vo -$vo $vo)
|
||||||
( $vo $vo $vo)
|
( $vo $vo $vo)
|
||||||
($mvo $vo $vo)
|
(-$vo $vo $vo)
|
||||||
);
|
);
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
|
|||||||
@ -37,35 +37,33 @@ geometry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outer box sizes
|
// Outer box size
|
||||||
vo #eval{ sqrt($outerRadius/3) };
|
vo #eval{ sqrt($outerRadius/3) };
|
||||||
mvo #eval{ -$vo };
|
|
||||||
|
|
||||||
// Inner box sizes - % of overall dimension
|
// Inner box size - % of overall dimension
|
||||||
vi #eval{ $vo * $innerRatio };
|
vi #eval{ $vo * $innerRatio };
|
||||||
mvi #eval{ -$vi };
|
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
// Inner block
|
// Inner block
|
||||||
($mvi $mvi $mvi)
|
(-$vi -$vi -$vi)
|
||||||
( $vi $mvi $mvi)
|
( $vi -$vi -$vi)
|
||||||
( $vi $vi $mvi)
|
( $vi $vi -$vi)
|
||||||
($mvi $vi $mvi)
|
(-$vi $vi -$vi)
|
||||||
($mvi $mvi $vi)
|
(-$vi -$vi $vi)
|
||||||
( $vi $mvi $vi)
|
( $vi -$vi $vi)
|
||||||
( $vi $vi $vi)
|
( $vi $vi $vi)
|
||||||
($mvi $vi $vi)
|
(-$vi $vi $vi)
|
||||||
|
|
||||||
// Outer blocks
|
// Outer blocks
|
||||||
($mvo $mvo $mvo)
|
(-$vo -$vo -$vo)
|
||||||
( $vo $mvo $mvo)
|
( $vo -$vo -$vo)
|
||||||
( $vo $vo $mvo)
|
( $vo $vo -$vo)
|
||||||
($mvo $vo $mvo)
|
(-$vo $vo -$vo)
|
||||||
($mvo $mvo $vo)
|
(-$vo -$vo $vo)
|
||||||
( $vo $mvo $vo)
|
( $vo -$vo $vo)
|
||||||
( $vo $vo $vo)
|
( $vo $vo $vo)
|
||||||
($mvo $vo $vo)
|
(-$vo $vo $vo)
|
||||||
);
|
);
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
|
|||||||
@ -44,35 +44,33 @@ geometry
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Outer box sizes (approximate)
|
// Outer box size (approximate)
|
||||||
vo #eval{ sqrt($outerRadius/3) };
|
vo #eval{ sqrt($outerRadius/3) };
|
||||||
mvo #eval{ -$vo };
|
|
||||||
|
|
||||||
// Inner box sizes - % of overall dimension
|
// Inner box size - % of overall dimension
|
||||||
vi #eval{ $vo * $innerRatio };
|
vi #eval{ $vo * $innerRatio };
|
||||||
mvi #eval{ -$vi };
|
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
// Inner block points
|
// Inner block points
|
||||||
project ($mvi $mvi $mvi) (innerSphere)
|
project (-$vi -$vi -$vi) (innerSphere)
|
||||||
project ( $vi $mvi $mvi) (innerSphere)
|
project ( $vi -$vi -$vi) (innerSphere)
|
||||||
project ( $vi $vi $mvi) (innerSphere)
|
project ( $vi $vi -$vi) (innerSphere)
|
||||||
project ($mvi $vi $mvi) (innerSphere)
|
project (-$vi $vi -$vi) (innerSphere)
|
||||||
project ($mvi $mvi $vi) (innerSphere)
|
project (-$vi -$vi $vi) (innerSphere)
|
||||||
project ( $vi $mvi $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
|
// Outer block points
|
||||||
project ($mvo $mvo $mvo) (sphere)
|
project (-$vo -$vo -$vo) (sphere)
|
||||||
project ( $vo $mvo $mvo) (sphere)
|
project ( $vo -$vo -$vo) (sphere)
|
||||||
project ( $vo $vo $mvo) (sphere)
|
project ( $vo $vo -$vo) (sphere)
|
||||||
project ($mvo $vo $mvo) (sphere)
|
project (-$vo $vo -$vo) (sphere)
|
||||||
project ($mvo $mvo $vo) (sphere)
|
project (-$vo -$vo $vo) (sphere)
|
||||||
project ( $vo $mvo $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
|
blocks
|
||||||
|
|||||||
@ -44,47 +44,42 @@ geometry
|
|||||||
innerSphere
|
innerSphere
|
||||||
{
|
{
|
||||||
$sphere
|
$sphere
|
||||||
radius
|
radius #eval{ $innerRatio*$[(vector) ../sphere/radius] };
|
||||||
(
|
|
||||||
#eval{ $rxo * $innerRatio }
|
|
||||||
#eval{ $ryo * $innerRatio }
|
|
||||||
#eval{ $rzo * $innerRatio }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Outer box sizes (approximate)
|
// Outer box sizes (approximate)
|
||||||
vxo #eval{ sqrt(1.0/3.0) * $rxo }; mvxo #eval{ -$vxo };
|
vxo #eval{ sqrt(1.0/3.0) * $rxo };
|
||||||
vyo #eval{ sqrt(1.0/3.0) * $ryo }; mvyo #eval{ -$vyo };
|
vyo #eval{ sqrt(1.0/3.0) * $ryo };
|
||||||
vzo #eval{ sqrt(1.0/3.0) * $rzo }; mvzo #eval{ -$vzo };
|
vzo #eval{ sqrt(1.0/3.0) * $rzo };
|
||||||
|
|
||||||
// Inner box sizes - % of overall dimension
|
// Inner box sizes - % of overall dimension
|
||||||
vxi #eval{ $vxo * $innerRatio }; mvxi #eval{ -$vxi };
|
vxi #eval{ $vxo * $innerRatio };
|
||||||
vyi #eval{ $vyo * $innerRatio }; mvyi #eval{ -$vyi };
|
vyi #eval{ $vyo * $innerRatio };
|
||||||
vzi #eval{ $vzo * $innerRatio }; mvzi #eval{ -$vzi };
|
vzi #eval{ $vzo * $innerRatio };
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
// Inner block points
|
// Inner block points
|
||||||
project ($mvxi $mvyi $mvzi) (innerSphere)
|
project (-$vxi -$vyi -$vzi) (innerSphere)
|
||||||
project ( $vxi $mvyi $mvzi) (innerSphere)
|
project ( $vxi -$vyi -$vzi) (innerSphere)
|
||||||
project ( $vxi $vyi $mvzi) (innerSphere)
|
project ( $vxi $vyi -$vzi) (innerSphere)
|
||||||
project ($mvxi $vyi $mvzi) (innerSphere)
|
project (-$vxi $vyi -$vzi) (innerSphere)
|
||||||
project ($mvxi $mvyi $vzi) (innerSphere)
|
project (-$vxi -$vyi $vzi) (innerSphere)
|
||||||
project ( $vxi $mvyi $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
|
// Outer block points
|
||||||
project ($mvxo $mvyo $mvzo) (sphere)
|
project (-$vxo -$vyo -$vzo) (sphere)
|
||||||
project ( $vxo $mvyo $mvzo) (sphere)
|
project ( $vxo -$vyo -$vzo) (sphere)
|
||||||
project ( $vxo $vyo $mvzo) (sphere)
|
project ( $vxo $vyo -$vzo) (sphere)
|
||||||
project ($mvxo $vyo $mvzo) (sphere)
|
project (-$vxo $vyo -$vzo) (sphere)
|
||||||
project ($mvxo $mvyo $vzo) (sphere)
|
project (-$vxo -$vyo $vzo) (sphere)
|
||||||
project ( $vxo $mvyo $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
|
blocks
|
||||||
|
|||||||
@ -37,21 +37,21 @@ geometry
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Box sizes
|
// Box sizes
|
||||||
vxo #eval{sqrt(1.0/3.0) * $rxo}; mvxo #eval{-$vxo};
|
vxo ${{sqrt(1.0/3.0) * $rxo}};
|
||||||
vyo #eval{sqrt(1.0/3.0) * $ryo}; mvyo #eval{-$vyo};
|
vyo ${{sqrt(1.0/3.0) * $ryo}};
|
||||||
vzo #eval{sqrt(1.0/3.0) * $rzo}; mvzo #eval{-$vzo};
|
vzo ${{sqrt(1.0/3.0) * $rzo}};
|
||||||
|
|
||||||
vertices
|
vertices
|
||||||
(
|
(
|
||||||
// Outer block points
|
// Outer block points
|
||||||
project ($mvxo $mvyo $mvzo) (sphere)
|
project (-$vxo -$vyo -$vzo) (sphere)
|
||||||
project ( $vxo $mvyo $mvzo) (sphere)
|
project ( $vxo -$vyo -$vzo) (sphere)
|
||||||
project ( $vxo $vyo $mvzo) (sphere)
|
project ( $vxo $vyo -$vzo) (sphere)
|
||||||
project ($mvxo $vyo $mvzo) (sphere)
|
project (-$vxo $vyo -$vzo) (sphere)
|
||||||
project ($mvxo $mvyo $vzo) (sphere)
|
project (-$vxo -$vyo $vzo) (sphere)
|
||||||
project ( $vxo $mvyo $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
|
blocks
|
||||||
|
|||||||
@ -25,7 +25,7 @@ boundaryField
|
|||||||
type rotatingWallVelocity;
|
type rotatingWallVelocity;
|
||||||
axis (0 1 0);
|
axis (0 1 0);
|
||||||
origin (0 0 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);
|
value uniform (0 0 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ boundaryField
|
|||||||
type rotatingWallVelocity;
|
type rotatingWallVelocity;
|
||||||
axis (0 1 0);
|
axis (0 1 0);
|
||||||
origin (0 0 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);
|
value uniform (0 0 0);
|
||||||
}
|
}
|
||||||
vessel
|
vessel
|
||||||
|
|||||||
@ -42,7 +42,7 @@ solvers
|
|||||||
|
|
||||||
centreOfMass (0.5 0.5 0.4);
|
centreOfMass (0.5 0.5 0.4);
|
||||||
cOfGdisplacement CofG;
|
cOfGdisplacement CofG;
|
||||||
|
|
||||||
// Cuboid dimensions
|
// Cuboid dimensions
|
||||||
Lx 0.24;
|
Lx 0.24;
|
||||||
Ly 0.24;
|
Ly 0.24;
|
||||||
|
|||||||
@ -16,29 +16,25 @@ FoamFile
|
|||||||
|
|
||||||
actions
|
actions
|
||||||
(
|
(
|
||||||
|
pickCells
|
||||||
{
|
{
|
||||||
name zone;
|
name zone;
|
||||||
type cellSet;
|
type cellSet;
|
||||||
action new;
|
action new;
|
||||||
source boxToCell;
|
source boxToCell;
|
||||||
sourceInfo
|
boxes
|
||||||
{
|
(
|
||||||
boxes
|
(0 0.4 0) (0.15 0.5 0.1)
|
||||||
(
|
);
|
||||||
(0 0.4 0) (0.15 0.5 0.1)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
convertToZone
|
||||||
{
|
{
|
||||||
name zone;
|
name zone;
|
||||||
type cellZoneSet;
|
type cellZoneSet;
|
||||||
action new;
|
action new;
|
||||||
source setToCellZone;
|
source setToCellZone;
|
||||||
sourceInfo
|
set zone;
|
||||||
{
|
|
||||||
set zone;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@ adjustTimeStep false;
|
|||||||
|
|
||||||
|
|
||||||
// Allow 10% of time for initialisation before sampling
|
// Allow 10% of time for initialisation before sampling
|
||||||
timeStart #eval #{ 0.1 * ${/endTime} #};
|
timeStart #eval{ 0.1 * ${/endTime} };
|
||||||
|
|
||||||
functions
|
functions
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user