cpplint_wrapper.py
Go to the documentation of this file.
1 # Software License Agreement (BSD License)
2 #
3 # copyright (c) 2014-2015 roslint contributors
4 # all rights reserved
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following
14 # disclaimer in the documentation and/or other materials provided
15 # with the distribution.
16 # * Neither the name of Willow Garage, Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 # POSSIBILITY OF SUCH DAMAGE.
32 
33 from roslint import cpplint
34 from roslint.cpplint import Match, IsBlankLine, main
35 from functools import partial
36 
37 import os.path
38 import re
39 
40 # Line length as per the ROS C++ Style Guide
41 cpplint._line_length = 120
42 
43 
44 def patch(original_module):
45  """ Decorator to easily allow wrapping/overriding of the Check* functions in cpplint. Should
46  decorate a function which matches the signature of the function it replaces expect with
47  the addition of a fn parameter, which is a pass-through of the replaced function, in case
48  the replacement would like call through to the original functionality. """
49  def wrap(override_fn):
50  original_fn = getattr(original_module, override_fn.__name__)
51  setattr(original_module, override_fn.__name__, partial(override_fn, original_fn))
52 
53  # Don't actually modify the function being decorated.
54  return override_fn
55  return wrap
56 
57 
58 def makeErrorFn(original_fn, suppress_categories, suppress_message_matches):
59  """ Create a return a wrapped version of the error-report function which suppresses specific
60  error categories. """
61  def newError(filename, linenum, category, confidence, message):
62  if category in suppress_categories:
63  return
64  if True in [bool(Match(r, message)) for r in suppress_message_matches]:
65  return
66  original_fn(filename, linenum, category, confidence, message)
67  return newError
68 
69 
70 @patch(cpplint)
71 def GetHeaderGuardCPPVariable(fn, filename):
72  """ Replacement for the function which determines the header guard variable, to pick one which
73  matches ROS C++ Style. """
74  var_parts = list()
75  head = filename
76  while head:
77  head, tail = os.path.split(head)
78  var_parts.insert(0, tail)
79  if head.endswith('include') or os.path.exists(os.path.join(head, "package.xml")) or tail == "":
80  break
81  return re.sub(r'[-./\s]', '_', "_".join(var_parts)).upper()
82 
83 
84 @patch(cpplint)
85 def CheckBraces(fn, filename, clean_lines, linenum, error):
86  """ Complete replacement for cpplint.CheckBraces, since the brace rules for ROS C++ Style
87  are completely different from the Google style guide ones. """
88  line = clean_lines.elided[linenum]
89  if Match(r'^(.*){(.*)}.*$', line):
90  # Special case when both braces are on the same line together, as is the
91  # case for one-line getters and setters, for example, or rows of a multi-
92  # dimenstional array initializer.
93  pass
94  else:
95  # Line does not contain both an opening and closing brace.
96  m = Match(r'^(.*){(.*)$', line)
97  if m and not (IsBlankLine(m.group(1))):
98  # Line contains a starting brace and is not empty, uh oh.
99  if "=" in line and Match(r'\)( *){$', line):
100  # Opening brace is permissable in case of an initializer.
101  pass
102  else:
103  error(filename, linenum, 'whitespace/braces', 4,
104  'when starting a new scope, { should be on a line by itself')
105  m = Match(r'^(.*)}(.*)$', line)
106  if m and (not IsBlankLine(m.group(1)) or not IsBlankLine(m.group(2))):
107  if m.group(2) != ";":
108  error(filename, linenum, 'whitespace/braces', 4,
109  '} should be on a line by itself')
110  pass
111 
112 
113 @patch(cpplint)
114 def CheckIncludeLine(fn, filename, clean_lines, linenum, include_state, error):
115  """ Run the function to get include state, but suppress all the errors, since
116  ROS C++ Style is silent on include order, and contains no prohibition on use of streams. """
117  fn(filename, clean_lines, linenum, include_state,
118  makeErrorFn(error, ['build/include_order', 'build/include_alpha', 'readability/streams'], []))
119 
120 
121 @patch(cpplint)
122 def CheckSpacing(fn, filename, clean_lines, linenum, nesting_state, error):
123  """ Do most of the original Spacing checks, but suppress the ones related to braces, since
124  the ROS C++ Style rules are different. """
125  fn(filename, clean_lines, linenum, nesting_state,
126  makeErrorFn(error, ['readability/braces', 'whitespace/braces'], []))
127 
128 
129 @patch(cpplint)
130 def ProcessLine(fn, filename, file_extension, clean_lines, line,
131  include_state, function_state, nesting_state, error,
132  extra_check_functions=[]):
133  """ Squelch the error about access control indents. """
134  fn(filename, file_extension, clean_lines, line,
135  include_state, function_state, nesting_state,
136  makeErrorFn(error, [], [r'(.*)should be indented \+1 space inside(.*)']),
137  extra_check_functions=[])
138 
139 
140 @patch(cpplint)
141 def CheckEmptyBlockBody(fn, filename, clean_lines, linenum, error):
142  """ Look for empty loop/conditional body with only a single semicolon,
143  but allow ros-style do while loops. """
144  from cpplint import CloseExpression
145 
146  # Search for loop keywords at the beginning of the line. Because only
147  # whitespaces are allowed before the keywords, this will also ignore most
148  # do-while-loops, since those lines should start with closing brace.
149  #
150  # We also check "if" blocks here, since an empty conditional block
151  # is likely an error.
152  line = clean_lines.elided[linenum]
153  matched = Match(r'\s*(for|while|if)\s*\(', line)
154  if matched:
155  # Find the end of the conditional expression
156  (end_line, end_linenum, end_pos) = CloseExpression(
157  clean_lines, linenum, line.find('('))
158 
159  # Output warning if what follows the condition expression is a
160  # semicolon. No warning for all other cases, including
161  # whitespace or newline, since we have a separate check for
162  # semicolons preceded by whitespace.
163  if end_pos >= 0 and Match(r';', end_line[end_pos:]):
164  if matched.group(1) == 'if':
165  error(filename, end_linenum,
166  'whitespace/empty_conditional_body', 5,
167  'Empty conditional bodies should use {}')
168  elif matched.group(1) == 'while' and linenum is not 0 \
169  and "}" in clean_lines.elided[linenum-1]:
170  # Don't report an error for ros style do-whiles. Works
171  # by checking for a closing brace on the previous
172  # line, since that means it's probably a do-while
173  # loop.
174  return
175  else:
176  error(filename, end_linenum, 'whitespace/empty_loop_body', 5,
177  'Empty loop bodies should use {} or continue')
def ProcessLine(fn, filename, file_extension, clean_lines, line, include_state, function_state, nesting_state, error, extra_check_functions=[])
def IsBlankLine(line)
Definition: cpplint.py:2818
def CheckSpacing(fn, filename, clean_lines, linenum, nesting_state, error)
def Match(pattern, s)
Definition: cpplint.py:562
def CheckIncludeLine(fn, filename, clean_lines, linenum, include_state, error)
def CheckEmptyBlockBody(fn, filename, clean_lines, linenum, error)
def CloseExpression(clean_lines, linenum, pos)
Definition: cpplint.py:1468
def GetHeaderGuardCPPVariable(fn, filename)
def makeErrorFn(original_fn, suppress_categories, suppress_message_matches)
def patch(original_module)
def CheckBraces(fn, filename, clean_lines, linenum, error)


roslint
Author(s): Mike Purvis, Jack O'Quin
autogenerated on Wed May 1 2019 02:23:59