public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes
@ 2022-09-04 18:47 Philipp Fent
  2022-09-04 18:47 ` [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream Philipp Fent
  2022-09-06  1:06 ` [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes Will Hawkins
  0 siblings, 2 replies; 8+ messages in thread
From: Philipp Fent @ 2022-09-04 18:47 UTC (permalink / raw)
  To: libstdc++, gcc-patches; +Cc: Philipp Fent

Signed-off-by: Philipp Fent <fent@in.tum.de>
---
 libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc | 2 +-
 libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
index cc91803e247..af335d0d3c7 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
@@ -29,7 +29,7 @@ main()
 // { dg-final { note-test t1 {empty std::tuple} } }
 
   std::tuple<std::string, int, std::tuple<>> t2{ "Johnny", 5, {} };
-// { dg-final { regexp-test t2 {std::tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = empty std::tuple}} } }
+// { dg-final { regexp-test t2 {std::tuple containing = {\[0\] = "Johnny", \[1\] = 5, \[2\] = empty std::tuple}} } }
 
   std::cout << "\n";
   return 0; // Mark SPOT
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
index f97640a0189..bc5978ee69d 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
@@ -166,9 +166,9 @@ main()
 // { dg-final { note-test runiq_ptr {std::unique_ptr<int> = {get() = 0x0}} } }
 
   ExTuple tpl(6,7);
-// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
+// { dg-final { note-test tpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
   ExTuple &rtpl = tpl;
-// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
+// { dg-final { note-test rtpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
 
   std::error_code e0;
   // { dg-final { note-test e0 {std::error_code = { }} } }
-- 
2.37.3


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream
  2022-09-04 18:47 [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes Philipp Fent
@ 2022-09-04 18:47 ` Philipp Fent
  2022-09-06 11:27   ` Jonathan Wakely
  2022-09-06  1:06 ` [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes Will Hawkins
  1 sibling, 1 reply; 8+ messages in thread
From: Philipp Fent @ 2022-09-04 18:47 UTC (permalink / raw)
  To: libstdc++, gcc-patches; +Cc: Philipp Fent

Signed-off-by: Philipp Fent <fent@in.tum.de>
---
 libstdc++-v3/python/libstdcxx/v6/printers.py  | 37 +++++++++++++++++++
 .../libstdc++-prettyprinters/debug.cc         |  5 +++
 .../libstdc++-prettyprinters/simple.cc        |  5 +++
 .../libstdc++-prettyprinters/simple11.cc      |  5 +++
 4 files changed, 52 insertions(+)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index d70c8d5d616..5083f693387 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -969,6 +969,39 @@ class StdStringPrinter:
     def display_hint (self):
         return 'string'
 
+class StdStringBufPrinter:
+    "Print a std::basic_stringbuf"
+
+    def __init__(self, _, val):
+        self.val = val
+
+    def to_string(self):
+        pbase = self.val['_M_out_beg']
+        pptr = self.val['_M_out_cur']
+        egptr = self.val['_M_in_end']
+        # Logic from basic_stringbuf::_M_high_mark()
+        if pptr:
+            if not egptr or pptr > egptr:
+                return pbase.string(length = pptr - pbase)
+            else:
+                return pbase.string(length = pptr - egptr)
+        return self.val['_M_string']
+
+    def display_hint(self):
+        return 'string'
+
+class StdStringStreamPrinter:
+    "Print a std::basic_stringstream"
+
+    def __init__(self, _, val):
+        self.val = val
+
+    def to_string(self):
+        return self.val['_M_stringbuf']
+
+    def display_hint(self):
+        return 'string'
+
 class Tr1HashtableIterator(Iterator):
     def __init__ (self, hashtable):
         self.buckets = hashtable['_M_buckets']
@@ -2232,6 +2265,10 @@ def build_libstdcxx_dictionary ():
     libstdcxx_printer.add_version('std::', 'initializer_list',
                                   StdInitializerListPrinter)
     libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter)
+    libstdcxx_printer.add_version('std::', 'basic_stringbuf', StdStringBufPrinter)
+    libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringbuf', StdStringBufPrinter)
+    libstdcxx_printer.add_version('std::', 'basic_stringstream', StdStringStreamPrinter)
+    libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringstream', StdStringStreamPrinter)
 
     # std::regex components
     libstdcxx_printer.add_version('std::__detail::', '_State',
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
index 98bbc182551..7efec6d0f8b 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
@@ -29,6 +29,7 @@
 #include <list>
 #include <map>
 #include <set>
+#include <sstream>
 #include <vector>
 #include <ext/slist>
 
@@ -110,6 +111,10 @@ main()
   __gnu_cxx::slist<int>::iterator slliter = sll.begin();
 // { dg-final { note-test slliter {47} } }
 
+  std::stringstream sstream;
+  sstream << "abc";
+// { dg-final { note-test sstream "\"abc\"" } }
+
   std::cout << "\n";
   return 0;			// Mark SPOT
 }
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
index 1f85775bff0..584989ce09f 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
@@ -30,6 +30,7 @@
 #include <list>
 #include <map>
 #include <set>
+#include <sstream>
 #include <vector>
 #include <ext/slist>
 
@@ -169,6 +170,10 @@ main()
   __gnu_cxx::slist<int>::iterator slliter0;
 // { dg-final { note-test slliter0 {non-dereferenceable iterator for __gnu_cxx::slist} } }
 
+  std::stringstream sstream;
+  sstream << "abc";
+// { dg-final { note-test sstream "\"abc\"" } }
+
   std::cout << "\n";
   return 0;			// Mark SPOT
 }
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
index 6f21675cf41..6edd7e929fe 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
@@ -30,6 +30,7 @@
 #include <list>
 #include <map>
 #include <set>
+#include <sstream>
 #include <vector>
 #include <ext/slist>
 
@@ -162,6 +163,10 @@ main()
   __gnu_cxx::slist<int>::iterator slliter0;
 // { dg-final { note-test slliter0 {non-dereferenceable iterator for __gnu_cxx::slist} } }
 
+  std::stringstream sstream;
+  sstream << "abc";
+// { dg-final { note-test sstream "\"abc\"" } }
+
   std::cout << "\n";
   return 0;			// Mark SPOT
 }
-- 
2.37.3


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes
  2022-09-04 18:47 [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes Philipp Fent
  2022-09-04 18:47 ` [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream Philipp Fent
@ 2022-09-06  1:06 ` Will Hawkins
  2022-09-06 11:12   ` Jonathan Wakely
  1 sibling, 1 reply; 8+ messages in thread
From: Will Hawkins @ 2022-09-06  1:06 UTC (permalink / raw)
  To: Philipp Fent; +Cc: libstdc++, gcc-patches

Confirming that patch 1 of 2 *does* fix the failing tests here (x86-64).

Will

PS: Please tell me if emails like this are helpful or not. Just trying to help!

On Sun, Sep 4, 2022 at 2:48 PM Philipp Fent via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> Signed-off-by: Philipp Fent <fent@in.tum.de>
> ---
>  libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc | 2 +-
>  libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
> index cc91803e247..af335d0d3c7 100644
> --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
> +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
> @@ -29,7 +29,7 @@ main()
>  // { dg-final { note-test t1 {empty std::tuple} } }
>
>    std::tuple<std::string, int, std::tuple<>> t2{ "Johnny", 5, {} };
> -// { dg-final { regexp-test t2 {std::tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = empty std::tuple}} } }
> +// { dg-final { regexp-test t2 {std::tuple containing = {\[0\] = "Johnny", \[1\] = 5, \[2\] = empty std::tuple}} } }
>
>    std::cout << "\n";
>    return 0; // Mark SPOT
> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> index f97640a0189..bc5978ee69d 100644
> --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> @@ -166,9 +166,9 @@ main()
>  // { dg-final { note-test runiq_ptr {std::unique_ptr<int> = {get() = 0x0}} } }
>
>    ExTuple tpl(6,7);
> -// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
> +// { dg-final { note-test tpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
>    ExTuple &rtpl = tpl;
> -// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
> +// { dg-final { note-test rtpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
>
>    std::error_code e0;
>    // { dg-final { note-test e0 {std::error_code = { }} } }
> --
> 2.37.3
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes
  2022-09-06  1:06 ` [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes Will Hawkins
@ 2022-09-06 11:12   ` Jonathan Wakely
  0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Wakely @ 2022-09-06 11:12 UTC (permalink / raw)
  To: Will Hawkins; +Cc: Philipp Fent, libstdc++, gcc-patches

On Tue, 6 Sept 2022 at 02:07, Will Hawkins <hawkinsw@obs.cr> wrote:
>
> Confirming that patch 1 of 2 *does* fix the failing tests here (x86-64).
>
> Will
>
> PS: Please tell me if emails like this are helpful or not. Just trying to help!

Thanks. I wasn't even seeing the failing tests, due to errors from GDB:

Dwarf Error: wrong version in compilation unit header (is 5, should be
2, 3, or 4) [in module
/home/jwakely/build/powerpc64le-unknown-linux-gnu/lib
stdc++-v3/testsuite/cxx11.exe

This meant they were UNSUPPORTED on my test machine.

I've pushed Philipp's [PATCH 1/2] now. Thank you both.


>
> On Sun, Sep 4, 2022 at 2:48 PM Philipp Fent via Libstdc++
> <libstdc++@gcc.gnu.org> wrote:
> >
> > Signed-off-by: Philipp Fent <fent@in.tum.de>
> > ---
> >  libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc | 2 +-
> >  libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc | 4 ++--
> >  2 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
> > index cc91803e247..af335d0d3c7 100644
> > --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
> > +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
> > @@ -29,7 +29,7 @@ main()
> >  // { dg-final { note-test t1 {empty std::tuple} } }
> >
> >    std::tuple<std::string, int, std::tuple<>> t2{ "Johnny", 5, {} };
> > -// { dg-final { regexp-test t2 {std::tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = empty std::tuple}} } }
> > +// { dg-final { regexp-test t2 {std::tuple containing = {\[0\] = "Johnny", \[1\] = 5, \[2\] = empty std::tuple}} } }
> >
> >    std::cout << "\n";
> >    return 0; // Mark SPOT
> > diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> > index f97640a0189..bc5978ee69d 100644
> > --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> > +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> > @@ -166,9 +166,9 @@ main()
> >  // { dg-final { note-test runiq_ptr {std::unique_ptr<int> = {get() = 0x0}} } }
> >
> >    ExTuple tpl(6,7);
> > -// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
> > +// { dg-final { note-test tpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
> >    ExTuple &rtpl = tpl;
> > -// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
> > +// { dg-final { note-test rtpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
> >
> >    std::error_code e0;
> >    // { dg-final { note-test e0 {std::error_code = { }} } }
> > --
> > 2.37.3
> >
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream
  2022-09-04 18:47 ` [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream Philipp Fent
@ 2022-09-06 11:27   ` Jonathan Wakely
  2022-09-06 21:24     ` [PATCH v2] libstdc++: Add pretty printer for std::stringstreams Philipp Fent
  2022-09-12  8:37     ` [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream Philipp Fent
  0 siblings, 2 replies; 8+ messages in thread
From: Jonathan Wakely @ 2022-09-06 11:27 UTC (permalink / raw)
  To: Philipp Fent; +Cc: libstdc++, gcc-patches

Thanks for the patch. Comments below.


On Sun, 4 Sept 2022 at 19:48, Philipp Fent via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> Signed-off-by: Philipp Fent <fent@in.tum.de>
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py  | 37 +++++++++++++++++++
>  .../libstdc++-prettyprinters/debug.cc         |  5 +++
>  .../libstdc++-prettyprinters/simple.cc        |  5 +++
>  .../libstdc++-prettyprinters/simple11.cc      |  5 +++
>  4 files changed, 52 insertions(+)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index d70c8d5d616..5083f693387 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -969,6 +969,39 @@ class StdStringPrinter:
>      def display_hint (self):
>          return 'string'
>
> +class StdStringBufPrinter:
> +    "Print a std::basic_stringbuf"
> +
> +    def __init__(self, _, val):
> +        self.val = val
> +
> +    def to_string(self):
> +        pbase = self.val['_M_out_beg']
> +        pptr = self.val['_M_out_cur']
> +        egptr = self.val['_M_in_end']

It would be nice to encapsulate this into a generic helper for all
streambufs, as this part isn't specific to basic_stringbuf. We could
then reuse it for printing spanbufs and other types in future. It
could be a function that takes a streambuf and returns a tuple of
(pbase, pptr, egptr).

> +        # Logic from basic_stringbuf::_M_high_mark()
> +        if pptr:
> +            if not egptr or pptr > egptr:
> +                return pbase.string(length = pptr - pbase)
> +            else:
> +                return pbase.string(length = pptr - egptr)

Shouldn't this be egptr - pbase?

This suggests the tests are inadequate. I think this bug would have
been found by a test something like:

std::stringstream ssin("input", std::ios::in);
// { dg-final { note-test ssin "\"input\"" } }

The (egptr - pbase) case is also needed for printing an istringstream.

> +        return self.val['_M_string']
> +
> +    def display_hint(self):
> +        return 'string'
> +
> +class StdStringStreamPrinter:
> +    "Print a std::basic_stringstream"
> +
> +    def __init__(self, _, val):
> +        self.val = val
> +
> +    def to_string(self):
> +        return self.val['_M_stringbuf']

This assumes that the stream is still using its stringbuf, which is
probably true 99% of the time, but isn't guaranteed. In the following
situation, the printer would give potentially misleading output:

std::stringstream ss("xxx");
ss.rdbuf(std::cin.rdbuf());

I wonder if we want to have a check that self.val['_M_streambuf'] ==
self.val['_M_stringbuf'].address

Alternatively, don't provide a printer for the stringstream at all,
just for the stringbuf, and then when GDB uses its default display for
the stringstream it will show that member.


> +
> +    def display_hint(self):
> +        return 'string'
> +
>  class Tr1HashtableIterator(Iterator):
>      def __init__ (self, hashtable):
>          self.buckets = hashtable['_M_buckets']
> @@ -2232,6 +2265,10 @@ def build_libstdcxx_dictionary ():
>      libstdcxx_printer.add_version('std::', 'initializer_list',
>                                    StdInitializerListPrinter)
>      libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter)
> +    libstdcxx_printer.add_version('std::', 'basic_stringbuf', StdStringBufPrinter)
> +    libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringbuf', StdStringBufPrinter)
> +    libstdcxx_printer.add_version('std::', 'basic_stringstream', StdStringStreamPrinter)
> +    libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringstream', StdStringStreamPrinter)

Wouldn't we want it for ostringstream and istringstream too?


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2] libstdc++: Add pretty printer for std::stringstreams
  2022-09-06 11:27   ` Jonathan Wakely
@ 2022-09-06 21:24     ` Philipp Fent
  2022-09-14 12:45       ` Jonathan Wakely
  2022-09-12  8:37     ` [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream Philipp Fent
  1 sibling, 1 reply; 8+ messages in thread
From: Philipp Fent @ 2022-09-06 21:24 UTC (permalink / raw)
  To: jwakely; +Cc: libstdc++, gcc-patches, Philipp Fent

To display (o-,i-)stringstreams in the common case, we just print the
underlying stringbuf, without the many ios_base members. In the
unconventional case that the underlying streambuf was redirected, we
report the redirected target.

Signed-off-by: Philipp Fent <fent@in.tum.de>
---
 libstdc++-v3/python/libstdcxx/v6/printers.py  | 56 +++++++++++++++++++
 .../libstdc++-prettyprinters/debug.cc         | 15 +++++
 .../libstdc++-prettyprinters/simple.cc        | 15 +++++
 .../libstdc++-prettyprinters/simple11.cc      | 15 +++++
 4 files changed, 101 insertions(+)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index d70c8d5d616..bd4289c1c62 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -969,6 +969,57 @@ class StdStringPrinter:
     def display_hint (self):
         return 'string'
 
+def access_streambuf_ptrs(streambuf):
+    "Access the streambuf put area pointers"
+    pbase = streambuf['_M_out_beg']
+    pptr = streambuf['_M_out_cur']
+    egptr = streambuf['_M_in_end']
+    return pbase, pptr, egptr
+
+class StdStringBufPrinter:
+    "Print a std::basic_stringbuf"
+
+    def __init__(self, _, val):
+        self.val = val
+
+    def to_string(self):
+        (pbase, pptr, egptr) = access_streambuf_ptrs(self.val)
+        # Logic from basic_stringbuf::_M_high_mark()
+        if pptr:
+            if not egptr or pptr > egptr:
+                return pbase.string(length = pptr - pbase)
+            else:
+                return pbase.string(length = egptr - pbase)
+        return self.val['_M_string']
+
+    def display_hint(self):
+        return 'string'
+
+class StdStringStreamPrinter:
+    "Print a std::basic_stringstream"
+
+    def __init__(self, typename, val):
+        self.val = val
+        self.typename = typename
+
+        # Check if the stream was redirected:
+        # This is essentially: val['_M_streambuf'] == val['_M_stringbuf'].address
+        # However, GDB can't resolve the virtual inheritance, so we do that manually
+        basetype = [f.type for f in val.type.fields() if f.is_base_class][0]
+        gdb.set_convenience_variable('__stream', val.cast(basetype).address)
+        self.streambuf = gdb.parse_and_eval('$__stream->rdbuf()')
+        self.was_redirected = self.streambuf != val['_M_stringbuf'].address
+
+    def to_string(self):
+        if self.was_redirected:
+            return "%s redirected to %s" % (self.typename, self.streambuf.dereference())
+        return self.val['_M_stringbuf']
+
+    def display_hint(self):
+        if self.was_redirected:
+            return None
+        return 'string'
+
 class Tr1HashtableIterator(Iterator):
     def __init__ (self, hashtable):
         self.buckets = hashtable['_M_buckets']
@@ -2232,6 +2283,11 @@ def build_libstdcxx_dictionary ():
     libstdcxx_printer.add_version('std::', 'initializer_list',
                                   StdInitializerListPrinter)
     libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter)
+    libstdcxx_printer.add_version('std::', 'basic_stringbuf', StdStringBufPrinter)
+    libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringbuf', StdStringBufPrinter)
+    for sstream in ('istringstream', 'ostringstream', 'stringstream'):
+        libstdcxx_printer.add_version('std::', 'basic_' + sstream, StdStringStreamPrinter)
+        libstdcxx_printer.add_version('std::__cxx11::', 'basic_' + sstream, StdStringStreamPrinter)
 
     # std::regex components
     libstdcxx_printer.add_version('std::__detail::', '_State',
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
index 98bbc182551..3c6195591c5 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
@@ -29,6 +29,7 @@
 #include <list>
 #include <map>
 #include <set>
+#include <sstream>
 #include <vector>
 #include <ext/slist>
 
@@ -110,6 +111,20 @@ main()
   __gnu_cxx::slist<int>::iterator slliter = sll.begin();
 // { dg-final { note-test slliter {47} } }
 
+  std::stringstream sstream;
+  sstream << "abc";
+// { dg-final { note-test sstream "\"abc\"" } }
+  std::stringstream ssin("input", std::ios::in);
+// { dg-final { note-test ssin "\"input\"" } }
+  std::istringstream ssin2("input");
+// { dg-final { note-test ssin2 "\"input\"" } }
+  std::ostringstream ssout;
+  ssout << "out";
+// { dg-final { note-test ssout "\"out\"" } }
+  std::stringstream redirected("xxx");
+  static_cast<std::basic_ios<std::stringstream::char_type>&>(redirected).rdbuf(sstream.rdbuf());
+// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } }
+
   std::cout << "\n";
   return 0;			// Mark SPOT
 }
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
index 1f85775bff0..1609ae2c8db 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
@@ -30,6 +30,7 @@
 #include <list>
 #include <map>
 #include <set>
+#include <sstream>
 #include <vector>
 #include <ext/slist>
 
@@ -169,6 +170,20 @@ main()
   __gnu_cxx::slist<int>::iterator slliter0;
 // { dg-final { note-test slliter0 {non-dereferenceable iterator for __gnu_cxx::slist} } }
 
+  std::stringstream sstream;
+  sstream << "abc";
+// { dg-final { note-test sstream "\"abc\"" } }
+  std::stringstream ssin("input", std::ios::in);
+// { dg-final { note-test ssin "\"input\"" } }
+  std::istringstream ssin2("input");
+// { dg-final { note-test ssin2 "\"input\"" } }
+  std::ostringstream ssout;
+  ssout << "out";
+// { dg-final { note-test ssout "\"out\"" } }
+  std::stringstream redirected("xxx");
+  static_cast<std::basic_ios<std::stringstream::char_type>&>(redirected).rdbuf(sstream.rdbuf());
+// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } }
+
   std::cout << "\n";
   return 0;			// Mark SPOT
 }
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
index 6f21675cf41..a4b82e30f9c 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
@@ -30,6 +30,7 @@
 #include <list>
 #include <map>
 #include <set>
+#include <sstream>
 #include <vector>
 #include <ext/slist>
 
@@ -162,6 +163,20 @@ main()
   __gnu_cxx::slist<int>::iterator slliter0;
 // { dg-final { note-test slliter0 {non-dereferenceable iterator for __gnu_cxx::slist} } }
 
+  std::stringstream sstream;
+  sstream << "abc";
+// { dg-final { note-test sstream "\"abc\"" } }
+  std::stringstream ssin("input", std::ios::in);
+// { dg-final { note-test ssin "\"input\"" } }
+  std::istringstream ssin2("input");
+// { dg-final { note-test ssin2 "\"input\"" } }
+  std::ostringstream ssout;
+  ssout << "out";
+// { dg-final { note-test ssout "\"out\"" } }
+  std::stringstream redirected("xxx");
+  static_cast<std::basic_ios<std::stringstream::char_type>&>(redirected).rdbuf(sstream.rdbuf());
+// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } }
+
   std::cout << "\n";
   return 0;			// Mark SPOT
 }
-- 
2.37.3


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream
  2022-09-06 11:27   ` Jonathan Wakely
  2022-09-06 21:24     ` [PATCH v2] libstdc++: Add pretty printer for std::stringstreams Philipp Fent
@ 2022-09-12  8:37     ` Philipp Fent
  1 sibling, 0 replies; 8+ messages in thread
From: Philipp Fent @ 2022-09-12  8:37 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

Hi Jonathan,

I've sent an updated patch addressing your comments here:
https://gcc.gnu.org/pipermail/libstdc++/2022-September/054587.html

Details below.

On 06.09.22 13:27, Jonathan Wakely wrote:
>> +        pbase = self.val['_M_out_beg']
>> +        pptr = self.val['_M_out_cur']
>> +        egptr = self.val['_M_in_end']
> 
> It would be nice to encapsulate this into a generic helper for all
> streambufs, as this part isn't specific to basic_stringbuf. We could
> then reuse it for printing spanbufs and other types in future. It
> could be a function that takes a streambuf and returns a tuple of
> (pbase, pptr, egptr).

I factored this into a reusable access_streambuf_ptrs().

>> +        # Logic from basic_stringbuf::_M_high_mark()
>> +        if pptr:
>> +            if not egptr or pptr > egptr:
>> +                return pbase.string(length = pptr - pbase)
>> +            else:
>> +                return pbase.string(length = pptr - egptr)
> 
> Shouldn't this be egptr - pbase?
> 
> This suggests the tests are inadequate. I think this bug would have
> been found by a test something like:
> 
> std::stringstream ssin("input", std::ios::in);
> // { dg-final { note-test ssin "\"input\"" } }
> 
> The (egptr - pbase) case is also needed for printing an istringstream.

Good catch! I fixed that bug and added a test for this in the testsuite.

> 
>> +        return self.val['_M_string']
>> +
>> +    def display_hint(self):
>> +        return 'string'
>> +
>> +class StdStringStreamPrinter:
>> +    "Print a std::basic_stringstream"
>> +
>> +    def __init__(self, _, val):
>> +        self.val = val
>> +
>> +    def to_string(self):
>> +        return self.val['_M_stringbuf']
> 
> This assumes that the stream is still using its stringbuf, which is
> probably true 99% of the time, but isn't guaranteed. In the following
> situation, the printer would give potentially misleading output:
> 
> std::stringstream ss("xxx");
> ss.rdbuf(std::cin.rdbuf());
> 
> I wonder if we want to have a check that self.val['_M_streambuf'] ==
> self.val['_M_stringbuf'].address
> 
> Alternatively, don't provide a printer for the stringstream at all,
> just for the stringbuf, and then when GDB uses its default display for
> the stringstream it will show that member.

I didn't know one could redirect a stringstream, since its rdbuf() 
method hides the basic_ios rdbuf() methods. But of course, that's still 
possible via the base class...
The Patch v2 checks that case in the StdStringStreamPrinter constructor, 
and follows that redirect in to_string().

> 
>> +
>> +    def display_hint(self):
>> +        return 'string'
>> +
>>   class Tr1HashtableIterator(Iterator):
>>       def __init__ (self, hashtable):
>>           self.buckets = hashtable['_M_buckets']
>> @@ -2232,6 +2265,10 @@ def build_libstdcxx_dictionary ():
>>       libstdcxx_printer.add_version('std::', 'initializer_list',
>>                                     StdInitializerListPrinter)
>>       libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter)
>> +    libstdcxx_printer.add_version('std::', 'basic_stringbuf', StdStringBufPrinter)
>> +    libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringbuf', StdStringBufPrinter)
>> +    libstdcxx_printer.add_version('std::', 'basic_stringstream', StdStringStreamPrinter)
>> +    libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringstream', StdStringStreamPrinter)
> 
> Wouldn't we want it for ostringstream and istringstream too?

Indeed. The updated patch registers the pretty printer for all flavors.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] libstdc++: Add pretty printer for std::stringstreams
  2022-09-06 21:24     ` [PATCH v2] libstdc++: Add pretty printer for std::stringstreams Philipp Fent
@ 2022-09-14 12:45       ` Jonathan Wakely
  0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Wakely @ 2022-09-14 12:45 UTC (permalink / raw)
  To: Philipp Fent; +Cc: libstdc++, gcc-patches

On Tue, 6 Sept 2022 at 22:25, Philipp Fent <fent@in.tum.de> wrote:
>
> To display (o-,i-)stringstreams in the common case, we just print the
> underlying stringbuf, without the many ios_base members. In the
> unconventional case that the underlying streambuf was redirected, we
> report the redirected target.
>
> Signed-off-by: Philipp Fent <fent@in.tum.de>
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py  | 56 +++++++++++++++++++
>  .../libstdc++-prettyprinters/debug.cc         | 15 +++++
>  .../libstdc++-prettyprinters/simple.cc        | 15 +++++
>  .../libstdc++-prettyprinters/simple11.cc      | 15 +++++
>  4 files changed, 101 insertions(+)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index d70c8d5d616..bd4289c1c62 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -969,6 +969,57 @@ class StdStringPrinter:
>      def display_hint (self):
>          return 'string'
>
> +def access_streambuf_ptrs(streambuf):
> +    "Access the streambuf put area pointers"
> +    pbase = streambuf['_M_out_beg']
> +    pptr = streambuf['_M_out_cur']
> +    egptr = streambuf['_M_in_end']
> +    return pbase, pptr, egptr
> +
> +class StdStringBufPrinter:
> +    "Print a std::basic_stringbuf"
> +
> +    def __init__(self, _, val):
> +        self.val = val
> +
> +    def to_string(self):
> +        (pbase, pptr, egptr) = access_streambuf_ptrs(self.val)
> +        # Logic from basic_stringbuf::_M_high_mark()
> +        if pptr:
> +            if not egptr or pptr > egptr:
> +                return pbase.string(length = pptr - pbase)
> +            else:
> +                return pbase.string(length = egptr - pbase)
> +        return self.val['_M_string']
> +
> +    def display_hint(self):
> +        return 'string'
> +
> +class StdStringStreamPrinter:
> +    "Print a std::basic_stringstream"
> +
> +    def __init__(self, typename, val):
> +        self.val = val
> +        self.typename = typename
> +
> +        # Check if the stream was redirected:
> +        # This is essentially: val['_M_streambuf'] == val['_M_stringbuf'].address
> +        # However, GDB can't resolve the virtual inheritance, so we do that manually

Oh yuck, sorry you had to figure that out.

The patch looks good, thanks. I'll get it pushed to trunk.


> +        basetype = [f.type for f in val.type.fields() if f.is_base_class][0]
> +        gdb.set_convenience_variable('__stream', val.cast(basetype).address)
> +        self.streambuf = gdb.parse_and_eval('$__stream->rdbuf()')
> +        self.was_redirected = self.streambuf != val['_M_stringbuf'].address
> +
> +    def to_string(self):
> +        if self.was_redirected:
> +            return "%s redirected to %s" % (self.typename, self.streambuf.dereference())
> +        return self.val['_M_stringbuf']
> +
> +    def display_hint(self):
> +        if self.was_redirected:
> +            return None
> +        return 'string'
> +
>  class Tr1HashtableIterator(Iterator):
>      def __init__ (self, hashtable):
>          self.buckets = hashtable['_M_buckets']
> @@ -2232,6 +2283,11 @@ def build_libstdcxx_dictionary ():
>      libstdcxx_printer.add_version('std::', 'initializer_list',
>                                    StdInitializerListPrinter)
>      libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter)
> +    libstdcxx_printer.add_version('std::', 'basic_stringbuf', StdStringBufPrinter)
> +    libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringbuf', StdStringBufPrinter)
> +    for sstream in ('istringstream', 'ostringstream', 'stringstream'):
> +        libstdcxx_printer.add_version('std::', 'basic_' + sstream, StdStringStreamPrinter)
> +        libstdcxx_printer.add_version('std::__cxx11::', 'basic_' + sstream, StdStringStreamPrinter)
>
>      # std::regex components
>      libstdcxx_printer.add_version('std::__detail::', '_State',
> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
> index 98bbc182551..3c6195591c5 100644
> --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
> +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
> @@ -29,6 +29,7 @@
>  #include <list>
>  #include <map>
>  #include <set>
> +#include <sstream>
>  #include <vector>
>  #include <ext/slist>
>
> @@ -110,6 +111,20 @@ main()
>    __gnu_cxx::slist<int>::iterator slliter = sll.begin();
>  // { dg-final { note-test slliter {47} } }
>
> +  std::stringstream sstream;
> +  sstream << "abc";
> +// { dg-final { note-test sstream "\"abc\"" } }
> +  std::stringstream ssin("input", std::ios::in);
> +// { dg-final { note-test ssin "\"input\"" } }
> +  std::istringstream ssin2("input");
> +// { dg-final { note-test ssin2 "\"input\"" } }
> +  std::ostringstream ssout;
> +  ssout << "out";
> +// { dg-final { note-test ssout "\"out\"" } }
> +  std::stringstream redirected("xxx");
> +  static_cast<std::basic_ios<std::stringstream::char_type>&>(redirected).rdbuf(sstream.rdbuf());
> +// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } }
> +
>    std::cout << "\n";
>    return 0;                    // Mark SPOT
>  }
> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
> index 1f85775bff0..1609ae2c8db 100644
> --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
> +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
> @@ -30,6 +30,7 @@
>  #include <list>
>  #include <map>
>  #include <set>
> +#include <sstream>
>  #include <vector>
>  #include <ext/slist>
>
> @@ -169,6 +170,20 @@ main()
>    __gnu_cxx::slist<int>::iterator slliter0;
>  // { dg-final { note-test slliter0 {non-dereferenceable iterator for __gnu_cxx::slist} } }
>
> +  std::stringstream sstream;
> +  sstream << "abc";
> +// { dg-final { note-test sstream "\"abc\"" } }
> +  std::stringstream ssin("input", std::ios::in);
> +// { dg-final { note-test ssin "\"input\"" } }
> +  std::istringstream ssin2("input");
> +// { dg-final { note-test ssin2 "\"input\"" } }
> +  std::ostringstream ssout;
> +  ssout << "out";
> +// { dg-final { note-test ssout "\"out\"" } }
> +  std::stringstream redirected("xxx");
> +  static_cast<std::basic_ios<std::stringstream::char_type>&>(redirected).rdbuf(sstream.rdbuf());
> +// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } }
> +
>    std::cout << "\n";
>    return 0;                    // Mark SPOT
>  }
> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
> index 6f21675cf41..a4b82e30f9c 100644
> --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
> +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
> @@ -30,6 +30,7 @@
>  #include <list>
>  #include <map>
>  #include <set>
> +#include <sstream>
>  #include <vector>
>  #include <ext/slist>
>
> @@ -162,6 +163,20 @@ main()
>    __gnu_cxx::slist<int>::iterator slliter0;
>  // { dg-final { note-test slliter0 {non-dereferenceable iterator for __gnu_cxx::slist} } }
>
> +  std::stringstream sstream;
> +  sstream << "abc";
> +// { dg-final { note-test sstream "\"abc\"" } }
> +  std::stringstream ssin("input", std::ios::in);
> +// { dg-final { note-test ssin "\"input\"" } }
> +  std::istringstream ssin2("input");
> +// { dg-final { note-test ssin2 "\"input\"" } }
> +  std::ostringstream ssout;
> +  ssout << "out";
> +// { dg-final { note-test ssout "\"out\"" } }
> +  std::stringstream redirected("xxx");
> +  static_cast<std::basic_ios<std::stringstream::char_type>&>(redirected).rdbuf(sstream.rdbuf());
> +// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } }
> +
>    std::cout << "\n";
>    return 0;                    // Mark SPOT
>  }
> --
> 2.37.3
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-09-14 12:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-04 18:47 [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes Philipp Fent
2022-09-04 18:47 ` [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream Philipp Fent
2022-09-06 11:27   ` Jonathan Wakely
2022-09-06 21:24     ` [PATCH v2] libstdc++: Add pretty printer for std::stringstreams Philipp Fent
2022-09-14 12:45       ` Jonathan Wakely
2022-09-12  8:37     ` [PATCH 2/2] libstdc++: Add pretty printer for std::stringstream Philipp Fent
2022-09-06  1:06 ` [PATCH 1/2] libstdc++: Fix pretty printer tests of tuple indexes Will Hawkins
2022-09-06 11:12   ` Jonathan Wakely

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).