diff --git a/source/dub/internal/sdlang/lexer.d b/source/dub/internal/sdlang/lexer.d index bab2609..0da140a 100644 --- a/source/dub/internal/sdlang/lexer.d +++ b/source/dub/internal/sdlang/lexer.d @@ -196,7 +196,12 @@ return hasNextCh && nextCh == ch; } - private bool isNewline(dchar ch) + private bool lookahead(bool function(dchar) condition) + { + return hasNextCh && condition(nextCh); + } + + private static bool isNewline(dchar ch) { return ch == '\n' || ch == '\r' || ch == lineSep || ch == paraSep; } @@ -313,7 +318,6 @@ enum ErrorOnEOF { No, Yes } /// Advance one code point. - /// Returns false if EOF was reached private void advanceChar(ErrorOnEOF errorOnEOF) { if(auto cnt = isAtNewline()) @@ -541,10 +545,9 @@ buf.put( source[spanStart..location.index] ); } + advanceChar(ErrorOnEOF.Yes); do { - advanceChar(ErrorOnEOF.Yes); - if(ch == '\\') { updateBuf(); @@ -578,6 +581,7 @@ else if(isNewline(ch)) error("Unescaped newlines are only allowed in raw strings, not regular strings."); + advanceChar(ErrorOnEOF.Yes); } while(ch != '"'); updateBuf(); @@ -1372,6 +1376,7 @@ commentStart = location; state = State.lineComment; + continue; } else if(ch == '/' || ch == '-') @@ -1384,6 +1389,7 @@ advanceChar(ErrorOnEOF.No); state = State.lineComment; + continue; } else if(ch == '/' && lookahead('*')) { @@ -1392,6 +1398,7 @@ advanceChar(ErrorOnEOF.No); state = State.blockComment; + continue; } else return; // Done @@ -1419,7 +1426,7 @@ break; case State.lineComment: - if(isNewline(ch)) + if(lookahead(&isNewline)) state = State.normal; break; @@ -1716,9 +1723,10 @@ testLex(`" hello world "`, [ Token(symbol!"Value",loc,Value(" hello world " )) ]); testLex(`"hello \t world"`, [ Token(symbol!"Value",loc,Value("hello \t world")) ]); testLex(`"hello \n world"`, [ Token(symbol!"Value",loc,Value("hello \n world")) ]); - testLex("\"hello \\\n world\"", [ Token(symbol!"Value",loc,Value("hello world" )) ]); - testLex("\"hello \\ \n world\"", [ Token(symbol!"Value",loc,Value("hello world" )) ]); - testLex("\"hello \\ \n\n world\"", [ Token(symbol!"Value",loc,Value("hello world" )) ]); + testLex("\"hello \\\n world\"", [ Token(symbol!"Value",loc,Value("hello world" )) ]); + testLex("\"hello \\ \n world\"", [ Token(symbol!"Value",loc,Value("hello world" )) ]); + testLex("\"hello \\ \n\n world\"", [ Token(symbol!"Value",loc,Value("hello world" )) ]); + testLex(`"\"hello world\""`, [ Token(symbol!"Value",loc,Value(`"hello world"` )) ]); testLexThrows("\"hello \n world\""); testLexThrows(`"foo`); @@ -1969,10 +1977,12 @@ Token(symbol!":", loc, Value( null ), ":"), Token(symbol!"Ident", loc, Value( null ), "favorite_color"), Token(symbol!"Value", loc, Value( "blue" ), `"blue"`), + Token(symbol!"EOL", loc, Value( null ), "\n"), Token(symbol!"Ident", loc, Value( null ), "somedate"), Token(symbol!"Value", loc, Value( DateTimeFrac(DateTime(2013, 2, 22, 7, 53, 0)) ), "2013/2/22 07:53"), Token(symbol!"EOL", loc, Value( null ), "\n"), + Token(symbol!"EOL", loc, Value( null ), "\n"), Token(symbol!"Ident", loc, Value(null), "inventory"), Token(symbol!"{", loc, Value(null), "{"), @@ -2009,10 +2019,21 @@ writeln("lexer: Regression test issue #11..."); stdout.flush(); - testLex("//X\na", [ Token(symbol!"Ident",loc,Value(null),"a") ]); - testLex("//\na", [ Token(symbol!"Ident",loc,Value(null),"a") ]); - testLex("--\na", [ Token(symbol!"Ident",loc,Value(null),"a") ]); - testLex("#\na", [ Token(symbol!"Ident",loc,Value(null),"a") ]); + void test(string input) + { + testLex( + input, + [ + Token(symbol!"EOL", loc, Value(null), "\n"), + Token(symbol!"Ident",loc,Value(null), "a") + ] + ); + } + + test("//X\na"); + test("//\na"); + test("--\na"); + test("#\na"); } version(sdlangUnittest) diff --git a/source/dub/internal/sdlang/package.d b/source/dub/internal/sdlang/package.d index 03e2f9d..c128a46 100644 --- a/source/dub/internal/sdlang/package.d +++ b/source/dub/internal/sdlang/package.d @@ -2,17 +2,29 @@ // Written in the D programming language. /++ -SDLang-D: Library for parsing SDL (Simple Declarative Language). +$(H2 SDLang-D v0.9.3) + +Library for parsing and generating SDL (Simple Declarative Language). Import this module to use SDLang-D as a library. -This should work with DMD 2.061 and up (currently tested up through v2.067.0). +For the list of officially supported compiler versions, see the +$(LINK2 https://github.com/Abscissa/SDLang-D/blob/master/.travis.yml, .travis.yml) +file included with your version of SDLang-D. -Homepage: http://github.com/Abscissa/SDLang-D -API: http://semitwist.com/sdlang-d-api -SDL: http://sdl.ikayzo.org/display/SDL/Language+Guide +Links: +$(UL + $(LI $(LINK2 https://github.com/Abscissa/SDLang-D, SDLang-D Homepage) ) + $(LI $(LINK2 http://semitwist.com/sdlang-d, SDLang-D API Reference (latest version) ) ) + $(LI $(LINK2 http://semitwist.com/sdlang-d-docs, SDLang-D API Reference (earlier versions) ) ) + $(LI $(LINK2 http://sdl.ikayzo.org/display/SDL/Language+Guide, Official SDL Site) [$(LINK2 http://semitwist.com/sdl-mirror/Language+Guide.html, mirror)] ) +) Authors: Nick Sabalausky ("Abscissa") http://semitwist.com/contact +Copyright: +Copyright (C) 2012-2015 Nick Sabalausky. + +License: $(LINK2 https://github.com/Abscissa/SDLang-D/blob/master/LICENSE.txt, zlib/libpng) +/ module dub.internal.sdlang; diff --git a/source/dub/internal/sdlang/parser.d b/source/dub/internal/sdlang/parser.d index 048535b..3e32690 100644 --- a/source/dub/internal/sdlang/parser.d +++ b/source/dub/internal/sdlang/parser.d @@ -44,7 +44,7 @@ with any syntax error messages. Warning! The FileStartEvent and FileEndEvent events *might* be removed later. -See $(WEB https://github.com/Abscissa/SDLang-D/issues/17) +See $(LINK https://github.com/Abscissa/SDLang-D/issues/17) Example: ------------------ @@ -539,3 +539,16 @@ event.peek!FileStartEvent(); } } + +// Regression test, issue #31: https://github.com/Abscissa/SDLang-D/issues/31 +// "Escape sequence results in range violation error" +version(sdlangUnittest) +unittest +{ + import std.stdio; + writeln("parser: Regression test issue #31..."); + stdout.flush(); + + // Shouldn't get a Range violation + parseSource(`test "\"foo\""`); +} diff --git a/source/dub/internal/sdlang/token.d b/source/dub/internal/sdlang/token.d index 5a5ab50..e339a2c 100644 --- a/source/dub/internal/sdlang/token.d +++ b/source/dub/internal/sdlang/token.d @@ -271,9 +271,9 @@ else sink.put("+"); - sink.put("%.2s".format(offset.hours)); + sink.put("%.2s".format(offset.split.hours)); sink.put(":"); - sink.put("%.2s".format(offset.minutes)); + sink.put("%.2s".format(offset.split.minutes)); } else sink.put(tzString); @@ -303,16 +303,16 @@ sink.put("d:"); } - sink.put("%.2s".format(value.hours)); + sink.put("%.2s".format(value.split.hours)); sink.put(':'); - sink.put("%.2s".format(value.minutes)); + sink.put("%.2s".format(value.split.minutes)); sink.put(':'); - sink.put("%.2s".format(value.seconds)); + sink.put("%.2s".format(value.split.seconds)); - if(value.fracSec.msecs != 0) + if(value.split.msecs != 0) { sink.put('.'); - sink.put("%.3s".format(value.fracSec.msecs)); + sink.put("%.3s".format(value.split.msecs)); } }