Skip to content

Commit 548195f

Browse files
author
thk123
committed
Added check for position of &/* for types
We attempt to validate that the */& for pointer/reference types are attached to the variable rather than the type. For example should be int *x; rather than int* x; We attempt to check this by looking for things that are at the very start of the line and not in brackets to avoid picking up cases where the * or & is used as a binary operator. We can still miss cases inside a function declaration. Updated the coding standard to also explicityl mention this preference
1 parent 14f2a98 commit 548195f

File tree

4 files changed

+128
-12
lines changed

4 files changed

+128
-12
lines changed

CODING_STANDARD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ Whitespaces:
1717
Exceptions: Spaces around &&, || and <<
1818
- Space after comma (parameter lists, argument lists, ...)
1919
- Space after colon inside 'for'
20+
- For pointers and references, the */& should be attached to the variable name
21+
as oppposed to the tyep. E.g. for a pointer to an int the syntax would be:
22+
`int *x;`
2023
- No whitespaces at end of line
2124
- No whitespaces in blank lines
2225
- Put argument lists on next line (and ident 2 spaces) if too long
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*******************************************************************\
2+
3+
Module: Lint Examples
4+
5+
Author: Thomas Kiley, thomas@diffblue.com
6+
7+
\*******************************************************************/
8+
9+
/*******************************************************************\
10+
11+
Function: fun
12+
13+
Inputs:
14+
15+
Outputs:
16+
17+
Purpose:
18+
19+
\*******************************************************************/
20+
21+
static void fun()
22+
{
23+
bool *x=nullptr; // Valid
24+
bool* x=nullptr; // Invalid
25+
26+
int &x=nullptr; // Valid
27+
int& x=nullptr; // Invalid
28+
29+
int y=at*bt; // Valid
30+
31+
// Probably valid - could be a pointer to type yt or a
32+
// variable called yt multilied by z. Would have to know
33+
// it is a function call rather than a function declaration
34+
foo(
35+
x,
36+
yt*z);
37+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.cpp
3+
4+
^main\.cpp:24: Pointer type name must have \* attached to the type name \[whitespace/operators\] \[4\]$
5+
^main\.cpp:27: Reference type name must have & attached to the type name \[whitespace/operators\] \[4\]$
6+
^Total errors found: 2$
7+
^SIGNAL=0$
8+
--

scripts/cpplint.py

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,34 +1547,28 @@ def IsTemplateArgumentList_DB(clean_lines, linenum, pos):
15471547

15481548
return True
15491549

1550-
def OpenExpression(clean_lines, linenum, pos):
1551-
"""If input points to ) or } or ] or >, finds the position that opens it.
1552-
1553-
If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the
1554-
linenum/pos that correspond to the closing of the expression.
1555-
1556-
Essentially a mirror of what CloseExpression does
1550+
def ForceOpenExpression(clean_lines, linenum, pos, bracket):
1551+
"""Find an opening bracket matching the specified closing bracket
15571552
1558-
TODO(tkiley): could probably be merged with CloseExpression
1553+
Search starting at the position for a matching closing bracket of the
1554+
same type as bracket.
15591555
15601556
Args:
15611557
clean_lines: A CleansedLines instance containing the file.
15621558
linenum: The number of the line to check.
15631559
pos: A position on the line.
1560+
bracket: The style of bracket to match
15641561
15651562
Returns:
15661563
A tuple (line, linenum, pos) pointer *to* the closing brace, or
15671564
(line, len(lines), -1) if we never find a close. Note we ignore
15681565
strings and comments when matching; and the line we return is the
15691566
'cleansed' line at linenum.
15701567
"""
1571-
15721568
line = clean_lines.elided[linenum]
1573-
if (line[pos] not in ')}]>'):
1574-
return (line, clean_lines.NumLines(), -1)
15751569

15761570
# Check first line
1577-
(end_pos, stack) = FindStartOfExpressionInLine(line, pos , [])
1571+
(end_pos, stack) = FindStartOfExpressionInLine(line, pos , [bracket])
15781572
if end_pos > -1:
15791573
return (line, linenum, end_pos)
15801574

@@ -1589,6 +1583,37 @@ def OpenExpression(clean_lines, linenum, pos):
15891583
# Did not find end of expression before end of file, give up
15901584
return (line, clean_lines.NumLines(), -1)
15911585

1586+
def OpenExpression(clean_lines, linenum, pos):
1587+
"""If input points to ) or } or ] or >, finds the position that opens it.
1588+
1589+
If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the
1590+
linenum/pos that correspond to the closing of the expression.
1591+
1592+
Essentially a mirror of what CloseExpression does
1593+
1594+
Calls ForceOpenExpression with the bracket type pointed at
1595+
1596+
TODO(tkiley): could probably be merged with CloseExpression
1597+
1598+
Args:
1599+
clean_lines: A CleansedLines instance containing the file.
1600+
linenum: The number of the line to check.
1601+
pos: A position on the line.
1602+
1603+
Returns:
1604+
A tuple (line, linenum, pos) pointer *to* the closing brace, or
1605+
(line, len(lines), -1) if we never find a close. Note we ignore
1606+
strings and comments when matching; and the line we return is the
1607+
'cleansed' line at linenum.
1608+
"""
1609+
1610+
line = clean_lines.elided[linenum]
1611+
if (line[pos] not in ')}]>'):
1612+
return (line, clean_lines.NumLines(), -1)
1613+
else:
1614+
return ForceOpenExpression(clean_lines, linenum, pos-1, line[pos])
1615+
1616+
15921617
def FindEndOfExpressionInLine(line, startpos, stack):
15931618
"""Find the position just after the end of current parenthesized expression.
15941619
@@ -3656,6 +3681,48 @@ def CheckOperatorSpacing(filename, clean_lines, linenum, error):
36563681
error(filename, linenum, 'whitespace/operators', 4,
36573682
'Extra space for operator %s' % match.group(1))
36583683

3684+
def CheckPointerReferenceSpacing(filename, clean_lines, linenum, error):
3685+
"""Checks the */& are attached to variable names rather than types
3686+
3687+
A pointer or reference type should have the */& attached to the variable
3688+
name rather than the type. I.e. a pointer to an int should be:
3689+
3690+
int *var_name;
3691+
3692+
Args:
3693+
filename: The name of the current file.
3694+
clean_lines: A CleansedLines instance containing the file.
3695+
linenum: The number of the line to check.
3696+
error: The function to call with any errors found.
3697+
"""
3698+
line = clean_lines.elided[linenum]
3699+
3700+
# Find types by looking for word_names that are at the start of the line
3701+
# If there are followed by a * or & (after an optional ' const')
3702+
# then they appear to be a reference/pointer type with it attached to
3703+
# the type rather than the variable
3704+
wrong_type_match = Search(r'^\s*([\w_])+( const)?(?P<type>[&\*])\s*\w', line)
3705+
3706+
if wrong_type_match:
3707+
# This still could be a false positive, we must
3708+
# check that we are not inside brackets as then could be just be
3709+
# operators (multiply and logical AND)
3710+
pos = wrong_type_match.start(1)
3711+
_, _, opening_pos = ForceOpenExpression(clean_lines, linenum, pos, ')')
3712+
3713+
# If we don't find a matching close brace then we aren't in brackets
3714+
# so can assume this is a type with the * or & attached to it
3715+
if opening_pos == -1:
3716+
op_type = wrong_type_match.group('type')
3717+
op_word = ""
3718+
if op_type == '*':
3719+
op_word = 'Pointer'
3720+
else:
3721+
op_word = 'Reference'
3722+
error(filename, linenum, 'whitespace/operators', 4,
3723+
op_word + ' type name must have ' + op_type + ' attached to the type name')
3724+
3725+
36593726

36603727
def CheckParenthesisSpacing(filename, clean_lines, linenum, error):
36613728
"""Checks for horizontal spacing around parentheses.
@@ -4671,6 +4738,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
46714738
CheckAccess(filename, clean_lines, linenum, nesting_state, error)
46724739
CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
46734740
CheckOperatorSpacing(filename, clean_lines, linenum, error)
4741+
CheckPointerReferenceSpacing(filename, clean_lines, linenum, error)
46744742
CheckParenthesisSpacing(filename, clean_lines, linenum, error)
46754743
CheckCommaSpacing(filename, clean_lines, linenum, error)
46764744
CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error)

0 commit comments

Comments
 (0)