Fixes to block scalars and yamlTestSuite

* Properly handle empty block scalars and trailing lines
 * Fixed a bug in yamlTestSuite that led to lots of open file handles
This commit is contained in:
Felix Krause 2016-03-18 22:29:35 +01:00
parent b9eb4b62f6
commit ae933d90a1
2 changed files with 32 additions and 13 deletions

View File

@ -844,6 +844,8 @@ template blockScalar(lexer: BaseLexer, content: var string,
chomp: ChompType = ctClip chomp: ChompType = ctClip
detectedIndent = false detectedIndent = false
recentLineMoreIndented = false recentLineMoreIndented = false
let parentIndent = if ancestry.len > 0:
ancestry[ancestry.high].indentation else: 0
case lexer.buf[lexer.bufpos] case lexer.buf[lexer.bufpos]
of '|': literal = true of '|': literal = true
@ -877,8 +879,6 @@ template blockScalar(lexer: BaseLexer, content: var string,
# TODO: is this correct? # TODO: is this correct?
else: assert(false) else: assert(false)
var newlines = 0 var newlines = 0
let parentIndent = if ancestry.len > 0:
ancestry[ancestry.high].indentation else: 0
content = "" content = ""
block outer: block outer:
while true: while true:
@ -947,6 +947,10 @@ template blockScalar(lexer: BaseLexer, content: var string,
break outer break outer
else: else:
blockIndent = lexer.getColNumber(lexer.bufpos) - parentIndent blockIndent = lexer.getColNumber(lexer.bufpos) - parentIndent
if blockIndent == 0:
stateAfter = if blockIndent + parentIndent > 0:
fpBlockObjectStart else: fpBlockLineStart
break outer
detectedIndent = true detectedIndent = true
break break
lexer.bufpos.inc() lexer.bufpos.inc()
@ -964,9 +968,9 @@ template blockScalar(lexer: BaseLexer, content: var string,
break outer break outer
of ' ', '\t': of ' ', '\t':
if not literal: if not literal:
if not recentLineMoreIndented: if content.len > 0:
recentLineMoreIndented = true recentLineMoreIndented = true
newlines.inc() newlines.inc()
else: else:
if not literal: if not literal:
if recentLineMoreIndented: if recentLineMoreIndented:
@ -974,8 +978,12 @@ template blockScalar(lexer: BaseLexer, content: var string,
newlines.inc() newlines.inc()
if newlines > 0: if newlines > 0:
if literal: content.add(repeat('\l', newlines)) if literal: content.add(repeat('\l', newlines))
elif newlines == 1: content.add(' ') elif newlines == 1:
else: content.add(repeat('\l', newlines - 1)) if content.len == 0: content.add('\l')
else: content.add(' ')
else:
if content.len == 0: content.add(repeat('\l', newlines))
else: content.add(repeat('\l', newlines - 1))
newlines = 0 newlines = 0
while true: while true:
let c = lexer.buf[lexer.bufpos] let c = lexer.buf[lexer.bufpos]
@ -994,8 +1002,11 @@ template blockScalar(lexer: BaseLexer, content: var string,
else: content.add(c) else: content.add(c)
lexer.bufpos.inc() lexer.bufpos.inc()
case chomp case chomp
of ctClip: content.add('\l') of ctClip:
of ctKeep: content.add(repeat('\l', newlines)) if content.len > 0: content.add('\l')
of ctKeep:
if content.len > 0: content.add(repeat('\l', newlines))
else: content.add(repeat('\l', newlines - 1))
of ctStrip: discard of ctStrip: discard
debug("lex: \"" & content & '\"') debug("lex: \"" & content & '\"')
@ -1158,8 +1169,8 @@ proc parse*(p: YamlParser, s: Stream): YamlStream =
p.lexer.plainScalar(content, cBlock) p.lexer.plainScalar(content, cBlock)
state = fpBlockAfterPlainScalar state = fpBlockAfterPlainScalar
of ' ': of ' ':
let c = p.lexer.buf[p.lexer.bufpos]
p.lexer.skipIndentation() p.lexer.skipIndentation()
let c = p.lexer.buf[p.lexer.bufpos]
if c in {'\l', '\c', '#', EndOfFile}: if c in {'\l', '\c', '#', EndOfFile}:
p.lexer.lineEnding() p.lexer.lineEnding()
handleLineEnd(true) handleLineEnd(true)
@ -1350,7 +1361,8 @@ proc parse*(p: YamlParser, s: Stream): YamlStream =
if tag == yTagQuestionMark: tag = yTagExclamationMark if tag == yTagQuestionMark: tag = yTagExclamationMark
yield scalarEvent(content, tag, anchor) yield scalarEvent(content, tag, anchor)
handleObjectEnd(stateAfter) handleObjectEnd(stateAfter)
if stateAfter == fpBlockObjectStart: if stateAfter == fpBlockObjectStart and
p.lexer.buf[p.lexer.bufpos] != '#':
indentation = p.lexer.getColNumber(p.lexer.bufpos) indentation = p.lexer.getColNumber(p.lexer.bufpos)
closeMoreIndentedLevels() closeMoreIndentedLevels()
of '-': of '-':

View File

@ -31,9 +31,10 @@ for kind, dirPath in walkDir("yaml-dev-kit"):
var var
tagLib = initExtendedTagLibrary() tagLib = initExtendedTagLibrary()
parser = newYamlParser(tagLib) parser = newYamlParser(tagLib)
actual = parser.parse(newFileStream(dirPath / "in.yaml")) actualIn = newFileStream(dirPath / "in.yaml")
expected = parseEventStream( actual = parser.parse(actualIn)
newFileStream(dirPath / "test.event"), tagLib) expectedIn = newFileStream(dirPath / "test.event")
expected = parseEventStream(expectedIn, tagLib)
styledWriteLine(stdout, fgBlue, "[test] ", fgWhite, dirPath[^4..^1], styledWriteLine(stdout, fgBlue, "[test] ", fgWhite, dirPath[^4..^1],
": ", strip(readFile(dirPath / "===")), resetStyle) ": ", strip(readFile(dirPath / "===")), resetStyle)
try: try:
@ -45,6 +46,8 @@ for kind, dirPath in walkDir("yaml-dev-kit"):
": Expected stream end, got " & ": Expected stream end, got " &
$actualEvent.kind) $actualEvent.kind)
gotErrors = true gotErrors = true
actualIn.close()
expectedIn.close()
break curTest break curTest
let expectedEvent = expected.next() let expectedEvent = expected.next()
if expectedEvent != actualEvent: if expectedEvent != actualEvent:
@ -52,6 +55,8 @@ for kind, dirPath in walkDir("yaml-dev-kit"):
echoError("At token #" & $i & echoError("At token #" & $i &
": Actual tokens do not match expected tokens") ": Actual tokens do not match expected tokens")
gotErrors = true gotErrors = true
actualIn.close()
expectedIn.close()
break curTest break curTest
i.inc() i.inc()
if not expected.finished(): if not expected.finished():
@ -68,6 +73,8 @@ for kind, dirPath in walkDir("yaml-dev-kit"):
pe.msg pe.msg
echo pe.lineContent echo pe.lineContent
else: echo e.msg else: echo e.msg
actualIn.close()
expectedIn.close()
if gotErrors: if gotErrors:
echoError("There were errors while running the tests") echoError("There were errors while running the tests")