./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 / 318
0.0%
Branches:
0 / 165
0.0%
Functions:
0 / 66
0.0%

libs/kdl/src/eu/kdl/kdl.cc
Line Branch Exec Source
1 #include "eu/kdl/kdl.h"
2
3 #include <cassert>
4 #include <kdl/kdl.h>
5
6 namespace eu::kdl
7 {
8
9
10 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11 // internal helper functions
12 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
13
14 namespace
15 {
16 ✗ std::string_view to_u8string_view(kdl_str const& s)
17 {
18 ✗ return std::string_view{reinterpret_cast<char const*>(s.data), s.len};
19 }
20
21 ✗ kdl_str to_kdl_str(std::string_view s)
22 {
23 ✗ return kdl_str{.data = (s.data()), .len = s.size()};
24 }
25
26 ✗ std::variant<integer_type, float_type, std::string> kdl_number_to_variant(kdl_number const& n)
27 {
28
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ Branch 2 → 5 not taken.
✗ Branch 2 → 13 not taken.
✗ switch (n.type) {
29 ✗ case KDL_NUMBER_TYPE_INTEGER:
30 ✗ return n.integer;
31 ✗ case KDL_NUMBER_TYPE_FLOATING_POINT:
32 ✗ return n.floating_point;
33 ✗ case KDL_NUMBER_TYPE_STRING_ENCODED:
34
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 15 not taken.
✗ return std::string{to_u8string_view(n.string)};
35 ✗ default:
36 ✗ assert(false && "invalid kdl_number");
37 return 0;
38 }
39 }
40
41 ✗ std::variant<std::monostate, bool, Number, std::string> kdl_value_to_variant(kdl_value const& val)
42 {
43
0/5
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 5 not taken.
✗ Branch 2 → 6 not taken.
✗ Branch 2 → 10 not taken.
✗ Branch 2 → 18 not taken.
✗ switch (val.type) {
44 ✗ case KDL_TYPE_NULL:
45 ✗ return std::monostate{};
46 ✗ case KDL_TYPE_BOOLEAN:
47 ✗ return val.boolean;
48 ✗ case KDL_TYPE_NUMBER:
49
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 20 not taken.
✗ return Number{val.number};
50 ✗ case KDL_TYPE_STRING:
51
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 21 not taken.
✗ return std::string{to_u8string_view(val.string)};
52 ✗ default:
53 ✗ assert(false && "invalid kdl_value");
54 return std::monostate{};
55 }
56 }
57
58 [[nodiscard]]
59 ✗ bool emit_nodes(kdl_emitter* emitter, std::vector<Node> const& nodes)
60 {
61
0/2
✗ Branch 73 → 4 not taken.
✗ Branch 73 → 74 not taken.
✗ for (const auto& node : nodes)
62 {
63
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 16 not taken.
✗ if (node.type_annotation.has_value())
64 {
65
0/4
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 81 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 21 not taken.
✗ if (!kdl_emit_node_with_type(
66 ✗ emitter, to_kdl_str(*node.type_annotation), to_kdl_str(node.name)))
67 {
68 ✗ return false;
69 }
70 } else {
71
0/4
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 81 not taken.
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 21 not taken.
✗ if (!kdl_emit_node(emitter, to_kdl_str(node.name)))
72 {
73 ✗ return false;
74 }
75 }
76
77
0/2
✗ Branch 38 → 23 not taken.
✗ Branch 38 → 39 not taken.
✗ for (const auto& arg : node.args)
78 {
79
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 77 not taken.
✗ auto v = static_cast<kdl_value>(arg);
80
0/4
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 77 not taken.
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
✗ if (!kdl_emit_arg(emitter, &v))
81 {
82 ✗ return false;
83 }
84 }
85
86
0/2
✗ Branch 52 → 41 not taken.
✗ Branch 52 → 53 not taken.
✗ for (const auto& [key, value] : node.properties)
87 {
88
0/2
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 79 not taken.
✗ auto v = static_cast<kdl_value>(value);
89
0/4
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 79 not taken.
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 50 not taken.
✗ if (!kdl_emit_property(emitter, to_kdl_str(key), &v))
90 {
91 ✗ return false;
92 }
93 }
94
95
0/2
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 64 not taken.
✗ if (!node.children.empty())
96 {
97
0/4
✗ Branch 55 → 56 not taken.
✗ Branch 55 → 81 not taken.
✗ Branch 56 → 57 not taken.
✗ Branch 56 → 58 not taken.
✗ if (!kdl_start_emitting_children(emitter))
98 {
99 ✗ return false;
100 }
101
0/4
✗ Branch 58 → 59 not taken.
✗ Branch 58 → 81 not taken.
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 61 not taken.
✗ if (emit_nodes(emitter, node.children) == false)
102 {
103 ✗ return false;
104 }
105
0/4
✗ Branch 61 → 62 not taken.
✗ Branch 61 → 81 not taken.
✗ Branch 62 → 63 not taken.
✗ Branch 62 → 64 not taken.
✗ if (!kdl_finish_emitting_children(emitter))
106 {
107 ✗ return false;
108 }
109 }
110 }
111
112 ✗ return true;
113 }
114
115 template<typename TDefer>
116 struct Defer
117 {
118 TDefer t;
119
120 ✗ explicit Defer(TDefer&& a)
121 ✗ : t(std::move(a))
122 ✗ {}
123
124 ✗ ~Defer()
125 {
126 ✗ t();
127 ✗ }
128
129 Defer() = delete;
130
131 Defer(const Defer&) = delete;
132 Defer(Defer&&) = delete;
133
134 Defer operator=(const Defer&) = delete;
135 Defer operator=(Defer&&) = delete;
136 };
137 } // namespace
138
139
140
141 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
142 // Number
143 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
144
145
146 ✗ Number::Number()
147 ✗ : m_value{ 0ll }
148 ✗ {}
149
150 ✗ Number::Number(long long n)
151 ✗ : m_value{ n }
152 ✗ {}
153
154 ✗ Number::Number(long n)
155 ✗ : m_value{ static_cast<integer_type>(n) }
156 ✗ {}
157
158 ✗ Number::Number(int n)
159 ✗ : m_value{ static_cast<integer_type>(n) }
160 ✗ {}
161
162 ✗ Number::Number(short n)
163 ✗ : m_value{ static_cast<integer_type>(n) }
164 ✗ {}
165
166 ✗ Number::Number(double n)
167 ✗ : m_value{ n }
168 ✗ {}
169
170 ✗ Number::Number(float n)
171 ✗ : m_value{ static_cast<float_type>(n) }
172 ✗ {}
173
174 ✗ Number::Number(kdl_number const& n)
175 ✗ : m_value{ kdl_number_to_variant(n) }
176 ✗ {}
177
178 ✗ NumberType Number::type() const noexcept
179 {
180 ✗ return static_cast<NumberType>(m_value.index());
181 }
182
183 ✗ Number::operator kdl_number() const
184 {
185 kdl_number result;
186 ✗ std::visit(
187 ✗ [&result]<typename T0>(const T0& n) {
188 using T = std::decay_t<T0>;
189 if constexpr (std::is_same_v<T, integer_type>) {
190 ✗ result.type = KDL_NUMBER_TYPE_INTEGER;
191 ✗ result.integer = n;
192 } else if constexpr (std::is_same_v<T, float_type>) {
193 ✗ result.type = KDL_NUMBER_TYPE_FLOATING_POINT;
194 ✗ result.floating_point = n;
195 } else if constexpr (std::is_same_v<T, std::string>) {
196 ✗ result.type = KDL_NUMBER_TYPE_STRING_ENCODED;
197 ✗ result.string = to_kdl_str(n);
198 } else {
199 assert(false && "incomplete visit");
200 result.type = KDL_NUMBER_TYPE_INTEGER;
201 result.integer = 0;
202 }
203 ✗ },
204
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 5 not taken.
✗ m_value);
205 ✗ return result;
206 }
207
208
209 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
210 // HasTypeAnnotation
211 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
212
213 ✗ HasTypeAnnotation::HasTypeAnnotation(std::string_view t)
214 ✗ : type_annotation{ t }
215 ✗ {}
216
217 ✗ void HasTypeAnnotation::remove_type_annotation()
218 {
219 ✗ type_annotation.reset();
220 ✗ }
221
222
223 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
224 // Value
225 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
226
227
228 ✗ Value::Value(bool b)
229 ✗ : m_value{ b }
230 ✗ {}
231
232 ✗ Value::Value(std::string_view s)
233
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 10 not taken.
✗ : m_value{ std::string{s} }
234 ✗ {}
235
236 ✗ Value::Value(std::string s)
237 ✗ : m_value{ std::move(s) }
238 ✗ {}
239
240 ✗ Value::Value(char const* s)
241
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 10 not taken.
✗ : m_value{ std::string{s} }
242 ✗ {}
243
244 ✗ Value::Value(Number n)
245 ✗ : m_value{ std::move(n) }
246 ✗ {}
247
248 ✗ Value::Value(std::string_view ta, bool b)
249 : HasTypeAnnotation{ ta }
250 ✗ , m_value{ b }
251 ✗ {}
252
253 ✗ Value::Value(std::string_view ta, std::string_view s)
254 : HasTypeAnnotation{ ta }
255
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 10 not taken.
✗ , m_value{ std::string{s} }
256 ✗ {}
257
258 ✗ Value::Value(std::string_view ta, std::string s)
259 : HasTypeAnnotation{ ta },
260 ✗ m_value{ std::move(s) }
261 ✗ {}
262
263 ✗ Value::Value(std::string_view ta, Number n)
264 : HasTypeAnnotation{ ta },
265 ✗ m_value{ std::move(n) }
266 ✗ {}
267
268 ✗ Value::Value(kdl_value const& val)
269
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 12 not taken.
✗ : m_value(kdl_value_to_variant(val))
270 {
271
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 8 not taken.
✗ if (val.type_annotation.data != nullptr) {
272
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 9 not taken.
✗ type_annotation = to_u8string_view(val.type_annotation);
273 }
274 ✗ }
275
276 ✗ Value& Value::operator=(bool b)
277 {
278 ✗ m_value = b;
279 ✗ return *this;
280 }
281
282 ✗ Value& Value::operator=(std::string_view s)
283 {
284
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 10 not taken.
✗ m_value = std::string{ s };
285 ✗ return *this;
286 }
287
288 ✗ Value& Value::operator=(std::string s)
289 {
290 ✗ m_value = std::move(s);
291 ✗ return *this;
292 }
293
294 ✗ Value& Value::operator=(Number const& n)
295 {
296 ✗ m_value = n;
297 ✗ return *this;
298 }
299
300 ✗ Value& Value::operator=(Number&& n)
301 {
302 ✗ m_value = std::move(n);
303 ✗ return *this;
304 }
305
306 ✗ void Value::set_to_null()
307 {
308 ✗ m_value = std::monostate{};
309 ✗ }
310
311 ✗ Type Value::type() const noexcept
312 {
313 ✗ return static_cast<Type>(m_value.index());
314 }
315
316 ✗ const Number& Value::as_number() const
317 {
318
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 6 not taken.
✗ if (std::holds_alternative<Number>(m_value)) {
319 ✗ return std::get<Number>(m_value);
320 }
321 else {
322
0/4
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 12 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 12 not taken.
✗ static const Number missing_number = 0;
323 ✗ return missing_number;
324 }
325 }
326
327 ✗ const std::string& Value::as_string() const
328 {
329
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 6 not taken.
✗ if (std::holds_alternative<std::string>(m_value)) {
330 ✗ return std::get<std::string>(m_value);
331 }
332 else {
333
0/4
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 11 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 11 not taken.
✗ static const std::string missing_string = "";
334 ✗ return missing_string;
335 }
336 }
337
338 ✗ bool Value::as_bool() const
339 {
340
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 6 not taken.
✗ if (std::holds_alternative<bool>(m_value)) {
341 ✗ return std::get<bool>(m_value);
342 }
343 else {
344 ✗ return false;
345 }
346 }
347
348 ✗ bool Value::is_null() const
349 {
350 ✗ return std::holds_alternative<std::monostate>(m_value);
351 }
352
353 ✗ Value::operator kdl_value() const
354 {
355 kdl_value result;
356
357 ✗ std::visit([&result](const auto& v)
358 {
359 using T = std::decay_t<decltype(v)>;
360 if constexpr (std::is_same_v<T, bool>)
361 {
362 ✗ result.type = KDL_TYPE_BOOLEAN;
363 ✗ result.boolean = v;
364 } else if constexpr (std::is_same_v<T, Number>)
365 {
366 ✗ result.type = KDL_TYPE_NUMBER;
367 ✗ result.number = static_cast<kdl_number>(v);
368 } else if constexpr (std::is_same_v<T, std::string>)
369 {
370 ✗ result.type = KDL_TYPE_STRING;
371 ✗ result.string = to_kdl_str(v);
372 } else {
373 ✗ result.type = KDL_TYPE_NULL;
374 }
375 ✗ },
376
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 11 not taken.
✗ m_value);
377
378
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 8 not taken.
✗ if (type_annotation.has_value())
379 {
380 ✗ result.type_annotation = to_kdl_str(*type_annotation);
381 }
382 else
383 {
384 ✗ result.type_annotation = {.data = nullptr, .len = 0};
385 }
386
387 ✗ return result;
388 }
389
390
391 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
392 // Node
393 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
394
395
396 ✗ Node::Node(std::string_view name)
397
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
✗ : name{ name }
398 ✗ {}
399
400 ✗ Node::Node(std::string_view ta, std::string_view name)
401 : HasTypeAnnotation{ ta }
402
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
✗ , name{ name }
403 ✗ {}
404
405 ✗ Node::Node(std::string_view name, std::vector<Value> args, std::map<std::string, Value, std::less<>> properties, std::vector<Node> children)
406
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 17 not taken.
✗ : name{ name }
407 ✗ , args{ std::move(args) }
408 ✗ , properties{ std::move(properties) }
409 ✗ , children{ std::move(children) }
410 ✗ {}
411
412 ✗ Node::Node(std::string_view ta, std::string_view name, std::vector<Value> args, std::map<std::string, Value, std::less<>> properties, std::vector<Node> children)
413 : HasTypeAnnotation{ ta }
414
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 17 not taken.
✗ , name{ name }
415 ✗ , args{ std::move(args) }
416 ✗ , properties{ std::move(properties) }
417 ✗ , children{ std::move(children) }
418 ✗ {}
419
420
421
422 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
423 // Document
424 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
425
426 ✗ Document::Document(std::vector<Node> nodes)
427 ✗ : nodes{ std::move(nodes) }
428 ✗ {}
429
430 ✗ Document::Document(std::initializer_list<Node> nodes)
431
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 7 not taken.
✗ : nodes{ nodes }
432 ✗ {}
433
434 ✗ std::optional<std::string> Document::to_string() const
435 {
436 ✗ return to_string(Version::kdl_1);
437 }
438
439 ✗ std::optional<std::string> Document::to_string(Version version) const
440 {
441 ✗ kdl_emitter_options opts = KDL_DEFAULT_EMITTER_OPTIONS;
442
443 ✗ opts.version = ([&version] {
444
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ if (version == Version::kdl_1) {
445 ✗ return KDL_VERSION_1;
446 }
447
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
✗ if (version == Version::kdl_2) {
448 ✗ return KDL_VERSION_2;
449 }
450 ✗ assert(false && "any version ");
451 return KDL_VERSION_2;
452 ✗ })();
453
454
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 28 not taken.
✗ kdl_emitter* emitter = kdl_create_buffering_emitter(&opts);
455
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
✗ if (emitter == nullptr)
456 {
457 ✗ assert(false && "Error initializing the KDL emitter");
458 return std::nullopt;
459 }
460 ✗ auto defer_emitter = Defer{[&]{ kdl_destroy_emitter(emitter); }};
461
462
0/4
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 26 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ if (false == emit_nodes(emitter, nodes))
463 {
464 ✗ return std::nullopt;
465 }
466
467
0/4
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 24 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 21 not taken.
✗ auto result = std::string{to_u8string_view(kdl_get_emitter_buffer(emitter))};
468 ✗ return result;
469 ✗ }
470
471 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
472 // DocumentResult
473 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
474
475
476 ✗ DocumentResult::DocumentResult(Document doc)
477 ✗ : document{ std::move(doc) }
478 ✗ {}
479
480 ✗ DocumentResult::DocumentResult(std::string err)
481 ✗ : error{ std::move(err) }
482 ✗ {}
483
484
485 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
486 // Parsing
487 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
488
489 namespace
490 {
491
492 ✗ DocumentResult document_read_from(kdl_parser* parser)
493 {
494 ✗ Document doc;
495 ✗ auto* node_list = &doc.nodes;
496 ✗ Node* current_node = nullptr;
497 ✗ std::vector<Node*> stack;
498
499 while (true)
500 {
501
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 72 not taken.
✗ auto* ev = kdl_parser_next_event(parser);
502
503
0/8
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 9 not taken.
✗ Branch 4 → 17 not taken.
✗ Branch 4 → 27 not taken.
✗ Branch 4 → 34 not taken.
✗ Branch 4 → 36 not taken.
✗ Branch 4 → 47 not taken.
✗ Branch 4 → 48 not taken.
✗ switch (ev->event)
504 {
505 ✗ case KDL_EVENT_EOF:
506
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 54 not taken.
✗ return DocumentResult{ doc };
507 ✗ case KDL_EVENT_PARSE_ERROR:
508
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 55 not taken.
✗ return DocumentResult{ static_cast<std::string>(to_u8string_view(ev->value.string)) };
509 ✗ case KDL_EVENT_START_NODE:
510 {
511 ✗ auto name = to_u8string_view(ev->name);
512
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 22 not taken.
✗ if (ev->value.type_annotation.data != nullptr)
513 {
514 ✗ auto ta = to_u8string_view(ev->value.type_annotation);
515
0/2
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 60 not taken.
✗ current_node = &node_list->emplace_back(ta, name);
516 }
517 else
518 {
519
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 61 not taken.
✗ current_node = &node_list->emplace_back(name);
520 }
521 ✗ node_list = &current_node->children;
522
0/2
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 61 not taken.
✗ stack.push_back(current_node);
523 ✗ break;
524 }
525 ✗ case KDL_EVENT_END_NODE:
526 ✗ stack.pop_back();
527
0/2
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 31 not taken.
✗ if (stack.empty())
528 {
529 ✗ current_node = nullptr;
530 ✗ node_list = &doc.nodes;
531 }
532 else
533 {
534 ✗ current_node = stack.back();
535 ✗ node_list = &current_node->children;
536 }
537 ✗ break;
538 ✗ case KDL_EVENT_ARGUMENT:
539
0/2
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 72 not taken.
✗ current_node->args.emplace_back(ev->value);
540 ✗ break;
541 ✗ case KDL_EVENT_PROPERTY:
542
0/6
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 71 not taken.
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 64 not taken.
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 62 not taken.
✗ current_node->properties[std::string{ to_u8string_view(ev->name) }] = Value{ ev->value };
543 ✗ break;
544 ✗ case KDL_EVENT_COMMENT:
545 // ignore comments
546 ✗ break;
547 ✗ default:
548 ✗ assert(false && "Invalid event from kdl_parser");
549 break;
550 }
551 ✗ }
552 ✗ }
553 }
554
555
556 ✗ DocumentResult parse(std::string_view kdl_text)
557 {
558 ✗ return parse(kdl_text, Version::any);
559 }
560
561 ✗ DocumentResult parse(std::string_view kdl_text, Version version)
562 {
563 ✗ kdl_parse_option opts = KDL_DEFAULTS;
564
565
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ Branch 2 → 5 not taken.
✗ Branch 2 → 14 not taken.
✗ switch (version)
566 {
567 ✗ case Version::kdl_1:
568 ✗ opts = KDL_READ_VERSION_1;
569 ✗ break;
570 ✗ case Version::kdl_2:
571 ✗ opts = KDL_READ_VERSION_2;
572 ✗ break;
573 ✗ case Version::any:
574 {
575
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 29 not taken.
✗ auto ret = parse(kdl_text, Version::kdl_2);
576
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 10 not taken.
✗ if (ret.document.has_value())
577 {
578 ✗ return ret;
579 }
580 else
581 {
582
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 27 not taken.
✗ return parse(kdl_text, Version::kdl_1);
583 }
584 ✗ }
585
586 ✗ default:
587 ✗ assert(false && "unhandled case");
588 break;
589 }
590
591 ✗ const kdl_str text = {.data = (kdl_text.data()), .len = kdl_text.size()};
592
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 32 not taken.
✗ kdl_parser* parser = kdl_create_string_parser(text, opts);
593
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
✗ if (parser == nullptr)
594 {
595 ✗ assert(false && "Error initializing the KDL parser");
596 return DocumentResult("internal error");
597 }
598 ✗ auto defer_parser = Defer{[&]{ kdl_destroy_parser(parser); }};
599
600
0/2
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 30 not taken.
✗ auto doc = document_read_from(parser);
601 ✗ return doc;
602 ✗ }
603
604 }
605