From 627ff08d23e64868fce2ce67410507d88a417b73 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 14 Mar 2023 17:49:36 +0800 Subject: [PATCH 01/11] - fix: The comboxbox to input search keyword in the search dialog is case insensitive. - fix: The comboxbox to input replace text in the search dialog is case insensitive. - fix: The comboxbox to input search keyword in the search in files dialog is case insensitive. - fix: The comboxbox to input address expression in the debug panel's memory view is case insensitive. - fix: The comboxbox to input evaluation expression in the debug panel is case insensitive. - fix: The comboxbox to input replace text in the search panel is case insensitive. --- NEWS.md | 6 ++++++ RedPandaIDE/mainwindow.cpp | 6 ++++++ RedPandaIDE/mainwindow.ui | 5 ++--- RedPandaIDE/widgets/searchdialog.cpp | 3 +++ RedPandaIDE/widgets/searchinfiledialog.cpp | 3 +++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 35151a6f..c62d08da 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,12 @@ Red Panda C++ Version 2.18 - enhancement: Options in compiler set settings, to generate syntax error for large stack objects. (Enable for Debug settings by default) - enhancement: Options in compiler set settings, to generate protection code for stack smashing attack. (Enable for Debug settings by default) - enhancement: Options in compiler set settings, to enable address sanitizer. Not available in windows.(Enable for Debug settings by default) + - fix: The comboxbox to input search keyword in the search dialog is case insensitive. + - fix: The comboxbox to input replace text in the search dialog is case insensitive. + - fix: The comboxbox to input search keyword in the search in files dialog is case insensitive. + - fix: The comboxbox to input address expression in the debug panel's memory view is case insensitive. + - fix: The comboxbox to input evaluation expression in the debug panel is case insensitive. + - fix: The comboxbox to input replace text in the search panel is case insensitive. Red Panda C++ Version 2.17 diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 0d985370..198da6ed 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -77,6 +77,7 @@ #include #include #include +#include #include "mainwindow.h" #include @@ -260,6 +261,11 @@ MainWindow::MainWindow(QWidget *parent) // updateEditorActions(); // updateCaretActions(); + ui->cbReplaceInHistory->completer()->setCaseSensitivity(Qt::CaseSensitive); + ui->cbEvaluate->completer()->setCaseSensitivity(Qt::CaseSensitive); + ui->cbMemoryAddress->completer()->setCaseSensitivity(Qt::CaseSensitive); + ui->cbFilesPath->completer()->setCaseSensitivity(Qt::CaseInsensitive); + connect(ui->debugConsole,&QConsole::commandInput,this,&MainWindow::onDebugCommandInput); connect(ui->cbEvaluate->lineEdit(), &QLineEdit::returnPressed, this, &MainWindow::onDebugEvaluateInput); diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index 7901310b..3da4f4e7 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -487,7 +487,7 @@ QTabWidget::West - 1 + 0 true @@ -971,7 +971,6 @@ - 50 false @@ -1133,7 +1132,7 @@ QTabWidget::North - 1 + 2 diff --git a/RedPandaIDE/widgets/searchdialog.cpp b/RedPandaIDE/widgets/searchdialog.cpp index 45d5dee6..061d3ab3 100644 --- a/RedPandaIDE/widgets/searchdialog.cpp +++ b/RedPandaIDE/widgets/searchdialog.cpp @@ -1,6 +1,7 @@ #include "searchdialog.h" #include "ui_searchdialog.h" +#include #include #include #include @@ -29,6 +30,8 @@ SearchDialog::SearchDialog(QWidget *parent) : onTabBarCurrentChanged(mSearchTabIdx); mBasicSearchEngine = std::make_shared(); mRegexSearchEngine = std::make_shared(); + ui->cbFind->completer()->setCaseSensitivity(Qt::CaseSensitive); + ui->cbReplace->completer()->setCaseSensitivity(Qt::CaseSensitive); } SearchDialog::~SearchDialog() diff --git a/RedPandaIDE/widgets/searchinfiledialog.cpp b/RedPandaIDE/widgets/searchinfiledialog.cpp index 276edd05..61615a2d 100644 --- a/RedPandaIDE/widgets/searchinfiledialog.cpp +++ b/RedPandaIDE/widgets/searchinfiledialog.cpp @@ -27,6 +27,7 @@ #include #include #include +#include SearchInFileDialog::SearchInFileDialog(QWidget *parent) : @@ -38,6 +39,8 @@ SearchInFileDialog::SearchInFileDialog(QWidget *parent) : mSearchOptions&=0; mBasicSearchEngine= QSynedit::PSynSearchBase(new QSynedit::BasicSearcher()); mRegexSearchEngine= QSynedit::PSynSearchBase(new QSynedit::RegexSearcher()); + ui->cbFind->completer()->setCaseSensitivity(Qt::CaseSensitive); + } SearchInFileDialog::~SearchInFileDialog() From e8a3c6b4bc38241865020b52947b9f461710a688 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Wed, 15 Mar 2023 15:37:28 +0800 Subject: [PATCH 02/11] typo in translations --- RedPandaIDE/translations/RedPandaIDE_zh_CN.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts index a037ef31..8335071e 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts @@ -3220,7 +3220,7 @@ Are you really want to continue? Insert empty lines around all blocks Insert empy lines around all blocks - 在所有代码段之间加入空格 + 在所有代码段之间加入空行 From 5e5f5a11225bd31a335453c1f8a9ebdc019ca5fa Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 16 Mar 2023 17:06:48 +0800 Subject: [PATCH 03/11] add gdb scripts for gcc 11.2 stl types --- .../gcc-11.2.0/python/libstdcxx/__init__.py | 1 + .../gcc-11.2.0/python/libstdcxx/__init__.pyc | Bin 0 -> 163 bytes .../python/libstdcxx/v6/__init__.py | 33 + .../python/libstdcxx/v6/__init__.pyc | Bin 0 -> 863 bytes .../python/libstdcxx/v6/printers.py | 2032 +++++++++++++++++ .../python/libstdcxx/v6/printers.pyc | Bin 0 -> 85322 bytes .../python/libstdcxx/v6/xmethods.py | 805 +++++++ 7 files changed, 2871 insertions(+) create mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/__init__.py create mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/__init__.pyc create mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.py create mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.pyc create mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.py create mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.pyc create mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/xmethods.py diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/__init__.py b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/__init__.py @@ -0,0 +1 @@ + diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/__init__.pyc b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be2fb0be29ae78269f26e2902fbb450c82980e5e GIT binary patch literal 163 zcmZSn%*!=z>ZHVE1}In0QWRQgKO2az%xHe0*kJW=VX! Y9#97d&_J8q{FKt1R6CHhB|yvo05p9iH~;_u literal 0 HcmV?d00001 diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.py b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.py new file mode 100644 index 00000000..c35e7d36 --- /dev/null +++ b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.py @@ -0,0 +1,33 @@ +# Copyright (C) 2014-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import gdb + +# Load the xmethods if GDB supports them. +def gdb_has_xmethods(): + try: + import gdb.xmethod + return True + except ImportError: + return False + +def register_libstdcxx_printers(obj): + # Load the pretty-printers. + from .printers import register_libstdcxx_printers + register_libstdcxx_printers(obj) + + if gdb_has_xmethods(): + from .xmethods import register_libstdcxx_xmethods + register_libstdcxx_xmethods(obj) diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.pyc b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60dc66340288e353c1f8c1416985b46713495299 GIT binary patch literal 863 zcmcIiO^*^m5UuKAiCg}skup2NhLOc~J^IEuc*VTwKH zD7hN>6~NLz7z0PaI9_1gV3`ig=851y1eP6UW-&&Nj2m=Eycm*YFz z$AafQ)on9|^5nPt>ES(w~N9%R>+jTb#(;~HD7$B*A zs1nX6COmd%9wTNNFvK1=xyCJyq$TM{Ugv~)14mR*qDs!RW8y8-mS_(T((H+J-$6Xe zJjyGyQ-G)vQXpUS5D8-$0VR~bm;e9( literal 0 HcmV?d00001 diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.py b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.py new file mode 100644 index 00000000..550e0ecd --- /dev/null +++ b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.py @@ -0,0 +1,2032 @@ +# Pretty-printers for libstdc++. + +# Copyright (C) 2008-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import gdb +import itertools +import re +import sys + +### Python 2 + Python 3 compatibility code + +# Resources about compatibility: +# +# * : Documentation of the "six" module + +# FIXME: The handling of e.g. std::basic_string (at least on char) +# probably needs updating to work with Python 3's new string rules. +# +# In particular, Python 3 has a separate type (called byte) for +# bytestrings, and a special b"" syntax for the byte literals; the old +# str() type has been redefined to always store Unicode text. +# +# We probably can't do much about this until this GDB PR is addressed: +# + +if sys.version_info[0] > 2: + ### Python 3 stuff + Iterator = object + # Python 3 folds these into the normal functions. + imap = map + izip = zip + # Also, int subsumes long + long = int +else: + ### Python 2 stuff + class Iterator: + """Compatibility mixin for iterators + + Instead of writing next() methods for iterators, write + __next__() methods and use this mixin to make them work in + Python 2 as well as Python 3. + + Idea stolen from the "six" documentation: + + """ + + def next(self): + return self.__next__() + + # In Python 2, we still need these from itertools + from itertools import imap, izip + +# Try to use the new-style pretty-printing if available. +_use_gdb_pp = True +try: + import gdb.printing +except ImportError: + _use_gdb_pp = False + +# Try to install type-printers. +_use_type_printing = False +try: + import gdb.types + if hasattr(gdb.types, 'TypePrinter'): + _use_type_printing = True +except ImportError: + pass + +# Starting with the type ORIG, search for the member type NAME. This +# handles searching upward through superclasses. This is needed to +# work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615. +def find_type(orig, name): + typ = orig.strip_typedefs() + while True: + # Use Type.tag to ignore cv-qualifiers. PR 67440. + search = '%s::%s' % (typ.tag, name) + try: + return gdb.lookup_type(search) + except RuntimeError: + pass + # The type was not found, so try the superclass. We only need + # to check the first superclass, so we don't bother with + # anything fancier here. + fields = typ.fields() + if len(fields) and fields[0].is_base_class: + typ = fields[0].type + else: + raise ValueError("Cannot find type %s::%s" % (str(orig), name)) + +_versioned_namespace = '__8::' + +def lookup_templ_spec(templ, *args): + """ + Lookup template specialization templ + """ + t = '{}<{}>'.format(templ, ', '.join([str(a) for a in args])) + try: + return gdb.lookup_type(t) + except gdb.error as e: + # Type not found, try again in versioned namespace. + global _versioned_namespace + if _versioned_namespace and _versioned_namespace not in templ: + t = t.replace('::', '::' + _versioned_namespace, 1) + try: + return gdb.lookup_type(t) + except gdb.error: + # If that also fails, rethrow the original exception + pass + raise e + +# Use this to find container node types instead of find_type, +# see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91997 for details. +def lookup_node_type(nodename, containertype): + """ + Lookup specialization of template NODENAME corresponding to CONTAINERTYPE. + e.g. if NODENAME is '_List_node' and CONTAINERTYPE is std::list + then return the type std::_List_node. + Returns None if not found. + """ + # If nodename is unqualified, assume it's in namespace std. + if '::' not in nodename: + nodename = 'std::' + nodename + try: + valtype = find_type(containertype, 'value_type') + except: + valtype = containertype.template_argument(0) + valtype = valtype.strip_typedefs() + try: + return lookup_templ_spec(nodename, valtype) + except gdb.error as e: + # For debug mode containers the node is in std::__cxx1998. + if is_member_of_namespace(nodename, 'std'): + if is_member_of_namespace(containertype, 'std::__cxx1998', + 'std::__debug', '__gnu_debug'): + nodename = nodename.replace('::', '::__cxx1998::', 1) + try: + return lookup_templ_spec(nodename, valtype) + except gdb.error: + pass + return None + +def is_member_of_namespace(typ, *namespaces): + """ + Test whether a type is a member of one of the specified namespaces. + The type can be specified as a string or a gdb.Type object. + """ + if type(typ) is gdb.Type: + typ = str(typ) + typ = strip_versioned_namespace(typ) + for namespace in namespaces: + if typ.startswith(namespace + '::'): + return True + return False + +def is_specialization_of(x, template_name): + "Test if a type is a given template instantiation." + global _versioned_namespace + if type(x) is gdb.Type: + x = x.tag + if _versioned_namespace: + return re.match('^std::(%s)?%s<.*>$' % (_versioned_namespace, template_name), x) is not None + return re.match('^std::%s<.*>$' % template_name, x) is not None + +def strip_versioned_namespace(typename): + global _versioned_namespace + if _versioned_namespace: + return typename.replace(_versioned_namespace, '') + return typename + +def strip_inline_namespaces(type_str): + "Remove known inline namespaces from the canonical name of a type." + type_str = strip_versioned_namespace(type_str) + type_str = type_str.replace('std::__cxx11::', 'std::') + expt_ns = 'std::experimental::' + for lfts_ns in ('fundamentals_v1', 'fundamentals_v2'): + type_str = type_str.replace(expt_ns+lfts_ns+'::', expt_ns) + fs_ns = expt_ns + 'filesystem::' + type_str = type_str.replace(fs_ns+'v1::', fs_ns) + return type_str + +def get_template_arg_list(type_obj): + "Return a type's template arguments as a list" + n = 0 + template_args = [] + while True: + try: + template_args.append(type_obj.template_argument(n)) + except: + return template_args + n += 1 + +class SmartPtrIterator(Iterator): + "An iterator for smart pointer types with a single 'child' value" + + def __init__(self, val): + self.val = val + + def __iter__(self): + return self + + def __next__(self): + if self.val is None: + raise StopIteration + self.val, val = None, self.val + return ('get()', val) + +class SharedPointerPrinter: + "Print a shared_ptr or weak_ptr" + + def __init__ (self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + self.pointer = val['_M_ptr'] + + def children (self): + return SmartPtrIterator(self.pointer) + + def to_string (self): + state = 'empty' + refcounts = self.val['_M_refcount']['_M_pi'] + if refcounts != 0: + usecount = refcounts['_M_use_count'] + weakcount = refcounts['_M_weak_count'] + if usecount == 0: + state = 'expired, weak count %d' % weakcount + else: + state = 'use count %d, weak count %d' % (usecount, weakcount - 1) + return '%s<%s> (%s)' % (self.typename, str(self.val.type.template_argument(0)), state) + +class UniquePointerPrinter: + "Print a unique_ptr" + + def __init__ (self, typename, val): + self.val = val + impl_type = val.type.fields()[0].type.strip_typedefs() + # Check for new implementations first: + if is_specialization_of(impl_type, '__uniq_ptr_data') \ + or is_specialization_of(impl_type, '__uniq_ptr_impl'): + tuple_member = val['_M_t']['_M_t'] + elif is_specialization_of(impl_type, 'tuple'): + tuple_member = val['_M_t'] + else: + raise ValueError("Unsupported implementation for unique_ptr: %s" % str(impl_type)) + tuple_impl_type = tuple_member.type.fields()[0].type # _Tuple_impl + tuple_head_type = tuple_impl_type.fields()[1].type # _Head_base + head_field = tuple_head_type.fields()[0] + if head_field.name == '_M_head_impl': + self.pointer = tuple_member['_M_head_impl'] + elif head_field.is_base_class: + self.pointer = tuple_member.cast(head_field.type) + else: + raise ValueError("Unsupported implementation for tuple in unique_ptr: %s" % str(impl_type)) + + def children (self): + return SmartPtrIterator(self.pointer) + + def to_string (self): + return ('std::unique_ptr<%s>' % (str(self.val.type.template_argument(0)))) + +def get_value_from_aligned_membuf(buf, valtype): + """Returns the value held in a __gnu_cxx::__aligned_membuf.""" + return buf['_M_storage'].address.cast(valtype.pointer()).dereference() + +def get_value_from_list_node(node): + """Returns the value held in an _List_node<_Val>""" + try: + member = node.type.fields()[1].name + if member == '_M_data': + # C++03 implementation, node contains the value as a member + return node['_M_data'] + elif member == '_M_storage': + # C++11 implementation, node stores value in __aligned_membuf + valtype = node.type.template_argument(0) + return get_value_from_aligned_membuf(node['_M_storage'], valtype) + except: + pass + raise ValueError("Unsupported implementation for %s" % str(node.type)) + +class StdListPrinter: + "Print a std::list" + + class _iterator(Iterator): + def __init__(self, nodetype, head): + self.nodetype = nodetype + self.base = head['_M_next'] + self.head = head.address + self.count = 0 + + def __iter__(self): + return self + + def __next__(self): + if self.base == self.head: + raise StopIteration + elt = self.base.cast(self.nodetype).dereference() + self.base = elt['_M_next'] + count = self.count + self.count = self.count + 1 + val = get_value_from_list_node(elt) + return ('[%d]' % count, val) + + def __init__(self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + + def children(self): + nodetype = lookup_node_type('_List_node', self.val.type).pointer() + return self._iterator(nodetype, self.val['_M_impl']['_M_node']) + + def to_string(self): + headnode = self.val['_M_impl']['_M_node'] + if headnode['_M_next'] == headnode.address: + return 'empty %s' % (self.typename) + return '%s' % (self.typename) + +class NodeIteratorPrinter: + def __init__(self, typename, val, contname, nodename): + self.val = val + self.typename = typename + self.contname = contname + self.nodetype = lookup_node_type(nodename, val.type) + + def to_string(self): + if not self.val['_M_node']: + return 'non-dereferenceable iterator for std::%s' % (self.contname) + node = self.val['_M_node'].cast(self.nodetype.pointer()).dereference() + return str(get_value_from_list_node(node)) + +class StdListIteratorPrinter(NodeIteratorPrinter): + "Print std::list::iterator" + + def __init__(self, typename, val): + NodeIteratorPrinter.__init__(self, typename, val, 'list', '_List_node') + +class StdFwdListIteratorPrinter(NodeIteratorPrinter): + "Print std::forward_list::iterator" + + def __init__(self, typename, val): + NodeIteratorPrinter.__init__(self, typename, val, 'forward_list', + '_Fwd_list_node') + +class StdSlistPrinter: + "Print a __gnu_cxx::slist" + + class _iterator(Iterator): + def __init__(self, nodetype, head): + self.nodetype = nodetype + self.base = head['_M_head']['_M_next'] + self.count = 0 + + def __iter__(self): + return self + + def __next__(self): + if self.base == 0: + raise StopIteration + elt = self.base.cast(self.nodetype).dereference() + self.base = elt['_M_next'] + count = self.count + self.count = self.count + 1 + return ('[%d]' % count, elt['_M_data']) + + def __init__(self, typename, val): + self.val = val + + def children(self): + nodetype = lookup_node_type('__gnu_cxx::_Slist_node', self.val.type) + return self._iterator(nodetype.pointer(), self.val) + + def to_string(self): + if self.val['_M_head']['_M_next'] == 0: + return 'empty __gnu_cxx::slist' + return '__gnu_cxx::slist' + +class StdSlistIteratorPrinter: + "Print __gnu_cxx::slist::iterator" + + def __init__(self, typename, val): + self.val = val + + def to_string(self): + if not self.val['_M_node']: + return 'non-dereferenceable iterator for __gnu_cxx::slist' + nodetype = lookup_node_type('__gnu_cxx::_Slist_node', self.val.type).pointer() + return str(self.val['_M_node'].cast(nodetype).dereference()['_M_data']) + +class StdVectorPrinter: + "Print a std::vector" + + class _iterator(Iterator): + def __init__ (self, start, finish, bitvec): + self.bitvec = bitvec + if bitvec: + self.item = start['_M_p'] + self.so = 0 + self.finish = finish['_M_p'] + self.fo = finish['_M_offset'] + itype = self.item.dereference().type + self.isize = 8 * itype.sizeof + else: + self.item = start + self.finish = finish + self.count = 0 + + def __iter__(self): + return self + + def __next__(self): + count = self.count + self.count = self.count + 1 + if self.bitvec: + if self.item == self.finish and self.so >= self.fo: + raise StopIteration + elt = bool(self.item.dereference() & (1 << self.so)) + self.so = self.so + 1 + if self.so >= self.isize: + self.item = self.item + 1 + self.so = 0 + return ('[%d]' % count, elt) + else: + if self.item == self.finish: + raise StopIteration + elt = self.item.dereference() + self.item = self.item + 1 + return ('[%d]' % count, elt) + + def __init__(self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + self.is_bool = val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL + + def children(self): + return self._iterator(self.val['_M_impl']['_M_start'], + self.val['_M_impl']['_M_finish'], + self.is_bool) + + def to_string(self): + start = self.val['_M_impl']['_M_start'] + finish = self.val['_M_impl']['_M_finish'] + end = self.val['_M_impl']['_M_end_of_storage'] + if self.is_bool: + start = self.val['_M_impl']['_M_start']['_M_p'] + finish = self.val['_M_impl']['_M_finish']['_M_p'] + fo = self.val['_M_impl']['_M_finish']['_M_offset'] + itype = start.dereference().type + bl = 8 * itype.sizeof + length = bl * (finish - start) + fo + capacity = bl * (end - start) + return ('%s of length %d, capacity %d' + % (self.typename, int (length), int (capacity))) + else: + return ('%s of length %d, capacity %d' + % (self.typename, int (finish - start), int (end - start))) + + def display_hint(self): + return 'array' + +class StdVectorIteratorPrinter: + "Print std::vector::iterator" + + def __init__(self, typename, val): + self.val = val + + def to_string(self): + if not self.val['_M_current']: + return 'non-dereferenceable iterator for std::vector' + return str(self.val['_M_current'].dereference()) + +class StdBitIteratorPrinter: + "Print std::vector's _Bit_iterator and _Bit_const_iterator" + + def __init__(self, typename, val): + self.val = val + + def to_string(self): + if not self.val['_M_p']: + return 'non-dereferenceable iterator for std::vector' + return bool(self.val['_M_p'].dereference() & (1 << self.val['_M_offset'])) + +class StdBitReferencePrinter: + "Print std::_Bit_reference" + + def __init__(self, typename, val): + self.val = val + + def to_string(self): + if not self.val['_M_p']: + return 'invalid std::_Bit_reference' + return bool(self.val['_M_p'].dereference() & (self.val['_M_mask'])) + +class StdTuplePrinter: + "Print a std::tuple" + + class _iterator(Iterator): + @staticmethod + def _is_nonempty_tuple (nodes): + if len (nodes) == 2: + if is_specialization_of (nodes[1].type, '__tuple_base'): + return True + elif len (nodes) == 1: + return True + elif len (nodes) == 0: + return False + raise ValueError("Top of tuple tree does not consist of a single node.") + + def __init__ (self, head): + self.head = head + + # Set the base class as the initial head of the + # tuple. + nodes = self.head.type.fields () + if self._is_nonempty_tuple (nodes): + # Set the actual head to the first pair. + self.head = self.head.cast (nodes[0].type) + self.count = 0 + + def __iter__ (self): + return self + + def __next__ (self): + # Check for further recursions in the inheritance tree. + # For a GCC 5+ tuple self.head is None after visiting all nodes: + if not self.head: + raise StopIteration + nodes = self.head.type.fields () + # For a GCC 4.x tuple there is a final node with no fields: + if len (nodes) == 0: + raise StopIteration + # Check that this iteration has an expected structure. + if len (nodes) > 2: + raise ValueError("Cannot parse more than 2 nodes in a tuple tree.") + + if len (nodes) == 1: + # This is the last node of a GCC 5+ std::tuple. + impl = self.head.cast (nodes[0].type) + self.head = None + else: + # Either a node before the last node, or the last node of + # a GCC 4.x tuple (which has an empty parent). + + # - Left node is the next recursion parent. + # - Right node is the actual class contained in the tuple. + + # Process right node. + impl = self.head.cast (nodes[1].type) + + # Process left node and set it as head. + self.head = self.head.cast (nodes[0].type) + + self.count = self.count + 1 + + # Finally, check the implementation. If it is + # wrapped in _M_head_impl return that, otherwise return + # the value "as is". + fields = impl.type.fields () + if len (fields) < 1 or fields[0].name != "_M_head_impl": + return ('[%d]' % self.count, impl) + else: + return ('[%d]' % self.count, impl['_M_head_impl']) + + def __init__ (self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val; + + def children (self): + return self._iterator (self.val) + + def to_string (self): + if len (self.val.type.fields ()) == 0: + return 'empty %s' % (self.typename) + return '%s containing' % (self.typename) + +class StdStackOrQueuePrinter: + "Print a std::stack or std::queue" + + def __init__ (self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.visualizer = gdb.default_visualizer(val['c']) + + def children (self): + return self.visualizer.children() + + def to_string (self): + return '%s wrapping: %s' % (self.typename, + self.visualizer.to_string()) + + def display_hint (self): + if hasattr (self.visualizer, 'display_hint'): + return self.visualizer.display_hint () + return None + +class RbtreeIterator(Iterator): + """ + Turn an RB-tree-based container (std::map, std::set etc.) into + a Python iterable object. + """ + + def __init__(self, rbtree): + self.size = rbtree['_M_t']['_M_impl']['_M_node_count'] + self.node = rbtree['_M_t']['_M_impl']['_M_header']['_M_left'] + self.count = 0 + + def __iter__(self): + return self + + def __len__(self): + return int (self.size) + + def __next__(self): + if self.count == self.size: + raise StopIteration + result = self.node + self.count = self.count + 1 + if self.count < self.size: + # Compute the next node. + node = self.node + if node.dereference()['_M_right']: + node = node.dereference()['_M_right'] + while node.dereference()['_M_left']: + node = node.dereference()['_M_left'] + else: + parent = node.dereference()['_M_parent'] + while node == parent.dereference()['_M_right']: + node = parent + parent = parent.dereference()['_M_parent'] + if node.dereference()['_M_right'] != parent: + node = parent + self.node = node + return result + +def get_value_from_Rb_tree_node(node): + """Returns the value held in an _Rb_tree_node<_Val>""" + try: + member = node.type.fields()[1].name + if member == '_M_value_field': + # C++03 implementation, node contains the value as a member + return node['_M_value_field'] + elif member == '_M_storage': + # C++11 implementation, node stores value in __aligned_membuf + valtype = node.type.template_argument(0) + return get_value_from_aligned_membuf(node['_M_storage'], valtype) + except: + pass + raise ValueError("Unsupported implementation for %s" % str(node.type)) + +# This is a pretty printer for std::_Rb_tree_iterator (which is +# std::map::iterator), and has nothing to do with the RbtreeIterator +# class above. +class StdRbtreeIteratorPrinter: + "Print std::map::iterator, std::set::iterator, etc." + + def __init__ (self, typename, val): + self.val = val + nodetype = lookup_node_type('_Rb_tree_node', self.val.type) + self.link_type = nodetype.pointer() + + def to_string (self): + if not self.val['_M_node']: + return 'non-dereferenceable iterator for associative container' + node = self.val['_M_node'].cast(self.link_type).dereference() + return str(get_value_from_Rb_tree_node(node)) + +class StdDebugIteratorPrinter: + "Print a debug enabled version of an iterator" + + def __init__ (self, typename, val): + self.val = val + + # Just strip away the encapsulating __gnu_debug::_Safe_iterator + # and return the wrapped iterator value. + def to_string (self): + base_type = gdb.lookup_type('__gnu_debug::_Safe_iterator_base') + itype = self.val.type.template_argument(0) + safe_seq = self.val.cast(base_type)['_M_sequence'] + if not safe_seq: + return str(self.val.cast(itype)) + if self.val['_M_version'] != safe_seq['_M_version']: + return "invalid iterator" + return str(self.val.cast(itype)) + +def num_elements(num): + """Return either "1 element" or "N elements" depending on the argument.""" + return '1 element' if num == 1 else '%d elements' % num + +class StdMapPrinter: + "Print a std::map or std::multimap" + + # Turn an RbtreeIterator into a pretty-print iterator. + class _iter(Iterator): + def __init__(self, rbiter, type): + self.rbiter = rbiter + self.count = 0 + self.type = type + + def __iter__(self): + return self + + def __next__(self): + if self.count % 2 == 0: + n = next(self.rbiter) + n = n.cast(self.type).dereference() + n = get_value_from_Rb_tree_node(n) + self.pair = n + item = n['first'] + else: + item = self.pair['second'] + result = ('[%d]' % self.count, item) + self.count = self.count + 1 + return result + + def __init__ (self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + + def to_string (self): + return '%s with %s' % (self.typename, + num_elements(len(RbtreeIterator (self.val)))) + + def children (self): + node = lookup_node_type('_Rb_tree_node', self.val.type).pointer() + return self._iter (RbtreeIterator (self.val), node) + + def display_hint (self): + return 'map' + +class StdSetPrinter: + "Print a std::set or std::multiset" + + # Turn an RbtreeIterator into a pretty-print iterator. + class _iter(Iterator): + def __init__(self, rbiter, type): + self.rbiter = rbiter + self.count = 0 + self.type = type + + def __iter__(self): + return self + + def __next__(self): + item = next(self.rbiter) + item = item.cast(self.type).dereference() + item = get_value_from_Rb_tree_node(item) + # FIXME: this is weird ... what to do? + # Maybe a 'set' display hint? + result = ('[%d]' % self.count, item) + self.count = self.count + 1 + return result + + def __init__ (self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + + def to_string (self): + return '%s with %s' % (self.typename, + num_elements(len(RbtreeIterator (self.val)))) + + def children (self): + node = lookup_node_type('_Rb_tree_node', self.val.type).pointer() + return self._iter (RbtreeIterator (self.val), node) + +class StdBitsetPrinter: + "Print a std::bitset" + + def __init__(self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + + def to_string (self): + # If template_argument handled values, we could print the + # size. Or we could use a regexp on the type. + return '%s' % (self.typename) + + def children (self): + try: + # An empty bitset may not have any members which will + # result in an exception being thrown. + words = self.val['_M_w'] + except: + return [] + + wtype = words.type + + # The _M_w member can be either an unsigned long, or an + # array. This depends on the template specialization used. + # If it is a single long, convert to a single element list. + if wtype.code == gdb.TYPE_CODE_ARRAY: + tsize = wtype.target ().sizeof + else: + words = [words] + tsize = wtype.sizeof + + nwords = wtype.sizeof / tsize + result = [] + byte = 0 + while byte < nwords: + w = words[byte] + bit = 0 + while w != 0: + if (w & 1) != 0: + # Another spot where we could use 'set'? + result.append(('[%d]' % (byte * tsize * 8 + bit), 1)) + bit = bit + 1 + w = w >> 1 + byte = byte + 1 + return result + +class StdDequePrinter: + "Print a std::deque" + + class _iter(Iterator): + def __init__(self, node, start, end, last, buffer_size): + self.node = node + self.p = start + self.end = end + self.last = last + self.buffer_size = buffer_size + self.count = 0 + + def __iter__(self): + return self + + def __next__(self): + if self.p == self.last: + raise StopIteration + + result = ('[%d]' % self.count, self.p.dereference()) + self.count = self.count + 1 + + # Advance the 'cur' pointer. + self.p = self.p + 1 + if self.p == self.end: + # If we got to the end of this bucket, move to the + # next bucket. + self.node = self.node + 1 + self.p = self.node[0] + self.end = self.p + self.buffer_size + + return result + + def __init__(self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + self.elttype = val.type.template_argument(0) + size = self.elttype.sizeof + if size < 512: + self.buffer_size = int (512 / size) + else: + self.buffer_size = 1 + + def to_string(self): + start = self.val['_M_impl']['_M_start'] + end = self.val['_M_impl']['_M_finish'] + + delta_n = end['_M_node'] - start['_M_node'] - 1 + delta_s = start['_M_last'] - start['_M_cur'] + delta_e = end['_M_cur'] - end['_M_first'] + + size = self.buffer_size * delta_n + delta_s + delta_e + + return '%s with %s' % (self.typename, num_elements(long(size))) + + def children(self): + start = self.val['_M_impl']['_M_start'] + end = self.val['_M_impl']['_M_finish'] + return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'], + end['_M_cur'], self.buffer_size) + + def display_hint (self): + return 'array' + +class StdDequeIteratorPrinter: + "Print std::deque::iterator" + + def __init__(self, typename, val): + self.val = val + + def to_string(self): + if not self.val['_M_cur']: + return 'non-dereferenceable iterator for std::deque' + return str(self.val['_M_cur'].dereference()) + +class StdStringPrinter: + "Print a std::basic_string of some kind" + + def __init__(self, typename, val): + self.val = val + self.new_string = typename.find("::__cxx11::basic_string") != -1 + + def to_string(self): + # Make sure &string works, too. + type = self.val.type + if type.code == gdb.TYPE_CODE_REF: + type = type.target () + + # Calculate the length of the string so that to_string returns + # the string according to length, not according to first null + # encountered. + ptr = self.val ['_M_dataplus']['_M_p'] + if self.new_string: + length = self.val['_M_string_length'] + # https://sourceware.org/bugzilla/show_bug.cgi?id=17728 + ptr = ptr.cast(ptr.type.strip_typedefs()) + else: + realtype = type.unqualified ().strip_typedefs () + reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer () + header = ptr.cast(reptype) - 1 + length = header.dereference ()['_M_length'] + if hasattr(ptr, "lazy_string"): + return ptr.lazy_string (length = length) + return ptr.string (length = length) + + def display_hint (self): + return 'string' + +class Tr1HashtableIterator(Iterator): + def __init__ (self, hashtable): + self.buckets = hashtable['_M_buckets'] + self.bucket = 0 + self.bucket_count = hashtable['_M_bucket_count'] + self.node_type = find_type(hashtable.type, '_Node').pointer() + self.node = 0 + while self.bucket != self.bucket_count: + self.node = self.buckets[self.bucket] + if self.node: + break + self.bucket = self.bucket + 1 + + def __iter__ (self): + return self + + def __next__ (self): + if self.node == 0: + raise StopIteration + node = self.node.cast(self.node_type) + result = node.dereference()['_M_v'] + self.node = node.dereference()['_M_next']; + if self.node == 0: + self.bucket = self.bucket + 1 + while self.bucket != self.bucket_count: + self.node = self.buckets[self.bucket] + if self.node: + break + self.bucket = self.bucket + 1 + return result + +class StdHashtableIterator(Iterator): + def __init__(self, hashtable): + self.node = hashtable['_M_before_begin']['_M_nxt'] + valtype = hashtable.type.template_argument(1) + cached = hashtable.type.template_argument(9).template_argument(0) + node_type = lookup_templ_spec('std::__detail::_Hash_node', str(valtype), + 'true' if cached else 'false') + self.node_type = node_type.pointer() + + def __iter__(self): + return self + + def __next__(self): + if self.node == 0: + raise StopIteration + elt = self.node.cast(self.node_type).dereference() + self.node = elt['_M_nxt'] + valptr = elt['_M_storage'].address + valptr = valptr.cast(elt.type.template_argument(0).pointer()) + return valptr.dereference() + +class Tr1UnorderedSetPrinter: + "Print a std::unordered_set or tr1::unordered_set" + + def __init__ (self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + + def hashtable (self): + if self.typename.startswith('std::tr1'): + return self.val + return self.val['_M_h'] + + def to_string (self): + count = self.hashtable()['_M_element_count'] + return '%s with %s' % (self.typename, num_elements(count)) + + @staticmethod + def format_count (i): + return '[%d]' % i + + def children (self): + counter = imap (self.format_count, itertools.count()) + if self.typename.startswith('std::tr1'): + return izip (counter, Tr1HashtableIterator (self.hashtable())) + return izip (counter, StdHashtableIterator (self.hashtable())) + +class Tr1UnorderedMapPrinter: + "Print a std::unordered_map or tr1::unordered_map" + + def __init__ (self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.val = val + + def hashtable (self): + if self.typename.startswith('std::tr1'): + return self.val + return self.val['_M_h'] + + def to_string (self): + count = self.hashtable()['_M_element_count'] + return '%s with %s' % (self.typename, num_elements(count)) + + @staticmethod + def flatten (list): + for elt in list: + for i in elt: + yield i + + @staticmethod + def format_one (elt): + return (elt['first'], elt['second']) + + @staticmethod + def format_count (i): + return '[%d]' % i + + def children (self): + counter = imap (self.format_count, itertools.count()) + # Map over the hash table and flatten the result. + if self.typename.startswith('std::tr1'): + data = self.flatten (imap (self.format_one, Tr1HashtableIterator (self.hashtable()))) + # Zip the two iterators together. + return izip (counter, data) + data = self.flatten (imap (self.format_one, StdHashtableIterator (self.hashtable()))) + # Zip the two iterators together. + return izip (counter, data) + + def display_hint (self): + return 'map' + +class StdForwardListPrinter: + "Print a std::forward_list" + + class _iterator(Iterator): + def __init__(self, nodetype, head): + self.nodetype = nodetype + self.base = head['_M_next'] + self.count = 0 + + def __iter__(self): + return self + + def __next__(self): + if self.base == 0: + raise StopIteration + elt = self.base.cast(self.nodetype).dereference() + self.base = elt['_M_next'] + count = self.count + self.count = self.count + 1 + valptr = elt['_M_storage'].address + valptr = valptr.cast(elt.type.template_argument(0).pointer()) + return ('[%d]' % count, valptr.dereference()) + + def __init__(self, typename, val): + self.val = val + self.typename = strip_versioned_namespace(typename) + + def children(self): + nodetype = lookup_node_type('_Fwd_list_node', self.val.type).pointer() + return self._iterator(nodetype, self.val['_M_impl']['_M_head']) + + def to_string(self): + if self.val['_M_impl']['_M_head']['_M_next'] == 0: + return 'empty %s' % self.typename + return '%s' % self.typename + +class SingleObjContainerPrinter(object): + "Base class for printers of containers of single objects" + + def __init__ (self, val, viz, hint = None): + self.contained_value = val + self.visualizer = viz + self.hint = hint + + def _recognize(self, type): + """Return TYPE as a string after applying type printers""" + global _use_type_printing + if not _use_type_printing: + return str(type) + return gdb.types.apply_type_recognizers(gdb.types.get_type_recognizers(), + type) or str(type) + + class _contained(Iterator): + def __init__ (self, val): + self.val = val + + def __iter__ (self): + return self + + def __next__(self): + if self.val is None: + raise StopIteration + retval = self.val + self.val = None + return ('[contained value]', retval) + + def children (self): + if self.contained_value is None: + return self._contained (None) + if hasattr (self.visualizer, 'children'): + return self.visualizer.children () + return self._contained (self.contained_value) + + def display_hint (self): + # if contained value is a map we want to display in the same way + if hasattr (self.visualizer, 'children') and hasattr (self.visualizer, 'display_hint'): + return self.visualizer.display_hint () + return self.hint + +def function_pointer_to_name(f): + "Find the name of the function referred to by the gdb.Value f, " + " which should contain a function pointer from the program." + + # Turn the function pointer into an actual address. + # This is needed to unpack ppc64 function descriptors. + f = f.dereference().address + + if sys.version_info[0] == 2: + # Older versions of GDB need to use long for Python 2, + # because int(f) on 64-bit big-endian values raises a + # gdb.error saying "Cannot convert value to int." + f = long(f) + else: + f = int(f) + + try: + # If the function can't be found older versions of GDB raise a + # RuntimeError saying "Cannot locate object file for block." + return gdb.block_for_pc(f).function.name + except: + return None + +class StdExpAnyPrinter(SingleObjContainerPrinter): + "Print a std::any or std::experimental::any" + + def __init__ (self, typename, val): + self.typename = strip_versioned_namespace(typename) + self.typename = re.sub('^std::experimental::fundamentals_v\d::', 'std::experimental::', self.typename, 1) + self.val = val + self.contained_type = None + contained_value = None + visualizer = None + mgr = self.val['_M_manager'] + if mgr != 0: + func = function_pointer_to_name(mgr) + if not func: + raise ValueError("Invalid function pointer in %s" % (self.typename)) + rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\((enum )?{0}::_Op, (const {0}|{0} const) ?\*, (union )?{0}::_Arg ?\*\)""".format(typename) + m = re.match(rx, func) + if not m: + raise ValueError("Unknown manager function in %s" % self.typename) + + mgrname = m.group(1) + # FIXME need to expand 'std::string' so that gdb.lookup_type works + if 'std::string' in mgrname: + mgrname = re.sub("std::string(?!\w)", str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1)) + + mgrtype = gdb.lookup_type(mgrname) + self.contained_type = mgrtype.template_argument(0) + valptr = None + if '::_Manager_internal' in mgrname: + valptr = self.val['_M_storage']['_M_buffer'].address + elif '::_Manager_external' in mgrname: + valptr = self.val['_M_storage']['_M_ptr'] + else: + raise ValueError("Unknown manager function in %s" % self.typename) + contained_value = valptr.cast(self.contained_type.pointer()).dereference() + visualizer = gdb.default_visualizer(contained_value) + super(StdExpAnyPrinter, self).__init__ (contained_value, visualizer) + + def to_string (self): + if self.contained_type is None: + return '%s [no contained value]' % self.typename + desc = "%s containing " % self.typename + if hasattr (self.visualizer, 'children'): + return desc + self.visualizer.to_string () + valtype = self._recognize (self.contained_type) + return desc + strip_versioned_namespace(str(valtype)) + +class StdExpOptionalPrinter(SingleObjContainerPrinter): + "Print a std::optional or std::experimental::optional" + + def __init__ (self, typename, val): + valtype = self._recognize (val.type.template_argument(0)) + typename = strip_versioned_namespace(typename) + self.typename = re.sub('^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3<%s>' % valtype, typename, 1) + payload = val['_M_payload'] + if self.typename.startswith('std::experimental'): + engaged = val['_M_engaged'] + contained_value = payload + else: + engaged = payload['_M_engaged'] + contained_value = payload['_M_payload'] + try: + # Since GCC 9 + contained_value = contained_value['_M_value'] + except: + pass + visualizer = gdb.default_visualizer (contained_value) + if not engaged: + contained_value = None + super (StdExpOptionalPrinter, self).__init__ (contained_value, visualizer) + + def to_string (self): + if self.contained_value is None: + return "%s [no contained value]" % self.typename + if hasattr (self.visualizer, 'children'): + return "%s containing %s" % (self.typename, + self.visualizer.to_string()) + return self.typename + +class StdVariantPrinter(SingleObjContainerPrinter): + "Print a std::variant" + + def __init__(self, typename, val): + alternatives = get_template_arg_list(val.type) + self.typename = strip_versioned_namespace(typename) + self.typename = "%s<%s>" % (self.typename, ', '.join([self._recognize(alt) for alt in alternatives])) + self.index = val['_M_index'] + if self.index >= len(alternatives): + self.contained_type = None + contained_value = None + visualizer = None + else: + self.contained_type = alternatives[int(self.index)] + addr = val['_M_u']['_M_first']['_M_storage'].address + contained_value = addr.cast(self.contained_type.pointer()).dereference() + visualizer = gdb.default_visualizer(contained_value) + super (StdVariantPrinter, self).__init__(contained_value, visualizer, 'array') + + def to_string(self): + if self.contained_value is None: + return "%s [no contained value]" % self.typename + if hasattr(self.visualizer, 'children'): + return "%s [index %d] containing %s" % (self.typename, self.index, + self.visualizer.to_string()) + return "%s [index %d]" % (self.typename, self.index) + +class StdNodeHandlePrinter(SingleObjContainerPrinter): + "Print a container node handle" + + def __init__(self, typename, val): + self.value_type = val.type.template_argument(1) + nodetype = val.type.template_argument(2).template_argument(0) + self.is_rb_tree_node = is_specialization_of(nodetype.name, '_Rb_tree_node') + self.is_map_node = val.type.template_argument(0) != self.value_type + nodeptr = val['_M_ptr'] + if nodeptr: + if self.is_rb_tree_node: + contained_value = get_value_from_Rb_tree_node(nodeptr.dereference()) + else: + contained_value = get_value_from_aligned_membuf(nodeptr['_M_storage'], + self.value_type) + visualizer = gdb.default_visualizer(contained_value) + else: + contained_value = None + visualizer = None + optalloc = val['_M_alloc'] + self.alloc = optalloc['_M_payload'] if optalloc['_M_engaged'] else None + super(StdNodeHandlePrinter, self).__init__(contained_value, visualizer, + 'array') + + def to_string(self): + desc = 'node handle for ' + if not self.is_rb_tree_node: + desc += 'unordered ' + if self.is_map_node: + desc += 'map'; + else: + desc += 'set'; + + if self.contained_value: + desc += ' with element' + if hasattr(self.visualizer, 'children'): + return "%s = %s" % (desc, self.visualizer.to_string()) + return desc + else: + return 'empty %s' % desc + +class StdExpStringViewPrinter: + "Print a std::basic_string_view or std::experimental::basic_string_view" + + def __init__ (self, typename, val): + self.val = val + + def to_string (self): + ptr = self.val['_M_str'] + len = self.val['_M_len'] + if hasattr (ptr, "lazy_string"): + return ptr.lazy_string (length = len) + return ptr.string (length = len) + + def display_hint (self): + return 'string' + +class StdExpPathPrinter: + "Print a std::experimental::filesystem::path" + + def __init__ (self, typename, val): + self.val = val + self.typename = typename + start = self.val['_M_cmpts']['_M_impl']['_M_start'] + finish = self.val['_M_cmpts']['_M_impl']['_M_finish'] + self.num_cmpts = int (finish - start) + + def _path_type(self): + t = str(self.val['_M_type']) + if t[-9:] == '_Root_dir': + return "root-directory" + if t[-10:] == '_Root_name': + return "root-name" + return None + + def to_string (self): + path = "%s" % self.val ['_M_pathname'] + if self.num_cmpts == 0: + t = self._path_type() + if t: + path = '%s [%s]' % (path, t) + return "experimental::filesystem::path %s" % path + + class _iterator(Iterator): + def __init__(self, cmpts, pathtype): + self.pathtype = pathtype + self.item = cmpts['_M_impl']['_M_start'] + self.finish = cmpts['_M_impl']['_M_finish'] + self.count = 0 + + def __iter__(self): + return self + + def __next__(self): + if self.item == self.finish: + raise StopIteration + item = self.item.dereference() + count = self.count + self.count = self.count + 1 + self.item = self.item + 1 + path = item['_M_pathname'] + t = StdExpPathPrinter(self.pathtype, item)._path_type() + if not t: + t = count + return ('[%s]' % t, path) + + def children(self): + return self._iterator(self.val['_M_cmpts'], self.typename) + +class StdPathPrinter: + "Print a std::filesystem::path" + + def __init__ (self, typename, val): + self.val = val + self.typename = typename + impl = self.val['_M_cmpts']['_M_impl']['_M_t']['_M_t']['_M_head_impl'] + self.type = impl.cast(gdb.lookup_type('uintptr_t')) & 3 + if self.type == 0: + self.impl = impl + else: + self.impl = None + + def _path_type(self): + t = str(self.type.cast(gdb.lookup_type(self.typename + '::_Type'))) + if t[-9:] == '_Root_dir': + return "root-directory" + if t[-10:] == '_Root_name': + return "root-name" + return None + + def to_string (self): + path = "%s" % self.val ['_M_pathname'] + if self.type != 0: + t = self._path_type() + if t: + path = '%s [%s]' % (path, t) + return "filesystem::path %s" % path + + class _iterator(Iterator): + def __init__(self, impl, pathtype): + self.pathtype = pathtype + if impl: + # We can't access _Impl::_M_size because _Impl is incomplete + # so cast to int* to access the _M_size member at offset zero, + int_type = gdb.lookup_type('int') + cmpt_type = gdb.lookup_type(pathtype+'::_Cmpt') + char_type = gdb.lookup_type('char') + impl = impl.cast(int_type.pointer()) + size = impl.dereference() + #self.capacity = (impl + 1).dereference() + if hasattr(gdb.Type, 'alignof'): + sizeof_Impl = max(2 * int_type.sizeof, cmpt_type.alignof) + else: + sizeof_Impl = 2 * int_type.sizeof + begin = impl.cast(char_type.pointer()) + sizeof_Impl + self.item = begin.cast(cmpt_type.pointer()) + self.finish = self.item + size + self.count = 0 + else: + self.item = None + self.finish = None + + def __iter__(self): + return self + + def __next__(self): + if self.item == self.finish: + raise StopIteration + item = self.item.dereference() + count = self.count + self.count = self.count + 1 + self.item = self.item + 1 + path = item['_M_pathname'] + t = StdPathPrinter(self.pathtype, item)._path_type() + if not t: + t = count + return ('[%s]' % t, path) + + def children(self): + return self._iterator(self.impl, self.typename) + + +class StdPairPrinter: + "Print a std::pair object, with 'first' and 'second' as children" + + def __init__(self, typename, val): + self.val = val + + class _iter(Iterator): + "An iterator for std::pair types. Returns 'first' then 'second'." + + def __init__(self, val): + self.val = val + self.which = 'first' + + def __iter__(self): + return self + + def __next__(self): + if self.which is None: + raise StopIteration + which = self.which + if which == 'first': + self.which = 'second' + else: + self.which = None + return (which, self.val[which]) + + def children(self): + return self._iter(self.val) + + def to_string(self): + return None + +class StdCmpCatPrinter: + "Print a comparison category object" + + def __init__ (self, typename, val): + self.typename = typename[typename.rfind(':')+1:] + self.val = val['_M_value'] + + def to_string (self): + if self.typename == 'strong_ordering' and self.val == 0: + name = 'equal' + else: + names = {2:'unordered', -1:'less', 0:'equivalent', 1:'greater'} + name = names[int(self.val)] + return 'std::{}::{}'.format(self.typename, name) + +# A "regular expression" printer which conforms to the +# "SubPrettyPrinter" protocol from gdb.printing. +class RxPrinter(object): + def __init__(self, name, function): + super(RxPrinter, self).__init__() + self.name = name + self.function = function + self.enabled = True + + def invoke(self, value): + if not self.enabled: + return None + + if value.type.code == gdb.TYPE_CODE_REF: + if hasattr(gdb.Value,"referenced_value"): + value = value.referenced_value() + + return self.function(self.name, value) + +# A pretty-printer that conforms to the "PrettyPrinter" protocol from +# gdb.printing. It can also be used directly as an old-style printer. +class Printer(object): + def __init__(self, name): + super(Printer, self).__init__() + self.name = name + self.subprinters = [] + self.lookup = {} + self.enabled = True + self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$') + + def add(self, name, function): + # A small sanity check. + # FIXME + if not self.compiled_rx.match(name): + raise ValueError('libstdc++ programming error: "%s" does not match' % name) + printer = RxPrinter(name, function) + self.subprinters.append(printer) + self.lookup[name] = printer + + # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION. + def add_version(self, base, name, function): + self.add(base + name, function) + if _versioned_namespace: + vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' % _versioned_namespace, base) + self.add(vbase + name, function) + + # Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER. + def add_container(self, base, name, function): + self.add_version(base, name, function) + self.add_version(base + '__cxx1998::', name, function) + + @staticmethod + def get_basic_type(type): + # If it points to a reference, get the reference. + if type.code == gdb.TYPE_CODE_REF: + type = type.target () + + # Get the unqualified type, stripped of typedefs. + type = type.unqualified ().strip_typedefs () + + return type.tag + + def __call__(self, val): + typename = self.get_basic_type(val.type) + if not typename: + return None + + # All the types we match are template types, so we can use a + # dictionary. + match = self.compiled_rx.match(typename) + if not match: + return None + + basename = match.group(1) + + if val.type.code == gdb.TYPE_CODE_REF: + if hasattr(gdb.Value,"referenced_value"): + val = val.referenced_value() + + if basename in self.lookup: + return self.lookup[basename].invoke(val) + + # Cannot find a pretty printer. Return None. + return None + +libstdcxx_printer = None + +class TemplateTypePrinter(object): + r""" + A type printer for class templates with default template arguments. + + Recognizes specializations of class templates and prints them without + any template arguments that use a default template argument. + Type printers are recursively applied to the template arguments. + + e.g. replace "std::vector >" with "std::vector". + """ + + def __init__(self, name, defargs): + self.name = name + self.defargs = defargs + self.enabled = True + + class _recognizer(object): + "The recognizer class for TemplateTypePrinter." + + def __init__(self, name, defargs): + self.name = name + self.defargs = defargs + # self.type_obj = None + + def recognize(self, type_obj): + """ + If type_obj is a specialization of self.name that uses all the + default template arguments for the class template, then return + a string representation of the type without default arguments. + Otherwise, return None. + """ + + if type_obj.tag is None: + return None + + if not type_obj.tag.startswith(self.name): + return None + + template_args = get_template_arg_list(type_obj) + displayed_args = [] + require_defaulted = False + for n in range(len(template_args)): + # The actual template argument in the type: + targ = template_args[n] + # The default template argument for the class template: + defarg = self.defargs.get(n) + if defarg is not None: + # Substitute other template arguments into the default: + defarg = defarg.format(*template_args) + # Fail to recognize the type (by returning None) + # unless the actual argument is the same as the default. + try: + if targ != gdb.lookup_type(defarg): + return None + except gdb.error: + # Type lookup failed, just use string comparison: + if targ.tag != defarg: + return None + # All subsequent args must have defaults: + require_defaulted = True + elif require_defaulted: + return None + else: + # Recursively apply recognizers to the template argument + # and add it to the arguments that will be displayed: + displayed_args.append(self._recognize_subtype(targ)) + + # This assumes no class templates in the nested-name-specifier: + template_name = type_obj.tag[0:type_obj.tag.find('<')] + template_name = strip_inline_namespaces(template_name) + + return template_name + '<' + ', '.join(displayed_args) + '>' + + def _recognize_subtype(self, type_obj): + """Convert a gdb.Type to a string by applying recognizers, + or if that fails then simply converting to a string.""" + + if type_obj.code == gdb.TYPE_CODE_PTR: + return self._recognize_subtype(type_obj.target()) + '*' + if type_obj.code == gdb.TYPE_CODE_ARRAY: + type_str = self._recognize_subtype(type_obj.target()) + if str(type_obj.strip_typedefs()).endswith('[]'): + return type_str + '[]' # array of unknown bound + return "%s[%d]" % (type_str, type_obj.range()[1] + 1) + if type_obj.code == gdb.TYPE_CODE_REF: + return self._recognize_subtype(type_obj.target()) + '&' + if hasattr(gdb, 'TYPE_CODE_RVALUE_REF'): + if type_obj.code == gdb.TYPE_CODE_RVALUE_REF: + return self._recognize_subtype(type_obj.target()) + '&&' + + type_str = gdb.types.apply_type_recognizers( + gdb.types.get_type_recognizers(), type_obj) + if type_str: + return type_str + return str(type_obj) + + def instantiate(self): + "Return a recognizer object for this type printer." + return self._recognizer(self.name, self.defargs) + +def add_one_template_type_printer(obj, name, defargs): + r""" + Add a type printer for a class template with default template arguments. + + Args: + name (str): The template-name of the class template. + defargs (dict int:string) The default template arguments. + + Types in defargs can refer to the Nth template-argument using {N} + (with zero-based indices). + + e.g. 'unordered_map' has these defargs: + { 2: 'std::hash<{0}>', + 3: 'std::equal_to<{0}>', + 4: 'std::allocator >' } + + """ + printer = TemplateTypePrinter('std::'+name, defargs) + gdb.types.register_type_printer(obj, printer) + + # Add type printer for same type in debug namespace: + printer = TemplateTypePrinter('std::__debug::'+name, defargs) + gdb.types.register_type_printer(obj, printer) + + if _versioned_namespace: + # Add second type printer for same type in versioned namespace: + ns = 'std::' + _versioned_namespace + # PR 86112 Cannot use dict comprehension here: + defargs = dict((n, d.replace('std::', ns)) for (n,d) in defargs.items()) + printer = TemplateTypePrinter(ns+name, defargs) + gdb.types.register_type_printer(obj, printer) + +class FilteringTypePrinter(object): + r""" + A type printer that uses typedef names for common template specializations. + + Args: + match (str): The class template to recognize. + name (str): The typedef-name that will be used instead. + + Checks if a specialization of the class template 'match' is the same type + as the typedef 'name', and prints it as 'name' instead. + + e.g. if an instantiation of std::basic_istream is the same type as + std::istream then print it as std::istream. + """ + + def __init__(self, match, name): + self.match = match + self.name = name + self.enabled = True + + class _recognizer(object): + "The recognizer class for TemplateTypePrinter." + + def __init__(self, match, name): + self.match = match + self.name = name + self.type_obj = None + + def recognize(self, type_obj): + """ + If type_obj starts with self.match and is the same type as + self.name then return self.name, otherwise None. + """ + if type_obj.tag is None: + return None + + if self.type_obj is None: + if not type_obj.tag.startswith(self.match): + # Filter didn't match. + return None + try: + self.type_obj = gdb.lookup_type(self.name).strip_typedefs() + except: + pass + if self.type_obj == type_obj: + return strip_inline_namespaces(self.name) + return None + + def instantiate(self): + "Return a recognizer object for this type printer." + return self._recognizer(self.match, self.name) + +def add_one_type_printer(obj, match, name): + printer = FilteringTypePrinter('std::' + match, 'std::' + name) + gdb.types.register_type_printer(obj, printer) + if _versioned_namespace: + ns = 'std::' + _versioned_namespace + printer = FilteringTypePrinter(ns + match, ns + name) + gdb.types.register_type_printer(obj, printer) + +def register_type_printers(obj): + global _use_type_printing + + if not _use_type_printing: + return + + # Add type printers for typedefs std::string, std::wstring etc. + for ch in ('', 'w', 'u8', 'u16', 'u32'): + add_one_type_printer(obj, 'basic_string', ch + 'string') + add_one_type_printer(obj, '__cxx11::basic_string', ch + 'string') + # Typedefs for __cxx11::basic_string used to be in namespace __cxx11: + add_one_type_printer(obj, '__cxx11::basic_string', + '__cxx11::' + ch + 'string') + add_one_type_printer(obj, 'basic_string_view', ch + 'string_view') + + # Add type printers for typedefs std::istream, std::wistream etc. + for ch in ('', 'w'): + for x in ('ios', 'streambuf', 'istream', 'ostream', 'iostream', + 'filebuf', 'ifstream', 'ofstream', 'fstream'): + add_one_type_printer(obj, 'basic_' + x, ch + x) + for x in ('stringbuf', 'istringstream', 'ostringstream', + 'stringstream'): + add_one_type_printer(obj, 'basic_' + x, ch + x) + # types are in __cxx11 namespace, but typedefs aren't: + add_one_type_printer(obj, '__cxx11::basic_' + x, ch + x) + + # Add type printers for typedefs regex, wregex, cmatch, wcmatch etc. + for abi in ('', '__cxx11::'): + for ch in ('', 'w'): + add_one_type_printer(obj, abi + 'basic_regex', abi + ch + 'regex') + for ch in ('c', 's', 'wc', 'ws'): + add_one_type_printer(obj, abi + 'match_results', abi + ch + 'match') + for x in ('sub_match', 'regex_iterator', 'regex_token_iterator'): + add_one_type_printer(obj, abi + x, abi + ch + x) + + # Note that we can't have a printer for std::wstreampos, because + # it is the same type as std::streampos. + add_one_type_printer(obj, 'fpos', 'streampos') + + # Add type printers for typedefs. + for dur in ('nanoseconds', 'microseconds', 'milliseconds', + 'seconds', 'minutes', 'hours'): + add_one_type_printer(obj, 'duration', dur) + + # Add type printers for typedefs. + add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand0') + add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand') + add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937') + add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937_64') + add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux24_base') + add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux48_base') + add_one_type_printer(obj, 'discard_block_engine', 'ranlux24') + add_one_type_printer(obj, 'discard_block_engine', 'ranlux48') + add_one_type_printer(obj, 'shuffle_order_engine', 'knuth_b') + + # Add type printers for experimental::basic_string_view typedefs. + ns = 'experimental::fundamentals_v1::' + for ch in ('', 'w', 'u8', 'u16', 'u32'): + add_one_type_printer(obj, ns + 'basic_string_view', + ns + ch + 'string_view') + + # Do not show defaulted template arguments in class templates. + add_one_template_type_printer(obj, 'unique_ptr', + { 1: 'std::default_delete<{0}>' }) + add_one_template_type_printer(obj, 'deque', { 1: 'std::allocator<{0}>'}) + add_one_template_type_printer(obj, 'forward_list', { 1: 'std::allocator<{0}>'}) + add_one_template_type_printer(obj, 'list', { 1: 'std::allocator<{0}>'}) + add_one_template_type_printer(obj, '__cxx11::list', { 1: 'std::allocator<{0}>'}) + add_one_template_type_printer(obj, 'vector', { 1: 'std::allocator<{0}>'}) + add_one_template_type_printer(obj, 'map', + { 2: 'std::less<{0}>', + 3: 'std::allocator>' }) + add_one_template_type_printer(obj, 'multimap', + { 2: 'std::less<{0}>', + 3: 'std::allocator>' }) + add_one_template_type_printer(obj, 'set', + { 1: 'std::less<{0}>', 2: 'std::allocator<{0}>' }) + add_one_template_type_printer(obj, 'multiset', + { 1: 'std::less<{0}>', 2: 'std::allocator<{0}>' }) + add_one_template_type_printer(obj, 'unordered_map', + { 2: 'std::hash<{0}>', + 3: 'std::equal_to<{0}>', + 4: 'std::allocator>'}) + add_one_template_type_printer(obj, 'unordered_multimap', + { 2: 'std::hash<{0}>', + 3: 'std::equal_to<{0}>', + 4: 'std::allocator>'}) + add_one_template_type_printer(obj, 'unordered_set', + { 1: 'std::hash<{0}>', + 2: 'std::equal_to<{0}>', + 3: 'std::allocator<{0}>'}) + add_one_template_type_printer(obj, 'unordered_multiset', + { 1: 'std::hash<{0}>', + 2: 'std::equal_to<{0}>', + 3: 'std::allocator<{0}>'}) + +def register_libstdcxx_printers (obj): + "Register libstdc++ pretty-printers with objfile Obj." + + global _use_gdb_pp + global libstdcxx_printer + + if _use_gdb_pp: + gdb.printing.register_pretty_printer(obj, libstdcxx_printer) + else: + if obj is None: + obj = gdb + obj.pretty_printers.append(libstdcxx_printer) + + register_type_printers(obj) + +def build_libstdcxx_dictionary (): + global libstdcxx_printer + + libstdcxx_printer = Printer("libstdc++-v6") + + # libstdc++ objects requiring pretty-printing. + # In order from: + # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html + libstdcxx_printer.add_version('std::', 'basic_string', StdStringPrinter) + libstdcxx_printer.add_version('std::__cxx11::', 'basic_string', StdStringPrinter) + libstdcxx_printer.add_container('std::', 'bitset', StdBitsetPrinter) + libstdcxx_printer.add_container('std::', 'deque', StdDequePrinter) + libstdcxx_printer.add_container('std::', 'list', StdListPrinter) + libstdcxx_printer.add_container('std::__cxx11::', 'list', StdListPrinter) + libstdcxx_printer.add_container('std::', 'map', StdMapPrinter) + libstdcxx_printer.add_container('std::', 'multimap', StdMapPrinter) + libstdcxx_printer.add_container('std::', 'multiset', StdSetPrinter) + libstdcxx_printer.add_version('std::', 'pair', StdPairPrinter) + libstdcxx_printer.add_version('std::', 'priority_queue', + StdStackOrQueuePrinter) + libstdcxx_printer.add_version('std::', 'queue', StdStackOrQueuePrinter) + libstdcxx_printer.add_version('std::', 'tuple', StdTuplePrinter) + libstdcxx_printer.add_container('std::', 'set', StdSetPrinter) + libstdcxx_printer.add_version('std::', 'stack', StdStackOrQueuePrinter) + libstdcxx_printer.add_version('std::', 'unique_ptr', UniquePointerPrinter) + libstdcxx_printer.add_container('std::', 'vector', StdVectorPrinter) + # vector + + # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG. + libstdcxx_printer.add('std::__debug::bitset', StdBitsetPrinter) + libstdcxx_printer.add('std::__debug::deque', StdDequePrinter) + libstdcxx_printer.add('std::__debug::list', StdListPrinter) + libstdcxx_printer.add('std::__debug::map', StdMapPrinter) + libstdcxx_printer.add('std::__debug::multimap', StdMapPrinter) + libstdcxx_printer.add('std::__debug::multiset', StdSetPrinter) + libstdcxx_printer.add('std::__debug::priority_queue', + StdStackOrQueuePrinter) + libstdcxx_printer.add('std::__debug::queue', StdStackOrQueuePrinter) + libstdcxx_printer.add('std::__debug::set', StdSetPrinter) + libstdcxx_printer.add('std::__debug::stack', StdStackOrQueuePrinter) + libstdcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter) + libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter) + + # These are the TR1 and C++11 printers. + # For array - the default GDB pretty-printer seems reasonable. + libstdcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter) + libstdcxx_printer.add_version('std::', 'weak_ptr', SharedPointerPrinter) + libstdcxx_printer.add_container('std::', 'unordered_map', + Tr1UnorderedMapPrinter) + libstdcxx_printer.add_container('std::', 'unordered_set', + Tr1UnorderedSetPrinter) + libstdcxx_printer.add_container('std::', 'unordered_multimap', + Tr1UnorderedMapPrinter) + libstdcxx_printer.add_container('std::', 'unordered_multiset', + Tr1UnorderedSetPrinter) + libstdcxx_printer.add_container('std::', 'forward_list', + StdForwardListPrinter) + + libstdcxx_printer.add_version('std::tr1::', 'shared_ptr', SharedPointerPrinter) + libstdcxx_printer.add_version('std::tr1::', 'weak_ptr', SharedPointerPrinter) + libstdcxx_printer.add_version('std::tr1::', 'unordered_map', + Tr1UnorderedMapPrinter) + libstdcxx_printer.add_version('std::tr1::', 'unordered_set', + Tr1UnorderedSetPrinter) + libstdcxx_printer.add_version('std::tr1::', 'unordered_multimap', + Tr1UnorderedMapPrinter) + libstdcxx_printer.add_version('std::tr1::', 'unordered_multiset', + Tr1UnorderedSetPrinter) + + # These are the C++11 printer registrations for -D_GLIBCXX_DEBUG cases. + # The tr1 namespace containers do not have any debug equivalents, + # so do not register printers for them. + libstdcxx_printer.add('std::__debug::unordered_map', + Tr1UnorderedMapPrinter) + libstdcxx_printer.add('std::__debug::unordered_set', + Tr1UnorderedSetPrinter) + libstdcxx_printer.add('std::__debug::unordered_multimap', + Tr1UnorderedMapPrinter) + libstdcxx_printer.add('std::__debug::unordered_multiset', + Tr1UnorderedSetPrinter) + libstdcxx_printer.add('std::__debug::forward_list', + StdForwardListPrinter) + + # Library Fundamentals TS components + libstdcxx_printer.add_version('std::experimental::fundamentals_v1::', + 'any', StdExpAnyPrinter) + libstdcxx_printer.add_version('std::experimental::fundamentals_v1::', + 'optional', StdExpOptionalPrinter) + libstdcxx_printer.add_version('std::experimental::fundamentals_v1::', + 'basic_string_view', StdExpStringViewPrinter) + # Filesystem TS components + libstdcxx_printer.add_version('std::experimental::filesystem::v1::', + 'path', StdExpPathPrinter) + libstdcxx_printer.add_version('std::experimental::filesystem::v1::__cxx11::', + 'path', StdExpPathPrinter) + libstdcxx_printer.add_version('std::filesystem::', + 'path', StdPathPrinter) + libstdcxx_printer.add_version('std::filesystem::__cxx11::', + 'path', StdPathPrinter) + + # C++17 components + libstdcxx_printer.add_version('std::', + 'any', StdExpAnyPrinter) + libstdcxx_printer.add_version('std::', + 'optional', StdExpOptionalPrinter) + libstdcxx_printer.add_version('std::', + 'basic_string_view', StdExpStringViewPrinter) + libstdcxx_printer.add_version('std::', + 'variant', StdVariantPrinter) + libstdcxx_printer.add_version('std::', + '_Node_handle', StdNodeHandlePrinter) + + # C++20 components + libstdcxx_printer.add_version('std::', 'partial_ordering', StdCmpCatPrinter) + libstdcxx_printer.add_version('std::', 'weak_ordering', StdCmpCatPrinter) + libstdcxx_printer.add_version('std::', 'strong_ordering', StdCmpCatPrinter) + + # Extensions. + libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter) + + if True: + # These shouldn't be necessary, if GDB "print *i" worked. + # But it often doesn't, so here they are. + libstdcxx_printer.add_container('std::', '_List_iterator', + StdListIteratorPrinter) + libstdcxx_printer.add_container('std::', '_List_const_iterator', + StdListIteratorPrinter) + libstdcxx_printer.add_version('std::', '_Rb_tree_iterator', + StdRbtreeIteratorPrinter) + libstdcxx_printer.add_version('std::', '_Rb_tree_const_iterator', + StdRbtreeIteratorPrinter) + libstdcxx_printer.add_container('std::', '_Deque_iterator', + StdDequeIteratorPrinter) + libstdcxx_printer.add_container('std::', '_Deque_const_iterator', + StdDequeIteratorPrinter) + libstdcxx_printer.add_version('__gnu_cxx::', '__normal_iterator', + StdVectorIteratorPrinter) + libstdcxx_printer.add_version('std::', '_Bit_iterator', + StdBitIteratorPrinter) + libstdcxx_printer.add_version('std::', '_Bit_const_iterator', + StdBitIteratorPrinter) + libstdcxx_printer.add_version('std::', '_Bit_reference', + StdBitReferencePrinter) + libstdcxx_printer.add_version('__gnu_cxx::', '_Slist_iterator', + StdSlistIteratorPrinter) + libstdcxx_printer.add_container('std::', '_Fwd_list_iterator', + StdFwdListIteratorPrinter) + libstdcxx_printer.add_container('std::', '_Fwd_list_const_iterator', + StdFwdListIteratorPrinter) + + # Debug (compiled with -D_GLIBCXX_DEBUG) printer + # registrations. + libstdcxx_printer.add('__gnu_debug::_Safe_iterator', + StdDebugIteratorPrinter) + +build_libstdcxx_dictionary () diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.pyc b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f230c733976baa3c48dd5a9435c7ba1b02354c1d GIT binary patch literal 85322 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. + +import gdb +import gdb.xmethod +import re + +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') + +class LibStdCxxXMethod(gdb.xmethod.XMethod): + def __init__(self, name, worker_class): + gdb.xmethod.XMethod.__init__(self, name) + self.worker_class = worker_class + +# Xmethods for std::array + +class ArrayWorkerBase(gdb.xmethod.XMethodWorker): + def __init__(self, val_type, size): + self._val_type = val_type + self._size = size + + def null_value(self): + nullptr = gdb.parse_and_eval('(void *) 0') + return nullptr.cast(self._val_type.pointer()).dereference() + +class ArraySizeWorker(ArrayWorkerBase): + def __init__(self, val_type, size): + ArrayWorkerBase.__init__(self, val_type, size) + + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return get_std_size_type() + + def __call__(self, obj): + return self._size + +class ArrayEmptyWorker(ArrayWorkerBase): + def __init__(self, val_type, size): + ArrayWorkerBase.__init__(self, val_type, size) + + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return get_bool_type() + + def __call__(self, obj): + return (int(self._size) == 0) + +class ArrayFrontWorker(ArrayWorkerBase): + def __init__(self, val_type, size): + ArrayWorkerBase.__init__(self, val_type, size) + + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + if int(self._size) > 0: + return obj['_M_elems'][0] + else: + return self.null_value() + +class ArrayBackWorker(ArrayWorkerBase): + def __init__(self, val_type, size): + ArrayWorkerBase.__init__(self, val_type, size) + + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + if int(self._size) > 0: + return obj['_M_elems'][self._size - 1] + else: + return self.null_value() + +class ArrayAtWorker(ArrayWorkerBase): + def __init__(self, val_type, size): + ArrayWorkerBase.__init__(self, val_type, size) + + def get_arg_types(self): + return get_std_size_type() + + def get_result_type(self, obj, index): + return self._val_type + + def __call__(self, obj, index): + if int(index) >= int(self._size): + raise IndexError('Array index "%d" should not be >= %d.' % + ((int(index), self._size))) + return obj['_M_elems'][index] + +class ArraySubscriptWorker(ArrayWorkerBase): + def __init__(self, val_type, size): + ArrayWorkerBase.__init__(self, val_type, size) + + def get_arg_types(self): + return get_std_size_type() + + def get_result_type(self, obj, index): + return self._val_type + + def __call__(self, obj, index): + if int(self._size) > 0: + return obj['_M_elems'][index] + else: + return self.null_value() + +class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self): + gdb.xmethod.XMethodMatcher.__init__(self, + matcher_name_prefix + 'array') + self._method_dict = { + 'size': LibStdCxxXMethod('size', ArraySizeWorker), + 'empty': LibStdCxxXMethod('empty', ArrayEmptyWorker), + 'front': LibStdCxxXMethod('front', ArrayFrontWorker), + 'back': LibStdCxxXMethod('back', ArrayBackWorker), + 'at': LibStdCxxXMethod('at', ArrayAtWorker), + 'operator[]': LibStdCxxXMethod('operator[]', ArraySubscriptWorker), + } + 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): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + try: + value_type = class_type.template_argument(0) + size = class_type.template_argument(1) + except: + return None + return method.worker_class(value_type, size) + +# Xmethods for std::deque + +class DequeWorkerBase(gdb.xmethod.XMethodWorker): + def __init__(self, val_type): + self._val_type = val_type + self._bufsize = 512 // val_type.sizeof or 1 + + def size(self, obj): + first_node = obj['_M_impl']['_M_start']['_M_node'] + last_node = obj['_M_impl']['_M_finish']['_M_node'] + cur = obj['_M_impl']['_M_finish']['_M_cur'] + first = obj['_M_impl']['_M_finish']['_M_first'] + return (last_node - first_node) * self._bufsize + (cur - first) + + def index(self, obj, idx): + first_node = obj['_M_impl']['_M_start']['_M_node'] + index_node = first_node + int(idx) // self._bufsize + return index_node[0][idx % self._bufsize] + +class DequeEmptyWorker(DequeWorkerBase): + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return get_bool_type() + + def __call__(self, obj): + return (obj['_M_impl']['_M_start']['_M_cur'] == + obj['_M_impl']['_M_finish']['_M_cur']) + +class DequeSizeWorker(DequeWorkerBase): + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return get_std_size_type() + + def __call__(self, obj): + return self.size(obj) + +class DequeFrontWorker(DequeWorkerBase): + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + return obj['_M_impl']['_M_start']['_M_cur'][0] + +class DequeBackWorker(DequeWorkerBase): + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + if (obj['_M_impl']['_M_finish']['_M_cur'] == + obj['_M_impl']['_M_finish']['_M_first']): + prev_node = obj['_M_impl']['_M_finish']['_M_node'] - 1 + return prev_node[0][self._bufsize - 1] + else: + return obj['_M_impl']['_M_finish']['_M_cur'][-1] + +class DequeSubscriptWorker(DequeWorkerBase): + def get_arg_types(self): + return get_std_size_type() + + def get_result_type(self, obj, subscript): + return self._val_type + + def __call__(self, obj, subscript): + return self.index(obj, subscript) + +class DequeAtWorker(DequeWorkerBase): + def get_arg_types(self): + return get_std_size_type() + + def get_result_type(self, obj, index): + return self._val_type + + def __call__(self, obj, index): + deque_size = int(self.size(obj)) + if int(index) >= deque_size: + raise IndexError('Deque index "%d" should not be >= %d.' % + (int(index), deque_size)) + else: + return self.index(obj, index) + +class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self): + gdb.xmethod.XMethodMatcher.__init__(self, + matcher_name_prefix + 'deque') + self._method_dict = { + 'empty': LibStdCxxXMethod('empty', DequeEmptyWorker), + 'size': LibStdCxxXMethod('size', DequeSizeWorker), + 'front': LibStdCxxXMethod('front', DequeFrontWorker), + 'back': LibStdCxxXMethod('back', DequeBackWorker), + 'operator[]': LibStdCxxXMethod('operator[]', DequeSubscriptWorker), + 'at': LibStdCxxXMethod('at', DequeAtWorker) + } + 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): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + return method.worker_class(class_type.template_argument(0)) + +# Xmethods for std::forward_list + +class ForwardListWorkerBase(gdb.xmethod.XMethodMatcher): + def __init__(self, val_type, node_type): + self._val_type = val_type + self._node_type = node_type + + def get_arg_types(self): + return None + +class ForwardListEmptyWorker(ForwardListWorkerBase): + def get_result_type(self, obj): + return get_bool_type() + + def __call__(self, obj): + return obj['_M_impl']['_M_head']['_M_next'] == 0 + +class ForwardListFrontWorker(ForwardListWorkerBase): + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + node = obj['_M_impl']['_M_head']['_M_next'].cast(self._node_type) + val_address = node['_M_storage']['_M_storage'].address + return val_address.cast(self._val_type.pointer()).dereference() + +class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self): + matcher_name = matcher_name_prefix + 'forward_list' + gdb.xmethod.XMethodMatcher.__init__(self, matcher_name) + self._method_dict = { + 'empty': LibStdCxxXMethod('empty', ForwardListEmptyWorker), + 'front': LibStdCxxXMethod('front', ForwardListFrontWorker) + } + 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): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + val_type = class_type.template_argument(0) + node_type = gdb.lookup_type(str(class_type) + '::_Node').pointer() + return method.worker_class(val_type, node_type) + +# Xmethods for std::list + +class ListWorkerBase(gdb.xmethod.XMethodWorker): + def __init__(self, val_type, node_type): + self._val_type = val_type + self._node_type = node_type + + def get_arg_types(self): + return None + + def get_value_from_node(self, node): + node = node.dereference() + if node.type.fields()[1].name == '_M_data': + # C++03 implementation, node contains the value as a member + return node['_M_data'] + # C++11 implementation, node stores value in __aligned_membuf + addr = node['_M_storage'].address + return addr.cast(self._val_type.pointer()).dereference() + +class ListEmptyWorker(ListWorkerBase): + def get_result_type(self, obj): + return get_bool_type() + + def __call__(self, obj): + base_node = obj['_M_impl']['_M_node'] + if base_node['_M_next'] == base_node.address: + return True + else: + return False + +class ListSizeWorker(ListWorkerBase): + def get_result_type(self, obj): + return get_std_size_type() + + def __call__(self, obj): + begin_node = obj['_M_impl']['_M_node']['_M_next'] + end_node = obj['_M_impl']['_M_node'].address + size = 0 + while begin_node != end_node: + begin_node = begin_node['_M_next'] + size += 1 + return size + +class ListFrontWorker(ListWorkerBase): + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + node = obj['_M_impl']['_M_node']['_M_next'].cast(self._node_type) + return self.get_value_from_node(node) + +class ListBackWorker(ListWorkerBase): + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + prev_node = obj['_M_impl']['_M_node']['_M_prev'].cast(self._node_type) + return self.get_value_from_node(prev_node) + +class ListMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self): + gdb.xmethod.XMethodMatcher.__init__(self, + matcher_name_prefix + 'list') + self._method_dict = { + 'empty': LibStdCxxXMethod('empty', ListEmptyWorker), + 'size': LibStdCxxXMethod('size', ListSizeWorker), + 'front': LibStdCxxXMethod('front', ListFrontWorker), + 'back': LibStdCxxXMethod('back', ListBackWorker) + } + 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): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + val_type = class_type.template_argument(0) + node_type = gdb.lookup_type(str(class_type) + '::_Node').pointer() + return method.worker_class(val_type, node_type) + +# Xmethods for std::vector + +class VectorWorkerBase(gdb.xmethod.XMethodWorker): + def __init__(self, val_type): + self._val_type = val_type + + def size(self, obj): + if self._val_type.code == gdb.TYPE_CODE_BOOL: + start = obj['_M_impl']['_M_start']['_M_p'] + finish = obj['_M_impl']['_M_finish']['_M_p'] + finish_offset = obj['_M_impl']['_M_finish']['_M_offset'] + bit_size = start.dereference().type.sizeof * 8 + return (finish - start) * bit_size + finish_offset + else: + return obj['_M_impl']['_M_finish'] - obj['_M_impl']['_M_start'] + + def get(self, obj, index): + if self._val_type.code == gdb.TYPE_CODE_BOOL: + start = obj['_M_impl']['_M_start']['_M_p'] + bit_size = start.dereference().type.sizeof * 8 + valp = start + index // bit_size + offset = index % bit_size + return (valp.dereference() & (1 << offset)) > 0 + else: + return obj['_M_impl']['_M_start'][index] + +class VectorEmptyWorker(VectorWorkerBase): + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return get_bool_type() + + def __call__(self, obj): + return int(self.size(obj)) == 0 + +class VectorSizeWorker(VectorWorkerBase): + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return get_std_size_type() + + def __call__(self, obj): + return self.size(obj) + +class VectorFrontWorker(VectorWorkerBase): + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + return self.get(obj, 0) + +class VectorBackWorker(VectorWorkerBase): + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return self._val_type + + def __call__(self, obj): + return self.get(obj, int(self.size(obj)) - 1) + +class VectorAtWorker(VectorWorkerBase): + def get_arg_types(self): + return get_std_size_type() + + def get_result_type(self, obj, index): + return self._val_type + + def __call__(self, obj, index): + size = int(self.size(obj)) + if int(index) >= size: + raise IndexError('Vector index "%d" should not be >= %d.' % + ((int(index), size))) + return self.get(obj, int(index)) + +class VectorSubscriptWorker(VectorWorkerBase): + def get_arg_types(self): + return get_std_size_type() + + def get_result_type(self, obj, subscript): + return self._val_type + + def __call__(self, obj, subscript): + return self.get(obj, int(subscript)) + +class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self): + gdb.xmethod.XMethodMatcher.__init__(self, + matcher_name_prefix + 'vector') + self._method_dict = { + 'size': LibStdCxxXMethod('size', VectorSizeWorker), + 'empty': LibStdCxxXMethod('empty', VectorEmptyWorker), + 'front': LibStdCxxXMethod('front', VectorFrontWorker), + 'back': LibStdCxxXMethod('back', VectorBackWorker), + 'at': LibStdCxxXMethod('at', VectorAtWorker), + 'operator[]': LibStdCxxXMethod('operator[]', + VectorSubscriptWorker), + } + 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): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + return method.worker_class(class_type.template_argument(0)) + +# Xmethods for associative containers + +class AssociativeContainerWorkerBase(gdb.xmethod.XMethodWorker): + def __init__(self, unordered): + self._unordered = unordered + + def node_count(self, obj): + if self._unordered: + return obj['_M_h']['_M_element_count'] + else: + return obj['_M_t']['_M_impl']['_M_node_count'] + + def get_arg_types(self): + return None + +class AssociativeContainerEmptyWorker(AssociativeContainerWorkerBase): + def get_result_type(self, obj): + return get_bool_type() + + def __call__(self, obj): + return int(self.node_count(obj)) == 0 + +class AssociativeContainerSizeWorker(AssociativeContainerWorkerBase): + def get_result_type(self, obj): + return get_std_size_type() + + def __call__(self, obj): + return self.node_count(obj) + +class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self, name): + gdb.xmethod.XMethodMatcher.__init__(self, + matcher_name_prefix + name) + self._name = name + self._method_dict = { + 'size': LibStdCxxXMethod('size', AssociativeContainerSizeWorker), + 'empty': LibStdCxxXMethod('empty', + AssociativeContainerEmptyWorker), + } + 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): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + unordered = 'unordered' in self._name + return method.worker_class(unordered) + +# Xmethods for std::unique_ptr + +class UniquePtrGetWorker(gdb.xmethod.XMethodWorker): + "Implements std::unique_ptr::get() and std::unique_ptr::operator->()" + + def __init__(self, elem_type): + self._is_array = elem_type.code == gdb.TYPE_CODE_ARRAY + if self._is_array: + self._elem_type = elem_type.target() + else: + self._elem_type = elem_type + + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return self._elem_type.pointer() + + def _supports(self, method_name): + "operator-> is not supported for unique_ptr" + return method_name == 'get' or not self._is_array + + 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): + tuple_member = obj['_M_t']['_M_t'] + elif re.match('^std::(__\d+::)?tuple<.*>$', impl_type): + tuple_member = obj['_M_t'] + else: + return None + tuple_impl_type = tuple_member.type.fields()[0].type # _Tuple_impl + tuple_head_type = tuple_impl_type.fields()[1].type # _Head_base + head_field = tuple_head_type.fields()[0] + if head_field.name == '_M_head_impl': + return tuple_member['_M_head_impl'] + elif head_field.is_base_class: + return tuple_member.cast(head_field.type) + else: + return None + +class UniquePtrDerefWorker(UniquePtrGetWorker): + "Implements std::unique_ptr::operator*()" + + def __init__(self, elem_type): + UniquePtrGetWorker.__init__(self, elem_type) + + def get_result_type(self, obj): + return self._elem_type + + def _supports(self, method_name): + "operator* is not supported for unique_ptr" + return not self._is_array + + def __call__(self, obj): + return UniquePtrGetWorker.__call__(self, obj).dereference() + +class UniquePtrSubscriptWorker(UniquePtrGetWorker): + "Implements std::unique_ptr::operator[](size_t)" + + def __init__(self, elem_type): + UniquePtrGetWorker.__init__(self, elem_type) + + def get_arg_types(self): + return get_std_size_type() + + def get_result_type(self, obj, index): + return self._elem_type + + def _supports(self, method_name): + "operator[] is only supported for unique_ptr" + return self._is_array + + def __call__(self, obj, index): + return UniquePtrGetWorker.__call__(self, obj)[index] + +class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self): + gdb.xmethod.XMethodMatcher.__init__(self, + matcher_name_prefix + 'unique_ptr') + self._method_dict = { + 'get': LibStdCxxXMethod('get', UniquePtrGetWorker), + 'operator->': LibStdCxxXMethod('operator->', UniquePtrGetWorker), + 'operator*': LibStdCxxXMethod('operator*', UniquePtrDerefWorker), + 'operator[]': LibStdCxxXMethod('operator[]', UniquePtrSubscriptWorker), + } + 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): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + worker = method.worker_class(class_type.template_argument(0)) + if worker._supports(method_name): + return worker + return None + +# Xmethods for std::shared_ptr + +class SharedPtrGetWorker(gdb.xmethod.XMethodWorker): + "Implements std::shared_ptr::get() and std::shared_ptr::operator->()" + + def __init__(self, elem_type): + self._is_array = elem_type.code == gdb.TYPE_CODE_ARRAY + if self._is_array: + self._elem_type = elem_type.target() + else: + self._elem_type = elem_type + + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return self._elem_type.pointer() + + def _supports(self, method_name): + "operator-> is not supported for shared_ptr" + return method_name == 'get' or not self._is_array + + def __call__(self, obj): + return obj['_M_ptr'] + +class SharedPtrDerefWorker(SharedPtrGetWorker): + "Implements std::shared_ptr::operator*()" + + def __init__(self, elem_type): + SharedPtrGetWorker.__init__(self, elem_type) + + def get_result_type(self, obj): + return self._elem_type + + def _supports(self, method_name): + "operator* is not supported for shared_ptr" + return not self._is_array + + def __call__(self, obj): + return SharedPtrGetWorker.__call__(self, obj).dereference() + +class SharedPtrSubscriptWorker(SharedPtrGetWorker): + "Implements std::shared_ptr::operator[](size_t)" + + def __init__(self, elem_type): + SharedPtrGetWorker.__init__(self, elem_type) + + def get_arg_types(self): + return get_std_size_type() + + def get_result_type(self, obj, index): + return self._elem_type + + def _supports(self, method_name): + "operator[] is only supported for shared_ptr" + return self._is_array + + def __call__(self, obj, index): + # Check bounds if _elem_type is an array of known bound + m = re.match('.*\[(\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)))) + return SharedPtrGetWorker.__call__(self, obj)[index] + +class SharedPtrUseCountWorker(gdb.xmethod.XMethodWorker): + "Implements std::shared_ptr::use_count()" + + def __init__(self, elem_type): + SharedPtrUseCountWorker.__init__(self, elem_type) + + def get_arg_types(self): + return None + + def get_result_type(self, obj): + return gdb.lookup_type('long') + + def __call__(self, obj): + refcounts = obj['_M_refcount']['_M_pi'] + return refcounts['_M_use_count'] if refcounts else 0 + +class SharedPtrUniqueWorker(SharedPtrUseCountWorker): + "Implements std::shared_ptr::unique()" + + def __init__(self, elem_type): + SharedPtrUseCountWorker.__init__(self, elem_type) + + def get_result_type(self, obj): + return gdb.lookup_type('bool') + + def __call__(self, obj): + return SharedPtrUseCountWorker.__call__(self, obj) == 1 + +class SharedPtrMethodsMatcher(gdb.xmethod.XMethodMatcher): + def __init__(self): + gdb.xmethod.XMethodMatcher.__init__(self, + matcher_name_prefix + 'shared_ptr') + self._method_dict = { + 'get': LibStdCxxXMethod('get', SharedPtrGetWorker), + 'operator->': LibStdCxxXMethod('operator->', SharedPtrGetWorker), + 'operator*': LibStdCxxXMethod('operator*', SharedPtrDerefWorker), + 'operator[]': LibStdCxxXMethod('operator[]', SharedPtrSubscriptWorker), + 'use_count': LibStdCxxXMethod('use_count', SharedPtrUseCountWorker), + 'unique': LibStdCxxXMethod('unique', SharedPtrUniqueWorker), + } + 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): + return None + method = self._method_dict.get(method_name) + if method is None or not method.enabled: + return None + worker = method.worker_class(class_type.template_argument(0)) + if worker._supports(method_name): + return worker + return None + +def register_libstdcxx_xmethods(locus): + gdb.xmethod.register_xmethod_matcher(locus, ArrayMethodsMatcher()) + gdb.xmethod.register_xmethod_matcher(locus, ForwardListMethodsMatcher()) + gdb.xmethod.register_xmethod_matcher(locus, DequeMethodsMatcher()) + gdb.xmethod.register_xmethod_matcher(locus, ListMethodsMatcher()) + gdb.xmethod.register_xmethod_matcher(locus, VectorMethodsMatcher()) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('set')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('map')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('multiset')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('multimap')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('unordered_set')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('unordered_map')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('unordered_multiset')) + gdb.xmethod.register_xmethod_matcher( + locus, AssociativeContainerMethodsMatcher('unordered_multimap')) + gdb.xmethod.register_xmethod_matcher(locus, UniquePtrMethodsMatcher()) + gdb.xmethod.register_xmethod_matcher(locus, SharedPtrMethodsMatcher()) From 4633a8f93ac9ea7c30a026f465fa3eee9eccb6b9 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 16 Mar 2023 17:07:19 +0800 Subject: [PATCH 04/11] remove pyc files --- .../gcc-11.2.0/python/libstdcxx/v6/__init__.pyc | Bin 863 -> 0 bytes .../gcc-11.2.0/python/libstdcxx/v6/printers.pyc | Bin 85322 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.pyc delete mode 100644 tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.pyc diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.pyc b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/__init__.pyc deleted file mode 100644 index 60dc66340288e353c1f8c1416985b46713495299..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 863 zcmcIiO^*^m5UuKAiCg}skup2NhLOc~J^IEuc*VTwKH zD7hN>6~NLz7z0PaI9_1gV3`ig=851y1eP6UW-&&Nj2m=Eycm*YFz z$AafQ)on9|^5nPt>ES(w~N9%R>+jTb#(;~HD7$B*A zs1nX6COmd%9wTNNFvK1=xyCJyq$TM{Ugv~)14mR*qDs!RW8y8-mS_(T((H+J-$6Xe zJjyGyQ-G)vQXpUS5D8-$0VR~bm;e9( diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.pyc b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.pyc deleted file mode 100644 index f230c733976baa3c48dd5a9435c7ba1b02354c1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85322 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 Date: Thu, 16 Mar 2023 17:27:00 +0800 Subject: [PATCH 05/11] handle not initialized std::vector in gdb --- .../gcc-11.2.0/python/libstdcxx/v6/printers.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.py b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.py index 550e0ecd..158b9b1d 100644 --- a/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.py +++ b/tools/gdb-scripts/gcc-11.2.0/python/libstdcxx/v6/printers.py @@ -441,11 +441,21 @@ class StdVectorPrinter: self.typename = strip_versioned_namespace(typename) self.val = val self.is_bool = val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL + start = self.val['_M_impl']['_M_start'] + finish = self.val['_M_impl']['_M_finish'] + end = self.val['_M_impl']['_M_end_of_storage'] + if int(finish - start)<0 or int(end - start)<0 or finish > end : + self.valid = False + else: + self.valid = True def children(self): - return self._iterator(self.val['_M_impl']['_M_start'], + if self.valid: + return self._iterator(self.val['_M_impl']['_M_start'], self.val['_M_impl']['_M_finish'], self.is_bool) + else: + return None def to_string(self): start = self.val['_M_impl']['_M_start'] @@ -462,8 +472,11 @@ class StdVectorPrinter: return ('%s of length %d, capacity %d' % (self.typename, int (length), int (capacity))) else: - return ('%s of length %d, capacity %d' + if self.valid: + return ('%s of length %d, capacity %d' % (self.typename, int (finish - start), int (end - start))) + else: + return ('Not initialized') def display_hint(self): return 'array' From f8076dd069fd25aa47e8a3f71a2fae48513e56d2 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 16 Mar 2023 18:11:05 +0800 Subject: [PATCH 06/11] - fix: None initialized std::vector is not correctly displayed in the gdb of the gcc distributed with redpanda-c++ (Windows 64bit). --- NEWS.md | 1 + RedPandaIDE/mainwindow.cpp | 2 +- packages/msys/build-x64.sh | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index c62d08da..63b4635f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,6 +17,7 @@ Red Panda C++ Version 2.18 - fix: The comboxbox to input address expression in the debug panel's memory view is case insensitive. - fix: The comboxbox to input evaluation expression in the debug panel is case insensitive. - fix: The comboxbox to input replace text in the search panel is case insensitive. + - fix: None initialized std::vector is not correctly displayed in the gdb of the gcc distributed with redpanda-c++ (Windows 64bit). Red Panda C++ Version 2.17 diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 198da6ed..1d2521db 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -2395,7 +2395,7 @@ void MainWindow::debug() mDebugger->sendCommand("-gdb-set", "width 0"); // don't wrap output, very annoying mDebugger->sendCommand("-gdb-set", "confirm off"); mDebugger->sendCommand("-gdb-set", "print repeats 0"); // don't repeat elements - mDebugger->sendCommand("-gdb-set", "print elements 0"); // don't limit elements + mDebugger->sendCommand("-gdb-set", "print elements 500"); // limit array elements to 500 mDebugger->sendCommand("-environment-cd", QString("\"%1\"").arg(extractFileDir(filePath))); // restore working directory if (pSettings->debugger().useGDBServer()) { mDebugger->sendCommand("-target-select",QString("remote localhost:%1").arg(pSettings->debugger().GDBServerPort())); diff --git a/packages/msys/build-x64.sh b/packages/msys/build-x64.sh index b4bc0fea..8fdb7db1 100644 --- a/packages/msys/build-x64.sh +++ b/packages/msys/build-x64.sh @@ -59,7 +59,9 @@ echo "Making installer..." pushd . cd "${PACKAGE_DIR}" -ln -s "${MINGW}" $MinGW_NAME +cp -a "${MINGW}" . +rm -rf "${MINGW_NAME}/share/gcc-11.2.0" +cp -a "${SOURCE_DIR}/tools/gdb-scripts/gcc-11.2.0" "${MINGW_NAME}/share" cp "${SOURCE_DIR}/platform/windows/installer-scripts/lang.nsh" . cp "${SOURCE_DIR}/platform/windows/installer-scripts/redpanda-x64.nsi" . From 626217f8565bbd612535ecb6c0a3bccc2926e105 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 16 Mar 2023 22:02:32 +0800 Subject: [PATCH 07/11] - fix: Don't show completion info when input parameters for function definitions. - fix: Don't show function info tips when typing class variable definitions. - fix: Compare error in debug mode. --- NEWS.md | 2 + RedPandaIDE/editor.cpp | 110 ++++++++++++++++---------- RedPandaIDE/editor.h | 2 +- RedPandaIDE/parser/statementmodel.cpp | 11 ++- RedPandaIDE/parser/statementmodel.h | 2 +- 5 files changed, 80 insertions(+), 47 deletions(-) diff --git a/NEWS.md b/NEWS.md index 63b4635f..afc51503 100644 --- a/NEWS.md +++ b/NEWS.md @@ -18,6 +18,8 @@ Red Panda C++ Version 2.18 - fix: The comboxbox to input evaluation expression in the debug panel is case insensitive. - fix: The comboxbox to input replace text in the search panel is case insensitive. - fix: None initialized std::vector is not correctly displayed in the gdb of the gcc distributed with redpanda-c++ (Windows 64bit). + - fix: Don't show completion info when input parameters for function definitions. + - fix: Don't show function info tips when typing class variable definitions. Red Panda C++ Version 2.17 diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 65f9c0db..2f6a9e11 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -1780,7 +1780,7 @@ void Editor::onStatusChanged(QSynedit::StatusChanges changes) } } - if (changes.testFlag(QSynedit::scInsertMode) | changes.testFlag(QSynedit::scReadOnly)) + if (changes.testFlag(QSynedit::scInsertMode) || changes.testFlag(QSynedit::scReadOnly)) pMainWindow->updateForStatusbarModeInfo(); pMainWindow->updateEditorActions(); @@ -3573,45 +3573,71 @@ void Editor::cleanAutoBackup() } } -bool Editor::testInFunc(int x, int y) +bool Editor::testInFunc(const QSynedit::BufferCoord& pos) { - bool result = false; - QString s = document()->getLine(y); - int posY = y; - int posX = std::min(x,s.length()-1); // x is started from 1 - int bracketLevel=0; - while (true) { - while (posX < 0) { - posY--; - if (posY < 0) - return false; - s = document()->getLine(posY); - posX = s.length()-1; - } - if (s[posX] == '>' - || s[posX] == ']') { - bracketLevel++; - } else if (s[posX] == '<' - || s[posX] == '[') { - bracketLevel--; - } else if (bracketLevel==0) { - switch (s[posX].unicode()) { - case '(': - return true; - case ';': - case '{': - return false; - } - if (!(isIdentChar(s[posX]) - || s[posX] == ' ' - || s[posX] == '\t' - || s[posX] == '*' - || s[posX] == '&')) - break;; - } - posX--; + int y=pos.line-1; + int x=pos.ch; + if (!syntaxer() || syntaxer()->language()!=QSynedit::ProgrammingLanguage::CPP) + return false; + if (y==0) + syntaxer()->resetState(); + else + syntaxer()->setState(document()->getSyntaxState(y-1)); + syntaxer()->setLine(document()->getLine(y),y); +// qDebug()<getLine(y).length(); + QSynedit::SyntaxState state = syntaxer()->getState(); + while(!syntaxer()->eol()) { + int start = syntaxer()->getTokenPos(); + QString token = syntaxer()->getToken(); + int end = start + token.length(); +// qDebug()<getToken()<=x) + break; + state = syntaxer()->getState(); + syntaxer()->next(); } - return result; +// qDebug()<0; + + +// bool result = false; +// QString s = document()->getLine(y); +// int posY = y; +// int posX = std::min(x,s.length()-1); // x is started from 1 +// int bracketLevel=0; + +// while (true) { +// while (posX < 0) { +// posY--; +// if (posY < 0) +// return false; +// s = document()->getLine(posY); +// posX = s.length()-1; +// } +// if (s[posX] == '>' +// || s[posX] == ']') { +// bracketLevel++; +// } else if (s[posX] == '<' +// || s[posX] == '[') { +// bracketLevel--; +// } else if (bracketLevel==0) { +// switch (s[posX].unicode()) { +// case '(': +// return true; +// case ';': +// case '{': +// return false; +// } +// if (!(isIdentChar(s[posX]) +// || s[posX] == ' ' +// || s[posX] == '\t' +// || s[posX] == '*' +// || s[posX] == '&')) +// break;; +// } +// posX--; +// } +// return result; } void Editor::completionInsert(bool appendFunc) @@ -4188,7 +4214,6 @@ void Editor::updateFunctionTip(bool showTip) QSynedit::BufferCoord pWordBegin, pWordEnd; QString s = getWordAtPosition(this, functionNamePos, pWordBegin,pWordEnd, WordPurpose::wpInformation); - int x = pWordBegin.ch-1-1; QString line = document()->getLine(pWordBegin.line-1); bool hasPreviousWord=false; @@ -4206,9 +4231,10 @@ void Editor::updateFunctionTip(bool showTip) break; } + //handle class initializer if (x >= 0 && hasPreviousWord) { QSynedit::BufferCoord pos = pWordBegin; - pos.ch = x+1; + pos.ch = pWordBegin.ch; QString previousWord = getPreviousWordAtPositionForSuggestion(pos); PStatement statement = mParser->findStatementOf( @@ -4779,7 +4805,7 @@ QString Editor::getPreviousWordAtPositionForSuggestion(const QSynedit::BufferCoo if ((p.line<1) || (p.line>document()->count())) { return ""; } - bool inFunc = testInFunc(p.ch-1,p.line-1); + bool inFunc = testInFunc(p); QString s = document()->getLine(p.line - 1); int wordBegin; @@ -4800,7 +4826,7 @@ QString Editor::getPreviousWordAtPositionForSuggestion(const QSynedit::BufferCoo else return ""; } else if (bracketLevel==0) { - //we can't differentiate multiple definition and function parameter define here , so we don't handle ',' + //Differentiate multiple definition and function parameter define here if (s[wordEnd] == ',') { if (inFunc) // in func, dont skip ',' break; diff --git a/RedPandaIDE/editor.h b/RedPandaIDE/editor.h index 487b78a3..ce8037ab 100644 --- a/RedPandaIDE/editor.h +++ b/RedPandaIDE/editor.h @@ -271,7 +271,7 @@ private: void saveAutoBackup(); void cleanAutoBackup(); - bool testInFunc(int x,int y); + bool testInFunc(const QSynedit::BufferCoord& pos); void completionInsert(bool appendFunc=false); diff --git a/RedPandaIDE/parser/statementmodel.cpp b/RedPandaIDE/parser/statementmodel.cpp index dc1e195a..c564c1cb 100644 --- a/RedPandaIDE/parser/statementmodel.cpp +++ b/RedPandaIDE/parser/statementmodel.cpp @@ -84,6 +84,7 @@ void StatementModel::clear() { #endif } +#ifdef QT_DEBUG void StatementModel::dump(const QString &logFile) { QFile file(logFile); @@ -93,7 +94,6 @@ void StatementModel::dump(const QString &logFile) } } -#ifdef QT_DEBUG void StatementModel::dumpAll(const QString &logFile) { QFile file(logFile); @@ -104,11 +104,16 @@ void StatementModel::dumpAll(const QString &logFile) .arg(statement->command).arg(int(statement->kind)) .arg(statement->type).arg(statement->fullName) .arg((size_t)(statement->parentScope.lock().get())) - .arg((int)statement->classScope) + .arg((int)statement->accessibility) .arg(statement->fileName) .arg(statement->line) .arg(statement->definitionFileName) - .arg(statement->definitionLine)<definitionLine)<< +#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) + Qt::endl; +#else + endl; +#endif } } } diff --git a/RedPandaIDE/parser/statementmodel.h b/RedPandaIDE/parser/statementmodel.h index 48bca5c1..2709c244 100644 --- a/RedPandaIDE/parser/statementmodel.h +++ b/RedPandaIDE/parser/statementmodel.h @@ -36,8 +36,8 @@ public: const StatementMap& childrenStatements(const PStatement& statement = PStatement()) const; const StatementMap& childrenStatements(std::weak_ptr statement) const; void clear(); - void dump(const QString& logFile); #ifdef QT_DEBUG + void dump(const QString& logFile); void dumpAll(const QString& logFile); #endif private: From b4b41e43a18fc9e3dfdf0b3fe0bc4f7b0e27f31b Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Fri, 17 Mar 2023 08:47:05 +0800 Subject: [PATCH 08/11] - enhancement: Add option in the debug settings, to limit the length of the ouput generated by gdb for arrays. --- NEWS.md | 7 +- RedPandaIDE/mainwindow.cpp | 2 +- RedPandaIDE/settings.cpp | 12 + RedPandaIDE/settings.h | 4 + .../settingsdialog/debuggeneralwidget.cpp | 3 + .../settingsdialog/debuggeneralwidget.ui | 364 +++++++++++------- 6 files changed, 240 insertions(+), 152 deletions(-) diff --git a/NEWS.md b/NEWS.md index afc51503..ff9e15f1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,9 +8,9 @@ Red Panda C++ Version 2.18 - enhancement: Warn user and stop compile if project has missing files. - enhancement: Warn user when exit and save settings failed. - change: Remove compiler set options that's rarely used. - - enhancement: Options in compiler set settings, to generate syntax error for large stack objects. (Enable for Debug settings by default) - - enhancement: Options in compiler set settings, to generate protection code for stack smashing attack. (Enable for Debug settings by default) - - enhancement: Options in compiler set settings, to enable address sanitizer. Not available in windows.(Enable for Debug settings by default) + - enhancement: Add option in the compiler set settings, to generate syntax error for large stack objects. (Enable for Debug settings by default) + - enhancement: Add option in the compiler set settings, to generate protection code for stack smashing attack. (Enable for Debug settings by default) + - enhancement: Add option in the compiler set settings, to enable address sanitizer. Not available in windows.(Enable for Debug settings by default) - fix: The comboxbox to input search keyword in the search dialog is case insensitive. - fix: The comboxbox to input replace text in the search dialog is case insensitive. - fix: The comboxbox to input search keyword in the search in files dialog is case insensitive. @@ -20,6 +20,7 @@ Red Panda C++ Version 2.18 - fix: None initialized std::vector is not correctly displayed in the gdb of the gcc distributed with redpanda-c++ (Windows 64bit). - fix: Don't show completion info when input parameters for function definitions. - fix: Don't show function info tips when typing class variable definitions. + - enhancement: Add option in the debug settings, to limit the length of the ouput generated by gdb for arrays. Red Panda C++ Version 2.17 diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 1d2521db..24a7abcc 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -2395,7 +2395,7 @@ void MainWindow::debug() mDebugger->sendCommand("-gdb-set", "width 0"); // don't wrap output, very annoying mDebugger->sendCommand("-gdb-set", "confirm off"); mDebugger->sendCommand("-gdb-set", "print repeats 0"); // don't repeat elements - mDebugger->sendCommand("-gdb-set", "print elements 500"); // limit array elements to 500 + mDebugger->sendCommand("-gdb-set", QString("print elements %1").arg(pSettings->debugger().arrayElements())); // limit array elements to 500 mDebugger->sendCommand("-environment-cd", QString("\"%1\"").arg(extractFileDir(filePath))); // restore working directory if (pSettings->debugger().useGDBServer()) { mDebugger->sendCommand("-target-select",QString("remote localhost:%1").arg(pSettings->debugger().GDBServerPort())); diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index eeb8d966..1e40373c 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -4020,6 +4020,16 @@ void Settings::Debugger::setAutosave(bool newAutosave) mAutosave = newAutosave; } +int Settings::Debugger::arrayElements() const +{ + return mArrayElements; +} + +void Settings::Debugger::setArrayElements(int newArrayElements) +{ + mArrayElements = newArrayElements; +} + bool Settings::Debugger::useIntelStyle() const { return mUseIntelStyle; @@ -4068,6 +4078,7 @@ void Settings::Debugger::doSave() saveValue("gdb_server_port",mGDBServerPort); saveValue("memory_view_rows",mMemoryViewRows); saveValue("memory_view_columns",mMemoryViewColumns); + saveValue("array_elements",mArrayElements); } void Settings::Debugger::doLoad() @@ -4096,6 +4107,7 @@ void Settings::Debugger::doLoad() mGDBServerPort = intValue("gdb_server_port",41234); mMemoryViewRows = intValue("memory_view_rows",16); mMemoryViewColumns = intValue("memory_view_columns",16); + mArrayElements = intValue("array_elements",300); } Settings::CodeCompletion::CodeCompletion(Settings *settings):_Base(settings, SETTING_CODE_COMPLETION) diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index f4f4a41a..e98bf593 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -1281,6 +1281,9 @@ public: bool autosave() const; void setAutosave(bool newAutosave); + int arrayElements() const; + void setArrayElements(int newArrayElements); + private: bool mEnableDebugConsole; bool mShowDetailLog; @@ -1298,6 +1301,7 @@ public: int mGDBServerPort; int mMemoryViewRows; int mMemoryViewColumns; + int mArrayElements; // _Base interface protected: diff --git a/RedPandaIDE/settingsdialog/debuggeneralwidget.cpp b/RedPandaIDE/settingsdialog/debuggeneralwidget.cpp index 6f91da9f..c0847dfe 100644 --- a/RedPandaIDE/settingsdialog/debuggeneralwidget.cpp +++ b/RedPandaIDE/settingsdialog/debuggeneralwidget.cpp @@ -56,6 +56,7 @@ void DebugGeneralWidget::doLoad() ui->spinGDBServerPort->setValue(pSettings->debugger().GDBServerPort()); ui->spinMemoryViewRows->setValue(pSettings->debugger().memoryViewRows()); ui->spinMemoryViewColumns->setValue(pSettings->debugger().memoryViewColumns()); + ui->spinArrayElements->setValue(pSettings->debugger().arrayElements()); } void DebugGeneralWidget::doSave() @@ -78,6 +79,8 @@ void DebugGeneralWidget::doSave() pSettings->debugger().setGDBServerPort(ui->spinGDBServerPort->value()); pSettings->debugger().setMemoryViewRows(ui->spinMemoryViewRows->value()); pSettings->debugger().setMemoryViewColumns(ui->spinMemoryViewColumns->value()); + pSettings->debugger().setArrayElements(ui->spinArrayElements->value()); + pSettings->debugger().save(); pMainWindow->updateDebuggerSettings(); } diff --git a/RedPandaIDE/settingsdialog/debuggeneralwidget.ui b/RedPandaIDE/settingsdialog/debuggeneralwidget.ui index f298c2f9..fa54aaec 100644 --- a/RedPandaIDE/settingsdialog/debuggeneralwidget.ui +++ b/RedPandaIDE/settingsdialog/debuggeneralwidget.ui @@ -14,6 +14,58 @@ Form + + + + Autosave watches + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Max number of array elements displayed + + + + + + + 99999999 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -23,6 +75,18 @@ true + + 7 + + + 7 + + + 7 + + + 7 + @@ -57,24 +121,58 @@ - - - Skip system header and library files when step into - - - - - - - Skip project header and library files when step into - - - - - - - Skip custom header and library files when step into + + + Skip header files when step into + + + 7 + + + 7 + + + 7 + + + 7 + + + + + System library + + + + + + + Project library + + + + + + + Custom library + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + @@ -87,16 +185,16 @@ - 11 + 7 - 11 + 7 - 11 + 7 - 11 + 7 @@ -169,7 +267,11 @@ - + + + 999 + + @@ -202,128 +304,69 @@ Memory View - + 7 7 + + 7 + + + 7 + - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Memory View Rows - - - - - - - 1 - - - 999 - - - 8 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Memory View Columns - - - - - - - 1 - - - 8 - - - - - - - Qt::Horizontal - - - - 437 - 20 - - - - - - - - - - - - - - Autosave - - - - + - Autosave breakpoints and watches + Rows + + + + 1 + + + 999 + + + 8 + + + + + + + Columns + + + + + + + 1 + + + 8 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -333,6 +376,18 @@ CPU Window + + 7 + + + 7 + + + 7 + + + 7 + @@ -340,6 +395,13 @@ + + + + Show disassembly code in blend mode + + + @@ -373,7 +435,7 @@ 0 - + 0 @@ -386,6 +448,16 @@ 0 + + + + AT&&T + + + grpCPUDisassembly + + + @@ -397,14 +469,17 @@ - - - AT&&T + + + Qt::Horizontal - - grpCPUDisassembly - - + + + 40 + 20 + + + @@ -412,13 +487,6 @@ - - - - Show disassembly code in blend mode - - - From eb93d8369e79302c0ea57b9c640150f243457d19 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Fri, 17 Mar 2023 15:37:11 +0800 Subject: [PATCH 09/11] - enhancement: Show shortcut info in toolbar's tooltip. --- NEWS.md | 2 + RedPandaIDE/mainwindow.ui | 2 +- RedPandaIDE/shortcutmanager.cpp | 5 + RedPandaIDE/translations/RedPandaIDE_pt_BR.ts | 44 +- RedPandaIDE/translations/RedPandaIDE_zh_CN.ts | 1391 +++++++++-------- RedPandaIDE/translations/RedPandaIDE_zh_TW.ts | 50 +- 6 files changed, 779 insertions(+), 715 deletions(-) diff --git a/NEWS.md b/NEWS.md index ff9e15f1..b081b012 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,8 @@ Red Panda C++ Version 2.18 - fix: Don't show completion info when input parameters for function definitions. - fix: Don't show function info tips when typing class variable definitions. - enhancement: Add option in the debug settings, to limit the length of the ouput generated by gdb for arrays. + - enhancement: Show shortcut info in toolbar's tooltip. + Red Panda C++ Version 2.17 diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index 3da4f4e7..034ad9b0 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -2166,7 +2166,7 @@ Run - F10 + F11 diff --git a/RedPandaIDE/shortcutmanager.cpp b/RedPandaIDE/shortcutmanager.cpp index 2f832eda..ba0fd6fb 100644 --- a/RedPandaIDE/shortcutmanager.cpp +++ b/RedPandaIDE/shortcutmanager.cpp @@ -126,5 +126,10 @@ void ShortcutManager::applyTo(QAction *action) PEnvironmentShortcut item = mShortcuts.value(action->objectName(), PEnvironmentShortcut()); if (item && item->isAction) { action->setShortcut(QKeySequence::fromString(item->shortcut)); + action->setToolTip(action->text()+QString("(%1)").arg(item->shortcut)); + } else if (!action->shortcut().isEmpty()){ + action->setToolTip(action->text()+QString("(%1)").arg(action->shortcut().toString())); + } else { + action->setToolTip(action->text()); } } diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts index e1f66fbd..ebd8e6fe 100644 --- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts +++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts @@ -818,15 +818,15 @@ Skip system header and library files when step into - Ignorar os cabeçalho de sistema e os arquivos de biblioteca ao avançar + Ignorar os cabeçalho de sistema e os arquivos de biblioteca ao avançar Skip project header and library files when step into - Ignorar o cabeçalho de projeto e os arquivos de biblioteca ao avançar + Ignorar o cabeçalho de projeto e os arquivos de biblioteca ao avançar Skip custom header and library files when step into - Ignorar o cabeçalho personalizado e os arquivos de biblioteca ao avançar + Ignorar o cabeçalho personalizado e os arquivos de biblioteca ao avançar Debug Console @@ -850,7 +850,7 @@ Autosave - Salvar automaticamente + Salvar automaticamente Autosave breakpoints @@ -858,7 +858,7 @@ Autosave watches - Salvar automaticamente as observações + Salvar automaticamente as observações Show CPU Window when signal received @@ -890,14 +890,38 @@ Memory View Rows - Linhas da memória + Linhas da memória Memory View Columns - Colunas da memória + Colunas da memória - Autosave breakpoints and watches + Max number of array elements displayed + + + + Skip header files when step into + + + + System library + + + + Project library + + + + Custom library + + + + Rows + + + + Columns @@ -3453,7 +3477,7 @@ F10 - F10 + F10 Undo @@ -3561,7 +3585,7 @@ F11 - F11 + F11 Rebuild All diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts index 8335071e..1f55aed2 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts @@ -1147,78 +1147,77 @@ Are you really want to continue? 表单 - + + Max number of array elements displayed + 最多显示多少个数组元素 + + + Use GDB Server to debug 使用gdb server调试 - + GDB Server Port gdb server TCP端口号 - Skip system header and library files when step into - 单步进入时,跳过系统头文件和库文件 + 单步进入时,跳过系统头文件和库文件 - Skip project header and library files when step into - 单步进入时,跳过项目头文件和库文件 + 单步进入时,跳过项目头文件和库文件 - Skip custom header and library files when step into - 单步进入时,跳过自定义头文件和库文件 + 单步进入时,跳过自定义头文件和库文件 - + Debug Console 调试主控台 - + Font: 字体: - + Show only monospaced fonts 只显示等宽字体 - + Size: 大小: - + Show detail debug logs Show debug logs in the debug console 显示详细调试器日志 - + Memory View 内存视图 - Memory View Rows - 内存视图行数 + 内存视图行数 - Memory View Columns - 内存视图列数 + 内存视图列数 - Autosave breakpoints and watches - 自动保存断点和监视表达式 + 自动保存断点和监视表达式 - + Show CPU Window when signal received 程序收到信号停止时缺省打开CPU窗口 @@ -1227,44 +1226,74 @@ Are you really want to continue? 在调试主控台中显示gdb输出注解 - Autosave - 自动保存 + 自动保存 Autosave breakpoints 自动保存断点 + Autosave watches - 自动保存监视 + 自动保存监视 Disassembly Coding Style 反汇编代码样式 - + CPU Window CPU信息窗口 - + Disassembly Coding Style: 反汇编代码样式 - + Intel Intel - + AT&&T AT&&T - + + Skip header files when step into + 在单步进入时跳过下列头文件 + + + + System library + 系统库 + + + + Project library + 项目库 + + + + Custom library + 自定义库 + + + + Rows + + + + + Columns + + + + Show disassembly code in blend mode 以混合模式显示反汇编代码 @@ -1508,9 +1537,9 @@ Are you really want to continue? 打印文档 - - - + + + Ctrl+click for more info Ctrl+单击以获取更多信息 @@ -1519,27 +1548,27 @@ Are you really want to continue? 未找到符号'%1'! - + astyle not found 找不到astyle程序 - + Can't find astyle in "%1". 找不到astyle程序"%1". - + Break point condition 断点条件 - + Enter the condition of the breakpoint: 输入当前断点的生效条件: - + Readonly 只读 @@ -3220,7 +3249,7 @@ Are you really want to continue? Insert empty lines around all blocks Insert empy lines around all blocks - 在所有代码段之间加入空行 + 在所有代码段之间加入空行 @@ -4258,18 +4287,18 @@ Are you really want to continue? MainWindow - + Red Panda C++ 小熊猫C++ - - - - - - + + + + + + Issues 编译器 @@ -4288,8 +4317,8 @@ Are you really want to continue? 工具 - - + + Run 运行 @@ -4301,25 +4330,25 @@ Are you really want to continue? - + Project 项目 - + Watch 监视 - + Structure 结构 - + Files 文件 @@ -4329,68 +4358,68 @@ Are you really want to continue? - - - - + + + + Debug 调试 - + Evaluate: 求值 - - + + Debug Console 调试主控台 - + Call Stack 调用栈 - + Breakpoints 断点 - + Locals 局部变量 - - + + Search 查找 - + History: 历史: - + Search Again 重新查找 - + Replace with: 替换为: - + Replace 替换 - + Close 关闭 @@ -4419,76 +4448,76 @@ Are you really want to continue? 工具栏2 - + New 新建 - + Ctrl+N Ctrl+N - + Open... 打开... - + Ctrl+O Ctrl+O - + Save 保存 - + Ctrl+S Ctrl+S - + Save As... 另存为... - + Save As 另存为 - + Save All 全部保存 - + Ctrl+Shift+S Ctrl+Shift+S - + Options 选项 - - + + Compile 编译 - - + + Tools Output 工具输出 - - + + Choose Input File 选择输入文件 @@ -4512,133 +4541,132 @@ Are you really want to continue? 选择 - + F9 F9 - F10 - F10 + F10 - + Undo 恢复 - + Ctrl+Z Ctrl+Z - + Redo 重做 - + Ctrl+Y Ctrl+Y - + Cut 剪切 - + Ctrl+X Ctrl+X - - - - + + + + Copy 复制 - + Ctrl+C Ctrl+C - - + + Paste 粘贴 - + Ctrl+V Ctrl+V - - - + + + Select All 选择全部 - + Ctrl+A Ctrl+A - + Indent 缩进 - + UnIndent 取消缩进 - + Toggle Comment 切换注释 - + Ctrl+/ Ctrl+/ - + Collapse All 全部收起 - + Uncollapse All 全部展开 - + Encode in ANSI 使用ANSI编码 - + Encode in UTF-8 使用UTF-8编码 - + Auto Detect 自动检测 - + Convert to ANSI 转换为ANSI编码 - + Convert to UTF-8 转换为UTF-8编码 @@ -4647,182 +4675,183 @@ Are you really want to continue? 编译运行 + F11 - F11 + F11 - - + + Rebuild All 全部重编译 - + F12 F12 - + Stop Execution 停止执行 - + F6 F6 - + F5 F5 - + Step Over 单步跨过 - + F7 F7 - + Step Into 单步进入 - + Problem Set 试题集 - - + + New Problem Set 新建试题集 - + Add Problem 添加试题 - + Remove Problem 删除试题 - - + + Save Problem Set 保存试题集 - - + + Load Problem Set 载入试题集 - + Memory 内存 - + Address Expression: Address: 地址表达式: - + Cancel 取消 - - + + TODO TODO - - + + Bookmark 书签 - - - + + + Problem 试题 - - + + Add Probem Case 添加试题案例 - - - + + + Remove Problem Case Remove Problem Set 删除试题集 - - - + + + Open Anwser Source File 打开答案源代码文件 - - - + + + Run All Cases Run Current Case 运行所有案例 - - + + Problem Cases Validation Options 测试案例验证选项 - + %v/%m %v/%m - + Output 输出 - + Input 输入 - + Expected 期望输出 @@ -4862,15 +4891,15 @@ Are you really want to continue? - - + + Import FPS Problem Set 导入FPS试题集 - - + + Export FPS Problem Set 导出FPS试题集 @@ -4880,495 +4909,495 @@ Are you really want to continue? 消息 - + Open file in editors 在编辑器中打开文件 - + Choose Expected Output File 选择期望输出文件 - + Ignore Spaces 忽略空格 - + New C/C++ File 新建C/C++文件 - + New Source File 新建源代码文件 - + Tab Tab - + Shift+Tab Shift+Tab - + F8 F8 - + Step Out 单步跳出 - + Ctrl+F8 Ctrl+F8 - + Run To Cursor 执行到光标处 - + Ctrl+F5 Ctrl+F5 - + Continue 继续执行 - + F4 F4 - + Add Watch... 添加监视 - + View CPU Window... 打开CPU信息窗口... - + Exit 退出 - + Find... 查找... - + Ctrl+F Ctrl+F - + Find in Files... 在文件中查找... - + Ctrl+Shift+F Ctrl+Shift+F - + Replace... 替换 - + Ctrl+R Ctrl+R - + Find Next 查找下一个 - + F3 F3 - + Find Previous 查找前一个 - + Shift+F3 Shift+F3 - + Remove Watch 删除监视值 - + Remove All Watches Remove All 删除全部监视值 - + Modify Watch... 修改监视值 - + Reformat Code 对代码重新排版 - + Ctrl+Shift+A Ctrl+Shift+A - + Go back 前一次编辑位置 - + Ctrl+Alt+Left Ctrl+Alt+Left - + Forward 后一次编辑位置 - + Ctrl+Alt+Right Ctrl+Alt+Right - + Ctrl+W Ctrl+W - + Close All 全部关闭 - + Ctrl+Shift+W Ctrl+Shift+W - + Maximize Editor 最大化编辑器 - + Ctrl+F11 Ctrl+F11 - + Next 下一窗口 - + Ctrl+Tab Ctrl+Tab - + Previous 前一窗口 - + Ctrl+Shift+Tab Ctrl+Shift+Tab - + Toggle breakpoint 切换断点 - + Ctrl+F4 Ctrl+F4 - - + + Clear all breakpoints 删除所有断点 - + Breakpoint property... 设置断点条件... - + Goto Declaration 跳转到声明处 - + Ctrl+Shift+G Ctrl+Shift+G - + Goto Definition 跳转到定义处 - + Ctrl+G Ctrl+G - + Find references 查找符号的引用 - + Open containing folder 打开所在的文件夹 - + Ctrl+B Ctrl+B - + Open a terminal here 打开命令行窗口 - + File Properties... 文件属性... - + Close Project 关闭项目 - + Project options 项目属性 - + New Project... 新建项目... - - + + New Project File 新建项目文件 - + Ctrl+F12 Ctrl+F12 - + F1 F1 - + New GAS File 新建GNU汇编文件 - + GNU Assembler Manual GNU汇编器手册 - + x86 Assembly Language Reference Manual X86汇编语言参考手册 - + IA-32 Assembly Language Reference Manual IA32汇编语言参考手册 - + Add Watchpoint... 添加变量断点... - + Add a watchpoint that's triggered when it's modified. 添加一个变量断点。当该变量的值被改动时程序暂停。 - + New Text File 新建文本文件 - + Move Selection Up 向上移动选中的行 - + Ctrl+Shift+Up Ctrl+Shift+Up - + Move Selection Down 向下移动选中的行 - + Ctrl+Shift+Down Ctrl+Shift+Down - + Convert to UTF-8 BOM 转换为UTF-8 BOM编码 - + Encode in UTF-8 BOM 使用UTF-8 BOM编码 - + Compiler Options... 编译器选项... - + Toggle Explorer Panel 切换管理器面板 - + Ctrl+F9 Ctrl+F9 - + Toggle Messages Panel 切换消息面板 - + Ctrl+F10 Ctrl+F10 - + Raylib Manual Raylib教程 - + Select Word 选中当前单词 - + Go to Line... 跳转到行... - + New Template... 新建模板... - + New Template from Project 从项目创建模板 - + Goto block start 跳转到代码段开始 - + Ctrl+Alt+Up Ctrl+Alt+Up - + Goto block end 跳转到代码段结束 - + Ctrl+Alt+Down Ctrl+Alt+Down - + Switch header/source 切换头文件/源文件 - + Switch Header/Source 切换头文件/源文件 - + Generate Assembly 生成汇编 - + Trim trailing spaces 删除行尾空格 - + Toggle Readonly 切换只读模式 - + Submit Issues 反馈与建议 - + Document 使用说明 @@ -5377,199 +5406,199 @@ Are you really want to continue? 保存为模板... - + New File 新建文件 - + Add to project... 添加到项目... - + Remove from project 从项目删除 - + View Makefile 查看Makefile - + Clean 清理构建文件 - + Open Folder in Explorer 在浏览器中打开 - + Open In Terminal 在终端中打开 - + About 关于 - - + + Rename Symbol 重命名符号 - + Shift+F6 Shift+F6 - + Print... 打印... - + Ctrl+P Ctrl+P - - + + Export As RTF 导出为RTF - - + + Export As HTML 导出为HTML - + Move To Other View 移动到其他视图 - + Ctrl+M Ctrl+M - - + + C++ Reference C++参考手册 - + C Reference C参考手册 - + Show Tool Panels 显示全部工具面板 - + Create Git Repository Create Repository 创建Git仓库 - + Commit 提交(Commit) - + Revert 撤销(Revert) - + Reset 回滚(Reset) - + Add Files 添加文件 - + Restore 还原(Restore) - + Website 官方网站 - + Branch/Switch 分支切换(Switch) - + Merge 合并(Merge) - - + + Show Log Log 显示日志(Log) - + Remotes... 远程仓库... - + Fetch 取回(Fetch) - + Pull 拉取(Pull) - + Push 推送(Push) - + Hide Non Support Files 隐藏不支持的文件 - + Toggle Block Comment 切换块注释 - + Alt+Shift+A Alt+Shift+A - + Match Bracket 匹配当前括号 - + Ctrl+] Ctrl+] @@ -5578,50 +5607,50 @@ Are you really want to continue? 工具窗口栏 - + Status Bar 状态栏 - + Ctrl+Backspace Ctrl+Backspace - + Interrupt 中断 - - + + Delete To Word Begin 删除到单词开头 - + Ctrl+Shift+B Ctrl+Shift+B - + Delete to Word End 删除到单词结尾 - + Ctrl+Shift+E Ctrl+Shift+E - + New Class... Add Class... 新建类... - - + + New Header... New Header 新建头文件... @@ -5631,47 +5660,47 @@ Are you really want to continue? 插入行 - + Delete Line 删除当前行 - + Ctrl+D Ctrl+D - + Duplicate Line 复制当前行 - + Ctrl+E Ctrl+E - + Delete Word 删除当前单词 - + Ctrl+Shift+D Ctrl+Shift+D - + Delete to EOL 删除到行尾 - + Ctrl+Del Ctrl+Del - + Delete to BOL 删除到行首 @@ -5680,27 +5709,27 @@ Are you really want to continue? C/C++参考 - + EGE Manual EGE图形库手册 - + Add Bookmark 添加书签 - + Remove Bookmark 删除书签 - + Modify Bookmark Description 修改书签说明 - + Locate in Files View 在文件视图中定位 @@ -5709,47 +5738,47 @@ Are you really want to continue? 打开文件夹 - + Running Parameters... 运行参数... - + File Encoding 文件编码 - + Recent Files 文件历史 - - - - - - + + + + + + Debugging 正在调试 - - - - - - + + + + + + Running 正在运行 - - - - - - + + + + + + Compiling 正在编译 @@ -5763,17 +5792,17 @@ Are you really want to continue? 行: %1 列: %2 已选择 :%3 总行数: %4 总长度: %5 - + Read Only 只读 - + Insert 插入 - + Overwrite 覆写 @@ -5790,7 +5819,7 @@ Are you really want to continue? 确认 - + Source file is not compiled. 源文件尚未编译。 @@ -5807,44 +5836,44 @@ Are you really want to continue? 重新编译? - - - - + + + + Wrong Compiler Settings 错误的编译器设置 - - - - + + + + Compiler is set not to generate executable. 编译器被设置为不生成可执行文件。 - - + + We need the executabe to run problem case. 我们需要可执行文件来运行试题案例。 - + No compiler set 无编译器设置 - + No compiler set is configured. 没有配置编译器设置。 - + Can't start debugging. 无法启动调试器 - + Enable debugging 启用调试参数 @@ -5861,33 +5890,33 @@ Are you really want to continue? 项目尚未构建。是否构建? - + Host applcation missing 宿主程序不存在 - + DLL project needs a host application to run. 动态链接库(DLL)需要一个宿主程序来运行。 - + But it's missing. 但它不存在。 - + Host application not exists 宿主程序不存在 - + Host application file '%1' doesn't exist. 宿主程序'%1'不存在。 - - + + Please correct this before start debugging 请在调试前改正设置。 @@ -5896,8 +5925,8 @@ Are you really want to continue? 重新编译? - - + + Save last open info error 保存上次打开信息失败 @@ -5906,86 +5935,86 @@ Are you really want to continue? 无法删除旧上次打开信息文件'%1' - + Can't save last open info file '%1' 无法保存上次打开信息文件'%1' - - + + Load last open info error 载入上次打开信息失败 - - + + Can't load last open info file '%1' 无法载入上次打开信息文件'%1' - + Open Source File 打开源代码文件 - - + + Batch Set Cases 批量设置案例 - + Show detail debug logs 显示详细调试器日志 - + Copy all 全部复制 - + Go to Line 跳转到行 - + Line - + Template Exists 模板已存在 - + Template %1 already exists. Do you want to overwrite? 模板%1已存在。是否覆盖? - - - - - - + + + + + + Clear 清除 - + Export 导出 - + Insert Snippet 插入代码段 - - + + Problem Set %1 试题集%1 @@ -6014,56 +6043,56 @@ Are you really want to continue? 项目已经被修改过,是否需要重新构建? - + Auto Save Error 自动保存出错 - + Auto save "%1" to "%2" failed:%3 自动保存"%1"到"%2"失败:%3 - + Properties... 试题属性... - + Set Problem Set Name 设置试题集名称 - + Problem Set Name: 试题集名称: - + Remove 删除 - + Remove All Bookmarks 删除全部书签 - + Modify Description 修改描述 - - - + + + Bookmark Description 书签描述 - - - + + + Description: 描述: @@ -6072,65 +6101,65 @@ Are you really want to continue? 在调试主控台中显示调试器输出 - + Remove this search 清除这次搜索 - + Clear all searches 删除所有搜索 - + Breakpoint condition... 断点条件... - + Break point condition 断点条件 - + Enter the condition of the breakpoint: 输入当前断点的生效条件: - + Remove All Breakpoints Remove all breakpoints 删除所有断点 - + Remove Breakpoint 删除当前断点 - + Rename File 重命名文件 - - + + Add Folder 添加文件夹 - - + + New folder 新文件夹 - + Folder name: 文件夹: - + Rename Folder 重命名 @@ -6143,247 +6172,247 @@ Are you really want to continue? 要现在去修改设置吗? - + Rename Problem Set 修改试题集名称 - + Can't open last open information file '%1' for write! 无法写入配置文件'%1'。 - + Rename Problem 修改试题名称 - + Line: %1 Col: %2 Lines: %3 行: %1 列: %2 总行数: %3 - + Correct compiler setting 改正编译器设置 - - + + You are using a Debug compiler set with wrong compile/link settings: 您使用的Debug编译器配置集中存在错误的“编译/链接”选项设置: - - + + - "Generate debug info (-g3)" should be turned on - 应勾选"生成调试信息(-g3)"选项 - + - "Strip executable (-s)" should be turned off - 应取消"剥除附加信息(-s)"选项 - - + + Do you want to correct it now? 是否现在去改正? - + Missing Project Files 项目文件缺失 - + The following files is missing, can't build the project: 下列项目文件缺失,无法构建项目: - - + + Can't Debug 无法调试 - - + + Your compiler set's "Strip executable (-s)" options is turnned on 您的编译器配置集中的“剥除附加信息(-s)”选项被勾选了。 - - + + Please correct it, recompile and retry debug. 请取消该设置,重新编译然后重新启动调试。 - + Goto Url 跳转到试题网址 - + Add Problem Case 添加试题案例 - + Run Current Case 运行当前案例 - + Remove Folder 删除文件夹 - + Switch to normal view 切换为普通视图 - + Switch to custom view 切换为自定义视图 - + Sort By Type 按类型排序 - + Sort alphabetically 按名称排序 - + Show inherited members 显示继承的成员 - + Goto declaration 跳转到声明处 - + Goto definition 跳转到定义处 - + In current file 仅当前文件 - + In current project 整个项目 - - + + New Folder 新建文件夹 - + Rename 重命名 - - + - + + Delete 删除 - + Open in Editor 在编辑器中打开 - + Open in External Program 使用外部程序打开 - + Open in Terminal 在终端中打开 - + Open in Windows Explorer 在Windows浏览器中打开 - + Character sets 字符集 - + Convert to %1 转换为%1编码 - + Newline 换行符 - + %1 files autosaved 已自动保存%1个文件 - + Set answer to... 设置答案源代码... - + select other file... 选择其他文件... - + Select Answer Source File 选择答案源代码文件 - + Watchpoint hitted 变量断点被触发 - + Value of "%1" has changed: "%1"的值发生了变化: - + New value: %1 新值: %1 - + Save settings failed! 保存设置失败 - + Watchpoint variable name 被监控的变量 - + Stop execution when the following variable is modified (it must be visible from the currect scope): 当下面的变量被修改时暂停执行(该变量必须可以从当前程序处访问): @@ -6392,17 +6421,17 @@ Are you really want to continue? 中止 - + FPS Problem Set Files (*.fps;*.xml) FPS试题集文件(*.fps;*.xml) - + FPS Problem Set Files (*.fps) FPS试题集文件(*.fps) - + Export Error 导出时出错 @@ -6412,7 +6441,7 @@ Are you really want to continue? C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + New Folder %1 新建文件夹%1 @@ -6425,12 +6454,12 @@ Are you really want to continue? 无标题%1 - + Do you really want to delete %1? 你真的要删除%1吗? - + Do you really want to delete %1 files? 你真的要删除%1个文件吗? @@ -6443,7 +6472,7 @@ Are you really want to continue? 变量"%1"有改动: - + Old value: %1 旧值: %1 @@ -6452,63 +6481,63 @@ Are you really want to continue? 新值: %1 - + Save project 保存项目 - + The project '%1' has modifications. 项目'%1'有改动。 - - + + Do you want to save it? 需要保存吗? - - + + File Changed 文件已发生变化 - - - + + + New Project File? 新建项目文件? - - - + + + Do you want to add the new file to the project? 您是否要将新建的文件加入项目? - - - - - + + + + + Save Error 保存失败 - + Change Project Compiler Set 改变项目编译器配置集 - + Change the project's compiler set will lose all custom compiler set options. 改变项目的编译器配置集会导致所有的自定义编译器选项被重置。 - - + + Do you really want to do that? 你真的想要那么做吗? @@ -6517,12 +6546,12 @@ Are you really want to continue? 批量设置案例 - + Choose input files 选择输入数据文件 - + Input data files (*.in) 输入数据文件 (*.in) @@ -6531,78 +6560,78 @@ Are you really want to continue? 无标题%1 - + Modify Watch 修改监视表达式 - + Watch Expression 监视表达式 - + Do you really want to clear all breakpoints in this file? 您真的要清除该文件的所有断点吗? - + New project 新建项目 - + Close %1 and start new project? 关闭'%1'以打开新项目? - + Folder not exist 文件夹不存在 - + Folder '%1' doesn't exist. Create it now? 文件夹'%1'不存在。是否创建? - + Can't create folder 无法创建文件夹 - + Failed to create folder '%1'. 创建文件夹'%1'失败。 - + Save new project as - + Folder %1 is not empty. 文件夹%1不是空的。 - + Do you really want to delete it? 你真的要删除它吗? - + Change working folder 改变工作文件夹 - + File '%1' is not in the current working folder. File '%1' is not in the current working folder 文件'%1'不在当前工作文件夹中。 - + Do you want to change working folder to '%1'? 是否将工作文件夹改设为'%1'? @@ -6611,28 +6640,28 @@ Are you really want to continue? 正在删除试题... - + Can't Commit 无法提交 - + Git needs user info to commit. Git需要用信息进行提交。 - + Choose Input Data File 选择输入数据文件 - - + + All files (*.*) 所有文件 (*.*) - + Choose Expected Output Data File Choose Expected Input Data File 选择期望输出文件 @@ -6642,61 +6671,61 @@ Are you really want to continue? 第%1行 - - - + + + Choose Working Folder 选择工作文件夹 - - + + Header Exists 头文件已存在 - - + + Header file "%1" already exists! 头文件"%1"已存在! - + Source Exists 源文件已存在! - + Source file "%1" already exists! 源文件"%1"已存在! - + Can't commit! 无法提交! - + The following files are in conflicting: 下列文件处于冲突状态,请解决后重新添加和提交: - + Commit Message 提交信息 - + Commit Message: 提交信息: - + Commit Failed 提交失败 - + Commit message shouldn't be empty! 提交信息不能为空! @@ -6705,22 +6734,22 @@ Are you really want to continue? 小熊猫Dev-C++项目文件 (*.dev) - + New project fail 新建项目失败 - + Can't assign project template 无法使用模板创建项目 - + Remove file 删除文件 - + Remove the file from disk? 同时从硬盘上删除文件? @@ -6729,27 +6758,27 @@ Are you really want to continue? 无标题 - + New Project File Name 新的项目文件名 - + File Name: 文件名: - + File Already Exists! 文件已存在! - + File '%1' already exists! 文件'%1'已经存在! - + Add to project 添加到项目 @@ -6766,27 +6795,27 @@ Are you really want to continue? 请在工具栏中选择Debug编译器配置集,或者在“编译器配置集”设置的“编译/链接选项”页中<b>启用</b>“生成调试信息(-g3)”、<b>禁用</b>“剥除附件信息(-3)”。 - + C/C++ Source Files (*.c *.cpp *.cc *.cxx) C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + This operation will remove all cases for the current problem. 本操作会删除此试题的所有案例。 - + Debug Failed 调试失败 - + The executable doesn't have symbol table, and can't be debugged. 可执行文件中没有符号表信息,无法调试。 - + Please turn off your compiler set's "Strip executable (-s)" option, recompile and retry debug. 请在选项对话框的编译器配置集页中取消“剥除附加信息(-s)”选项,重新编译后再调试。 @@ -6807,134 +6836,134 @@ Are you really want to continue? 您也可以删除所有断点,打开“CPU信息窗口”,然后调试汇编代码。 - + Failed to generate the executable. 未能生成可执行文件。 - + Please check detail info in "Tools Output" panel. 请查看“工具输出”面板中的详细信息。 - + Red Panda C++ project file (*.dev) 小熊猫C++项目文件(*.dev) - + Rename Error 重命名出错 - + Symbol '%1' is defined in system header. 符号'%1'在系统头文件中定义,无法修改。 - + New Name 新名称 - - - - + + + + Replace Error 替换出错 - + Can't open file '%1' for replace! 无法打开文件'%1'进行替换! - + Contents has changed since last search! 内容和上次查找时不一致。 - + Rich Text Format Files (*.rtf) RTF格式文件 (*.rtf) - + HTML Files (*.html) HTML文件 (*.html) - + The current problem set is not empty. 当前的试题集不是空的。 - + Problem %1 试题%1 - - + + Problem Set Files (*.pbs) 试题集文件 (*.pbs) - - + + Load Error 载入失败 - - + + Problem Case %1 试题案例%1 - - - - - - - - - - - - - - + + + + + + + + + + + + + + Error 错误 - + Recent Projects 项目历史 - + Load Theme Error 载入主题失败 - - + + Clear History 清除历史 - - + + The generated executable doesn't have symbol table, and can't be debugged. 编译生成的可执行文件中没有符号表,无法被调试。 - - + + Version Control 版本控制 @@ -6943,80 +6972,80 @@ Are you really want to continue? 请在工具栏中选用Debug编译器配置集,或者在选项对话框的编辑器配置集页中勾选“生成调试信息(-g3)"选项。 - + File '%1' was changed. 磁盘文件'%1'已被修改。 - + Reload its content from disk? 是否重新读取它的内容? - + File '%1' was removed. 磁盘文件'%1'已被删除。 - + Keep it open? 是否保持它在小熊猫C++中打开的编辑窗口? - + Open 打开 - - + + Compile Failed 编译失败 - + Run Failed 运行失败 - - - - + + + + Confirm Convertion 确认转换 - - - - + + + + The editing file will be saved using %1 encoding. <br />This operation can't be reverted. <br />Are you sure to continue? 当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗? - + New Watch Expression 新监视表达式 - + Enter Watch Expression (it is recommended to use 'this->' for class members): 输入监视表达式 - + Parsing file %1 of %2: "%3" (%1/%2)正在解析文件"%3" - + Done parsing %1 files in %2 seconds 完成%1个文件的解析,用时%2秒 - + (%1 files per second) (每秒%1个文件) @@ -8357,13 +8386,13 @@ Are you really want to continue? QObject - + Save 保存 - + Save changes to %1? 将修改保存到"%1"? @@ -8537,7 +8566,7 @@ Are you really want to continue? 生成调试信息(-g3) - + Would you like Red Panda C++ to search for compilers in PATH? 您同意小熊猫C++在PATH路径中寻找gcc编译器吗? @@ -8547,7 +8576,7 @@ Are you really want to continue? 生成性能分析信息(-pg) - + Warnings 代码警告 @@ -8570,32 +8599,32 @@ Are you really want to continue? 启用 - + Check for stack smashing attacks (-fstack-protector) 检查栈溢出(stack smashing)错误 (-fstack-protector) - + Enable Sanitizer (-fsanitize=) 启用地址消毒(-fsanitize=) - + Inhibit all warning messages (-w) 忽略所有警告信息(-w) - + Show most warnings (-Wall) 启用常见问题警告(-Wall) - + Show some more warnings (-Wextra) 启用更多问题警告(-Wextra) - + Check ISO C/C++ conformance (-pedantic) 检查是否严格遵守ISO C/C++标准 @@ -8604,22 +8633,22 @@ Are you really want to continue? 检查ISO C/C++/C++0x语法一致性(-pedantic) - + Only check the code for syntax errors (-fsyntax-only) 只进行语法检查(不编译)(-fsyntax-only) - + Make all warnings into errors (-Werror) 将警告作为错误处理(-Werror) - + Abort compilation on first error (-Wfatal-errors) 遇到第一个错误后立即中止编译(-Wfatal-errors) - + Linker 链接器 @@ -8628,17 +8657,17 @@ Are you really want to continue? 链接Objective-C程序 (-lobjc) - + Do not use standard system libraries (-nostdlib) 不使用标准库和系统启动文件(-nostdlib) - + Do not create a console window (-mwindows) 不产生控制台窗口(-mwindows) - + Strip executable (-s) 剥除附加信息(-s) @@ -8659,7 +8688,7 @@ Are you really want to continue? 仅预处理(-E) - + Use pipes instead of temporary files during compilation (-pipe) 编译时使用管道而不是临时文件(-pipe) @@ -8668,7 +8697,7 @@ Are you really want to continue? 只生成汇编代码(-S) - + Confirm 确认 @@ -8689,13 +8718,13 @@ Are you really want to continue? 如果仍然保留这些设置,可能会导致编译错误。<br /><br />请选择“是”,除非您清楚的知道选择“否”的后果, - - + + Compiler set not configuared. 未配置编译器设置。 - + Would you like Red Panda C++ to search for compilers in the following locations: <BR />'%1'<BR />'%2'? 您需要小熊猫C++在下列位置搜索编译器吗:<br />%1<br />%2 @@ -9696,7 +9725,7 @@ Are you really want to continue? - + Replace 替换 @@ -9705,37 +9734,37 @@ Are you really want to continue? 在文件中替换 - - + + Continue Search Search Around 继续查找 - - + + End of file has been reached. End of file has been reached. 已到达文件结尾。 - + Search 查找 - + Beginning of file has been reached. 已到达文件开头 - + Do you want to continue from file's end? 是否从文件结尾继续? - - + + Do you want to continue from file's beginning? Do you want to start from beginning? 是否从文件开头继续? @@ -9850,13 +9879,13 @@ Are you really want to continue? 继续替换 - - + + Searching... 正在查找... - + Abort 中止 @@ -10102,18 +10131,18 @@ Are you really want to continue? 性能 - - - + + + Compiler Set 编译器配置集 - - - + + + Compiler @@ -10125,7 +10154,7 @@ Are you really want to continue? 自动链接 - + @@ -10201,15 +10230,15 @@ Are you really want to continue? 杂项 - - + + Program Runner 程序运行 - + Problem Set 试题集 diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts index 127c0c3a..a85bcf4b 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts @@ -713,18 +713,6 @@ GDB Server Port - - Skip system header and library files when step into - - - - Skip project header and library files when step into - - - - Skip custom header and library files when step into - - Debug Console @@ -745,10 +733,6 @@ Show detail debug logs - - Autosave - - Show CPU Window when signal received @@ -778,15 +762,35 @@ - Memory View Rows + Autosave watches - Memory View Columns + Max number of array elements displayed - Autosave breakpoints and watches + Skip header files when step into + + + + System library + + + + Project library + + + + Custom library + + + + Rows + + + + Columns @@ -3284,10 +3288,6 @@ Run - - F10 - - Undo @@ -4900,6 +4900,10 @@ Save settings failed! + + F11 + + MemoryModel From a088c29b6746fe75c4dbb1d4c2c24e8ae725cb51 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Fri, 17 Mar 2023 15:41:18 +0800 Subject: [PATCH 10/11] update NEWS.md - change: Use F11 as the shortcut for "Run". (It's the old shortcut for "Compile&Run") --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index b081b012..a7d1d7b9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -22,6 +22,7 @@ Red Panda C++ Version 2.18 - fix: Don't show function info tips when typing class variable definitions. - enhancement: Add option in the debug settings, to limit the length of the ouput generated by gdb for arrays. - enhancement: Show shortcut info in toolbar's tooltip. + - change: Use F11 as the shortcut for "Run". (It's the old shortcut for "Compile&Run") Red Panda C++ Version 2.17 From af80ee04c404f223c9f4ecc6da155419a94cc299 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Fri, 17 Mar 2023 17:57:49 +0800 Subject: [PATCH 11/11] fix: Tooltips for no-shortcut actions is not correct --- RedPandaIDE/shortcutmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RedPandaIDE/shortcutmanager.cpp b/RedPandaIDE/shortcutmanager.cpp index ba0fd6fb..9d355dc9 100644 --- a/RedPandaIDE/shortcutmanager.cpp +++ b/RedPandaIDE/shortcutmanager.cpp @@ -126,8 +126,8 @@ void ShortcutManager::applyTo(QAction *action) PEnvironmentShortcut item = mShortcuts.value(action->objectName(), PEnvironmentShortcut()); if (item && item->isAction) { action->setShortcut(QKeySequence::fromString(item->shortcut)); - action->setToolTip(action->text()+QString("(%1)").arg(item->shortcut)); - } else if (!action->shortcut().isEmpty()){ + } + if (!action->shortcut().isEmpty()){ action->setToolTip(action->text()+QString("(%1)").arg(action->shortcut().toString())); } else { action->setToolTip(action->text());