summaryrefslogtreecommitdiff
path: root/libgo/go/go/scanner
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-13 05:11:45 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-13 05:11:45 +0000
commit86240434eb153c149dbc3d77f4fedf9cffcbfc53 (patch)
treeeb5eccc07097c5fcf940967f33ab84a7d47c96fe /libgo/go/go/scanner
parent9599f526f8b241e01ca4d54b5bff9c2e6f6dd75a (diff)
downloadgcc-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.go27
-rw-r--r--libgo/go/go/scanner/scanner_test.go14
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)