diff options
Diffstat (limited to 'src/ext_depends/D-YAML/source/dyaml/scanner.d')
-rw-r--r-- | src/ext_depends/D-YAML/source/dyaml/scanner.d | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/src/ext_depends/D-YAML/source/dyaml/scanner.d b/src/ext_depends/D-YAML/source/dyaml/scanner.d index 3f0f394..77c3e38 100644 --- a/src/ext_depends/D-YAML/source/dyaml/scanner.d +++ b/src/ext_depends/D-YAML/source/dyaml/scanner.d @@ -72,6 +72,8 @@ alias isBChar = among!('\n', '\r', '\u0085', '\u2028', '\u2029'); alias isFlowScalarBreakSpace = among!(' ', '\t', '\0', '\n', '\r', '\u0085', '\u2028', '\u2029', '\'', '"', '\\'); +alias isNSAnchorName = c => !c.isWhiteSpace && !c.among!('[', ']', '{', '}', ',', '\uFEFF'); + /// Marked exception thrown at scanner errors. /// /// See_Also: MarkedYAMLException @@ -763,6 +765,25 @@ struct Scanner reader_.sliceBuilder.write(reader_.get(length)); } + /// Scan a string. + /// + /// Assumes that the caller is building a slice in Reader, and puts the scanned + /// characters into that slice. + void scanAnchorAliasToSlice(const Mark startMark) @safe + { + size_t length; + dchar c = reader_.peek(); + while (c.isNSAnchorName) + { + c = reader_.peek(++length); + } + + enforce(length > 0, new ScannerException("While scanning an anchor or alias", + startMark, expected("a printable character besides '[', ']', '{', '}' and ','", c), reader_.mark)); + + reader_.sliceBuilder.write(reader_.get(length)); + } + /// Scan and throw away all characters until next line break. void scanToNextBreak() @safe { @@ -988,20 +1009,14 @@ struct Scanner Token scanAnchor(const TokenID id) @safe { const startMark = reader_.mark; - const dchar i = reader_.get(); + reader_.forward(); // The */& character was only peeked, so we drop it now reader_.sliceBuilder.begin(); - if(i == '*') { scanAlphaNumericToSlice!"an alias"(startMark); } - else { scanAlphaNumericToSlice!"an anchor"(startMark); } + scanAnchorAliasToSlice(startMark); // On error, value is discarded as we return immediately char[] value = reader_.sliceBuilder.finish(); - enum anchorCtx = "While scanning an anchor"; - enum aliasCtx = "While scanning an alias"; - enforce(reader_.peek().isWhiteSpace || - reader_.peekByte().among!('?', ':', ',', ']', '}', '%', '@'), - new ScannerException(i == '*' ? aliasCtx : anchorCtx, startMark, - expected("alphanumeric, '-' or '_'", reader_.peek()), reader_.mark)); + assert(!reader_.peek().isNSAnchorName, "Anchor/alias name not fully scanned"); if(id == TokenID.alias_) { @@ -1212,7 +1227,10 @@ struct Scanner // is not Strip) else { - reader_.sliceBuilder.write(lineBreak); + if (lineBreak != '\0') + { + reader_.sliceBuilder.write(lineBreak); + } } } @@ -1792,3 +1810,17 @@ struct Scanner return '\0'; } } + +// Issue 309 - https://github.com/dlang-community/D-YAML/issues/309 +@safe unittest +{ + enum str = q"EOS +exp: | + foobar +EOS".chomp; + + auto r = new Reader(cast(ubyte[])str.dup); + auto s = Scanner(r); + auto elems = s.map!"a.value".filter!"a.length > 0".array; + assert(elems[1] == "foobar"); +} |