summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Abou-Samra <jean@abou-samra.fr>2022-08-15 11:45:13 +0200
committerGitHub <noreply@github.com>2022-08-15 11:45:13 +0200
commitd6968f804ab817c29f9f0ca408279adf82b006f9 (patch)
treef3225a3b29dcc71d85b512767b436f7e7af9e6d5
parentbf1ea528193f6404d91372a7254913ea03baccac (diff)
downloadpygments-git-d6968f804ab817c29f9f0ca408279adf82b006f9.tar.gz
CFamilyLexer: refuse quotes between parentheses for function definitions and declarations (#2208)
Something like id id2("){ ... }"); is no longer wrongly recognized as a "function" id id2(") { ... } "); As the difference in the tests shows, this has the unfortunate side effect that we no longer highlight something like int f(param="default"); as a function declaration, but it is hard to imagine another way to fix this (cf. “most vexing parse” problem). Fixes #2207
-rw-r--r--pygments/lexers/c_cpp.py8
-rw-r--r--tests/examplefiles/cpp/example.cpp.output2
-rw-r--r--tests/snippets/c/test_string_resembling_decl_end.txt41
3 files changed, 46 insertions, 5 deletions
diff --git a/pygments/lexers/c_cpp.py b/pygments/lexers/c_cpp.py
index 5d3b9c7d..59749fa6 100644
--- a/pygments/lexers/c_cpp.py
+++ b/pygments/lexers/c_cpp.py
@@ -132,9 +132,9 @@ class CFamilyLexer(RegexLexer):
r'(' + _possible_comments + r')' # possible comments
r'(' + _namespaced_ident + r')' # method name
r'(' + _possible_comments + r')' # possible comments
- r'(\([^;]*?\))' # signature
+ r'(\([^;"\']*?\))' # signature
r'(' + _possible_comments + r')' # possible comments
- r'([^;{/]*)(\{)',
+ r'([^;{/"\']*)(\{)',
bygroups(using(this), using(this, state='whitespace'), Name.Function, using(this, state='whitespace'),
using(this), using(this, state='whitespace'), using(this), Punctuation),
'function'),
@@ -143,9 +143,9 @@ class CFamilyLexer(RegexLexer):
r'(' + _possible_comments + r')' # possible comments
r'(' + _namespaced_ident + r')' # method name
r'(' + _possible_comments + r')' # possible comments
- r'(\([^;]*?\))' # signature
+ r'(\([^;"\']*?\))' # signature
r'(' + _possible_comments + r')' # possible comments
- r'([^;/]*)(;)',
+ r'([^;/"\']*)(;)',
bygroups(using(this), using(this, state='whitespace'), Name.Function, using(this, state='whitespace'),
using(this), using(this, state='whitespace'), using(this), Punctuation)),
include('types'),
diff --git a/tests/examplefiles/cpp/example.cpp.output b/tests/examplefiles/cpp/example.cpp.output
index b82dd095..1e2444fc 100644
--- a/tests/examplefiles/cpp/example.cpp.output
+++ b/tests/examplefiles/cpp/example.cpp.output
@@ -944,7 +944,7 @@
' ' Text.Whitespace
'string' Name
' ' Text.Whitespace
-'getOpenTag' Name.Function
+'getOpenTag' Name
'(' Punctuation
'const' Keyword
' ' Text.Whitespace
diff --git a/tests/snippets/c/test_string_resembling_decl_end.txt b/tests/snippets/c/test_string_resembling_decl_end.txt
new file mode 100644
index 00000000..17ce2233
--- /dev/null
+++ b/tests/snippets/c/test_string_resembling_decl_end.txt
@@ -0,0 +1,41 @@
+---input---
+// This should not be recognized as a function declaration followed by
+// garbage.
+string xyz(");");
+
+// This should not be recognized as a function definition.
+
+string xyz("){ }");
+
+---tokens---
+'// This should not be recognized as a function declaration followed by\n' Comment.Single
+
+'// garbage.\n' Comment.Single
+
+'string' Name
+' ' Text.Whitespace
+'xyz' Name
+'(' Punctuation
+'"' Literal.String
+');' Literal.String
+'"' Literal.String
+')' Punctuation
+';' Punctuation
+'\n' Text.Whitespace
+
+'\n' Text.Whitespace
+
+'// This should not be recognized as a function definition.\n' Comment.Single
+
+'\n' Text.Whitespace
+
+'string' Name
+' ' Text.Whitespace
+'xyz' Name
+'(' Punctuation
+'"' Literal.String
+'){ }' Literal.String
+'"' Literal.String
+')' Punctuation
+';' Punctuation
+'\n' Text.Whitespace