1 #!/usr/bin/env python 2 3 """ 4 A module providing elementary graph support for programs. 5 6 Copyright (C) 2008 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 import micropython.inspect 23 import micropython.common 24 import micropython.data 25 import sys 26 27 def get_graph(importer, out=None, with_builtins=0): 28 29 """ 30 Using the program maintained by the given 'importer', write out the graph 31 definition for consumption by the Graphviz tools such as the dot program. 32 If the optional 'out' parameter is set to a stream, that stream will be 33 used to write out the graph definition; otherwise, standard output will be 34 used. If 'with_builtins' is set to a true value, the module providing the 35 built-in classes and functions will also be represented in the graph. 36 """ 37 38 out = out or sys.stdout 39 print >>out, 'digraph G {' 40 print >>out, ' ratio=auto;' 41 print >>out, ' center=true;' 42 print >>out, ' rankdir=LR;' 43 for module in importer.modules_ordered: 44 if not with_builtins and module.name == "__builtins__": 45 continue 46 47 print >>out, ' subgraph "%s" {' % module.full_name() 48 print >>out, ' label="%s";' % module.full_name() 49 for obj in module.all_objects: 50 51 if isinstance(obj, micropython.inspect.Class): 52 print >>out, ' "%s" [' % obj.full_name(), 53 print >>out, 'shape=record,', 54 print >>out, 'label="{<%s> %s|{' % (obj.full_name(), obj.full_name()), 55 first = 1 56 for attr in obj.all_attributes().values(): 57 if not first: 58 print >>out, '|', 59 print >>out, '<%s> %s' % (attr.name, attr.name), 60 first = 0 61 print >>out, '}}"];' 62 63 elif isinstance(obj, micropython.inspect.Function): 64 print >>out, ' "%s" [' % obj.full_name(), 65 print >>out, 'shape=record,', 66 print >>out, 'label="{<%s> %s|{' % (obj.full_name(), obj.full_name()), 67 first = 1 68 for attr in obj.all_locals().values(): 69 if not first: 70 print >>out, '|', 71 print >>out, '<%s> %s' % (attr.name, attr.name), 72 first = 0 73 print >>out, '}}"];' 74 75 print >>out, ' }' 76 77 for module in importer.modules_ordered: 78 if not with_builtins and module.name == "__builtins__": 79 continue 80 81 print >>out, ' {' 82 for obj in module.all_objects: 83 if isinstance(obj, micropython.inspect.Class): 84 for attr in obj.all_attributes().values(): 85 if attr.value is not None: 86 print >>out, ' "%s":%s -> "%s";' % (obj.full_name(), attr.name, get_name(attr.value)) 87 elif isinstance(obj, micropython.inspect.Function): 88 for attr in obj.all_locals().values(): 89 if attr.value is not None: 90 print >>out, ' "%s":%s -> "%s";' % (obj.full_name(), attr.name, get_name(attr.value)) 91 print >>out, ' }' 92 93 print >>out, "}" 94 95 def get_name(obj): 96 if isinstance(obj, micropython.common.Naming): 97 return obj.full_name() 98 elif isinstance(obj, micropython.data.Const): 99 return obj.value_type_name() 100 else: 101 return "<None>" 102 103 # vim: tabstop=4 expandtab shiftwidth=4