diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index 54e553b9..5ab10f00 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -24,44 +24,30 @@ function! ale#c#FindProjectRoot(buffer) abort endfunction function! ale#c#ParseCFlagsToList(path_prefix, cflags) abort - let l:previous_option = '' - let l:shell_option = 0 - let l:macro_option = 0 let l:cflags_list = [] + let l:previous_options = [] for l:option in a:cflags - - " Check if cflag contained spaces - if l:shell_option || stridx(l:option, '=`') >= 0 - " Cflag contained shell command with spaces (ex. -D='date +%s') - let l:shell_option = 1 - let l:previous_option .= l:option - if l:option[-1: -1] isnot? '`' - let l:previous_option .= ' ' - continue - endif - let l:shell_option = 0 - elseif l:macro_option || stridx(l:option, '$((') > 0 - " Cflag contained macro with spaces (ex -Da=$(( 4 * 20 ))) - let l:macro_option = 1 - let l:previous_option .= l:option - if stridx(l:option, '))') < 0 - let l:previous_option .= ' ' - continue - endif - let l:macro_option = 0 + call add(l:previous_options, l:option) + " Check if cflag contained a '-' and should not have been splitted + let l:option_list = split(l:option, '\zs') + if l:option_list[-1] isnot# ' ' + continue endif - if l:previous_option isnot? '' - let l:option = l:previous_option - let l:previous_option = '' - endif + let l:option = join(l:previous_options, '-') + let l:previous_options = [] + + let l:option = '-' . substitute(l:option, '^\s*\(.\{-}\)\s*$', '\1', '') " Fix relative paths if needed - if stridx(l:option, '-I') >= 0 - if stridx(l:option, '-I' . s:sep) < 0 - let l:option = '-I' . a:path_prefix . s:sep . l:option[2:] - endif + if stridx(l:option, '-I') >= 0 && + \ stridx(l:option, '-I' . s:sep) < 0 + let l:rel_path = join(split(l:option, '\zs')[2:], '') + let l:rel_path = substitute(l:rel_path, '"', '', 'g') + let l:rel_path = substitute(l:rel_path, '''', '', 'g') + let l:option = ale#Escape('-I' . a:path_prefix . + \ s:sep . l:rel_path) endif " Parse the cflag @@ -81,11 +67,11 @@ function! ale#c#ParseCFlags(buffer, stdout_make) abort return [] endif - let l:buffer_filename = expand('#' . a:buffer . '...') - - for l:cflags in split(a:stdout_make, '\n') - if stridx(l:cflags, l:buffer_filename) - let l:cflags = split(l:cflags) + let l:buffer_filename = expand('#' . a:buffer . ':t') + let l:cflags = [] + for l:lines in split(a:stdout_make, '\\n') + if stridx(l:lines, l:buffer_filename) >= 0 + let l:cflags = split(l:lines, '-') break endif endfor diff --git a/test/test_c_parse_makefile.vader b/test/test_c_parse_makefile.vader index f1988ec8..7c2fc21e 100644 --- a/test/test_c_parse_makefile.vader +++ b/test/test_c_parse_makefile.vader @@ -25,7 +25,7 @@ Execute(The CFlags parser should be able to parse include directives): call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') AssertEqual - \ ['-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')] + \ [ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))] \ , ale#c#ParseCFlags(bufnr(''), 'gcc -Isubdir -c file.c') Execute(The CFlags parser should be able to parse macro directives): @@ -34,7 +34,7 @@ Execute(The CFlags parser should be able to parse macro directives): call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') AssertEqual - \ ['-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'), + \ [ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), \ '-DTEST=1'] \ , ale#c#ParseCFlags(bufnr(''), 'gcc -Isubdir -DTEST=1 -c file.c') @@ -44,7 +44,7 @@ Execute(The CFlags parser should be able to parse macro directives with spaces): call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') AssertEqual - \ ['-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'), + \ [ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), \ '-DTEST=$(( 2 * 4 ))'] \ , ale#c#ParseCFlags(bufnr(''), 'gcc -Isubdir -DTEST=$(( 2 * 4 )) -c file.c') @@ -54,7 +54,7 @@ Execute(The CFlags parser should be able to parse shell directives with spaces): call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') AssertEqual - \ ['-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'), + \ [ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), \ '-DTEST=`date +%s`'] \ , ale#c#ParseCFlags(bufnr(''), 'gcc -Isubdir -DTEST=`date +%s` -c file.c') @@ -64,10 +64,10 @@ Execute(The CFlagsToList parser should be able to parse multiple cflags): call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') AssertEqual - \ ['-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'), + \ [ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), \ '-DTEST=`date +%s`'] \ , ale#c#ParseCFlagsToList(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), - \ split('gcc -Isubdir -DTEST=`date +%s` -c file.c')) + \ split('gcc -Isubdir -DTEST=`date +%s` -c file.c', '-')) Execute(The CFlagsToList parser should be able to parse multiple cflags #2): runtime! ale_linters/c/gcc.vim @@ -75,13 +75,13 @@ Execute(The CFlagsToList parser should be able to parse multiple cflags #2): call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') AssertEqual - \ ['-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'), - \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'), + \ [ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')), \ '-DTEST=`date +%s`'] \ , ale#c#ParseCFlagsToList(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), \ split('gcc -Isubdir ' . \ '-I'. ale#path#Simplify('kernel/include') . - \ ' -DTEST=`date +%s` -c file.c')) + \ ' -DTEST=`date +%s` -c file.c', '-')) Execute(The CFlagsToList parser should be able to parse multiple cflags #3): runtime! ale_linters/c/gcc.vim @@ -90,13 +90,13 @@ Execute(The CFlagsToList parser should be able to parse multiple cflags #3): AssertEqual \ ['-Dgoal=9', - \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'), - \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')), \ '-DTEST=`date +%s`'] \ , ale#c#ParseCFlagsToList(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), \ split('gcc -Dgoal=9 -Isubdir ' . \ '-I'. ale#path#Simplify('kernel/include') . - \ ' -DTEST=`date +%s` -c file.c')) + \ ' -DTEST=`date +%s` -c file.c', '-')) Execute(The CFlagsToList parser should be able to parse multiple cflags #4): runtime! ale_linters/c/gcc.vim @@ -105,10 +105,80 @@ Execute(The CFlagsToList parser should be able to parse multiple cflags #4): AssertEqual \ ['-Dgoal=9', - \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'), - \ '-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')), \ '-DTEST=`date +%s`'] \ , ale#c#ParseCFlagsToList(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), \ split('gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' . \ '-I'. ale#path#Simplify('kernel/include') . - \ ' -DTEST=`date +%s` -c file.c')) + \ ' -DTEST=`date +%s` -c file.c', '-')) + +Execute(The CFlagsToList parser should be able to parse multiple cflags #5): + runtime! ale_linters/c/gcc.vim + + call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') + + AssertEqual + \ ['-Dgoal=9', + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')), + \ '-DTEST=`date +%s`'] + \ , ale#c#ParseCFlagsToList(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ split('gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' . + \ '-I"dir with spaces"' . ' -I'. ale#path#Simplify('kernel/include') . + \ ' -DTEST=`date +%s` -c file.c', '-')) + +Execute(The CFlagsToList parser should be able to parse multiple cflags #6): + runtime! ale_linters/c/gcc.vim + + call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') + + AssertEqual + \ ['-Dgoal=9', + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')), + \ '-DTEST=`date +%s`'] + \ , ale#c#ParseCFlagsToList(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ split('gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' . + \ '-I''dir with spaces''' . ' -I'. ale#path#Simplify('kernel/include') . + \ ' -DTEST=`date +%s` -c file.c', '-')) + +Execute(The CFlagsToList parser should be able to parse multiple cflags #7): + runtime! ale_linters/c/gcc.vim + + call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') + + AssertEqual + \ ['-Dgoal=9', + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')), + \ '-DTEST=`date +%s`'] + \ , ale#c#ParseCFlagsToList(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ split('gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' . + \ '-I''dir with spaces''' . ' -Idir-with-dash' . + \ ' -I'. ale#path#Simplify('kernel/include') . + \ ' -DTEST=`date +%s` -c file.c', '-')) + +Execute(The CFlagsToList parser should be able to parse multiple cflags #8): + runtime! ale_linters/c/gcc.vim + + call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') + + AssertEqual + \ ['-Dgoal=9', + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir')), + \ '-Dmacro-with-dash', + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash')), + \ ale#Escape('-I' . ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')), + \ '-DTEST=`date +%s`'] + \ , ale#c#ParseCFlagsToList(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ split('gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' . + \ '-Dmacro-with-dash ' . + \ '-I''dir with spaces''' . ' -Idir-with-dash' . + \ ' -I'. ale#path#Simplify('kernel/include') . + \ ' -DTEST=`date +%s` -c file.c', '-'))