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