diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index bfc20daac9..5df2747f41 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -219,6 +219,8 @@ $(functionEntries)/includeFuncEntry/includeFuncEntry.C
$(functionEntries)/includeIfPresentEntry/includeIfPresentEntry.C
$(functionEntries)/inputModeEntry/inputModeEntry.C
$(functionEntries)/removeEntry/removeEntry.C
+$(functionEntries)/ifeqEntry/ifeqEntry.C
+$(functionEntries)/ifEntry/ifEntry.C
IOdictionary = db/IOobjects/IOdictionary
$(IOdictionary)/baseIOdictionary.C
diff --git a/src/OpenFOAM/db/dictionary/functionEntries/ifEntry/ifEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/ifEntry/ifEntry.C
new file mode 100644
index 0000000000..15548efb90
--- /dev/null
+++ b/src/OpenFOAM/db/dictionary/functionEntries/ifEntry/ifEntry.C
@@ -0,0 +1,102 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "ifEntry.H"
+#include "Switch.H"
+#include "addToMemberFunctionSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionEntries
+{
+ defineTypeNameAndDebug(ifEntry, 0);
+
+ addNamedToMemberFunctionSelectionTable
+ (
+ functionEntry,
+ ifEntry,
+ execute,
+ dictionaryIstream,
+ if
+ );
+}
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+bool Foam::functionEntries::ifEntry::execute
+(
+ DynamicList& stack,
+ dictionary& parentDict,
+ Istream& is
+)
+{
+ const label nNested = stack.size();
+
+ stack.append(filePos(is.name(), is.lineNumber()));
+
+ // Read line
+ string line;
+ dynamic_cast(is).getLine(line);
+ line += ';';
+ IStringStream lineStream(line);
+ const primitiveEntry e("ifEntry", parentDict, lineStream);
+ const Switch doIf(e.stream());
+
+ // Info<< "Using #" << typeName << " " << doIf
+ // << " at line " << stack.last().second()
+ // << " in file " << stack.last().first() << endl;
+
+ bool ok = ifeqEntry::execute(doIf, stack, parentDict, is);
+
+ if (stack.size() != nNested)
+ {
+ FatalIOErrorInFunction(parentDict)
+ << "Did not find matching #endif for condition starting"
+ << " at line " << stack.last().second()
+ << " in file " << stack.last().first() << exit(FatalIOError);
+ }
+
+ return ok;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+bool Foam::functionEntries::ifEntry::execute
+(
+ dictionary& parentDict,
+ Istream& is
+)
+{
+ DynamicList stack(10);
+ return execute(stack, parentDict, is);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/dictionary/functionEntries/ifEntry/ifEntry.H b/src/OpenFOAM/db/dictionary/functionEntries/ifEntry/ifEntry.H
new file mode 100644
index 0000000000..eda651571b
--- /dev/null
+++ b/src/OpenFOAM/db/dictionary/functionEntries/ifEntry/ifEntry.H
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+Class
+ Foam::functionEntries::ifEntry
+
+Description
+ Conditional parsing of dictionary entries.
+
+ E.g.
+ \verbatim
+ U_inlet 15;
+
+ #if #calc "${U_inlet} < 10"
+ ..
+ #else
+ ..
+ #endif
+ \endverbatim
+
+ Note:
+ - only supports single line, '\' is not supported
+ - condition should be readable as a \c Switch
+ (supports 0,1, true, false, etc.)
+
+See also
+ Foam::functionEntries::ifeqEntry
+ Foam::Switch
+
+SourceFiles
+ ifEntry.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ifEntry_H
+#define ifEntry_H
+
+#include "ifeqEntry.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionEntries
+{
+
+/*---------------------------------------------------------------------------*\
+ Class ifEntry Declaration
+\*---------------------------------------------------------------------------*/
+
+class ifEntry
+:
+ public ifeqEntry
+{
+ friend class ifeqEntry;
+
+ // Private Member Functions
+
+ //- Execute the functionEntry in a sub-dict context
+ static bool execute
+ (
+ DynamicList& stack,
+ dictionary& parentDict,
+ Istream& is
+ );
+
+ //- Disallow default bitwise copy construct
+ ifEntry(const ifEntry&);
+
+ //- Disallow default bitwise assignment
+ void operator=(const ifEntry&);
+
+
+public:
+
+ //- Runtime type information
+ ClassName("if");
+
+ // Member Functions
+
+ //- Execute the functionEntry in a sub-dict context
+ static bool execute(dictionary& parentDict, Istream& is);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace functionEntries
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/dictionary/functionEntries/ifeqEntry/ifeqEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/ifeqEntry/ifeqEntry.C
new file mode 100644
index 0000000000..312bd1ed59
--- /dev/null
+++ b/src/OpenFOAM/db/dictionary/functionEntries/ifeqEntry/ifeqEntry.C
@@ -0,0 +1,471 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "ifeqEntry.H"
+#include "stringOps.H"
+#include "ifEntry.H"
+#include "Switch.H"
+#include "addToMemberFunctionSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionEntries
+{
+ defineTypeNameAndDebug(ifeqEntry, 0);
+
+ addNamedToMemberFunctionSelectionTable
+ (
+ functionEntry,
+ ifeqEntry,
+ execute,
+ dictionaryIstream,
+ ifeq
+ );
+}
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+void Foam::functionEntries::ifeqEntry::readToken(token& t, Istream& is)
+{
+ // Skip dummy tokens - avoids entry::getKeyword consuming #else, #endif
+ do
+ {
+ if
+ (
+ is.read(t).bad()
+ || is.eof()
+ || !t.good()
+ )
+ {
+ return;
+ }
+ }
+ while (t == token::END_STATEMENT);
+}
+
+
+Foam::token Foam::functionEntries::ifeqEntry::expand
+(
+ const dictionary& dict,
+ const string& keyword,
+ const token& t
+)
+{
+ if (keyword[0] == '$')
+ {
+ word varName = keyword(1, keyword.size()-1);
+
+ // lookup the variable name in the given dictionary
+ const entry* ePtr = dict.lookupScopedEntryPtr
+ (
+ varName,
+ true,
+ true
+ );
+ if (ePtr)
+ {
+ return token(ePtr->stream());
+ }
+ else
+ {
+ // String expansion. Allow unset variables
+ string expanded(keyword);
+ stringOps::inplaceExpand(expanded, dict, true, true);
+
+ // Re-form as a string token so we can compare to string
+ return token(expanded, t.lineNumber());
+ }
+ }
+ else if (!t.isString())
+ {
+ // Re-form as a string token so we can compare to string
+ return token(keyword, t.lineNumber());
+ }
+ else
+ {
+ return t;
+ }
+}
+
+
+Foam::token Foam::functionEntries::ifeqEntry::expand
+(
+ const dictionary& dict,
+ const token& t
+)
+{
+ if (t.isWord())
+ {
+ return expand(dict, t.wordToken(), t);
+ }
+ else if (t.isVariable())
+ {
+ return expand(dict, t.stringToken(), t);
+ }
+ else if (t.isString())
+ {
+ return expand(dict, t.stringToken(), t);
+ }
+ else
+ {
+ return t;
+ }
+}
+
+
+bool Foam::functionEntries::ifeqEntry::equalToken
+(
+ const token& t1,
+ const token& t2
+)
+{
+ const bool eqType = (t1.type() == t2.type());
+
+ switch (t1.type())
+ {
+ case token::UNDEFINED:
+ return eqType;
+
+ case token::PUNCTUATION:
+ return (eqType && t1.pToken() == t2.pToken());
+
+ case token::WORD:
+ if (eqType)
+ {
+ return t1.wordToken() == t2.wordToken();
+ }
+ else if (t2.isString())
+ {
+ return t1.wordToken() == t2.stringToken();
+ }
+ else
+ {
+ return false;
+ }
+
+ case token::STRING:
+ case token::VARIABLE:
+ case token::VERBATIMSTRING:
+ if (eqType)
+ {
+ return t1.stringToken() == t2.stringToken();
+ }
+ else if (t2.isWord())
+ {
+ return t1.stringToken() == t2.wordToken();
+ }
+ else
+ {
+ return false;
+ }
+
+ case token::LABEL:
+ if (eqType)
+ {
+ return t1.labelToken() == t2.labelToken();
+ }
+ else if (t2.isScalar())
+ {
+ return t1.labelToken() == t2.scalarToken();
+ }
+ else
+ {
+ return false;
+ }
+
+ case token::FLOAT_SCALAR:
+ if (eqType)
+ {
+ return equal(t1.floatScalarToken(), t2.floatScalarToken());
+ }
+ else if (t2.isScalar())
+ {
+ return t1.scalarToken() == t2.scalarToken();
+ }
+ else
+ {
+ return false;
+ }
+
+ case token::DOUBLE_SCALAR:
+ if (eqType)
+ {
+ return equal(t1.doubleScalarToken(), t2.doubleScalarToken());
+ }
+ else if (t2.isScalar())
+ {
+ return t1.scalarToken() == t2.scalarToken();
+ }
+ else
+ {
+ return false;
+ }
+
+ case token::LONG_DOUBLE_SCALAR:
+ if (eqType)
+ {
+ return equal
+ (
+ t1.longDoubleScalarToken(),
+ t2.longDoubleScalarToken()
+ );
+ }
+ else if (t2.isScalar())
+ {
+ return t1.scalarToken() == t2.scalarToken();
+ }
+ else
+ {
+ return false;
+ }
+
+ case token::COMPOUND:
+ return false;
+
+ case token::ERROR:
+ return eqType;
+ }
+ return false;
+}
+
+
+void Foam::functionEntries::ifeqEntry::skipUntil
+(
+ DynamicList& stack,
+ const dictionary& parentDict,
+ const word& endWord,
+ Istream& is
+)
+{
+ while (!is.eof())
+ {
+ token t;
+ readToken(t, is);
+ if (t.isWord())
+ {
+ if (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
+ {
+ stack.append(filePos(is.name(), is.lineNumber()));
+ skipUntil(stack, parentDict, "#endif", is);
+ stack.remove();
+ }
+ else if (t.wordToken() == endWord)
+ {
+ return;
+ }
+ }
+ }
+
+ FatalIOErrorInFunction(parentDict)
+ << "Did not find matching " << endWord << exit(FatalIOError);
+}
+
+
+bool Foam::functionEntries::ifeqEntry::evaluate
+(
+ const bool doIf,
+ DynamicList& stack,
+ dictionary& parentDict,
+ Istream& is
+)
+{
+ while (!is.eof())
+ {
+ token t;
+ readToken(t, is);
+
+ if (t.isWord() && t.wordToken() == "#ifeq")
+ {
+ // Recurse to evaluate
+ execute(stack, parentDict, is);
+ }
+ else if (t.isWord() && t.wordToken() == "#if")
+ {
+ // Recurse to evaluate
+ ifEntry::execute(stack, parentDict, is);
+ }
+ else if
+ (
+ doIf
+ && t.isWord()
+ && (t.wordToken() == "#else" || t.wordToken() == "#elif")
+ )
+ {
+ // Now skip until #endif
+ skipUntil(stack, parentDict, "#endif", is);
+ stack.remove();
+ break;
+ }
+ else if (t.isWord() && t.wordToken() == "#endif")
+ {
+ stack.remove();
+ break;
+ }
+ else
+ {
+ is.putBack(t);
+ bool ok = entry::New(parentDict, is);
+ if (!ok)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+
+bool Foam::functionEntries::ifeqEntry::execute
+(
+ const bool doIf,
+ DynamicList& stack,
+ dictionary& parentDict,
+ Istream& is
+)
+{
+ if (doIf)
+ {
+ evaluate(true, stack, parentDict, is);
+ }
+ else
+ {
+ // Fast-forward to #else
+ token t;
+ while (!is.eof())
+ {
+ readToken(t, is);
+ if
+ (
+ t.isWord()
+ && (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
+ )
+ {
+ stack.append(filePos(is.name(), is.lineNumber()));
+ skipUntil(stack, parentDict, "#endif", is);
+ stack.remove();
+ }
+ else if (t.isWord() && t.wordToken() == "#else")
+ {
+ break;
+ }
+ else if (t.isWord() && t.wordToken() == "#elif")
+ {
+ // const label lineNo = is.lineNumber();
+
+ // Read line
+ string line;
+ dynamic_cast(is).getLine(line);
+ line += ';';
+ IStringStream lineStream(line);
+ const primitiveEntry e("ifEntry", parentDict, lineStream);
+ const Switch doIf(e.stream());
+
+ if (doIf)
+ {
+ // Info<< "Using #elif " << doIf << " at line " << lineNo
+ // << " in file " << is.name() << endl;
+ break;
+ }
+ }
+ else if (t.isWord() && t.wordToken() == "#endif")
+ {
+ stack.remove();
+ break;
+ }
+ }
+
+ if (t.wordToken() == "#else")
+ {
+ // Evaluate until we hit #endif
+ evaluate(false, stack, parentDict, is);
+ }
+ else if (t.wordToken() == "#elif")
+ {
+ // Evaluate until we hit #else or #endif
+ evaluate(true, stack, parentDict, is);
+ }
+ }
+ return true;
+}
+
+
+bool Foam::functionEntries::ifeqEntry::execute
+(
+ DynamicList& stack,
+ dictionary& parentDict,
+ Istream& is
+)
+{
+ const label nNested = stack.size();
+
+ stack.append(filePos(is.name(), is.lineNumber()));
+
+ // Read first token and expand any string
+ token cond1(is);
+ cond1 = expand(parentDict, cond1);
+
+ // Read second token and expand any string
+ token cond2(is);
+ cond2 = expand(parentDict, cond2);
+
+ const bool equal = equalToken(cond1, cond2);
+
+ // Info<< "Using #" << typeName << " " << cond1
+ // << " == " << cond2
+ // << " at line " << stack.last().second()
+ // << " in file " << stack.last().first() << endl;
+
+ bool ok = ifeqEntry::execute(equal, stack, parentDict, is);
+
+ if (stack.size() != nNested)
+ {
+ FatalIOErrorInFunction(parentDict)
+ << "Did not find matching #endif for condition starting"
+ << " at line " << stack.last().second()
+ << " in file " << stack.last().first() << exit(FatalIOError);
+ }
+
+ return ok;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+bool Foam::functionEntries::ifeqEntry::execute
+(
+ dictionary& parentDict,
+ Istream& is
+)
+{
+ DynamicList stack(10);
+ return execute(stack, parentDict, is);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/dictionary/functionEntries/ifeqEntry/ifeqEntry.H b/src/OpenFOAM/db/dictionary/functionEntries/ifeqEntry/ifeqEntry.H
new file mode 100644
index 0000000000..679e4e256b
--- /dev/null
+++ b/src/OpenFOAM/db/dictionary/functionEntries/ifeqEntry/ifeqEntry.H
@@ -0,0 +1,190 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+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 .
+
+Class
+ Foam::functionEntries::ifeqEntry
+
+Description
+ Conditional parsing of dictionary entries.
+
+ E.g.
+ \verbatim
+ a #calc "0.123";
+ b 1.23e-1;
+
+ #ifeq $a $b
+ ..
+ #else
+ ..
+ #endif
+ \endverbatim
+
+ \verbatim
+ ddtSchemes
+ {
+ #ifeq ${FOAM_APPLICATION} simpleFoam
+ default steadyState;
+ #else
+ default Euler;
+ #endif
+ }
+ \endverbatim
+
+ Note:
+ - supports dictionary variables and environment variables
+ - the two arguments should be two tokens
+ - the comparison is a string comparison for any word/string/variable,
+ integer comparison for two integers and floating point comparison for
+ any floating point number.
+ - parsing of (non)matching \c #else, \c #endif is not very sophisticated
+
+See also
+ Foam::functionEntries::ifEntry
+
+SourceFiles
+ ifeqEntry.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ifeqEntry_H
+#define ifeqEntry_H
+
+#include "functionEntry.H"
+#include "DynamicList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace functionEntries
+{
+
+/*---------------------------------------------------------------------------*\
+ Class ifeqEntry Declaration
+\*---------------------------------------------------------------------------*/
+
+class ifeqEntry
+:
+ public functionEntry
+{
+
+protected:
+
+ typedef Tuple2 filePos;
+
+ // Protected Member Functions
+
+ //- Read tokens. Skip dummy tokens
+ static void readToken(token& t, Istream& is);
+
+ //- Expand a variable (string/word/var starting with '$')
+ static token expand
+ (
+ const dictionary& dict,
+ const string& keyword,
+ const token& t
+ );
+
+ //- Expand a string/word/var token
+ static token expand
+ (
+ const dictionary& dict,
+ const token& t
+ );
+
+ static bool equalToken
+ (
+ const token& t1,
+ const token& t2
+ );
+
+ //- Consume tokens until reached a specific word
+ static void skipUntil
+ (
+ DynamicList& stack,
+ const dictionary& parentDict,
+ const word& endWord,
+ Istream& is
+ );
+
+ static bool evaluate
+ (
+ const bool doIf,
+ DynamicList& stack,
+ dictionary& parentDict,
+ Istream& is
+ );
+
+ //- Main driver: depending on 'equal' starts evaluating or
+ // skips forward to #else
+ static bool execute
+ (
+ const bool equal,
+ DynamicList& stack,
+ dictionary& parentDict,
+ Istream& is
+ );
+
+ //- Main driver: depending on 'equal' starts evaluating or
+ // skips forward to #else
+ static bool execute
+ (
+ DynamicList& stack,
+ dictionary& parentDict,
+ Istream& is
+ );
+
+
+private:
+
+ // Private Member Functions
+
+ //- Disallow default bitwise copy construct
+ ifeqEntry(const ifeqEntry&);
+
+ //- Disallow default bitwise assignment
+ void operator=(const ifeqEntry&);
+
+
+public:
+
+ //- Runtime type information
+ ClassName("ifeq");
+
+ // Member Functions
+
+ //- Execute the functionEntry in a sub-dict context
+ static bool execute(dictionary& parentDict, Istream& is);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace functionEntries
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
index e6db4351c1..c2e1debe3c 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
+++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C
@@ -285,7 +285,7 @@ Foam::string Foam::stringOps::getVariable
{
value = getEnv(name);
- if (value.empty())
+ if (!allowEmpty && value.empty())
{
FatalIOErrorInFunction
(