| 1 | # SPDX-License-Identifier: MIT |
| 2 | |
| 3 | __all__ = ['Mark', 'YAMLError', 'MarkedYAMLError'] |
| 4 | |
| 5 | class Mark: |
| 6 | |
| 7 | def __init__(self, name, index, line, column, buffer, pointer): |
| 8 | self.name = name |
| 9 | self.index = index |
| 10 | self.line = line |
| 11 | self.column = column |
| 12 | self.buffer = buffer |
| 13 | self.pointer = pointer |
| 14 | |
| 15 | def get_snippet(self, indent=4, max_length=75): |
| 16 | if self.buffer is None: |
| 17 | return None |
| 18 | head = '' |
| 19 | start = self.pointer |
| 20 | while start > 0 and self.buffer[start-1] not in '\0\r\n\x85\u2028\u2029': |
| 21 | start -= 1 |
| 22 | if self.pointer-start > max_length/2-1: |
| 23 | head = ' ... ' |
| 24 | start += 5 |
| 25 | break |
| 26 | tail = '' |
| 27 | end = self.pointer |
| 28 | while end < len(self.buffer) and self.buffer[end] not in '\0\r\n\x85\u2028\u2029': |
| 29 | end += 1 |
| 30 | if end-self.pointer > max_length/2-1: |
| 31 | tail = ' ... ' |
| 32 | end -= 5 |
| 33 | break |
| 34 | snippet = self.buffer[start:end] |
| 35 | return ' '*indent + head + snippet + tail + '\n' \ |
| 36 | + ' '*(indent+self.pointer-start+len(head)) + '^' |
| 37 | |
| 38 | def __str__(self): |
| 39 | snippet = self.get_snippet() |
| 40 | where = " in \"%s\", line %d, column %d" \ |
| 41 | % (self.name, self.line+1, self.column+1) |
| 42 | if snippet is not None: |
| 43 | where += ":\n"+snippet |
| 44 | return where |
| 45 | |
| 46 | class YAMLError(Exception): |
| 47 | pass |
| 48 | |
| 49 | class MarkedYAMLError(YAMLError): |
| 50 | |
| 51 | def __init__(self, context=None, context_mark=None, |
| 52 | problem=None, problem_mark=None, note=None): |
| 53 | self.context = context |
| 54 | self.context_mark = context_mark |
| 55 | self.problem = problem |
| 56 | self.problem_mark = problem_mark |
| 57 | self.note = note |
| 58 | |
| 59 | def __str__(self): |
| 60 | lines = [] |
| 61 | if self.context is not None: |
| 62 | lines.append(self.context) |
| 63 | if self.context_mark is not None \ |
| 64 | and (self.problem is None or self.problem_mark is None |
| 65 | or self.context_mark.name != self.problem_mark.name |
| 66 | or self.context_mark.line != self.problem_mark.line |
| 67 | or self.context_mark.column != self.problem_mark.column): |
| 68 | lines.append(str(self.context_mark)) |
| 69 | if self.problem is not None: |
| 70 | lines.append(self.problem) |
| 71 | if self.problem_mark is not None: |
| 72 | lines.append(str(self.problem_mark)) |
| 73 | if self.note is not None: |
| 74 | lines.append(self.note) |
| 75 | return '\n'.join(lines) |
| 76 |