cpplint 新增自定义规则
cpplint 介绍
cpplint 是一个用于检查 C/C++ 代码风格的工具,它基于 Google 的 C++ 编码规范。通过使用 cpplint,开发者可以确保代码的一致性和可读性,从而提高代码质量。
新增自定义规则
在使用 cpplint 的过程中,有时需要根据项目的特定需求新增自定义规则。可以通过修改 cpplint 的源代码的方式来实现。
源码简单分析
首先我们可以下载cpplint的源码,进行简单的分析。
其中cpplint.py是其实际执行的检测脚本。在脚本的最后我们可以找到其中的main函数。
def main():
filenames = ParseArguments(sys.argv[1:])
backup_err = sys.stderr
try:
# Change stderr to write with replacement characters so we don't die
# if we try to print something containing non-ASCII characters.
sys.stderr = codecs.StreamReader(sys.stderr, 'replace')
_cpplint_state.ResetErrorCounts()
for filename in filenames:
ProcessFile(filename, _cpplint_state.verbose_level)
# If --quiet is passed, suppress printing error count unless there are errors.
if not _cpplint_state.quiet or _cpplint_state.error_count > 0:
_cpplint_state.PrintErrorCounts()
if _cpplint_state.output_format == 'junit':
sys.stderr.write(_cpplint_state.FormatJUnitXML())
finally:
sys.stderr = backup_err
sys.exit(_cpplint_state.error_count > 0)
if __name__ == '__main__':
main()
在main函数中我们可以看到,实际调用了ProcessFile函数对每个文件进行分析。
查看ProcessFile函数的定义,如下:
def ProcessFile(filename, vlevel, extra_check_functions=None):
"""Does google-lint on a single file.
Args:
filename: The name of the file to parse.
vlevel: The level of errors to report. Every error of confidence
>= verbose_level will be reported. 0 is a good default.
extra_check_functions: An array of additional check functions that will be
run on each source line. Each function takes 4
arguments: filename, clean_lines, line, error
"""
通过函数定义与注释可知,此函数可接收一个函数数组extra_check_functions。
数组中的每个函数都可对源码进行检测,且每个函数接收相同的四个参数。
通过这个参数我们就可以新增自定义的检测规则了。
这里介绍一下函数的四个参数:
- filename: 源码的文件名
- clean_lines: 一个CleansedLines类的实例,包含了文件内容,从中可提取原始的行、删除注释的行和去掉了注释和常量字符的行。
- line: 行号
- error: 一个cpplint的错误类的实例
新增自定义checker
通过简单分析源码后,新增自定义checker的整体流程如下:
- 新增自定义checker函数,按实际规则编写。
- 定义extra_check_functions数组,将新增checker函数加入其中。
- 修改main函数,将ProcessFile函数调用修改为带extra_check_functions的版本。
此处以一个检测源码中是否包含中文的情况为例子,展示新增自定义cheker的流程:
在cpplint.py中新增CheckSourceChinese函数,函数定义如下:
def CheckSourceChinese(filename, clean_lines, line, error): current_raw_line = clean_lines.raw_lines[line] if re.search(r'[\u4e00-\u9fa5]+', current_raw_line): error(filename, line, 'newchecker/chinese', 5, 'Chinese characters are not allowed.')
此函数会对文件的每一行都进行检测,此处中从clean_lines中获取了原始的行,因此不管是源码还是注释中出现中文都会报错。
定义extra_check_functions并新增CheckSourceChinese函数。
修改main函数,将ProcessFile函数调用修改为带extra_check_functions的版本。
2、3步代码如下标绿处:
def main(): filenames = ParseArguments(sys.argv[1:]) backup_err = sys.stderr try: # Change stderr to write with replacement characters so we don't die # if we try to print something containing non-ASCII characters. sys.stderr = codecs.StreamReader(sys.stderr, 'replace') _cpplint_state.ResetErrorCounts() extra_check_functions = [CheckSourceChinese,] for filename in filenames: ProcessFile(filename, _cpplint_state.verbose_level, extra_check_functions) # If --quiet is passed, suppress printing error count unless there are errors. if not _cpplint_state.quiet or _cpplint_state.error_count > 0: _cpplint_state.PrintErrorCounts() if _cpplint_state.output_format == 'junit': sys.stderr.write(_cpplint_state.FormatJUnitXML()) finally: sys.stderr = backup_err sys.exit(_cpplint_state.error_count > 0) if __name__ == '__main__': main()
测试效果:
a.cpp:23: Chinese characters are not allowed. [newchecker/chinese] [5]
总结
通过新增自定义规则,可以让 cpplint 更加贴合项目的编码规范,从而提高代码的质量和一致性。