diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-13 05:11:45 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-13 05:11:45 +0000 |
commit | 86240434eb153c149dbc3d77f4fedf9cffcbfc53 (patch) | |
tree | eb5eccc07097c5fcf940967f33ab84a7d47c96fe /libgo/go/go/scanner | |
parent | 9599f526f8b241e01ca4d54b5bff9c2e6f6dd75a (diff) | |
download | gcc-86240434eb153c149dbc3d77f4fedf9cffcbfc53.tar.gz |
libgo: Update to weekly.2011-12-22.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183150 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/go/scanner')
-rw-r--r-- | libgo/go/go/scanner/scanner.go | 27 | ||||
-rw-r--r-- | libgo/go/go/scanner/scanner_test.go | 14 |
2 files changed, 36 insertions, 5 deletions
diff --git a/libgo/go/go/scanner/scanner.go b/libgo/go/go/scanner/scanner.go index cef9c486508..7fb0104e450 100644 --- a/libgo/go/go/scanner/scanner.go +++ b/libgo/go/go/scanner/scanner.go @@ -426,13 +426,16 @@ func (S *Scanner) scanString() { S.next() } -func (S *Scanner) scanRawString() { +func (S *Scanner) scanRawString() (hasCR bool) { // '`' opening already consumed offs := S.offset - 1 for S.ch != '`' { ch := S.ch S.next() + if ch == '\r' { + hasCR = true + } if ch < 0 { S.error(offs, "string not terminated") break @@ -440,6 +443,7 @@ func (S *Scanner) scanRawString() { } S.next() + return } func (S *Scanner) skipWhitespace() { @@ -490,6 +494,18 @@ func (S *Scanner) switch4(tok0, tok1 token.Token, ch2 rune, tok2, tok3 token.Tok return tok0 } +func stripCR(b []byte) []byte { + c := make([]byte, len(b)) + i := 0 + for _, ch := range b { + if ch != '\r' { + c[i] = ch + i++ + } + } + return c[:i] +} + // Scan scans the next token and returns the token position, // the token, and the literal string corresponding to the // token. The source end is indicated by token.EOF. @@ -518,6 +534,7 @@ scanAgain: insertSemi := false offs := S.offset tok := token.ILLEGAL + hasCR := false // determine token value switch ch := S.ch; { @@ -556,7 +573,7 @@ scanAgain: case '`': insertSemi = true tok = token.STRING - S.scanRawString() + hasCR = S.scanRawString() case ':': tok = S.switch2(token.COLON, token.DEFINE) case '.': @@ -663,5 +680,9 @@ scanAgain: // TODO(gri): The scanner API should change such that the literal string // is only valid if an actual literal was scanned. This will // permit a more efficient implementation. - return S.file.Pos(offs), tok, string(S.src[offs:S.offset]) + lit := S.src[offs:S.offset] + if hasCR { + lit = stripCR(lit) + } + return S.file.Pos(offs), tok, string(lit) } diff --git a/libgo/go/go/scanner/scanner_test.go b/libgo/go/go/scanner/scanner_test.go index 7ed927a49fa..dc8ab2a748a 100644 --- a/libgo/go/go/scanner/scanner_test.go +++ b/libgo/go/go/scanner/scanner_test.go @@ -83,6 +83,8 @@ var tokens = [...]elt{ "`", literal, }, + {token.STRING, "`\r`", literal}, + {token.STRING, "`foo\r\nbar`", literal}, // Operators and delimiters {token.ADD, "+", operator}, @@ -239,8 +241,16 @@ func TestScan(t *testing.T) { if tok != e.tok { t.Errorf("bad token for %q: got %s, expected %s", lit, tok, e.tok) } - if e.tok.IsLiteral() && lit != e.lit { - t.Errorf("bad literal for %q: got %q, expected %q", lit, lit, e.lit) + if e.tok.IsLiteral() { + // no CRs in raw string literals + elit := e.lit + if elit[0] == '`' { + elit = string(stripCR([]byte(elit))) + epos.Offset += len(e.lit) - len(lit) // correct position + } + if lit != elit { + t.Errorf("bad literal for %q: got %q, expected %q", lit, lit, elit) + } } if tokenclass(tok) != e.class { t.Errorf("bad class for %q: got %d, expected %d", lit, tokenclass(tok), e.class) |