fix(parser): Correctly handle DOS new lines in 'line' rules
Do not consider the trailing `\r` of a line a part of it.
This commit is contained in:
@@ -77,7 +77,10 @@ def line_generator(buffer):
|
||||
cur = 0
|
||||
next = buffer.find('\n')
|
||||
while next != -1:
|
||||
yield Line(line_no, buffer, start=cur, end=next)
|
||||
if next > 0 and buffer[next - 1] == '\r':
|
||||
yield Line(line_no, buffer, start=cur, end=next - 1)
|
||||
else:
|
||||
yield Line(line_no, buffer, start=cur, end=next)
|
||||
cur = next + 1
|
||||
next = buffer.find('\n', cur)
|
||||
line_no += 1
|
||||
|
||||
@@ -66,27 +66,37 @@ DEFAULT = {'max': 2,
|
||||
def check(conf, line):
|
||||
if line.start == line.end and line.end < len(line.buffer):
|
||||
# Only alert on the last blank line of a series
|
||||
if (line.end < len(line.buffer) - 1 and
|
||||
line.buffer[line.end + 1] == '\n'):
|
||||
if (line.end + 2 <= len(line.buffer) and
|
||||
line.buffer[line.end:line.end + 2] == '\n\n'):
|
||||
return
|
||||
elif (line.end + 4 <= len(line.buffer) and
|
||||
line.buffer[line.end:line.end + 4] == '\r\n\r\n'):
|
||||
return
|
||||
|
||||
blank_lines = 0
|
||||
|
||||
while (line.start > blank_lines and
|
||||
line.buffer[line.start - blank_lines - 1] == '\n'):
|
||||
start = line.start
|
||||
while start >= 2 and line.buffer[start - 2:start] == '\r\n':
|
||||
blank_lines += 1
|
||||
start -= 2
|
||||
while start >= 1 and line.buffer[start - 1] == '\n':
|
||||
blank_lines += 1
|
||||
start -= 1
|
||||
|
||||
max = conf['max']
|
||||
|
||||
# Special case: start of document
|
||||
if line.start - blank_lines == 0:
|
||||
if start == 0:
|
||||
blank_lines += 1 # first line doesn't have a preceding \n
|
||||
max = conf['max-start']
|
||||
|
||||
# Special case: end of document
|
||||
# NOTE: The last line of a file is always supposed to end with a new
|
||||
# line. See POSIX definition of a line at:
|
||||
if line.end == len(line.buffer) - 1 and line.buffer[line.end] == '\n':
|
||||
if ((line.end == len(line.buffer) - 1 and
|
||||
line.buffer[line.end] == '\n') or
|
||||
(line.end == len(line.buffer) - 2 and
|
||||
line.buffer[line.end:line.end + 2] == '\r\n')):
|
||||
# Allow the exception of the one-byte file containing '\n'
|
||||
if line.end == 0:
|
||||
return
|
||||
|
||||
@@ -36,10 +36,11 @@ DEFAULT = {'type': 'unix'}
|
||||
def check(conf, line):
|
||||
if line.start == 0 and len(line.buffer) > line.end:
|
||||
if conf['type'] == 'dos':
|
||||
if line.buffer[line.end - 1:line.end + 1] != '\r\n':
|
||||
if (line.end + 2 > len(line.buffer) or
|
||||
line.buffer[line.end:line.end + 2] != '\r\n'):
|
||||
yield LintProblem(1, line.end - line.start + 1,
|
||||
'wrong new line character: expected \\r\\n')
|
||||
else:
|
||||
if line.end > 0 and line.buffer[line.end - 1] == '\r':
|
||||
yield LintProblem(1, line.end - line.start,
|
||||
if line.buffer[line.end] == '\r':
|
||||
yield LintProblem(1, line.end - line.start + 1,
|
||||
'wrong new line character: expected \\n')
|
||||
|
||||
Reference in New Issue
Block a user