libstdc++: Add pretty printer for std::locale
Print the locale's name, except when it uses the same named C locale for all categories except one, in which case print something like: std::locale = "en_GB.UTF-8" with "LC_CTYPE=en_US.UTF-8" libstdc++-v3/ChangeLog: * python/libstdcxx/v6/printers.py (StdLocalePrinter): New printer class. * testsuite/libstdc++-prettyprinters/locale.cc: New test.
This commit is contained in:
parent
701ce3c723
commit
3d2e240af7
2 changed files with 81 additions and 0 deletions
|
@ -2131,6 +2131,50 @@ class StdChronoTimeZoneRulePrinter:
|
|||
return 'time_zone rule {} from {} to {} starting on {}'.format(
|
||||
self.val['name'], self.val['from'], self.val['to'], start)
|
||||
|
||||
class StdLocalePrinter:
|
||||
"Print a std::locale"
|
||||
|
||||
def __init__(self, typename, val):
|
||||
self.val = val
|
||||
self.typename = typename
|
||||
|
||||
def to_string(self):
|
||||
names = self.val['_M_impl']['_M_names']
|
||||
mod = ''
|
||||
if names[0] == 0:
|
||||
name = '*'
|
||||
else:
|
||||
cats = gdb.parse_and_eval(self.typename + '::_S_categories')
|
||||
ncat = gdb.parse_and_eval(self.typename + '::_S_categories_size')
|
||||
n = names[0].string();
|
||||
cat = cats[0].string()
|
||||
name = '{}={}'.format(cat, n)
|
||||
cat_names = {cat: n}
|
||||
i = 1
|
||||
while i < ncat and names[i] != 0:
|
||||
n = names[i].string()
|
||||
cat = cats[i].string()
|
||||
name = '{};{}={}'.format(name, cat, n)
|
||||
cat_names[cat] = n
|
||||
i = i + 1
|
||||
uniq_names = set(cat_names.values())
|
||||
if len(uniq_names) == 1:
|
||||
name = n
|
||||
elif len(uniq_names) == 2:
|
||||
n1, n2 = (uniq_names)
|
||||
name_list = list(cat_names.values())
|
||||
other = None
|
||||
if name_list.count(n1) == 1:
|
||||
name = n2
|
||||
other = n1
|
||||
elif name_list.count(n2) == 1:
|
||||
name = n1
|
||||
other = n2
|
||||
if other is not None:
|
||||
cat = next(c for c,n in cat_names.items() if n == other)
|
||||
mod = ' with "{}={}"'.format(cat, other)
|
||||
return 'std::locale = "{}"{}'.format(name, mod)
|
||||
|
||||
|
||||
# A "regular expression" printer which conforms to the
|
||||
# "SubPrettyPrinter" protocol from gdb.printing.
|
||||
|
@ -2585,6 +2629,7 @@ def build_libstdcxx_dictionary ():
|
|||
libstdcxx_printer.add_version('std::', 'unique_ptr', UniquePointerPrinter)
|
||||
libstdcxx_printer.add_container('std::', 'vector', StdVectorPrinter)
|
||||
# vector<bool>
|
||||
libstdcxx_printer.add_version('std::', 'locale', StdLocalePrinter)
|
||||
|
||||
if hasattr(gdb.Value, 'dynamic_type'):
|
||||
libstdcxx_printer.add_version('std::', 'error_code',
|
||||
|
|
36
libstdc++-v3/testsuite/libstdc++-prettyprinters/locale.cc
Normal file
36
libstdc++-v3/testsuite/libstdc++-prettyprinters/locale.cc
Normal file
|
@ -0,0 +1,36 @@
|
|||
// { dg-do run }
|
||||
// { dg-options "-g -O0" }
|
||||
// { dg-require-namedlocale "fr_FR.ISO8859-15" }
|
||||
// { dg-require-namedlocale "de_DE.ISO8859-15" }
|
||||
// { dg-require-namedlocale "en_US.ISO8859-1" }
|
||||
|
||||
#include <locale>
|
||||
#include <testsuite_hooks.h> // for ISO_8859 macro
|
||||
|
||||
int main()
|
||||
{
|
||||
std::locale l1 = std::locale::classic();
|
||||
// { dg-final { note-test l1 {std::locale = "C"} } }
|
||||
|
||||
std::locale l2(ISO_8859(15,fr_FR));
|
||||
// { dg-final { regexp-test l2 {std::locale = "fr_FR.ISO8859-15(@euro)?"} } }
|
||||
|
||||
std::locale l3(l2, ISO_8859(15,de_DE), std::locale::time);
|
||||
// { dg-final { regexp-test l3 {std::locale = "fr_FR.ISO8859-15(@euro)?" with "LC_TIME=de_DE.ISO8859-15(@euro)?"} } }
|
||||
|
||||
std::locale l4(l3, ISO_8859(1,en_US), std::locale::monetary);
|
||||
// We don't know which order the categories will occur in the string,
|
||||
// so test three times, checking for the required substring each time:
|
||||
// { dg-final { regexp-test l4 {std::locale = "(.*;)?LC_CTYPE=fr_FR.ISO8859-15(@euro)?(;.*)?"} } }
|
||||
std::locale l5 = l4;
|
||||
// { dg-final { regexp-test l5 {std::locale = "(.*;)?LC_TIME=de_DE.ISO8859-15(@euro)?(;.*)?"} } }
|
||||
std::locale l6 = l5;
|
||||
// { dg-final { regexp-test l6 {std::locale = "(.*;)?LC_MONETARY=en_US.ISO8859-1(;.*)?"} } }
|
||||
|
||||
std::locale l7(l1, &std::use_facet<std::ctype<char> >(l1));
|
||||
// { dg-final { regexp-test l7 {std::locale = "\*"} } }
|
||||
|
||||
return 0; // Mark SPOT
|
||||
}
|
||||
|
||||
// { dg-final { gdb-test SPOT } }
|
Loading…
Add table
Reference in a new issue