ENH: refactor function arg splitting -> stringOps::splitFunctionArgs
This commit is contained in:
parent
44a243a94d
commit
c9fda67b5f
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)
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
(
|
(
|
||||||
|
Loading…
Reference in New Issue
Block a user