From b70efec1af718f332f0168a2469ecf6026407bf1 Mon Sep 17 00:00:00 2001 From: guwirth Date: Fri, 19 May 2023 12:00:37 +0200 Subject: [PATCH] correct handling of # in preprocessor Check if # is the first token in the line, only then it is a preprocessor command. Otherwise it is a special character which is treated e.g. in macros like any other string. --- .../sonar/cxx/channels/PreprocessorChannel.java | 8 ++++++++ .../lexer/CxxLexerWithPreprocessingTest.java | 17 +++++++++++++++++ .../lexer/CxxLexerWithoutPreprocessorTest.java | 3 +++ 3 files changed, 28 insertions(+) diff --git a/cxx-squid/src/main/java/org/sonar/cxx/channels/PreprocessorChannel.java b/cxx-squid/src/main/java/org/sonar/cxx/channels/PreprocessorChannel.java index b41ddb5d5d..0f8822d4bb 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/channels/PreprocessorChannel.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/channels/PreprocessorChannel.java @@ -57,6 +57,14 @@ public boolean consume(CodeReader code, Lexer output) { int line = code.getLinePosition(); int column = code.getColumnPosition(); + // if there was already a token in the line it's not a preprocessor command + var previousTokens = output.getTokens(); + if (!previousTokens.isEmpty()) { + if (previousTokens.get(previousTokens.size() - 1).getLine() == line) { + return false; + } + } + if (code.popTo(matcher, sb) <= 0) { return false; } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithPreprocessingTest.java b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithPreprocessingTest.java index bcb099d098..f71a2be4b0 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithPreprocessingTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithPreprocessingTest.java @@ -1030,4 +1030,21 @@ void string_problem_1903() { softly.assertAll(); } + @Test + void undefined_macro_with_hash_parameter() { + List tokens = lexer.lex("BOOST_PP_EXPAND(#) define BOOST_FT_config_valid 1"); + assertThat(tokens).hasSize(8); + } + + @Test + void defined_macro_with_hash_parameter() { + List tokens = lexer.lex("#define BOOST_PP_EXPAND(p) p\n" + + "BOOST_PP_EXPAND(#) define BOOST_FT_config_valid 1\n" + + "BOOST_FT_config_valid"); + + assertThat(tokens).anySatisfy(token -> assertThat(token) + .isValue("1") + .hasType(CxxTokenType.NUMBER)); + } + } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithoutPreprocessorTest.java b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithoutPreprocessorTest.java index 4cdbf7cb79..0d74061753 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithoutPreprocessorTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/lexer/CxxLexerWithoutPreprocessorTest.java @@ -40,6 +40,9 @@ public void init() { @Test void preprocessor_directives() { var softly = new SoftAssertions(); + + softly.assertThat(lexer.lex("#")).anySatisfy(token -> assertThat(token).isValue( + "#").hasType(CxxTokenType.PREPROCESSOR)); softly.assertThat(lexer.lex("#include ")).anySatisfy(token -> assertThat(token).isValue( "#include ").hasType(CxxTokenType.PREPROCESSOR)); softly.assertThat(lexer.lex("# include ")).anySatisfy(token -> assertThat(token).isValue(