public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jonathan Wakely <jwakely@redhat.com>
To: Philipp Fent <fent@in.tum.de>
Cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH v2] libstdc++: Add pretty printer for std::stringstreams
Date: Wed, 14 Sep 2022 13:45:56 +0100	[thread overview]
Message-ID: <CACb0b4nSJFYZX0eU+3p8oJUzL9NQPGbdyHtGKkFL_BM_Jw+scg@mail.gmail.com> (raw)
In-Reply-To: <20220906212429.42986-1-fent@in.tum.de>

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
>


  reply	other threads:[~2022-09-14 12:46 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

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=CACb0b4nSJFYZX0eU+3p8oJUzL9NQPGbdyHtGKkFL_BM_Jw+scg@mail.gmail.com \
    --to=jwakely@redhat.com \
    --cc=fent@in.tum.de \
    --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).