--- /dev/null
+# ---------------------------------------------------------------------
+#
+# Copyright (C) 2015 by the deal.II authors
+#
+# This file is part of the deal.II library.
+#
+# The deal.II library is free software; you can use it, redistribute
+# it, and/or modify it under the terms of the GNU Lesser General
+# Public License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# The full text of the license can be found in the file LICENSE at
+# the top level of the deal.II distribution.
+#
+# ---------------------------------------------------------------------
+
+#
+# Instructions: Place a copy of this file, renamed as ".gdbinit", in your home
+# directory to enable pretty-printing of various deal.II objects.
+#
+# This has only been tested with GDB 7.7.1 and newer, but it should work with
+# slightly older versions of GDB (the Python interface was added in 7.0,
+# released in 2009).
+#
+# Authors: Wolfgang Bangerth, 2015, David Wells, 2015
+#
+set print pretty 1
+
+python
+
+import gdb
+import re
+
+
+def build_output_string(keys, accessor):
+ """Build an output string of the form
+ {
+ a = foo,
+ b = bar
+ }
+ where a and b are elements of keys and foo and bar are values of
+ accessor (e.g., accessor['a'] = foo).
+
+ Note that accessor need not be a dictionary (i.e., gdb.Values
+ redefines __getitem__)."""
+ return ("{\n" +
+ ",\n".join([" {} = {}".format(key, accessor[key])
+ for key in keys]) +
+ "\n}")
+
+
+class PointPrinter(object):
+ """Print a deal.II Point instance."""
+ def __init__(self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string(self):
+ return self.val['values']
+
+
+class TensorPrinter(object):
+ """Print a deal.II Tensor instance."""
+ def __init__(self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string(self):
+ if int(self.val.type.template_argument(0)) == 0:
+ return self.val['value']
+ else:
+ return self.val['values']
+
+
+class TriaIteratorPrinter(object):
+ """Print a deal.II TriaIterator instance."""
+ def __init__(self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string(self):
+ keys = ['tria', 'present_level', 'present_index']
+ if 'DoFHandler' in str(self.val.type.template_argument(0)):
+ keys.insert(1, 'dof_handler')
+
+ return build_output_string(keys, self.val['accessor'])
+
+
+class VectorPrinter(object):
+ """Print a deal.II Vector instance."""
+ def __init__(self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def children(self):
+ # The first entry (see the "Pretty Printing API" documentation of GDB)
+ # in the tuple should be a name for the child, which should be nothing
+ # (an empty string) here.
+ return (("", (self.val['val'] + count).dereference())
+ for count in range(int(self.val['vec_size'])))
+
+ def to_string(self):
+ return "{}[{}]".format(self.val.type.template_argument(0),
+ self.val['vec_size'])
+
+ @staticmethod
+ def display_hint():
+ """Provide a hint to GDB that this is an array-like container
+ (so print values in sequence)."""
+ return "array"
+
+
+class QuadraturePrinter(object):
+ """Print a deal.II Quadrature instance."""
+ def __init__(self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string(self):
+ return build_output_string(['quadrature_points', 'weights'], self.val)
+
+
+class RxPrinter(object):
+ """A "regular expression" printer which conforms to the
+ "SubPrettyPrinter" protocol from gdb.printing."""
+ def __init__(self, name, function):
+ self.name = name
+ self.function = function
+ self.enabled = True
+
+ def __call__(self, value):
+ if self.enabled:
+ return self.function(self.name, value)
+ else:
+ return None
+
+
+class Printer(object):
+ """A pretty-printer that conforms to the "PrettyPrinter" protocol
+ from gdb.printing. It can also be used directly as an old-style
+ printer."""
+ def __init__(self, name):
+ self.name = name
+ self.subprinters = list()
+ self.lookup = dict()
+ self.enabled = True
+ self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)<.*>$')
+
+ def add(self, name, function):
+ printer = RxPrinter(name, function)
+ self.subprinters.append(printer)
+ self.lookup[name] = printer
+
+ @staticmethod
+ def get_basic_type(object_type):
+ # If it points to a reference, then get the reference.
+ if object_type.code == gdb.TYPE_CODE_REF:
+ object_type = object_type.target()
+
+ object_type = object_type.unqualified().strip_typedefs()
+
+ return object_type.tag
+
+ def __call__(self, val):
+ typename = self.get_basic_type(val.type)
+ if typename:
+ # All the types we match are template types, so we can use a
+ # dictionary.
+ match = self.compiled_rx.match(typename)
+ if match:
+ basename = match.group(1)
+ if basename in self.lookup:
+ return self.lookup[basename](val)
+
+ return None
+
+
+dealii_printer = Printer("deal.II")
+
+
+def register_dealii_printers():
+ """Register deal.II pretty-printers with gdb."""
+ printers = {
+ PointPrinter: ['Point'],
+ TensorPrinter: ['Tensor'],
+ VectorPrinter: ['Vector'],
+ TriaIteratorPrinter:
+ ['TriaRawIterator', 'TriaIterator', 'TriaActiveIterator'],
+ QuadraturePrinter:
+ ['Quadrature', 'QGauss', 'QGaussLobatto', 'QMidpoint', 'QSimpson',
+ 'QTrapez', 'QMilne', 'QWeddle', 'QGaussLog', 'QGaussLogR',
+ 'QGaussOneOverR', 'QSorted', 'QTelles', 'QGaussChebyshev',
+ 'QGaussRadauChebyshev', 'QIterated', 'QAnisotropic']
+ }
+ for printer, class_names in printers.items():
+ for class_name in class_names:
+ dealii_printer.add('dealii::' + class_name, printer)
+ try:
+ from gdb import printing
+ printing.register_pretty_printer(gdb, dealii_printer)
+ except ImportError:
+ gdb.pretty_printers.append(dealii_printer)
+
+
+register_dealii_printers()
+
+end