From f17b74679ffef9658e1a67fa280fe233c80aa378 Mon Sep 17 00:00:00 2001 From: tsjordan-eng <55999897+tsjordan-eng@users.noreply.github.com> Date: Thu, 6 Aug 2020 13:50:44 -0600 Subject: fix cppcheck for 1.89+, and add column support (#3030) * fix cppcheck for 1.89+, and add column support In cppcheck 1.89 the output changed to be more like GCC. This commit forces any version of cppcheck to output in that same format. This also allows for ALE to pick up the linter's column information * Add parameters to tests. Vader passes. * Fix c cppcheck for v1.89 --- ale_linters/c/cppcheck.vim | 2 ++ ale_linters/cpp/cppcheck.vim | 2 ++ autoload/ale/handlers/cppcheck.vim | 15 ++++++++----- .../test_c_cppcheck_command_callbacks.vader | 10 +++++---- .../test_cpp_cppcheck_command_callbacks.vader | 6 ++++- test/handler/test_cppcheck_handler.vader | 26 ++++++++++++++++------ 6 files changed, 44 insertions(+), 17 deletions(-) diff --git a/ale_linters/c/cppcheck.vim b/ale_linters/c/cppcheck.vim index 309b2851..b671fc8b 100644 --- a/ale_linters/c/cppcheck.vim +++ b/ale_linters/c/cppcheck.vim @@ -10,9 +10,11 @@ function! ale_linters#c#cppcheck#GetCommand(buffer) abort let l:buffer_path_include = empty(l:compile_commands_option) \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ : '' + let l:template = ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' return l:cd_command \ . '%e -q --language=c' + \ . l:template \ . ale#Pad(l:compile_commands_option) \ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options')) \ . l:buffer_path_include diff --git a/ale_linters/cpp/cppcheck.vim b/ale_linters/cpp/cppcheck.vim index 7cd80dbc..2c832246 100644 --- a/ale_linters/cpp/cppcheck.vim +++ b/ale_linters/cpp/cppcheck.vim @@ -10,9 +10,11 @@ function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort let l:buffer_path_include = empty(l:compile_commands_option) \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ : '' + let l:template = ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' return l:cd_command \ . '%e -q --language=c++' + \ . l:template \ . ale#Pad(l:compile_commands_option) \ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options')) \ . l:buffer_path_include diff --git a/autoload/ale/handlers/cppcheck.vim b/autoload/ale/handlers/cppcheck.vim index 6d8fa15d..7f68ba67 100644 --- a/autoload/ale/handlers/cppcheck.vim +++ b/autoload/ale/handlers/cppcheck.vim @@ -44,16 +44,21 @@ endfunction function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort " Look for lines like the following. " - " [test.cpp:5]: (error) Array 'a[10]' accessed at index 10, which is out of bounds - let l:pattern = '\v^\[(.+):(\d+)\]: \(([a-z]+)\) (.+)$' + "test.cpp:974:6: error: Array 'n[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\ + " n[3]=3; + " ^ + let l:pattern = '\v^(\f+):(\d+):(\d+): (\w+): (.*) \[(\w+)\]\' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) if ale#path#IsBufferPath(a:buffer, l:match[1]) call add(l:output, { - \ 'lnum': str2nr(l:match[2]), - \ 'type': l:match[3] is# 'error' ? 'E' : 'W', - \ 'text': l:match[4], + \ 'lnum': str2nr(l:match[2]), + \ 'col': str2nr(l:match[3]), + \ 'type': l:match[4] is# 'error' ? 'E' : 'W', + \ 'sub_type': l:match[4] is# 'style' ? 'style' : '', + \ 'text': l:match[5], + \ 'code': l:match[6] \}) endif endfor diff --git a/test/command_callback/test_c_cppcheck_command_callbacks.vader b/test/command_callback/test_c_cppcheck_command_callbacks.vader index 3d487a31..b6ea3179 100644 --- a/test/command_callback/test_c_cppcheck_command_callbacks.vader +++ b/test/command_callback/test_c_cppcheck_command_callbacks.vader @@ -1,7 +1,6 @@ Before: call ale#assert#SetUpLinterTest('c', 'cppcheck') - - let b:command_tail = ' -q --language=c --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t' + let b:command_tail = ' -q --language=c --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'' --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t' After: " Remove a test file we might open for some tests. @@ -10,9 +9,8 @@ After: set buftype=nofile endif - call ale#assert#TearDownLinterTest() - unlet! b:command_tail + call ale#assert#TearDownLinterTest() Execute(The executable should be configurable): AssertLinter 'cppcheck', ale#Escape('cppcheck') . b:command_tail @@ -28,6 +26,7 @@ Execute(cppcheck for C should detect compile_commands.json files): \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) \ . ale#Escape('cppcheck') \ . ' -q --language=c' + \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' \ . ' --project=' . ale#Escape('compile_commands.json') \ . ' --enable=style %t' @@ -38,6 +37,7 @@ Execute(cppcheck for C should detect compile_commands.json files in build direct \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir')) \ . ale#Escape('cppcheck') \ . ' -q --language=c' + \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) \ . ' --enable=style %t' @@ -47,6 +47,7 @@ Execute(cppcheck for C should include file dir if compile_commands.json file is AssertLinter 'cppcheck', \ ale#Escape('cppcheck') \ . ' -q --language=c' + \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' \ . ' --enable=style' \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths')) \ . ' %t' @@ -61,6 +62,7 @@ Execute(cppcheck for C should ignore compile_commands.json file if buffer is mod \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) \ . ale#Escape('cppcheck') \ . ' -q --language=c' + \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' \ . ' --enable=style' \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) \ . ' %t' diff --git a/test/command_callback/test_cpp_cppcheck_command_callbacks.vader b/test/command_callback/test_cpp_cppcheck_command_callbacks.vader index 02bdf748..b19c09b1 100644 --- a/test/command_callback/test_cpp_cppcheck_command_callbacks.vader +++ b/test/command_callback/test_cpp_cppcheck_command_callbacks.vader @@ -1,6 +1,6 @@ Before: call ale#assert#SetUpLinterTest('cpp', 'cppcheck') - let b:command_tail = ' -q --language=c++ --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t' + let b:command_tail = ' -q --language=c++ --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}'' --enable=style -I' . ale#Escape(ale#path#Simplify(g:dir)) .' %t' After: " Remove a test file we might open for some tests. @@ -26,6 +26,7 @@ Execute(cppcheck for C++ should detect compile_commands.json files): \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) \ . ale#Escape('cppcheck') \ . ' -q --language=c++' + \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' \ . ' --project=' . ale#Escape('compile_commands.json') \ . ' --enable=style %t' @@ -36,6 +37,7 @@ Execute(cppcheck for C++ should detect compile_commands.json files in build dire \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir')) \ . ale#Escape('cppcheck') \ . ' -q --language=c++' + \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) \ . ' --enable=style %t' @@ -45,6 +47,7 @@ Execute(cppcheck for C++ should include file dir if compile_commands.json file i AssertLinter 'cppcheck', \ ale#Escape('cppcheck') \ . ' -q --language=c++' + \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' \ . ' --enable=style' \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths')) \ . ' %t' @@ -59,6 +62,7 @@ Execute(cppcheck for C++ should ignore compile_commands.json file if buffer is m \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) \ . ale#Escape('cppcheck') \ . ' -q --language=c++' + \ . ' --template=''{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}''' \ . ' --enable=style' \ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) \ . ' %t' diff --git a/test/handler/test_cppcheck_handler.vader b/test/handler/test_cppcheck_handler.vader index f153b9b5..55a5d29b 100644 --- a/test/handler/test_cppcheck_handler.vader +++ b/test/handler/test_cppcheck_handler.vader @@ -10,19 +10,29 @@ Execute(Basic errors should be handled by cppcheck): AssertEqual \ [ \ { - \ 'lnum': 5, + \ 'lnum': 974, + \ 'col' : 6, \ 'type': 'E', - \ 'text': 'Array ''a[10]'' accessed at index 10, which is out of bounds', + \ 'sub_type': '', + \ 'text': 'Array ''n[3]'' accessed at index 3, which is out of bounds.', + \ 'code': 'arrayIndexOutOfBounds' \ }, \ { - \ 'lnum': 7, + \ 'lnum': 1185, + \ 'col' : 10, \ 'type': 'W', - \ 'text': 'Some other problem', + \ 'sub_type': 'style', + \ 'text': 'The scope of the variable ''indxStr'' can be reduced.', + \ 'code': 'variableScope' \ }, \ ], \ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [ - \ '[test.cpp:5]: (error) Array ''a[10]'' accessed at index 10, which is out of bounds', - \ '[test.cpp:7]: (warning) Some other problem', + \ 'test.cpp:974:6: error: Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\', + \ ' n[3]=3;', + \ ' ^', + \ 'test.cpp:1185:10: style: The scope of the variable ''indxStr'' can be reduced. [variableScope]\', + \ ' char indxStr[16];', + \ ' ^', \ ]) Execute(Problems from other files should be ignored by cppcheck): @@ -32,5 +42,7 @@ Execute(Problems from other files should be ignored by cppcheck): \ [ \ ], \ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [ - \ '[bar.cpp:5]: (error) Array ''a[10]'' accessed at index 10, which is out of bounds', + \ 'bar.cpp:974:6: error: Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\', + \ ' n[3]=3;', + \ ' ^', \ ]) -- cgit v1.2.3