Mercurial > lcfOS
diff python/ppci/common.py @ 312:2c9768114877
Added cool logging formatter
author | Windel Bouwman |
---|---|
date | Mon, 16 Dec 2013 17:58:15 +0100 |
parents | 6aa721e7b10b |
children | 6f4753202b9a |
line wrap: on
line diff
--- a/python/ppci/common.py Mon Dec 16 12:49:24 2013 +0100 +++ b/python/ppci/common.py Mon Dec 16 17:58:15 2013 +0100 @@ -1,5 +1,11 @@ from collections import namedtuple +import logging +""" + Error handling routines + Diagnostic utils + Source location structures +""" # Token is used in the lexical analyzer: class Token: @@ -27,3 +33,79 @@ SourceRange = namedtuple('SourceRange', ['p1', 'p2']) + + +class CompilerError(Exception): + def __init__(self, msg, loc=None): + self.msg = msg + self.loc = loc + if loc: + assert type(loc) is SourceLocation, \ + '{0} must be SourceLocation'.format(type(loc)) + self.row = loc.row + self.col = loc.col + else: + self.row = self.col = 0 + + def __repr__(self): + return '"{}"'.format(self.msg) + + +class DiagnosticsManager: + def __init__(self): + self.diags = [] + self.sources = {} + self.logger = logging.getLogger('diagnostics') + + def addSource(self, name, src): + self.logger.info('Adding source {}'.format(name)) + self.sources[name] = src + + def addDiag(self, d): + #self.logger.warning(str(d.msg)) + self.diags.append(d) + + def error(self, msg, loc): + self.addDiag(CompilerError(msg, loc)) + + def clear(self): + del self.diags[:] + self.sources.clear() + + def printErrors(self): + if len(self.diags) > 0: + print('{0} Errors'.format(len(self.diags))) + for d in self.diags: + self.printError(d) + + def printError(self, e): + def printLine(row, txt): + print(str(row)+':'+txt) + print('==============') + if not e.loc: + print('Error: {0}'.format(e)) + else: + if e.loc.filename not in self.sources: + print('Error: {0}'.format(e)) + return + print("File: {}".format(e.loc.filename)) + source = self.sources[e.loc.filename] + lines = source.split('\n') + ro, co = e.row, e.col + prerow = ro - 2 + if prerow < 1: + prerow = 1 + afterrow = ro + 3 + if afterrow > len(lines): + afterrow = len(lines) + + # print preceding source lines: + for r in range(prerow, ro): + printLine(r, lines[r-1]) + # print source line containing error: + printLine(ro, lines[ro-1]) + print(' '*(len(str(ro)+':')+co-1) + '^ Error: {0}'.format(e.msg)) + # print trailing source line: + for r in range(ro+1, afterrow+1): + printLine(r, lines[r-1]) + print('==============')