stringOpsSplit.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2016 OpenFOAM Foundation
9 Copyright (C) 2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "stringOps.H"
30#include "Pair.H"
31#include "Tuple2.H"
32#include <vector>
33
34// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
35
36namespace
37{
38
39inline Foam::word validateVariableName(const std::string& str)
40{
41 return Foam::stringOps::validate<Foam::word>
42 (
43 str,
44 [](char c)
45 {
46 return (Foam::word::valid(c) || c == '/' || c == '{' || c == '}');
47 }
48 );
49}
50
51} // End anonymous namespace
52
53
54// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
55
57(
58 const std::string& str,
60 List<Tuple2<word, string>>& namedArgs
61)
62{
63 args.clear();
64 namedArgs.clear();
65
66 // Similar to code originally in functionObjectList (v2012 and earlier)
67 // except that the function-name handling is now done prior to calling
68
69 // (U)
70 // -> named = ()
71 // -> unnamed = (U)
72 //
73 // (patch=inlet, p)
74 // -> named = ((patch inlet))
75 // -> unnamed = (p)
76 //
77 // start=100, stop=200
78 // -> named = ((start 100) (stop 200) )
79 // -> unnamed = ()
80 //
81 // origin=(0 0 0) , scale=2 , normal=(0 0 1)
82
83
84 // Use begin/end parse positions
85 typedef Pair<std::string::size_type> rangeType;
86
87 // For unnamed: beg/end range of each arg
88 std::vector<rangeType> unnamed;
89
90 // For named: list of beg/end ranges for (name, arg)
91 std::vector<rangeType> named;
92
93 // The beg/end range of the argument name
94 rangeType argName(0, 0);
95
96 // If argName is valid
97 bool isNamed = false;
98
99 // The depth of the argument parsing
100 int argLevel = 0;
101
102 const auto strLen = str.length();
103
104 // Pass 1: parsing begin/end parse positions.
105
106 for (std::string::size_type pos = 0, beg = 0; pos < strLen; ++pos)
107 {
108 const bool penultimate = ((pos + 1) == strLen);
109 const char c = str[pos];
110
111 if (c == ')')
112 {
113 --argLevel;
114 }
115
116 if (c == '=')
117 {
118 // Introducer for named argument
119 argName = rangeType(beg, pos);
120 isNamed = true;
121 beg = pos + 1;
122 }
123 else if (c == '(')
124 {
125 ++argLevel;
126 }
127 else if (penultimate || (c == ',')) // OR: (c == ',' || c == ';')
128 {
129 if (penultimate && (c != ',')) // OR: (c != ',' && c != ';')
130 {
131 ++pos; // Until the end, but do not include comma
132 }
133
134 if (argLevel == 0)
135 {
136 if (isNamed)
137 {
138 named.push_back(argName);
139 named.push_back(rangeType(beg, pos));
140 }
141 else
142 {
143 unnamed.push_back(rangeType(beg, pos));
144 }
145 isNamed = false;
146 beg = pos + 1;
147 }
148 }
149 }
150
151
152 // Stage 2: Convert to concrete string and store
153
154
155 // unnamed
156 {
157 const label nInputArgs = static_cast<label>(unnamed.size());
158 args.resize(nInputArgs);
159
160 label ngood = 0;
161 for (label i = 0; i < nInputArgs; ++i)
162 {
163 const auto& arg = unnamed[i];
164
165 args[ngood] = wordRe
166 (
167 word::validate
168 (
169 str.substr(arg.first(), (arg.second()-arg.first()))
170 )
171 );
172
173 // Only retain if non-empty
174 if (!args[ngood].empty())
175 {
176 ++ngood;
177 }
178 }
179
180 args.resize(ngood);
181 }
182
183 // named
184 {
185 const label nInputArgs = static_cast<label>(named.size());
186 namedArgs.resize(nInputArgs/2);
187
188 label ngood = 0;
189 for (label i = 0; i < nInputArgs; i += 2)
190 {
191 const auto& name = named[i];
192 const auto& arg = named[i+1];
193
194 namedArgs[ngood].first() =
195 validateVariableName
196 (
197 str.substr(name.first(), (name.second()-name.first()))
198 );
199
200 namedArgs[ngood].second() =
201 stringOps::trim
202 (
203 str.substr(arg.first(), (arg.second()-arg.first()))
204 );
205
206 // Only retain if name is non-empty
207 if (!namedArgs[ngood].first().empty())
208 {
209 ++ngood;
210 }
211 }
212
213 namedArgs.resize(ngood);
214 }
215
216 // Return total number of arguments
217 return (args.size() + namedArgs.size());
218}
219
220
221// ************************************************************************* //
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:69
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: Tuple2.H:58
label size() const noexcept
The number of arguments.
Definition: argListI.H:146
bool valid() const
True if all internal ids are non-negative.
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:83
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:54
A class for handling words, derived from Foam::string.
Definition: word.H:68
label splitFunctionArgs(const std::string &str, wordRes &args, List< Tuple2< word, string > > &namedArgs)
Split out arguments (named or unnamed) from an input string.
dimensionedScalar pos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::argList args(argc, argv)