forked from SonarOpenCommunity/sonar-cxx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
C++23: Trimming whitespaces before line splicing
- [P2223R2](https://wg21.link/P2223R2) - the cxx plugin supports line splicing still not in all cases (e.g. middle of number or identifier) - related to SonarOpenCommunity#2536
- Loading branch information
Showing
17 changed files
with
467 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
cxx-squid/src/main/java/org/sonar/cxx/channels/ChannelUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* C++ Community Plugin (cxx plugin) | ||
* Copyright (C) 2010-2023 SonarOpenCommunity | ||
* http://github.com/SonarOpenCommunity/sonar-cxx | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this program; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
*/ | ||
package org.sonar.cxx.channels; | ||
|
||
import org.sonar.cxx.sslr.channel.CodeReader; | ||
|
||
public class ChannelUtils { | ||
|
||
public static final char LF = '\n'; | ||
public static final char CR = '\r'; | ||
public static final char EOF = (char) -1; | ||
|
||
private ChannelUtils() { | ||
// empty | ||
} | ||
|
||
public static boolean isNewLine(char ch) { | ||
return (ch == LF) || (ch == CR); | ||
} | ||
|
||
public static boolean isWhitespace(char ch) { | ||
return (ch == ' ') || (ch == '\t'); | ||
} | ||
|
||
public static boolean isSuffix(char c) { | ||
return Character.isLowerCase(c) || Character.isUpperCase(c) || (c == '_'); | ||
} | ||
|
||
public static int handleLineSplicing(CodeReader code, int start) { | ||
int next = start; | ||
if (code.charAt(next) != '\\') { | ||
return 0; | ||
} | ||
|
||
boolean newline = false; | ||
next++; | ||
while (true) { | ||
var charAt = code.charAt(next); | ||
if (ChannelUtils.isNewLine(charAt)) { | ||
newline = true; | ||
break; | ||
} | ||
if (!ChannelUtils.isWhitespace(charAt)) { | ||
break; | ||
} | ||
next++; | ||
} | ||
|
||
return newline ? (next - start + 1) : 0; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
cxx-squid/src/main/java/org/sonar/cxx/channels/MultiLineCommentChannel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* C++ Community Plugin (cxx plugin) | ||
* Copyright (C) 2010-2023 SonarOpenCommunity | ||
* http://github.com/SonarOpenCommunity/sonar-cxx | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this program; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
*/ | ||
package org.sonar.cxx.channels; | ||
|
||
import static com.sonar.cxx.sslr.api.GenericTokenType.COMMENT; | ||
import com.sonar.cxx.sslr.api.Token; | ||
import com.sonar.cxx.sslr.api.Trivia; | ||
import com.sonar.cxx.sslr.impl.Lexer; | ||
import org.sonar.cxx.sslr.channel.Channel; | ||
import org.sonar.cxx.sslr.channel.CodeReader; | ||
|
||
public class MultiLineCommentChannel extends Channel<Lexer> { | ||
|
||
private final StringBuilder sb = new StringBuilder(256); | ||
private final Token.Builder tokenBuilder = Token.builder(); | ||
|
||
@Override | ||
public boolean consume(CodeReader code, Lexer lexer) { | ||
// start of multi line comment? | ||
int next = isComment(code); | ||
if (next == 0) { | ||
return false; | ||
} | ||
|
||
int line = code.getLinePosition(); | ||
int column = code.getColumnPosition(); | ||
|
||
code.skip(next); | ||
sb.append('/'); | ||
sb.append('*'); | ||
|
||
read(code, sb); // search end of multi line comment | ||
|
||
var value = sb.toString(); | ||
var token = tokenBuilder | ||
.setType(COMMENT) | ||
.setValueAndOriginalValue(value) | ||
.setURI(lexer.getURI()) | ||
.setLine(line) | ||
.setColumn(column) | ||
.build(); | ||
|
||
lexer.addTrivia(Trivia.createComment(token)); | ||
sb.delete(0, sb.length()); | ||
return true; | ||
} | ||
|
||
public static int isComment(CodeReader code) { | ||
int next = 0; | ||
|
||
// start of multi line comment? | ||
if (code.charAt(next) != '/') { | ||
return 0; | ||
} | ||
next += 1; | ||
next += ChannelUtils.handleLineSplicing(code, next); | ||
|
||
if (code.charAt(next) != '*') { | ||
return 0; | ||
} | ||
next += 1; | ||
return next; | ||
} | ||
|
||
public static boolean read(CodeReader code, StringBuilder sb) { | ||
boolean first = false; | ||
while (true) { // search end of multi line comment: */ | ||
var end = ChannelUtils.handleLineSplicing(code, 0); | ||
code.skip(end); // remove line splicing | ||
|
||
var charAt = (char) code.pop(); | ||
switch (charAt) { | ||
case '*': | ||
first = true; | ||
break; | ||
case '/': | ||
if (first) { | ||
sb.append('/'); | ||
return true; | ||
} | ||
break; | ||
case ChannelUtils.EOF: | ||
return false; | ||
default: | ||
first = false; | ||
break; | ||
} | ||
|
||
sb.append(charAt); | ||
} | ||
|
||
} | ||
|
||
} |
Oops, something went wrong.