Skip to content

Commit

Permalink
Fix cidentlist handling of single quotes in hex literals (#300)
Browse files Browse the repository at this point in the history
  • Loading branch information
KangarooKoala authored Dec 22, 2024
1 parent 85a96fe commit 5a5c5cb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
23 changes: 16 additions & 7 deletions wpiformat/wpiformat/cidentlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ def __print_failure(name):
def should_process_file(config_file, name):
return config_file.is_c_file(name) or config_file.is_cpp_file(name)

@staticmethod
def is_quote_in_number(lines, i):
if i == 0:
return False
c = lines[i - 1]
return (
ord("0") <= ord(c) <= ord("9")
or ord("A") <= ord(c) <= ord("F")
or ord("a") <= ord(c) <= ord("f")
)

def run_pipeline(self, config_file, name, lines):
linesep = super().get_linesep(lines)

Expand Down Expand Up @@ -46,7 +57,6 @@ def run_pipeline(self, config_file, name, lines):
comment_str = r"/\*|\*/|//|" + linesep + r"|"
string_str = r"\\\\|\\\"|\"|"
char_str = r"\\'|'|"
digits_str = r"(?P<digits>\d+)|"
extern_str = r"(?P<ext_decl>extern \"C(\+\+)?\")\s+(?P<ext_brace>\{)?|"
braces_str = r"\{|\}|;|def\s+\w+|\w+\**\s+\w+\s*(?P<paren>\(\))"
postfix_str = r"(?=\s*(;|\{))"
Expand All @@ -55,7 +65,6 @@ def run_pipeline(self, config_file, name, lines):
+ comment_str
+ string_str
+ char_str
+ digits_str
+ extern_str
+ braces_str
+ postfix_str
Expand All @@ -76,7 +85,6 @@ def run_pipeline(self, config_file, name, lines):
in_singlecomment = False
in_string = False
in_char = False
last_digit_end = -1
for match in token_regex.finditer(lines):
token = match.group()

Expand Down Expand Up @@ -117,8 +125,11 @@ def run_pipeline(self, config_file, name, lines):
elif token == "\\'":
continue
elif token == "'":
if not in_string and match.start() != last_digit_end:
in_char = not in_char
if in_string:
continue
if not in_char and self.is_quote_in_number(lines, match.start()):
continue
in_char = not in_char
elif in_string or in_char:
# Tokens processed after this branch are ignored if they are in
# double or single quotes
Expand Down Expand Up @@ -168,8 +179,6 @@ def run_pipeline(self, config_file, name, lines):
# Replaces () with (void)
output += lines[pos : match.span("paren")[0]] + "(void)"
pos = match.span("paren")[0] + len("()")
elif match.group("digits"):
last_digit_end = match.end()

# Write rest of file if it wasn't all processed
if pos < len(lines):
Expand Down
8 changes: 8 additions & 0 deletions wpiformat/wpiformat/test/test_cidentlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,8 +499,16 @@ def test_cidentlist():
test.add_input("./Test.cpp", "void func() { int x = 1'000; }")
test.add_latest_input_as_output(True)

# Ensure single quotes in hexadecimal literals are ignored
test.add_input("./Test.cpp", "void func() { int x = 0xffff'ffff; }")
test.add_latest_input_as_output(True)

# Ensure single quotes after numeric literals are not ignored
test.add_input("./Test.cpp", "void func() { std::cout << 1 << '0'; }")
test.add_latest_input_as_output(True)

# Ensure single quotes after hexadecimal characters are not ignored
test.add_input("./Test.cpp", "void func() { std::cout << 1 << 'a'; }")
test.add_latest_input_as_output(True)

test.run(OutputType.FILE)

0 comments on commit 5a5c5cb

Please sign in to comment.