|
@@ 4919-4968 (lines=50) @@
|
| 4916 |
|
' for more information.') |
| 4917 |
|
|
| 4918 |
|
|
| 4919 |
|
def CheckGlobalStatic(filename, clean_lines, linenum, error): |
| 4920 |
|
"""Check for unsafe global or static objects. |
| 4921 |
|
|
| 4922 |
|
Args: |
| 4923 |
|
filename: The name of the current file. |
| 4924 |
|
clean_lines: A CleansedLines instance containing the file. |
| 4925 |
|
linenum: The number of the line to check. |
| 4926 |
|
error: The function to call with any errors found. |
| 4927 |
|
""" |
| 4928 |
|
line = clean_lines.elided[linenum] |
| 4929 |
|
|
| 4930 |
|
# Match two lines at a time to support multiline declarations |
| 4931 |
|
if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line): |
| 4932 |
|
line += clean_lines.elided[linenum + 1].strip() |
| 4933 |
|
|
| 4934 |
|
# Check for people declaring static/global STL strings at the top level. |
| 4935 |
|
# This is dangerous because the C++ language does not guarantee that |
| 4936 |
|
# globals with constructors are initialized before the first access. |
| 4937 |
|
match = Match( |
| 4938 |
|
r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', |
| 4939 |
|
line) |
| 4940 |
|
|
| 4941 |
|
# Remove false positives: |
| 4942 |
|
# - String pointers (as opposed to values). |
| 4943 |
|
# string *pointer |
| 4944 |
|
# const string *pointer |
| 4945 |
|
# string const *pointer |
| 4946 |
|
# string *const pointer |
| 4947 |
|
# |
| 4948 |
|
# - Functions and template specializations. |
| 4949 |
|
# string Function<Type>(... |
| 4950 |
|
# string Class<Type>::Method(... |
| 4951 |
|
# |
| 4952 |
|
# - Operators. These are matched separately because operator names |
| 4953 |
|
# cross non-word boundaries, and trying to match both operators |
| 4954 |
|
# and functions at the same time would decrease accuracy of |
| 4955 |
|
# matching identifiers. |
| 4956 |
|
# string Class::operator*() |
| 4957 |
|
if (match and |
| 4958 |
|
not Search(r'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w', line) and |
| 4959 |
|
not Search(r'\boperator\W', line) and |
| 4960 |
|
not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(3))): |
| 4961 |
|
error(filename, linenum, 'runtime/string', 4, |
| 4962 |
|
'For a static/global string constant, use a C style string instead: ' |
| 4963 |
|
'"%schar %s[]".' % |
| 4964 |
|
(match.group(1), match.group(2))) |
| 4965 |
|
|
| 4966 |
|
if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): |
| 4967 |
|
error(filename, linenum, 'runtime/init', 4, |
| 4968 |
|
'You seem to be initializing a member variable with itself.') |
| 4969 |
|
|
| 4970 |
|
|
| 4971 |
|
def CheckPrintf(filename, clean_lines, linenum, error): |
|
@@ 4143-4175 (lines=33) @@
|
| 4140 |
|
"You don't need a ; after a }") |
| 4141 |
|
|
| 4142 |
|
|
| 4143 |
|
def CheckEmptyBlockBody(filename, clean_lines, linenum, error): |
| 4144 |
|
"""Look for empty loop/conditional body with only a single semicolon. |
| 4145 |
|
|
| 4146 |
|
Args: |
| 4147 |
|
filename: The name of the current file. |
| 4148 |
|
clean_lines: A CleansedLines instance containing the file. |
| 4149 |
|
linenum: The number of the line to check. |
| 4150 |
|
error: The function to call with any errors found. |
| 4151 |
|
""" |
| 4152 |
|
|
| 4153 |
|
# Search for loop keywords at the beginning of the line. Because only |
| 4154 |
|
# whitespaces are allowed before the keywords, this will also ignore most |
| 4155 |
|
# do-while-loops, since those lines should start with closing brace. |
| 4156 |
|
# |
| 4157 |
|
# We also check "if" blocks here, since an empty conditional block |
| 4158 |
|
# is likely an error. |
| 4159 |
|
line = clean_lines.elided[linenum] |
| 4160 |
|
matched = Match(r'\s*(for|while|if)\s*\(', line) |
| 4161 |
|
if matched: |
| 4162 |
|
# Find the end of the conditional expression |
| 4163 |
|
(end_line, end_linenum, end_pos) = CloseExpression( |
| 4164 |
|
clean_lines, linenum, line.find('(')) |
| 4165 |
|
|
| 4166 |
|
# Output warning if what follows the condition expression is a semicolon. |
| 4167 |
|
# No warning for all other cases, including whitespace or newline, since we |
| 4168 |
|
# have a separate check for semicolons preceded by whitespace. |
| 4169 |
|
if end_pos >= 0 and Match(r';', end_line[end_pos:]): |
| 4170 |
|
if matched.group(1) == 'if': |
| 4171 |
|
error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, |
| 4172 |
|
'Empty conditional bodies should use {}') |
| 4173 |
|
else: |
| 4174 |
|
error(filename, end_linenum, 'whitespace/empty_loop_body', 5, |
| 4175 |
|
'Empty loop bodies should use {} or continue') |
| 4176 |
|
|
| 4177 |
|
|
| 4178 |
|
def FindCheckMacro(line): |
|
@@ 4971-4997 (lines=27) @@
|
| 4968 |
|
'You seem to be initializing a member variable with itself.') |
| 4969 |
|
|
| 4970 |
|
|
| 4971 |
|
def CheckPrintf(filename, clean_lines, linenum, error): |
| 4972 |
|
"""Check for printf related issues. |
| 4973 |
|
|
| 4974 |
|
Args: |
| 4975 |
|
filename: The name of the current file. |
| 4976 |
|
clean_lines: A CleansedLines instance containing the file. |
| 4977 |
|
linenum: The number of the line to check. |
| 4978 |
|
error: The function to call with any errors found. |
| 4979 |
|
""" |
| 4980 |
|
line = clean_lines.elided[linenum] |
| 4981 |
|
|
| 4982 |
|
# When snprintf is used, the second argument shouldn't be a literal. |
| 4983 |
|
match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) |
| 4984 |
|
if match and match.group(2) != '0': |
| 4985 |
|
# If 2nd arg is zero, snprintf is used to calculate size. |
| 4986 |
|
error(filename, linenum, 'runtime/printf', 3, |
| 4987 |
|
'If you can, use sizeof(%s) instead of %s as the 2nd arg ' |
| 4988 |
|
'to snprintf.' % (match.group(1), match.group(2))) |
| 4989 |
|
|
| 4990 |
|
# Check if some verboten C functions are being used. |
| 4991 |
|
if Search(r'\bsprintf\s*\(', line): |
| 4992 |
|
error(filename, linenum, 'runtime/printf', 5, |
| 4993 |
|
'Never use sprintf. Use snprintf instead.') |
| 4994 |
|
match = Search(r'\b(strcpy|strcat)\s*\(', line) |
| 4995 |
|
if match: |
| 4996 |
|
error(filename, linenum, 'runtime/printf', 4, |
| 4997 |
|
'Almost always, snprintf is better than %s' % match.group(1)) |
| 4998 |
|
|
| 4999 |
|
|
| 5000 |
|
def IsDerivedFunction(clean_lines, linenum): |