1 #!/usr/bin/env python 2 3 """ 4 View annotated sources. 5 6 Copyright (C) 2006 Paul Boddie <paul@boddie.org.uk> 7 8 This software is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License as 10 published by the Free Software Foundation; either version 2 of 11 the License, or (at your option) any later version. 12 13 This software is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public 19 License along with this library; see the file LICENCE.txt 20 If not, write to the Free Software Foundation, Inc., 21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 22 """ 23 24 from compiler.visitor import ASTVisitor 25 import sys 26 27 class Viewer(ASTVisitor): 28 29 """ 30 A viewing visitor for AST nodes. 31 """ 32 33 def __init__(self, stream): 34 ASTVisitor.__init__(self) 35 self.cached_files = {} 36 self.printed_lines = {} 37 self.visitor = self 38 self.stream = stream 39 40 def process(self, module): 41 self.dispatch(module) 42 43 def dispatch(self, node): 44 self.print_line(getattr(node, "filename", None), getattr(node, "lineno", None)) 45 ASTVisitor.dispatch(self, node) 46 47 def print_line(self, filename, lineno): 48 last_printed = self.printed_lines.get(filename, 0) 49 if lineno > last_printed: 50 self.stream.write(self.get_line(filename, lineno)) 51 self.printed_lines[filename] = lineno 52 53 def get_line(self, filename, lineno): 54 if filename is None or lineno is None: 55 return "" 56 57 if self.cached_files.has_key(filename): 58 lines = self.cached_files[filename] 59 else: 60 f = open(filename) 61 try: 62 self.cached_files[filename] = lines = f.readlines() 63 finally: 64 f.close() 65 66 try: 67 return lines[lineno - 1] 68 except IndexError: 69 return "" 70 71 # Convenience functions. 72 73 def view(module, stream=None): 74 viewer = Viewer(stream or sys.stdout) 75 viewer.process(module.original) 76 77 # vim: tabstop=4 expandtab shiftwidth=4