public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jonathan Wakely <jwakely@redhat.com>
To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: [committed] libstdc++: Refactor Python Xmethods to use is_specialization_of
Date: Thu, 28 Sep 2023 21:21:57 +0100	[thread overview]
Message-ID: <20230928202203.3004612-1-jwakely@redhat.com> (raw)

Tested x86_64-linux (GDB 13.2, Python 3.11). Pushed to trunk.

-- >8 --

This copies the is_specialization_of function from printers.py (with
slight modification for versioned namespace handling) and reuses it in
xmethods.py to replace repetitive re.match calls in every class.

This fixes the problem that the regular expressions used \d without
escaping the backslash properly.

libstdc++-v3/ChangeLog:

	* python/libstdcxx/v6/xmethods.py (is_specialization_of): Define
	new function.
	(ArrayMethodsMatcher, DequeMethodsMatcher)
	(ForwardListMethodsMatcher, ListMethodsMatcher)
	(VectorMethodsMatcher, AssociativeContainerMethodsMatcher)
	(UniquePtrGetWorker, UniquePtrMethodsMatcher)
	(SharedPtrSubscriptWorker, SharedPtrMethodsMatcher): Use
	is_specialization_of instead of re.match.
---
 libstdc++-v3/python/libstdcxx/v6/xmethods.py | 36 +++++++++++++-------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index ef0a6e3cef3..844c8a2105a 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -25,10 +25,21 @@ matcher_name_prefix = 'libstdc++::'
 def get_bool_type():
     return gdb.lookup_type('bool')
 
-
 def get_std_size_type():
     return gdb.lookup_type('std::size_t')
 
+def is_specialization_of(x, template_name):
+    """
+    Test whether a type is a specialization of the named class template.
+    The type can be specified as a string or a gdb.Type object.
+    The template should be the name of a class template as a string,
+    without any 'std' qualification.
+    """
+    if isinstance(x, gdb.Type):
+        x = x.tag
+    if _versioned_namespace:
+        template_name = '(%s)?%s' % (_versioned_namespace, template_name)
+    return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not None
 
 class LibStdCxxXMethod(gdb.xmethod.XMethod):
     def __init__(self, name, worker_class):
@@ -159,7 +170,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag):
+        if not is_specialization_of(class_type, 'array'):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -171,6 +182,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
             return None
         return method.worker_class(value_type, size)
 
+
 # Xmethods for std::deque
 
 
@@ -284,7 +296,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag):
+        if not is_specialization_of(class_type, 'deque'):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -332,7 +344,7 @@ class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__\d+::)?forward_list<.*>$', class_type.tag):
+        if not is_specialization_of(class_type, 'forward_list'):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -419,7 +431,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__\d+::)?(__cxx11::)?list<.*>$', class_type.tag):
+        if not is_specialization_of(class_type, '(__cxx11::)?list'):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -542,7 +554,7 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__\d+::)?vector<.*>$', class_type.tag):
+        if not is_specialization_of(class_type, 'vector'):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -595,7 +607,7 @@ class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__\d+::)?%s<.*>$' % self._name, class_type.tag):
+        if not is_specialization_of(class_type, self._name):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -631,9 +643,9 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
     def __call__(self, obj):
         impl_type = obj.dereference().type.fields()[0].type.tag
         # Check for new implementations first:
-        if re.match('^std::(__\d+::)?__uniq_ptr_(data|impl)<.*>$', impl_type):
+        if is_specialization_of(impl_type, '__uniq_ptr_(data|impl)'):
             tuple_member = obj['_M_t']['_M_t']
-        elif re.match('^std::(__\d+::)?tuple<.*>$', impl_type):
+        elif is_specialization_of(impl_type, 'tuple'):
             tuple_member = obj['_M_t']
         else:
             return None
@@ -698,7 +710,7 @@ class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__\d+::)?unique_ptr<.*>$', class_type.tag):
+        if not is_specialization_of(class_type, 'unique_ptr'):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
@@ -772,7 +784,7 @@ class SharedPtrSubscriptWorker(SharedPtrGetWorker):
 
     def __call__(self, obj, index):
         # Check bounds if _elem_type is an array of known bound
-        m = re.match('.*\[(\d+)]$', str(self._elem_type))
+        m = re.match(r'.*\[(\d+)]$', str(self._elem_type))
         if m and index >= int(m.group(1)):
             raise IndexError('shared_ptr<%s> index "%d" should not be >= %d.' %
                              (self._elem_type, int(index), int(m.group(1))))
@@ -827,7 +839,7 @@ class SharedPtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
         self.methods = [self._method_dict[m] for m in self._method_dict]
 
     def match(self, class_type, method_name):
-        if not re.match('^std::(__\d+::)?shared_ptr<.*>$', class_type.tag):
+        if not is_specialization_of(class_type, 'shared_ptr'):
             return None
         method = self._method_dict.get(method_name)
         if method is None or not method.enabled:
-- 
2.41.0


                 reply	other threads:[~2023-09-28 20:22 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230928202203.3004612-1-jwakely@redhat.com \
    --to=jwakely@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).