GCC Code Coverage Report


Directory: ./
File: src/util/config-helpers.cc
Date: 2025-09-01 06:19:01
Exec Total Coverage
Lines: 235 282 83.3%
Functions: 26 27 96.3%
Branches: 162 218 74.3%

Line Branch Exec Source
1 #include "na64util/config-helpers.hh"
2 #include "na64util/exception.hh"
3 #include "na64util/pair-hash.hh"
4 #include "na64util/str-fmt.hh"
5 #include <cctype>
6 #include <limits>
7 #include <sstream>
8 #include <stdexcept>
9 #include <typeindex>
10 #include <typeinfo>
11 #include <yaml-cpp/exceptions.h>
12 #include <iostream>
13
14 #include <cstring>
15 #include <regex>
16
17 namespace na64dp {
18 namespace util {
19 namespace pdef {
20
21 //
22 // Path object
23
24 //
25 // TODO: perhaps, it might be better in general to substitute this hand-written
26 // parser by some generated one? I foresee difficulties with future
27 // maintenance of this thing...
28
29 static const std::regex gRxStrPathTok(R"~([A-Za-z_][A-Za-z_0-9\-]*)~");
30
31 8 bool validate_parameter_name(const char * nm) {
32
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 if((!nm) || '\0' == nm[0]) return false;
33 8 return std::regex_match(nm, gRxStrPathTok);
34 }
35
36 struct PathParserState {
37 size_t nChar;
38 char * c, * token;
39 bool isIndex, isStr, done;
40
41 std::vector<PathToken> & dest;
42
43 90 void _reset_state() {
44 90 token = NULL;
45 90 isIndex = false;
46 90 isStr = false;
47 90 }
48
49 40 void finalize_index_token() {
50
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 assert(']' == *c);
51
4/4
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 37 times.
40 if((!isIndex) || NULL == token)
52 3 throw errors::BadPath("Bad integer index notion (near closing `]')", nChar);
53 37 *c = '\0';
54
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 13 times.
37 if(!strcmp(token, "*")) {
55 24 PathToken tok;
56 24 tok.type = PathToken::kAnyIndex;
57
1/1
✓ Branch 1 taken 24 times.
24 dest.push_back(tok);
58 24 _reset_state();
59 24 return;
60 }
61 13 char * strEnd = NULL;
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 assert(token);
63 13 ssize_t i = strtol(token, &strEnd, 10);
64
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10 times.
13 if(strEnd != c) {
65 3 throw errors::BadPath(util::format("Bad integer literal \"%s\" near closing `]'",
66 6 token).c_str(), nChar);
67 }
68 10 PathToken tok(i);
69
1/1
✓ Branch 1 taken 10 times.
10 dest.push_back(tok);
70 10 _reset_state();
71 }
72
73 58 void finalize_string_token() {
74 58 done = ('\0' == *c);
75
5/6
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 23 times.
58 assert(done || '.' == *c || '[' == *c);
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if(isIndex)
77 throw errors::BadPath("Bad integer key"
78 " near end of expression or prior to delimiter `.' or `['"
79 " (integer index expected)", nChar);
80
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if(NULL == token) {
81
0/1
✗ Branch 1 not taken.
20 if(done) return; // ok for string terminator
82 throw errors::BadPath("Bad string key"
83 " near end of expression or prior to delimiter `.' or `['"
84 " -- nothing to terminate", nChar);
85 }
86 58 *c = '\0';
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if(!isStr)
88 throw errors::BadPath(util::format("Bad string key \"%s\""
89 " near end of expression or prior to delimiter `.' or `['"
90 , token).c_str() , nChar);
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if( 1 > (c - token)) {
92 throw errors::BadPath("Empty string key, near end of expression or delimiter `.' or `['", nChar);
93 }
94
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 38 times.
58 if(!strcmp(token, "*")) {
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if(!isStr)
96 throw errors::BadPath("Unexpected `*' selector", nChar);
97 20 PathToken tok;
98 20 tok.type = PathToken::kAnyStrKey;
99
1/1
✓ Branch 1 taken 20 times.
20 dest.push_back(tok);
100 20 _reset_state();
101 20 return;
102 }
103
3/3
✓ Branch 1 taken 38 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 36 times.
38 if(!std::regex_match(token, gRxStrPathTok)) {
104 2 throw errors::BadPath(format("Bad string key (\"%s\" doesn't match"
105 " permitted pattern), near end of expression"
106 4 " or delimiter `.'", token).c_str(), nChar);
107 }
108 //std::cout << "token \"" << token << "\"" << std::endl; // XXX
109 36 PathToken tok(token);
110
1/1
✓ Branch 1 taken 36 times.
36 dest.push_back(tok);
111 36 _reset_state();
112 }
113 };
114
115 static void
116 36 tokenize_path(char * path, std::vector<PathToken> & p) {
117 36 PathParserState state = {0, path, NULL, false, true, false, p};
118 36 const size_t strLen = strlen(path);
119
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 6 times.
354 for(state.c = path; !state.done; ++state.c, ++state.nChar) {
120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
348 if(state.nChar > strLen) {
121 throw errors::BadPath("Bad path expression", state.nChar - 1);
122 }
123
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 305 times.
348 if('[' == *state.c) {
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if(state.isIndex)
125 throw errors::BadPath("Bad integer index notion near opening `['", state.nChar);
126
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 10 times.
43 if(state.isStr) {
127
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25 times.
33 if(state.c == path) {
128 // first char in expression, switch to numeric index
129 8 state.isIndex = true;
130 8 state.isStr = false;
131 8 *state.c = '\0';
132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(state.token == NULL);
133 8 continue;
134 }
135
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 23 times.
25 if(NULL == state.token) {
136 2 throw errors::BadPath("No item to index near opening `['", state.nChar);
137 }
138 //std::cout << " xxx str:\"" << state.token << "\"" << std::endl; // XXX
139
1/1
✓ Branch 1 taken 23 times.
23 state.finalize_string_token();
140 } else {
141 10 *state.c = '\0';
142 }
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 assert(!state.isStr);
144 33 state.isIndex = true;
145 33 continue;
146 }
147
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 265 times.
305 if(']' == *state.c) {
148
1/1
✓ Branch 1 taken 34 times.
40 state.finalize_index_token();
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 assert(!state.isIndex);
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 assert(!state.isStr);
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 assert(NULL == state.token);
152 34 continue;
153 }
154
4/4
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 198 times.
265 if('.' == *state.c || '\0' == *state.c) {
155
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
67 if(state.isIndex && '.' == *state.c) {
156 2 throw errors::BadPath("Expected integer index before `.' or end of line", state.nChar);
157 }
158
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 30 times.
65 if(state.token) {
159
1/1
✓ Branch 1 taken 33 times.
35 state.finalize_string_token();
160 } else {
161
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 11 times.
30 if('\0' != *state.c) {
162
6/6
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 5 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 13 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 13 times.
19 if( (p.empty() || !(p.back().type & PathToken::kAnyIndex) ) ) {
163 6 throw errors::BadPath("Expected item before `.'", state.nChar);
164 }
165 // NOTE: do nothing otherwise and just expect string
166 } else {
167 11 break;
168 }
169 }
170 46 state.isStr = true;
171 46 continue;
172 }
173
3/4
✓ Branch 0 taken 198 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 99 times.
198 if(*state.c != '\0' && NULL == state.token) {
174 99 state.token = state.c;
175
4/4
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 59 times.
99 if(!(state.isIndex || state.isStr)) {
176 1 throw errors::BadPath("Unable to assume token type", state.nChar);
177 }
178 }
179 }
180
5/6
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 16 times.
17 if(p.empty() && strLen) {
181 1 throw errors::BadPath("Can not interpret path expression", strLen - 1);
182 }
183 16 }
184
185 36 Path::Path(const char * strexpr) {
186
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 35 times.
36 if(!strexpr) {
187 1 _strBuf = nullptr;
188 1 _strBufLen = 0;
189 1 return;
190 }
191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 assert('\0' != *strexpr);
192 35 _strBufLen = strlen(strexpr);
193
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 if(_strBufLen) {
194 35 _strBuf = static_cast<char*>(malloc(_strBufLen+1));
195 35 memcpy(_strBuf, strexpr, _strBufLen+1);
196 // tokensize expression
197 try {
198
1/1
✓ Branch 1 taken 15 times.
35 tokenize_path(_strBuf, *this);
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 } catch(errors::BadPath & e) {
200
1/1
✓ Branch 1 taken 20 times.
20 e.path = strexpr;
201
1/1
✓ Branch 2 taken 20 times.
20 throw e;
202 20 }
203 } else {
204 _strBuf = nullptr;
205 }
206 20 }
207
208 Path &
209 1 Path::operator=(const Path & orig) {
210 1 clear();
211
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if(orig.empty()) return *this;
212
1/1
✓ Branch 1 taken 1 times.
1 std::string strexpr = orig.to_string();
213 1 _strBufLen = strexpr.size();
214 1 _strBuf = static_cast<char*>(realloc(_strBuf, _strBufLen + 1));
215 1 memcpy(_strBuf, strexpr.c_str(), _strBufLen + 1);
216 // tokensize expression
217 try {
218
1/1
✓ Branch 1 taken 1 times.
1 tokenize_path(_strBuf, *this);
219 } catch(errors::BadPath & e) {
220 e.path = strexpr;
221 throw e;
222 }
223 1 return *this;
224 1 }
225
226 16 Path::~Path() {
227
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if(_strBufLen) free(_strBuf);
228 16 _strBufLen = 0;
229 16 }
230
231 std::string
232 5 Path::to_string() const {
233
1/1
✓ Branch 1 taken 5 times.
5 std::ostringstream oss;
234 5 bool isFirst = true;
235
2/2
✓ Branch 4 taken 50 times.
✓ Branch 5 taken 5 times.
55 for(const PathToken & tok: *this) {
236
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 20 times.
50 if(tok.type & PathToken::kAnyStrKey) {
237
3/3
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 5 times.
✓ Branch 3 taken 25 times.
30 if(!isFirst) { oss << "."; }
238
239
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 if(tok.type == PathToken::kStrKey) {
240
1/1
✓ Branch 1 taken 20 times.
20 oss << tok.pl.stringKey;
241 } else {
242
1/1
✓ Branch 1 taken 10 times.
10 oss << "*";
243 }
244
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 } else if(tok.type & PathToken::kAnyIndex) {
245
1/1
✓ Branch 1 taken 20 times.
20 oss << "[";
246
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if(tok.type == PathToken::kIntKey) {
247
1/1
✓ Branch 1 taken 5 times.
5 oss << tok.pl.index;
248 } else {
249
1/1
✓ Branch 1 taken 15 times.
15 oss << "*";
250 }
251
1/1
✓ Branch 1 taken 20 times.
20 oss << "]";
252 } else {
253 NA64DP_RUNTIME_ERROR("Undefined node type in path object.");
254 }
255 50 isFirst = false;
256 }
257
1/1
✓ Branch 1 taken 5 times.
10 return oss.str();
258 5 }
259
260 //
261 // Scalars
262
263 #if 0
264 template< typename SourceT
265 , typename DestT> void
266 assign_numeric_value(DestT & dest, const SourceT & src) {
267 if(src > std::numeric_limits<DestT>::max()) {
268 std::stringstream oss;
269 oss << "Value " << src << " is greater than destination"
270 " type's upper limit (" << std::numeric_limits<DestT>::max() << ")";
271 throw errors::ParameterTypeOverflow(oss.str().c_str());
272 }
273 if(src < std::numeric_limits<DestT>::min()) {
274 std::stringstream oss;
275 oss << "Value " << src << " is lesser than destination"
276 " type's lower limit (" << std::numeric_limits<DestT>::min() << ")";
277 throw errors::ParameterTypeOverflow(oss.str().c_str());
278 }
279 dest = static_cast<DestT>(src);
280 }
281
282 std::unordered_map< std::pair<std::type_index, std::type_index>
283 , void(*)(void *, void *)
284 , util::PairHash
285 > gConversionTable;
286
287 void
288 assign( void * destPtr, const std::type_info & destTI
289 , void * srcPtr, const std::type_info & srcTI
290 ) {
291 // ...
292 }
293 #endif
294
295 //
296 // Config node object
297
298 const char *
299 11 Node::node_type_name() const {
300
3/7
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
11 switch(_type) {
301 case kUnset:
302 return "UNSET";
303 4 case kScalar:
304 4 return "SCALAR";
305 4 case kArray:
306 4 return "ARRAY";
307 3 case kSection:
308 3 return "SECTION";
309 case kUnion:
310 return "UNION";
311 case kCustom:
312 return "CUSTOM";
313 default:
314 return "?";
315 };
316 }
317
318 Node::Section &
319 6 Node::set_section() {
320
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(_type != kUnset)
321 throw errors::NodeRedefinition(
322 2 format("Node type has been set as %s already, can't reset as section"
323
1/1
✓ Branch 2 taken 1 times.
3 , node_type_name()).c_str());
324 5 _type = kSection;
325 5 _pl.section = new Section;
326 5 return *_pl.section;
327 }
328
329 Node::Array &
330 4 Node::set_array() {
331
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if(_type != kUnset)
332 throw errors::NodeRedefinition(
333 2 format("Node type has been set as %s already, can't reset as array"
334
1/1
✓ Branch 2 taken 1 times.
3 , node_type_name()).c_str());
335 3 _type = kArray;
336 3 _pl.array = new Array;
337 3 return *_pl.array;
338 }
339
340
341 BaseScalar &
342 7 Node::as_scalar() {
343
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
7 if(kScalar != _type) throw errors::InvalidParameterType(
344 8 format("Node is of type %s while scalar requested."
345
1/1
✓ Branch 2 taken 4 times.
12 , node_type_name() ).c_str());
346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 assert(_pl.parameterPtr);
347 3 return static_cast<BaseScalar&>(*_pl.parameterPtr);
348 }
349
350 const BaseScalar &
351 4 Node::as_scalar() const {
352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(kScalar != _type) throw errors::InvalidParameterType(
353 format("Node is of type %s while (const) scalar requested."
354 , node_type_name() ).c_str());
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 assert(_pl.parameterPtr);
356 4 return static_cast<BaseScalar&>(*_pl.parameterPtr);
357 }
358
359
360 Node::Section &
361 16 Node::as_section() {
362
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 13 times.
16 if(kSection != _type)
363 throw errors::InvalidParameterType(
364 6 format("Node is of type %s while section requested."
365
1/1
✓ Branch 2 taken 3 times.
9 , node_type_name() ).c_str());
366
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 assert(_pl.section);
367 13 return static_cast<Section&>(*_pl.section);
368 }
369
370 const Node::Section &
371 2 Node::as_section() const {
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(kSection != _type)
373 throw errors::InvalidParameterType(
374 format("Node is of type %s while (const) section requested."
375 , node_type_name() ).c_str());
376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(_pl.section);
377 2 return static_cast<const Section&>(*_pl.section);
378 }
379
380
381 Node::Array &
382 8 Node::as_array() {
383
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if(kArray != _type)
384 throw errors::InvalidParameterType(
385 4 format("Node is of type %s while array requested."
386
1/1
✓ Branch 2 taken 2 times.
6 , node_type_name() ).c_str());
387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 assert(_pl.array);
388 6 return static_cast<Array&>(*_pl.array);
389 }
390
391 const Node::Array &
392 5 Node::as_array() const {
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if(kArray != _type)
394 throw errors::InvalidParameterType(
395 format("Node is of type %s while (const) array requested."
396 , node_type_name() ).c_str());
397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 assert(_pl.array);
398 5 return static_cast<const Array&>(*_pl.array);
399 }
400
401
402 Node &
403 4 Node::operator[](const std::string & nm) {
404
1/1
✓ Branch 1 taken 3 times.
4 auto & sec = as_section();
405
1/1
✓ Branch 1 taken 3 times.
3 auto it = sec.find(nm);
406
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if(sec.end() == it) {
407 throw errors::NoKeyInSection(nm.c_str());
408 }
409
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 assert(it->second);
410 6 return *it->second;
411 }
412
413 const Node &
414 Node::operator[](const std::string & nm) const {
415 auto & sec = as_section();
416 auto it = sec.find(nm);
417 if(sec.end() == it) {
418 throw errors::NoKeyInSection(nm.c_str());
419 }
420 assert(it->second);
421 return *it->second;
422 }
423
424 bool
425 2 Node::has(const std::string & nm) const {
426
1/1
✓ Branch 1 taken 2 times.
2 auto & sec = as_section();
427
1/1
✓ Branch 1 taken 2 times.
2 auto it = sec.find(nm);
428 2 return sec.end() != it;
429 }
430
431
432 Node &
433 3 Node::operator[](ssize_t n) {
434 3 return const_cast<Node&>(static_cast<const Node *>(this)->operator[](n));
435 }
436
437 const Node &
438 3 Node::operator[](ssize_t n) const {
439 3 const ssize_t origN = n;
440 3 auto & arr = as_array();
441
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(n < 0) {
442 n = arr.size() + n;
443 if(n < 0)
444 throw errors::NoItemInArray(origN);
445 }
446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 assert(n >= 0);
447
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 assert(static_cast<size_t>(n) <= std::numeric_limits<size_t>::max());
448 3 size_t n_ = n;
449
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if(n_ >= arr.size())
450 throw errors::NoItemInArray(origN);
451 3 return *arr[n_];
452 }
453
454 bool
455 2 Node::has(ssize_t n) const {
456 2 auto & arr = as_array();
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(n < 0) {
458 n = arr.size() + n;
459 if(n < 0)
460 return false;
461 }
462
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(n >= 0);
463
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 assert(static_cast<size_t>(n) <= std::numeric_limits<size_t>::max());
464 2 size_t n_ = n;
465
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if(n_ >= arr.size())
466 return false;
467 2 return true;
468 }
469
470 //
471 // Composer
472
473 3 Composer::Composer(Node & n) {
474 3 _stack.push_back({n, "", 0});
475 9 }
476
477 void
478 8 Composer::_assure_section() {
479
2/2
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 3 times.
8 if(_stack.back().node.is_section()) return;
480
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if(!_stack.back().node.is_unset()) {
481 throw errors::InvalidParameterType(format("Parent node is"
482 " of %s type while section implied"
483 , _stack.back().node.node_type_name()).c_str());
484 }
485 3 _stack.back().node.set_section();
486 }
487
488 void
489 2 Composer::_assure_array() {
490
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if(_stack.back().node.is_array()) return;
491
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(!_stack.back().node.is_unset()) {
492 throw errors::InvalidParameterType(format("Parent node is of %s type"
493 " while array implied"
494 , _stack.back().node.node_type_name()).c_str());
495 }
496 1 _stack.back().node.set_array();
497 }
498
499 } // namespace ::na64dp::util::pdef
500
501 #if 0
502 void
503 Node::apply(const YAML::Node & yamlValueNode) {
504 switch( _type ) {
505 case kScalar:
506 _pl.parameterPtr->set(yamlValueNode);
507 break;
508 case kSection:
509 for(auto & p : *_pl.section) {
510 YAML::Node v;
511 try {
512 v = yamlValueNode[p.first];
513 } catch(YAML::Exception & e) {
514 auto ee = errors::GenericYAMLError(e
515 , "YAML emitted error"
516 );
517 ee.path.push_front(p.first);
518 throw ee;
519 }
520 try {
521 p.second->apply(v);
522 } catch( na64dp::errors::PDefError & e ) {
523 e.path.push_back(p.first);
524 throw e;
525 }
526 }
527 break;
528 // ...
529 default:
530 throw std::runtime_error("Inconsistency in pdef: bad node type."); // TODO
531 };
532 }
533
534 } // namespace ::na64dp::util::pdef
535
536 void
537 RuntimeCfg::_finalize_last_node() {
538 assert(_lastNode);
539 assert(_lastNodeName);
540 try {
541 _lastNode->_check_consistency();
542 } catch( errors::PDefError & pdErr ) {
543 pdErr.path.push_front(_lastNodeName);
544 throw pdErr;
545 }
546 _nodes.emplace(_lastNodeName, _lastNode);
547 _lastNode = nullptr;
548 }
549 #endif
550
551 } // namespace ::na64dp::util
552 } // namespace na64dp
553
554