|
"""JSON token scanner |
|
""" |
|
import re |
|
|
|
__all__ = ['HjsonDecodeError'] |
|
|
|
class HjsonDecodeError(ValueError): |
|
"""Subclass of ValueError with the following additional properties: |
|
|
|
msg: The unformatted error message |
|
doc: The JSON document being parsed |
|
pos: The start index of doc where parsing failed |
|
end: The end index of doc where parsing failed (may be None) |
|
lineno: The line corresponding to pos |
|
colno: The column corresponding to pos |
|
endlineno: The line corresponding to end (may be None) |
|
endcolno: The column corresponding to end (may be None) |
|
|
|
""" |
|
|
|
def __init__(self, msg, doc, pos, end=None): |
|
ValueError.__init__(self, errmsg(msg, doc, pos, end=end)) |
|
self.msg = msg |
|
self.doc = doc |
|
self.pos = pos |
|
self.end = end |
|
self.lineno, self.colno = linecol(doc, pos) |
|
if end is not None: |
|
self.endlineno, self.endcolno = linecol(doc, end) |
|
else: |
|
self.endlineno, self.endcolno = None, None |
|
|
|
def __reduce__(self): |
|
return self.__class__, (self.msg, self.doc, self.pos, self.end) |
|
|
|
|
|
def linecol(doc, pos): |
|
lineno = doc.count('\n', 0, pos) + 1 |
|
if lineno == 1: |
|
colno = pos + 1 |
|
else: |
|
colno = pos - doc.rindex('\n', 0, pos) |
|
return lineno, colno |
|
|
|
|
|
def errmsg(msg, doc, pos, end=None): |
|
lineno, colno = linecol(doc, pos) |
|
msg = msg.replace('%r', repr(doc[pos:pos + 1])) |
|
if end is None: |
|
fmt = '%s: line %d column %d (char %d)' |
|
return fmt % (msg, lineno, colno, pos) |
|
endlineno, endcolno = linecol(doc, end) |
|
fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' |
|
return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) |
|
|
|
|
|
|