Skip to content
Snippets Groups Projects
Commit 520a54d9 authored by Campbell Barton's avatar Campbell Barton
Browse files

Allow preprocessor to split lines without warnings

Also quiet false positive warnings with casts and whitespace.
parent 76065e2c
No related branches found
No related tags found
No related merge requests found
...@@ -73,12 +73,21 @@ tokens = [] ...@@ -73,12 +73,21 @@ tokens = []
# could store index here too, then have prev/next methods # could store index here too, then have prev/next methods
class TokStore: class TokStore:
__slots__ = ("type", "text", "line") __slots__ = (
"type",
"text",
"line",
"flag",
)
def __init__(self, type, text, line): def __init__(self, type, text, line):
self.type = type self.type = type
self.text = text self.text = text
self.line = line self.line = line
self.flag = 0
# flags
IS_CAST = (1 << 0)
def tk_range_to_str(a, b, expand_tabs=False): def tk_range_to_str(a, b, expand_tabs=False):
...@@ -163,6 +172,13 @@ def tk_advance_line_to_token(index, direction, text, type_): ...@@ -163,6 +172,13 @@ def tk_advance_line_to_token(index, direction, text, type_):
return None return None
def tk_advance_flag(index, direction, flag):
state = (tokens[index].flag & flag)
while ((tokens[index + direction].flag) & flag == state) and index > 0:
index += direction
return index
def tk_match_backet(index): def tk_match_backet(index):
backet_start = tokens[index].text backet_start = tokens[index].text
assert(tokens[index].type == Token.Punctuation) assert(tokens[index].type == Token.Punctuation)
...@@ -326,8 +342,21 @@ def extract_cast(index): ...@@ -326,8 +342,21 @@ def extract_cast(index):
print() print()
''' '''
# Set the cast flags, so other checkers can use
for i in range(i_start, i_end + 1):
tokens[i].flag |= IS_CAST
return (i_start, i_end) return (i_start, i_end)
A = print
def tk_range_find_by_type(index_start, index_end, type_, filter_tk=None):
if index_start < index_end:
for i in range(index_start, index_end + 1):
if tokens[i].type == type_:
if filter_tk is None or filter_tk(tokens[i]):
return i
return -1
def warning(id_, message, index_kw_start, index_kw_end): def warning(id_, message, index_kw_start, index_kw_end):
if PRINT_QTC_TASKFORMAT: if PRINT_QTC_TASKFORMAT:
...@@ -369,6 +398,14 @@ def blender_check_kw_if(index_kw_start, index_kw, index_kw_end): ...@@ -369,6 +398,14 @@ def blender_check_kw_if(index_kw_start, index_kw, index_kw_end):
if ((tokens[index_kw].line == tokens[index_kw_end].line) and if ((tokens[index_kw].line == tokens[index_kw_end].line) and
(tokens[index_kw].line == tokens[index_next].line - 1)): (tokens[index_kw].line == tokens[index_next].line - 1)):
if ((tokens[index_kw].line + 1 != tokens[index_next].line) and
(tk_range_find_by_type(index_kw + 1, index_next - 1, Token.Comment.Preproc,
filter_tk=lambda tk: tk.text in {
"if", "ifdef", "ifndef", "else", "elif", "endif"}) != -1)
):
# allow this to go unnoticed
pass
else:
warning("E108", "if body brace on a new line '%s ()\\n{'" % warning("E108", "if body brace on a new line '%s ()\\n{'" %
tokens[index_kw].text, index_kw, index_kw_end) tokens[index_kw].text, index_kw, index_kw_end)
else: else:
...@@ -542,7 +579,6 @@ def blender_check_kw_else(index_kw): ...@@ -542,7 +579,6 @@ def blender_check_kw_else(index_kw):
# else # else
# #endif # #endif
# if # if
import sys
if ((tokens[index_kw].line + 1 != tokens[i_next].line) and if ((tokens[index_kw].line + 1 != tokens[i_next].line) and
any(True for i in range(index_kw + 1, i_next) any(True for i in range(index_kw + 1, i_next)
if (tokens[i].type == Token.Comment.Preproc and if (tokens[i].type == Token.Comment.Preproc and
...@@ -555,6 +591,14 @@ def blender_check_kw_else(index_kw): ...@@ -555,6 +591,14 @@ def blender_check_kw_else(index_kw):
): ):
# allow this to go unnoticed # allow this to go unnoticed
pass pass
if ((tokens[index_kw].line + 1 != tokens[i_next].line) and
(tk_range_find_by_type(index_kw + 1, i_next - 1, Token.Comment.Preproc,
filter_tk=lambda tk: tk.text in {
"if", "ifdef", "ifndef", "else", "elif", "endif", }) != -1)
):
# allow this to go unnoticed
pass
else: else:
warning("E115", "else if is split by a new line 'else\\nif'", index_kw, i_next) warning("E115", "else if is split by a new line 'else\\nif'", index_kw, i_next)
...@@ -751,8 +795,15 @@ def blender_check_operator(index_start, index_end, op_text, is_cpp): ...@@ -751,8 +795,15 @@ def blender_check_operator(index_start, index_end, op_text, is_cpp):
if len(op_text) == 1: if len(op_text) == 1:
if op_text in {"+", "-"}: if op_text in {"+", "-"}:
# detect (-a) vs (a - b) # detect (-a) vs (a - b)
if (not tokens[index_start - 1].text.isspace() and index_prev = index_start - 1
tokens[index_start - 1].text not in {"[", "(", "{"}): if (tokens[index_prev].text.isspace() and
tokens[index_prev - 1].flag & IS_CAST):
index_prev -= 1
if tokens[index_prev].flag & IS_CAST:
index_prev = tk_advance_flag(index_prev, -1, IS_CAST)
if (not tokens[index_prev].text.isspace() and
tokens[index_prev].text not in {"[", "(", "{"}):
warning("E130", "no space before operator '%s'" % op_text, index_start, index_end) warning("E130", "no space before operator '%s'" % op_text, index_start, index_end)
if (not tokens[index_end + 1].text.isspace() and if (not tokens[index_end + 1].text.isspace() and
tokens[index_end + 1].text not in {"]", ")", "}"}): tokens[index_end + 1].text not in {"]", ")", "}"}):
...@@ -778,8 +829,23 @@ def blender_check_operator(index_start, index_end, op_text, is_cpp): ...@@ -778,8 +829,23 @@ def blender_check_operator(index_start, index_end, op_text, is_cpp):
elif op_text == "&": elif op_text == "&":
pass # TODO, check if this is a pointer reference or not pass # TODO, check if this is a pointer reference or not
elif op_text == "*": elif op_text == "*":
index_prev = index_start - 1
if (tokens[index_prev].text.isspace() and
tokens[index_prev - 1].flag & IS_CAST):
index_prev -= 1
if tokens[index_prev].flag & IS_CAST:
index_prev = tk_advance_flag(index_prev, -1, IS_CAST)
# This check could be improved, its a bit fuzzy # This check could be improved, its a bit fuzzy
if ((tokens[index_start - 1].type in Token.Number) or if ((tokens[index_start - 1].flag & IS_CAST) or
(tokens[index_start + 1].flag & IS_CAST)):
# allow:
# a = *(int *)b;
# and:
# b = (int *)*b;
pass
elif ((tokens[index_start - 1].type in Token.Number) or
(tokens[index_start + 1].type in Token.Number)): (tokens[index_start + 1].type in Token.Number)):
warning("E130", "no space around operator '%s'" % op_text, index_start, index_end) warning("E130", "no space around operator '%s'" % op_text, index_start, index_end)
elif not (tokens[index_start - 1].text.isspace() or tokens[index_start - 1].text in {"(", "[", "{"}): elif not (tokens[index_start - 1].text.isspace() or tokens[index_start - 1].text in {"(", "[", "{"}):
......
...@@ -101,6 +101,25 @@ void func(void) ...@@ -101,6 +101,25 @@ void func(void)
code = FUNC_BEGIN + """ code = FUNC_BEGIN + """
\tif (1) { \tif (1) {
\t\t/* pass */ \t\t/* pass */
\t}""" + FUNC_END
err_found = test_code(code)
self.assertWarning(err_found)
# allow preprocessor splitting newlines
#
# #ifdef USE_FOO
# if (1)
# #endif
# {
# ...
# }
#
code = FUNC_BEGIN + """
#ifdef USE_FOO
\tif (1)
#endif
\t{
\t\t/* pass */
\t}""" + FUNC_END \t}""" + FUNC_END
err_found = test_code(code) err_found = test_code(code)
self.assertWarning(err_found) self.assertWarning(err_found)
...@@ -336,6 +355,14 @@ void func(void) ...@@ -336,6 +355,14 @@ void func(void)
"if (a ? c : d) { call(); }"), "if (a ? c : d) { call(); }"),
("if (a ?c : d) { call(); }", ("if (a ?c : d) { call(); }",
"if (a ? c : d) { call(); }"), "if (a ? c : d) { call(); }"),
# check casts don't confuse us
("a = 1+ (size_t)-b;",
"a = 1 + (size_t)-b;"),
("a = -(int)b+1;",
"a = -(int)b + 1;"),
("a = 1+ (int *)*b;",
"a = 1 + (int *)*b;"),
) )
for expr_fail, expr_ok in ab_test: for expr_fail, expr_ok in ab_test:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment