Skip to content

Commit 3deedb4

Browse files
committed
add printer for boost::property_tree::basic_ptree
1 parent 60da4b4 commit 3deedb4

File tree

4 files changed

+95
-0
lines changed

4 files changed

+95
-0
lines changed

SUPPORTED.org

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
| =boost::wave::util::flex_string= | 1.71 | =wave_1_71= | yes | Jeff Trull | |
2727
| =boost::wave::util::file_position= | " | " | yes | " | |
2828
| =boost::wave::cpplexer::lex_token= | " | " | yes | " | |
29+
| =boost::property_tree::ptree= | 1.42 | =multi_index_1_42= | yes | Alastair Rankine (randomphrase) | |
2930

3031
***** Notes
3132

boost/multi_index_1_42.py

+52
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,55 @@ def to_string(self):
411411
if self.empty_cont():
412412
return 'empty %s' % self.type_name
413413
return '%s' % self.type_name
414+
415+
416+
@add_printer
417+
class Boost_Property_Tree:
418+
"Printer for boost::property_tree::basic_ptree"
419+
printer_name = 'boost::property_tree'
420+
min_supported_version = (1, 42, 0)
421+
max_supported_version = last_supported_boost_version
422+
template_name = 'boost::property_tree::basic_ptree'
423+
424+
def __init__(self, v):
425+
self._value = v
426+
subs_type = get_inner_type(self._value.type, "subs");
427+
container_type = get_inner_type(subs_type, "base_container");
428+
self._container_value_type = get_inner_type(container_type, "value_type");
429+
430+
container = v['m_children'].cast(container_type.pointer()).dereference()
431+
self._node_count = container['node_count']
432+
#message('node count: ' + str(self._node_count))
433+
434+
ptr_size = gdb.lookup_type('void').pointer().sizeof
435+
elem_size = self._container_value_type.sizeof + (self._container_value_type.sizeof % ptr_size)
436+
#message('elem_size: ' + str(elem_size))
437+
438+
header_holder_subtype = container_type.fields()[1].type
439+
assert str(header_holder_subtype).strip().startswith('boost::multi_index::detail::header_holder')
440+
head_node = container.cast(header_holder_subtype)['member'].dereference()
441+
#message('head_node.type.sizeof: ' + str(head_node.type.sizeof))
442+
443+
self._index_offset = head_node.type.sizeof - 2 * ptr_size
444+
#message('index_offset: ' + str(self._index_offset))
445+
self._head_index_ptr = intptr(head_node.address) + self._index_offset
446+
#message('head_index_ptr: ' + hex(self._head_index_ptr))
447+
448+
def children(self):
449+
if not self._node_count:
450+
return Boost_Multi_Index.empty_iterator()
451+
452+
get_next_ptr = Boost_Multi_Index.sequenced_iterator.get_next_ptr
453+
node = get_next_ptr(self._head_index_ptr)
454+
while node != self._head_index_ptr:
455+
val_ptr = Boost_Multi_Index.get_val_ptr(node, self._index_offset)
456+
val = parse_and_eval('*(' + str(self._container_value_type) + '*)' + str(val_ptr))
457+
yield ('key', val["first"])
458+
yield ('val', val["second"])
459+
node = get_next_ptr(node)
460+
461+
def display_hint(self):
462+
return 'map'
463+
464+
def to_string(self):
465+
return self._value["m_data"]

tests/testsuite.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <boost/date_time/gregorian/gregorian.hpp>
4141
#include <boost/date_time/posix_time/posix_time.hpp>
4242
#include <boost/logic/tribool.hpp>
43+
#include <boost/property_tree/ptree.hpp>
4344

4445
#include <boost/multi_index_container.hpp>
4546
#include <boost/multi_index/sequenced_index.hpp>
@@ -994,6 +995,18 @@ void test_wave()
994995

995996
}
996997

998+
void test_property_tree()
999+
{
1000+
boost::property_tree::ptree empty;
1001+
boost::property_tree::ptree pt;
1002+
pt.put_value("val");
1003+
pt.put("node_a", "val_a");
1004+
pt.put("node_a.sub_1", "val_a1");
1005+
pt.put("node_a.sub_2", "val_a2");
1006+
1007+
dummy_function();
1008+
}
1009+
9971010
int main()
9981011
{
9991012
test_iterator_range();
@@ -1037,5 +1050,7 @@ int main()
10371050

10381051
test_wave();
10391052

1053+
test_property_tree();
1054+
10401055
return EXIT_SUCCESS;
10411056
}

tests/testsuite.py

+27
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,33 @@ def test_token(self):
11801180
self.assertIsNone(children)
11811181
self.assertIsNone(display_hint)
11821182

1183+
class PropertyTreeTest(PrettyPrinterTest):
1184+
@classmethod
1185+
def setUpClass(cls):
1186+
execute_cpp_function('test_property_tree')
1187+
1188+
def test_empty(self):
1189+
string, children, display_hint = self.get_printer_result('empty')
1190+
self.assertEqual(string,'""')
1191+
self.assertEqual(children, [])
1192+
1193+
def test_pt(self):
1194+
string, children, display_hint = self.get_printer_result('pt')
1195+
self.assertEqual(string,'"val"')
1196+
def _to_str(val):
1197+
# FIXME: remove this dependency on the std::string pretty-printer
1198+
return gdb.default_visualizer(val).to_string().value().string('utf-8')
1199+
def _to_str_subtree(val):
1200+
# returns a tuple of (value, children)
1201+
v=gdb.default_visualizer(val)
1202+
return (_to_str(v.to_string()), as_map(list(v.children()), _to_str, _to_str_subtree))
1203+
self.assertEqual(as_map(children, _to_str, _to_str_subtree),
1204+
[("node_a", ("val_a", [
1205+
( "sub_1", ( "val_a1", [] )),
1206+
( "sub_2", ( "val_a2", [] ))
1207+
]))])
1208+
self.assertEqual(display_hint, 'map')
1209+
11831210

11841211
# TODO: More intrusive tests:
11851212
# 1. Non-raw pointers

0 commit comments

Comments
 (0)