printers.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # This file is part of Eigen, a lightweight C++ template library
3 # for linear algebra.
4 #
5 # Copyright (C) 2009 Benjamin Schindler <bschindler@inf.ethz.ch>
6 #
7 # This Source Code Form is subject to the terms of the Mozilla Public
8 # License, v. 2.0. If a copy of the MPL was not distributed with this
9 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 # Pretty printers for Eigen::Matrix
12 # This is still pretty basic as the python extension to gdb is still pretty basic.
13 # It cannot handle complex eigen types and it doesn't support any of the other eigen types
14 # Such as quaternion or some other type.
15 # This code supports fixed size as well as dynamic size matrices
16 
17 # To use it:
18 #
19 # * Create a directory and put the file as well as an empty __init__.py in
20 # that directory.
21 # * Create a ~/.gdbinit file, that contains the following:
22 # python
23 # import sys
24 # sys.path.insert(0, '/path/to/eigen/printer/directory')
25 # from printers import register_eigen_printers
26 # register_eigen_printers (None)
27 # end
28 
29 import gdb
30 import re
31 import itertools
32 
33 
35  "Print Eigen Matrix or Array of some kind"
36 
37  def __init__(self, variety, val):
38  "Extract all the necessary information"
39 
40  # Save the variety (presumably "Matrix" or "Array") for later usage
41  self.variety = variety
42 
43  # The gdb extension does not support value template arguments - need to extract them by hand
44  type = val.type
45  if type.code == gdb.TYPE_CODE_REF:
46  type = type.target()
47  self.type = type.unqualified().strip_typedefs()
48  tag = self.type.tag
49  regex = re.compile('<.*>')
50  m = regex.findall(tag)[0][1:-1]
51  template_params = m.split(',')
52  template_params = [x.replace(" ", "") for x in template_params]
53 
54  if template_params[1] == '-0x00000000000000001' or template_params[1] == '-0x000000001' or template_params[1] == '-1':
55  self.rows = val['m_storage']['m_rows']
56  else:
57  self.rows = int(template_params[1])
58 
59  if template_params[2] == '-0x00000000000000001' or template_params[2] == '-0x000000001' or template_params[2] == '-1':
60  self.cols = val['m_storage']['m_cols']
61  else:
62  self.cols = int(template_params[2])
63 
64  self.options = 0 # default value
65  if len(template_params) > 3:
66  self.options = template_params[3];
67 
68  self.rowMajor = (int(self.options) & 0x1)
69 
70  self.innerType = self.type.template_argument(0)
71 
72  self.val = val
73 
74  # Fixed size matrices have a struct as their storage, so we need to walk through this
75  self.data = self.val['m_storage']['m_data']
76  if self.data.type.code == gdb.TYPE_CODE_STRUCT:
77  self.data = self.data['array']
78  self.data = self.data.cast(self.innerType.pointer())
79 
80  class _iterator:
81  def __init__ (self, rows, cols, dataPtr, rowMajor):
82  self.rows = rows
83  self.cols = cols
84  self.dataPtr = dataPtr
85  self.currentRow = 0
86  self.currentCol = 0
87  self.rowMajor = rowMajor
88 
89  def __iter__ (self):
90  return self
91 
92  def next(self):
93  return self.__next__() # Python 2.x compatibility
94 
95  def __next__(self):
96 
97  row = self.currentRow
98  col = self.currentCol
99  if self.rowMajor == 0:
100  if self.currentCol >= self.cols:
101  raise StopIteration
102 
103  self.currentRow = self.currentRow + 1
104  if self.currentRow >= self.rows:
105  self.currentRow = 0
106  self.currentCol = self.currentCol + 1
107  else:
108  if self.currentRow >= self.rows:
109  raise StopIteration
110 
111  self.currentCol = self.currentCol + 1
112  if self.currentCol >= self.cols:
113  self.currentCol = 0
114  self.currentRow = self.currentRow + 1
115 
116 
117  item = self.dataPtr.dereference()
118  self.dataPtr = self.dataPtr + 1
119  if (self.cols == 1): #if it's a column vector
120  return ('[%d]' % (row,), item)
121  elif (self.rows == 1): #if it's a row vector
122  return ('[%d]' % (col,), item)
123  return ('[%d,%d]' % (row, col), item)
124 
125  def children(self):
126 
127  return self._iterator(self.rows, self.cols, self.data, self.rowMajor)
128 
129  def to_string(self):
130  return "Eigen::%s<%s,%d,%d,%s> (data ptr: %s)" % (self.variety, self.innerType, self.rows, self.cols, "RowMajor" if self.rowMajor else "ColMajor", self.data)
131 
133  "Print an Eigen Quaternion"
134 
135  def __init__(self, val):
136  "Extract all the necessary information"
137  # The gdb extension does not support value template arguments - need to extract them by hand
138  type = val.type
139  if type.code == gdb.TYPE_CODE_REF:
140  type = type.target()
141  self.type = type.unqualified().strip_typedefs()
142  self.innerType = self.type.template_argument(0)
143  self.val = val
144 
145  # Quaternions have a struct as their storage, so we need to walk through this
146  self.data = self.val['m_coeffs']['m_storage']['m_data']['array']
147  self.data = self.data.cast(self.innerType.pointer())
148 
149  class _iterator:
150  def __init__ (self, dataPtr):
151  self.dataPtr = dataPtr
152  self.currentElement = 0
153  self.elementNames = ['x', 'y', 'z', 'w']
154 
155  def __iter__ (self):
156  return self
157 
158  def next(self):
159  return self.__next__() # Python 2.x compatibility
160 
161  def __next__(self):
162  element = self.currentElement
163 
164  if self.currentElement >= 4: #there are 4 elements in a quanternion
165  raise StopIteration
166 
167  self.currentElement = self.currentElement + 1
168 
169  item = self.dataPtr.dereference()
170  self.dataPtr = self.dataPtr + 1
171  return ('[%s]' % (self.elementNames[element],), item)
172 
173  def children(self):
174 
175  return self._iterator(self.data)
176 
177  def to_string(self):
178  return "Eigen::Quaternion<%s> (data ptr: %s)" % (self.innerType, self.data)
179 
181  pretty_printers_dict[re.compile('^Eigen::Quaternion<.*>$')] = lambda val: EigenQuaternionPrinter(val)
182  pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter("Matrix", val)
183  pretty_printers_dict[re.compile('^Eigen::Array<.*>$')] = lambda val: EigenMatrixPrinter("Array", val)
184 
186  "Register eigen pretty-printers with objfile Obj"
187 
188  if obj == None:
189  obj = gdb
190  obj.pretty_printers.append(lookup_function)
191 
193  "Look-up and return a pretty-printer that can print va."
194 
195  type = val.type
196 
197  if type.code == gdb.TYPE_CODE_REF:
198  type = type.target()
199 
200  type = type.unqualified().strip_typedefs()
201 
202  typename = type.tag
203  if typename == None:
204  return None
205 
206  for function in pretty_printers_dict:
207  if function.search(typename):
208  return pretty_printers_dict[function](val)
209 
210  return None
211 
212 pretty_printers_dict = {}
213 
214 build_eigen_dictionary ()
def __init__(self, rows, cols, dataPtr, rowMajor)
Definition: printers.py:81
return int(ret)+1
def lookup_function(val)
Definition: printers.py:192
def __init__(self, variety, val)
Definition: printers.py:37
def register_eigen_printers(obj)
Definition: printers.py:185
def build_eigen_dictionary()
Definition: printers.py:180
size_t len(handle h)
Definition: pytypes.h:1514


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:43:29