From 2475fe0010cb641d3c6799262a3600da689a8612 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 30 Aug 2010 15:55:14 +0000 Subject: [PATCH] Bug 316311 - [C++0x] Raw and unicode string literals --- .../core/parser/tests/scanner/LexerTests.java | 127 ++++++++++++++-- .../parser/cpp/CPPASTLiteralExpression.java | 22 ++- .../internal/core/parser/scanner/Lexer.java | 143 ++++++++++++++---- 3 files changed, 251 insertions(+), 41 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LexerTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LexerTests.java index b2a56bd21e2..aba5c29b8ff 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LexerTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LexerTests.java @@ -18,8 +18,8 @@ import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.tests.ast2.TestLexerLog; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.internal.core.parser.scanner.Lexer; -import org.eclipse.cdt.internal.core.parser.scanner.Token; import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions; +import org.eclipse.cdt.internal.core.parser.scanner.Token; public class LexerTests extends BaseTestCase { @@ -64,6 +64,12 @@ public class LexerTests extends BaseTestCase { fLastEndOffset= 0; } + private void nextDirective() throws Exception { + IToken t= fLexer.nextDirective(); + assertNotNull(t); + fLastEndOffset= t.getOffset(); + } + private void token(int tokenType) throws Exception { token(tokenType, null); } @@ -102,11 +108,35 @@ public class LexerTests extends BaseTestCase { private void utf16str(String expectedImage) throws Exception { token(IToken.tUTF16STRING, "u\"" + expectedImage + "\""); } - + + private void utf8str(String expectedImage) throws Exception { + token(IToken.tSTRING, "u8\"" + expectedImage + "\""); + } + private void utf32str(String expectedImage) throws Exception { token(IToken.tUTF32STRING, "U\"" + expectedImage + "\""); } - + + private void rstr(String marker, String expectedImage) throws Exception { + token(IToken.tSTRING, "R\"" + marker + '(' + expectedImage + ')' + marker + "\""); + } + + private void wrstr(String marker, String expectedImage) throws Exception { + token(IToken.tLSTRING, "LR\"" + marker + '(' + expectedImage + ')' + marker + "\""); + } + + private void utf16rstr(String marker, String expectedImage) throws Exception { + token(IToken.tUTF16STRING, "uR\"" + marker + '(' + expectedImage + ')' + marker + "\""); + } + + private void utf8rstr(String marker, String expectedImage) throws Exception { + token(IToken.tSTRING, "u8R\"" + marker + '(' + expectedImage + ')' + marker + "\""); + } + + private void utf32rstr(String marker, String expectedImage) throws Exception { + token(IToken.tUTF32STRING, "UR\"" + marker + '(' + expectedImage + ')' + marker + "\""); + } + private void ch(String expectedImage) throws Exception { token(IToken.tCHAR, expectedImage); } @@ -481,7 +511,11 @@ public class LexerTests extends BaseTestCase { init("L\"" + lit + '"'); wstr(lit); eof(); - + + init("u8\"" + lit + '"'); + utf8str(lit); + eof(); + init("u\"" + lit + '"'); utf16str(lit); eof(); @@ -540,6 +574,78 @@ public class LexerTests extends BaseTestCase { eof(); } + public void testRawStringLiteral() throws Exception { + String lit= "abc0123\\\"'.:; \\\\ \n\"("; + init("R\"(" + lit + ")\""); + rstr("", lit); + eof(); + + init("LR\"(" + lit + ")\""); + wrstr("", lit); + eof(); + + init("u8R\"(" + lit + ")\""); + utf8rstr("", lit); + eof(); + + init("uR\"(" + lit + ")\""); + utf16rstr("", lit); + eof(); + + init("UR\"(" + lit + ")\""); + utf32rstr("", lit); + eof(); + + init("R\"ut"); + problem(IProblem.SCANNER_UNBOUNDED_STRING, "R\"ut"); + token(IToken.tSTRING, "R\"ut"); + eof(); + + init("LR\"(ut"); + problem(IProblem.SCANNER_UNBOUNDED_STRING, "LR\"(ut"); + token(IToken.tLSTRING, "LR\"(ut"); + eof(); + + init("uR\"p()"); + problem(IProblem.SCANNER_UNBOUNDED_STRING, "uR\"p()"); + token(IToken.tUTF16STRING, "uR\"p()"); + eof(); + + init("UR\"(ut"); + problem(IProblem.SCANNER_UNBOUNDED_STRING, "UR\"(ut"); + token(IToken.tUTF32STRING, "UR\"(ut"); + eof(); + + init("R\"+=(Text)=+\"Text)+=\""); + rstr("+=", "Text)=+\"Text"); + eof(); + + init("UR uR LR u8R U8R\"\""); + id("UR"); ws(); + id("uR"); ws(); + id("LR"); ws(); + id("u8R"); ws(); + id("U8R"); str(""); + eof(); + } + + public void testRawStringLiteralInInactiveCode() throws Exception { + init("start\n" + "inactive: Rbla\n" + "#end"); + id("start"); + nextDirective(); + token(IToken.tPOUND); + id("end"); + eof(); + + // raw string containing a directive + init("start\n" + "inactive: uR\"(\n#endif\n)\"\n" + "#end"); + id("start"); + nextDirective(); + token(IToken.tPOUND); + id("end"); + eof(); + } + public void testOperatorAndPunctuators() throws Exception { final String ops= "{}[]###()<::><%%>%:%:%:;:...?.::..*+-*/%^&|~=!<>+=-=*=/=%=" + "^=&=|=<<>><<=>>===!=<=>=&&||++--,->*->?\\"; @@ -563,17 +669,17 @@ public class LexerTests extends BaseTestCase { StringBuffer buf= new StringBuffer(); String input= useTrigraphs(ops.toCharArray(), trigraphs); init(instertLineSplices(input, splices)); - for (int i = 0; i < tokens.length; i++) { + for (int token2 : tokens) { Token token= fLexer.currentToken(); buf.append(token.getCharImage()); - token(tokens[i]); + token(token2); } eof(); assertEquals(ops, buf.toString()); // check token image init(input, NO_MINMAX); - for (int i = 0; i < tokens.length; i++) { - switch (tokens[i]) { + for (int token : tokens) { + switch (token) { case IGCCToken.tMIN: token(IToken.tLT); token(IToken.tQUESTION); @@ -583,7 +689,7 @@ public class LexerTests extends BaseTestCase { token(IToken.tQUESTION); break; default: - token(tokens[i]); + token(token); break; } } @@ -630,8 +736,7 @@ public class LexerTests extends BaseTestCase { boolean yes= mode > 1; StringBuffer result= new StringBuffer(); - for (int i = 0; i < input.length; i++) { - char c = input[i]; + for (char c : input) { int idx= TRIGRAPH_REPLACES_CHARS.indexOf(c); if (idx > 0) { if (yes) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java index 42b876e0d9d..31e53e9c2f6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java @@ -121,8 +121,26 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx private IValue getStringLiteralSize() { char[] value= getValue(); int length= value.length-1; - if (value[0] != '"') { - length--; + boolean isRaw= false; + for (int i = 0; i < length; i++) { + final char c = value[i]; + if (c == '"') { + if (isRaw) { + for (int j=i+1; j