[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58466] trunk/blender/source/tools/ check_style_c.py: style checker now checks each block ends with break/ return/goto/continue or comment /* fall-through */
Campbell Barton
ideasman42 at gmail.com
Sun Jul 21 10:20:33 CEST 2013
Revision: 58466
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58466
Author: campbellbarton
Date: 2013-07-21 08:20:33 +0000 (Sun, 21 Jul 2013)
Log Message:
-----------
style checker now checks each block ends with break/return/goto/continue or comment /* fall-through */
shows up some suspicious code and false positive rate isnt too bad.
Modified Paths:
--------------
trunk/blender/source/tools/check_style_c.py
Modified: trunk/blender/source/tools/check_style_c.py
===================================================================
--- trunk/blender/source/tools/check_style_c.py 2013-07-21 08:16:37 UTC (rev 58465)
+++ trunk/blender/source/tools/check_style_c.py 2013-07-21 08:20:33 UTC (rev 58466)
@@ -83,8 +83,11 @@
self.line = line
-def tk_range_to_str(a, b):
- return "".join([tokens[i].text for i in range(a, b + 1)])
+def tk_range_to_str(a, b, expand_tabs=False):
+ txt = "".join([tokens[i].text for i in range(a, b + 1)])
+ if expand_tabs:
+ txt = txt.expandtabs(TAB_SIZE)
+ return txt
def tk_item_is_newline(tok):
@@ -172,10 +175,6 @@
return tokens[index_prev].line < tokens[index].line
-def extract_text(index_start, index_end):
- return "".join(tokens[i].text for i in range(index_start, index_end))
-
-
def extract_to_linestart(index):
ls = []
line = tokens[index].line
@@ -307,7 +306,7 @@
else:
print("%s:%d: warning: %s" % (filepath, tokens[index_kw_start].line, message))
if WARN_TEXT:
- print("".join([tokens[i].text for i in range(index_kw_start, index_kw_end + 1)]))
+ print(tk_range_to_str(index_kw_start, index_kw_end, expand_tabs=True))
def warning_lineonly(message, line):
@@ -438,29 +437,92 @@
if tokens[index_next].type == Token.Punctuation and tokens[index_next].text == "{":
ws_switch_indent = extract_to_linestart(index_kw)
- # TODO, check case statement has a break, return or /* fall-through */
-
if ws_switch_indent.isspace():
# 'case' should have at least 1 indent.
# otherwise expect 2 indent (or more, for nested switches)
ws_test = {
"case": ws_switch_indent + "\t",
- "default": ws_switch_indent + "\t",
+ "default:": ws_switch_indent + "\t",
+
"break": ws_switch_indent + "\t\t",
"return": ws_switch_indent + "\t\t",
+ "continue": ws_switch_indent + "\t\t",
+ "goto": ws_switch_indent + "\t\t",
}
index_final = tk_match_backet(index_next)
+ case_ls = []
+
for i in range(index_next + 1, index_final):
- if tokens[i].type == Token.Keyword:
- if tokens[i].text in {"case", "break", "return"}:
+ # 'default' is seen as a label
+ # print(tokens[i].type, tokens[i].text)
+ if tokens[i].type in {Token.Keyword, Token.Name.Label}:
+ if tokens[i].text in {"case", "default:", "break", "return", "comtinue", "goto"}:
ws_other_indent = extract_to_linestart(i)
# non ws start - we ignore for now, allow case A: case B: ...
if ws_other_indent.isspace():
- if not ws_other_indent.startswith(ws_test[tokens[i].text]):
+ ws_test_other = ws_test[tokens[i].text]
+ if not ws_other_indent.startswith(ws_test_other):
warning("%s is not indented enough" % tokens[i].text, i, i)
+
+ # assumes correct indentation...
+ if tokens[i].text in {"case", "default:"}:
+ if ws_other_indent == ws_test_other:
+ case_ls.append(i)
+
+ case_ls.append(index_final - 1)
+
+ # detect correct use of break/return
+ for j in range(len(case_ls) - 1):
+ i_case = case_ls[j]
+ i_end = case_ls[j + 1]
+
+ # detect cascading cases, check there is one line inbetween at least
+ if tokens[i_case].line + 1 < tokens[i_end].line:
+ ok = False
+
+ # scan case body backwards
+ for i in reversed(range(i_case, i_end)):
+ if tokens[i].type == Token.Punctuation:
+ if tokens[i].text == "}":
+ ws_other_indent = extract_to_linestart(i)
+ if ws_other_indent != ws_test["case"]:
+ # break/return _not_ found
+ break
+
+ elif tokens[i].type in Token.Comment:
+ if tokens[i].text == "/* fall-through */":
+ ok = True
+ break
+ else:
+ #~ print("Commment '%s'" % tokens[i].text)
+ pass
+
+
+ elif tokens[i].type == Token.Keyword:
+ if tokens[i].text in {"break", "return", "continue", "goto"}:
+ if tokens[i_case].line == tokens[i].line:
+ # Allow for...
+ # case BLAH: var = 1; break;
+ # ... possible there is if statements etc, but assume not
+ ok = True
+ break
+ else:
+ ws_other_indent = extract_to_linestart(i)
+ ws_other_indent = ws_other_indent[:len(ws_other_indent) - len(ws_other_indent.lstrip())]
+ ws_test_other = ws_test[tokens[i].text]
+ if ws_other_indent == ws_test_other:
+ ok = True
+ break
+ else:
+ print("indent mismatch...")
+ print("'%s'" % ws_other_indent)
+ print("'%s'" % ws_test_other)
+ if not ok:
+ warning("case/default statement has no break", i_case, i_end)
+ #~ print(tk_range_to_str(i_case - 1, i_end - 1, expand_tabs=True))
else:
warning("switch isn't the first token in the line", index_kw_start, index_kw_end)
else:
@@ -636,9 +698,8 @@
def blender_check_linelength(index_start, index_end, length):
if length > LIN_SIZE:
- text = "".join([tokens[i].text for i in range(index_start, index_end + 1)])
+ text = tk_range_to_str(index_start, index_end, expand_tabs=True)
for l in text.split("\n"):
- l = l.expandtabs(TAB_SIZE)
if len(l) > LIN_SIZE:
warning("line length %d > %d" % (len(l), LIN_SIZE), index_start, index_end)
@@ -724,7 +785,7 @@
# 3, 4}
# ... so only check braces which are the first text
if ws_i_match.isspace():
- ws_i = extract_to_linestart(i)
+ ws_i = extract_to_linestart(i)
ws_i_match_lstrip = ws_i_match.lstrip()
ws_i = ws_i[:len(ws_i) - len(ws_i.lstrip())]
More information about the Bf-blender-cvs
mailing list