00001
00002
00003
00004 from roslint import cpplint
00005 from roslint.cpplint import Match, IsBlankLine, main
00006 from functools import partial
00007
00008 import os.path
00009 import re
00010
00011
00012 cpplint._line_length = 120
00013
00014
00015 def patch(original_module):
00016 """ Decorator to easily allow wrapping/overriding of the Check* functions in cpplint. Should
00017 decorate a function which matches the signature of the function it replaces expect with
00018 the addition of a fn parameter, which is a pass-through of the replaced function, in case
00019 the replacement would like call through to the original functionality. """
00020 def wrap(override_fn):
00021 original_fn = getattr(original_module, override_fn.__name__)
00022 setattr(original_module, override_fn.__name__, partial(override_fn, original_fn))
00023
00024
00025 return override_fn
00026 return wrap
00027
00028
00029 def makeErrorFn(original_fn, suppress_categories, suppress_message_matches):
00030 """ Create a return a wrapped version of the error-report function which suppresses specific
00031 error categories. """
00032 def newError(filename, linenum, category, confidence, message):
00033 if category in suppress_categories:
00034 return
00035
00036
00037 if True in [bool(Match(r, message)) for r in suppress_message_matches]:
00038 return
00039 original_fn(filename, linenum, category, confidence, message)
00040 return newError
00041
00042
00043 @patch(cpplint)
00044 def GetHeaderGuardCPPVariable(fn, filename):
00045 """ Replacement for the function which determines the header guard variable, to pick one which
00046 matches ROS C++ Style. """
00047 var_parts = list()
00048 head = filename
00049 while head:
00050 head, tail = os.path.split(head)
00051 var_parts.insert(0, tail)
00052 if head.endswith('include') or tail == "":
00053 break
00054 return re.sub(r'[-./\s]', '_', "_".join(var_parts)).upper()
00055
00056
00057 @patch(cpplint)
00058 def CheckBraces(fn, filename, clean_lines, linenum, error):
00059 """ Complete replacement for cpplint.CheckBraces, since the brace rules for ROS C++ Style
00060 are completely different from the Google style guide ones. """
00061 line = clean_lines.elided[linenum]
00062 if Match(r'^(.*){(.*)}.?$', line):
00063
00064
00065
00066 pass
00067 else:
00068
00069 m = Match(r'^(.*){(.*)$', line)
00070 if m and not (IsBlankLine(m.group(1))):
00071
00072 if "=" in line:
00073
00074 pass
00075 else:
00076 error(filename, linenum, 'whitespace/braces', 4,
00077 'when starting a new scope, { should be on a line by itself')
00078 m = Match(r'^(.*)}(.*)$', line)
00079 if m and (not IsBlankLine(m.group(1)) or not IsBlankLine(m.group(2))):
00080 if m.group(2) != ";":
00081 error(filename, linenum, 'whitespace/braces', 4,
00082 '} should be on a line by itself')
00083 pass
00084
00085
00086 @patch(cpplint)
00087 def CheckIncludeLine(fn, filename, clean_lines, linenum, include_state, error):
00088 """ Run the function to get include state, but suppress all the errors, since
00089 ROS C++ Style is silent on include order, and contains no prohibition on use of streams. """
00090 fn(filename, clean_lines, linenum, include_state,
00091 makeErrorFn(error, ['build/include_order', 'build/include_alpha', 'readability/streams'], []))
00092
00093
00094 @patch(cpplint)
00095 def CheckSpacing(fn, filename, clean_lines, linenum, nesting_state, error):
00096 """ Do most of the original Spacing checks, but suppress the ones related to braces, since
00097 the ROS C++ Style rules are different. """
00098 fn(filename, clean_lines, linenum, nesting_state,
00099 makeErrorFn(error, ['readability/braces', 'whitespace/braces'], []))
00100
00101
00102 @patch(cpplint)
00103 def ProcessLine(fn, filename, file_extension, clean_lines, line,
00104 include_state, function_state, nesting_state, error,
00105 extra_check_functions=[]):
00106 """ Squelch the error about access control indents. """
00107 fn(filename, file_extension, clean_lines, line,
00108 include_state, function_state, nesting_state,
00109 makeErrorFn(error, [], [r'(.*)should be indented \+1 space inside class(.*)']),
00110 extra_check_functions=[])