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 -------------------------------------------------------------------------------
11 License
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 
36 namespace
37 {
38 
39 inline 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,
59  wordRes& args,
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  (
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() =
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 // ************************************************************************* //
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Tuple2.H
Foam::stringOps::trim
string trim(const std::string &s)
Return string trimmed of leading and trailing whitespace.
Definition: stringOps.C:1046
Pair.H
Foam::wordRe
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:80
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:76
Foam::word::valid
static bool valid(char c)
Is this character valid for a word?
Definition: wordI.H:59
Foam::argList::size
label size() const noexcept
The number of arguments.
Definition: argListI.H:146
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:54
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::Tuple2
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: stringOps.H:60
Foam::stringOps::validate
StringType validate(const std::string &str, const UnaryPredicate &accept, const bool invert=false)
Return a copy of the input string with validated characters.
Definition: stringOpsTemplates.C:71
args
Foam::argList args(argc, argv)
stringOps.H
Foam::stringOps::splitFunctionArgs
label splitFunctionArgs(const std::string &str, wordRes &args, List< Tuple2< word, string >> &namedArgs)
Split out arguments (named or unnamed) from an input string.
Definition: stringOpsSplit.C:57
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177