Skip to content

Commit 3704993

Browse files
committed
Add GDB pretty printer module
1 parent aba5d4b commit 3704993

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed

extra/decimal_printer_gdb.py

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Copyright 2025 Matt Borland
2+
# Distributed under the Boost Software License, Version 1.0.
3+
# https://www.boost.org/LICENSE_1_0.txt
4+
5+
from detail.decode_ieee_type import decode_decimal32
6+
from detail.decode_ieee_type import decode_decimal64
7+
from detail.decode_ieee_type import decode_decimal128
8+
from detail.decode_fast_type import decode_decimal_fast32
9+
from detail.decode_fast_type import decode_decimal_fast64
10+
from detail.decode_fast_type import decode_decimal_fast128
11+
12+
import gdb
13+
import gdb.printing
14+
15+
class Decimal32Printer:
16+
"""Pretty printer for decimal32_t type"""
17+
18+
def __init__(self, val):
19+
self.val = val
20+
21+
def to_string(self):
22+
try:
23+
bits = int(self.val['bits_'])
24+
return decode_decimal32(bits)
25+
except Exception as e:
26+
return f"<invalid decimal32_t: {e}>"
27+
28+
def children(self):
29+
yield ('bits_', self.val['bits_'])
30+
31+
32+
class Decimal64Printer:
33+
"""Pretty printer for decimal64_t type"""
34+
35+
def __init__(self, val):
36+
self.val = val
37+
38+
def to_string(self):
39+
try:
40+
bits = int(self.val['bits_'])
41+
return decode_decimal64(bits)
42+
except Exception as e:
43+
return f"<invalid decimal64_t: {e}>"
44+
45+
def children(self):
46+
yield ('bits_', self.val['bits_'])
47+
48+
49+
class Decimal128Printer:
50+
"""Pretty printer for decimal128_t type"""
51+
52+
def __init__(self, val):
53+
self.val = val
54+
55+
def to_string(self):
56+
try:
57+
bits = self.val['bits_']
58+
bits_high = int(bits['high'])
59+
bits_low = int(bits['low'])
60+
combined_bits = (bits_high << 64) | bits_low
61+
return decode_decimal128(combined_bits)
62+
except Exception as e:
63+
return f"<invalid decimal128_t: {e}>"
64+
65+
def children(self):
66+
yield ('bits_', self.val['bits_'])
67+
68+
69+
class DecimalFast32Printer:
70+
"""Pretty printer for decimal_fast32_t type"""
71+
72+
def __init__(self, val):
73+
self.val = val
74+
75+
def to_string(self):
76+
try:
77+
significand = int(self.val['significand_'])
78+
exp = int(self.val['exponent_'])
79+
sign = int(self.val['sign_'])
80+
return decode_decimal_fast32(significand, exp, sign)
81+
except Exception as e:
82+
return f"<invalid decimal_fast32_t: {e}>"
83+
84+
def children(self):
85+
yield ('significand_', self.val['significand_'])
86+
yield ('exponent_', self.val['exponent_'])
87+
yield ('sign_', self.val['sign_'])
88+
89+
90+
class DecimalFast64Printer:
91+
"""Pretty printer for decimal_fast64_t type"""
92+
93+
def __init__(self, val):
94+
self.val = val
95+
96+
def to_string(self):
97+
try:
98+
significand = int(self.val['significand_'])
99+
exp = int(self.val['exponent_'])
100+
sign = int(self.val['sign_'])
101+
return decode_decimal_fast64(significand, exp, sign)
102+
except Exception as e:
103+
return f"<invalid decimal_fast64_t: {e}>"
104+
105+
def children(self):
106+
yield ('significand_', self.val['significand_'])
107+
yield ('exponent_', self.val['exponent_'])
108+
yield ('sign_', self.val['sign_'])
109+
110+
111+
class DecimalFast128Printer:
112+
"""Pretty printer for decimal_fast128_t type"""
113+
114+
def __init__(self, val):
115+
self.val = val
116+
117+
def to_string(self):
118+
try:
119+
significand = self.val['significand_']
120+
bits_high = int(significand['high'])
121+
bits_low = int(significand['low'])
122+
combined_bits = (bits_high << 64) | bits_low
123+
124+
exp = int(self.val['exponent_'])
125+
sign = int(self.val['sign_'])
126+
127+
return decode_decimal_fast128(combined_bits, exp, sign)
128+
except Exception as e:
129+
return f"<invalid decimal_fast128_t: {e}>"
130+
131+
def children(self):
132+
yield ('significand_', self.val['significand_'])
133+
yield ('exponent_', self.val['exponent_'])
134+
yield ('sign_', self.val['sign_'])
135+
136+
137+
def build_pretty_printer():
138+
"""Build and return the pretty printer collection"""
139+
pp = gdb.printing.RegexpCollectionPrettyPrinter("boost_decimal")
140+
141+
# IEEE types
142+
pp.add_printer('decimal32_t',
143+
r'^(const )?(boost::decimal::)?decimal32_t( &| \*)?$',
144+
Decimal32Printer)
145+
pp.add_printer('decimal64_t',
146+
r'^(const )?(boost::decimal::)?decimal64_t( &| \*)?$',
147+
Decimal64Printer)
148+
pp.add_printer('decimal128_t',
149+
r'^(const )?(boost::decimal::)?decimal128_t( &| \*)?$',
150+
Decimal128Printer)
151+
152+
# Fast types
153+
pp.add_printer('decimal_fast32_t',
154+
r'^(const )?(boost::decimal::)?decimal_fast32_t( &| \*)?$',
155+
DecimalFast32Printer)
156+
pp.add_printer('decimal_fast64_t',
157+
r'^(const )?(boost::decimal::)?decimal_fast64_t( &| \*)?$',
158+
DecimalFast64Printer)
159+
pp.add_printer('decimal_fast128_t',
160+
r'^(const )?(boost::decimal::)?decimal_fast128_t( &| \*)?$',
161+
DecimalFast128Printer)
162+
163+
return pp
164+
165+
166+
def register_printers(objfile=None):
167+
gdb.printing.register_pretty_printer(objfile, build_pretty_printer())
168+
169+
170+
# Auto-register when the module is loaded
171+
register_printers()
172+
print("Boost.Decimal pretty printers loaded successfully")

0 commit comments

Comments
 (0)