summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw0rp <w0rp@users.noreply.github.com>2018-03-27 09:55:43 +0100
committerGitHub <noreply@github.com>2018-03-27 09:55:43 +0100
commit018831d601a6fc53216ad448a91bb76b0ac4d8e3 (patch)
tree5a34d094612bc4acbfc5500ef21282ac45a1adbd
parent27c5faeafe055954b6e3164467844e78f7a07e55 (diff)
parentdfb3e194d7a05b747c77d312a72e5149595bbcef (diff)
downloadale-018831d601a6fc53216ad448a91bb76b0ac4d8e3.zip
Merge pull request #1434 from roel0/master
Automatically determine build flags by parsing `make -n` output #1167
-rw-r--r--ale_linters/c/clang.vim11
-rw-r--r--ale_linters/c/gcc.vim11
-rw-r--r--autoload/ale/c.vim85
-rw-r--r--test/command_callback/test_c_clang_command_callbacks.vader4
-rw-r--r--test/command_callback/test_c_gcc_command_callbacks.vader4
-rw-r--r--test/test_c_import_paths.vader16
-rw-r--r--test/test_c_parse_makefile.vader184
-rw-r--r--test/test_c_projects/makefile_project/subdir/file.c0
8 files changed, 294 insertions, 21 deletions
diff --git a/ale_linters/c/clang.vim b/ale_linters/c/clang.vim
index 76803056..ddec4fcb 100644
--- a/ale_linters/c/clang.vim
+++ b/ale_linters/c/clang.vim
@@ -8,15 +8,15 @@ function! ale_linters#c#clang#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_clang_executable')
endfunction
-function! ale_linters#c#clang#GetCommand(buffer) abort
- let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
+function! ale_linters#c#clang#GetCommand(buffer, output) abort
+ let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#c#clang#GetExecutable(a:buffer))
\ . ' -S -x c -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
- \ . ale#c#IncludeOptions(l:paths)
+ \ . l:cflags
\ . ale#Var(a:buffer, 'c_clang_options') . ' -'
endfunction
@@ -24,6 +24,9 @@ call ale#linter#Define('c', {
\ 'name': 'clang',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#c#clang#GetExecutable',
-\ 'command_callback': 'ale_linters#c#clang#GetCommand',
+\ 'command_chain': [
+\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
+\ {'callback': 'ale_linters#c#clang#GetCommand'}
+\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/c/gcc.vim b/ale_linters/c/gcc.vim
index 4b241e37..98563952 100644
--- a/ale_linters/c/gcc.vim
+++ b/ale_linters/c/gcc.vim
@@ -8,15 +8,15 @@ function! ale_linters#c#gcc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'c_gcc_executable')
endfunction
-function! ale_linters#c#gcc#GetCommand(buffer) abort
- let l:paths = ale#c#FindLocalHeaderPaths(a:buffer)
+function! ale_linters#c#gcc#GetCommand(buffer, output) abort
+ let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
" -iquote with the directory the file is in makes #include work for
" headers in the same directory.
return ale#Escape(ale_linters#c#gcc#GetExecutable(a:buffer))
\ . ' -S -x c -fsyntax-only '
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) . ' '
- \ . ale#c#IncludeOptions(l:paths)
+ \ . l:cflags
\ . ale#Var(a:buffer, 'c_gcc_options') . ' -'
endfunction
@@ -24,6 +24,9 @@ call ale#linter#Define('c', {
\ 'name': 'gcc',
\ 'output_stream': 'stderr',
\ 'executable_callback': 'ale_linters#c#gcc#GetExecutable',
-\ 'command_callback': 'ale_linters#c#gcc#GetCommand',
+\ 'command_chain': [
+\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
+\ {'callback': 'ale_linters#c#gcc#GetCommand'}
+\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim
index f6ad7deb..5ab10f00 100644
--- a/autoload/ale/c.vim
+++ b/autoload/ale/c.vim
@@ -1,6 +1,7 @@
-" Author: gagbo <gagbobada@gmail.com>, w0rp <devw0rp@gmail.com>
+" Author: gagbo <gagbobada@gmail.com>, w0rp <devw0rp@gmail.com>, roel0 <postelmansroel@gmail.com>
" Description: Functions for integrating with C-family linters.
+call ale#Set('c_parse_makefile', 0)
let s:sep = has('win32') ? '\' : '/'
function! ale#c#FindProjectRoot(buffer) abort
@@ -22,6 +23,88 @@ function! ale#c#FindProjectRoot(buffer) abort
return ''
endfunction
+function! ale#c#ParseCFlagsToList(path_prefix, cflags) abort
+ let l:cflags_list = []
+ let l:previous_options = []
+
+ for l:option in a:cflags
+ 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
+
+ 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 &&
+ \ 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
+ if stridx(l:option, '-I') >= 0 ||
+ \ stridx(l:option, '-D') >= 0
+ if index(l:cflags_list, l:option) < 0
+ call add(l:cflags_list, l:option)
+ endif
+ endif
+ endfor
+
+ return l:cflags_list
+endfunction
+
+function! ale#c#ParseCFlags(buffer, stdout_make) abort
+ if !g:ale_c_parse_makefile
+ return []
+ endif
+
+ 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
+
+ let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile')
+ return ale#c#ParseCFlagsToList(fnamemodify(l:makefile_path, ':p:h'), l:cflags)
+endfunction
+
+function! ale#c#GetCFlags(buffer, output) abort
+ let l:cflags = ' '
+
+ if g:ale_c_parse_makefile && !empty(a:output)
+ let l:cflags = join(ale#c#ParseCFlags(a:buffer, join(a:output, '\n')), ' ') . ' '
+ endif
+
+ if l:cflags is# ' '
+ let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
+ endif
+
+ return l:cflags
+endfunction
+
+function! ale#c#GetMakeCommand(buffer) abort
+ if g:ale_c_parse_makefile
+ let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile')
+ if !empty(l:makefile_path)
+ return 'cd '. fnamemodify(l:makefile_path, ':p:h') . ' && make -n'
+ endif
+ endif
+
+ return ''
+endfunction
+
" Given a buffer number, search for a project root, and output a List
" of directories to include based on some heuristics.
"
diff --git a/test/command_callback/test_c_clang_command_callbacks.vader b/test/command_callback/test_c_clang_command_callbacks.vader
index d6fc8ca6..2f6d4dd0 100644
--- a/test/command_callback/test_c_clang_command_callbacks.vader
+++ b/test/command_callback/test_c_clang_command_callbacks.vader
@@ -30,10 +30,10 @@ Execute(The executable should be configurable):
Execute(The executable should be used in the command):
AssertEqual
\ ale#Escape('clang') . b:command_tail,
- \ ale_linters#c#clang#GetCommand(bufnr(''))
+ \ ale_linters#c#clang#GetCommand(bufnr(''), [])
let b:ale_c_clang_executable = 'foobar'
AssertEqual
\ ale#Escape('foobar') . b:command_tail,
- \ ale_linters#c#clang#GetCommand(bufnr(''))
+ \ ale_linters#c#clang#GetCommand(bufnr(''), [])
diff --git a/test/command_callback/test_c_gcc_command_callbacks.vader b/test/command_callback/test_c_gcc_command_callbacks.vader
index 8038f410..3557576e 100644
--- a/test/command_callback/test_c_gcc_command_callbacks.vader
+++ b/test/command_callback/test_c_gcc_command_callbacks.vader
@@ -30,10 +30,10 @@ Execute(The executable should be configurable):
Execute(The executable should be used in the command):
AssertEqual
\ ale#Escape('gcc') . b:command_tail,
- \ ale_linters#c#gcc#GetCommand(bufnr(''))
+ \ ale_linters#c#gcc#GetCommand(bufnr(''), [])
let b:ale_c_gcc_executable = 'foobar'
AssertEqual
\ ale#Escape('foobar') . b:command_tail,
- \ ale_linters#c#gcc#GetCommand(bufnr(''))
+ \ ale_linters#c#gcc#GetCommand(bufnr(''), [])
diff --git a/test/test_c_import_paths.vader b/test/test_c_import_paths.vader
index 6080779f..a2ffe54e 100644
--- a/test/test_c_import_paths.vader
+++ b/test/test_c_import_paths.vader
@@ -42,7 +42,7 @@ Execute(The C GCC handler should include 'include' directories for projects with
\ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/subdir')) . ' '
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/include')) . ' '
\ . ' -'
- \ , ale_linters#c#gcc#GetCommand(bufnr(''))
+ \ , ale_linters#c#gcc#GetCommand(bufnr(''), [])
Execute(The C GCC handler should include 'include' directories for projects with a configure file):
runtime! ale_linters/c/gcc.vim
@@ -55,7 +55,7 @@ Execute(The C GCC handler should include 'include' directories for projects with
\ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/configure_project/subdir')) . ' '
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/configure_project/include')) . ' '
\ . ' -'
- \ , ale_linters#c#gcc#GetCommand(bufnr(''))
+ \ , ale_linters#c#gcc#GetCommand(bufnr(''), [])
Execute(The C GCC handler should include root directories for projects with .h files in them):
runtime! ale_linters/c/gcc.vim
@@ -68,7 +68,7 @@ Execute(The C GCC handler should include root directories for projects with .h f
\ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/h_file_project/subdir')) . ' '
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/h_file_project')) . ' '
\ . ' -'
- \ , ale_linters#c#gcc#GetCommand(bufnr(''))
+ \ , ale_linters#c#gcc#GetCommand(bufnr(''), [])
Execute(The C GCC handler should include root directories for projects with .hpp files in them):
runtime! ale_linters/c/gcc.vim
@@ -81,7 +81,7 @@ Execute(The C GCC handler should include root directories for projects with .hpp
\ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/hpp_file_project/subdir')) . ' '
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/hpp_file_project')) . ' '
\ . ' -'
- \ , ale_linters#c#gcc#GetCommand(bufnr(''))
+ \ , ale_linters#c#gcc#GetCommand(bufnr(''), [])
Execute(The C Clang handler should include 'include' directories for projects with a Makefile):
runtime! ale_linters/c/clang.vim
@@ -94,7 +94,7 @@ Execute(The C Clang handler should include 'include' directories for projects wi
\ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/subdir')) . ' '
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/include')) . ' '
\ . ' -'
- \ , ale_linters#c#clang#GetCommand(bufnr(''))
+ \ , ale_linters#c#clang#GetCommand(bufnr(''), [])
Execute(The C Clang handler should include 'include' directories for projects with a configure file):
runtime! ale_linters/c/clang.vim
@@ -107,7 +107,7 @@ Execute(The C Clang handler should include 'include' directories for projects wi
\ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/h_file_project/subdir')) . ' '
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/h_file_project')) . ' '
\ . ' -'
- \ , ale_linters#c#clang#GetCommand(bufnr(''))
+ \ , ale_linters#c#clang#GetCommand(bufnr(''), [])
Execute(The C Clang handler should include root directories for projects with .h files in them):
runtime! ale_linters/c/clang.vim
@@ -120,7 +120,7 @@ Execute(The C Clang handler should include root directories for projects with .h
\ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/h_file_project/subdir')) . ' '
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/h_file_project')) . ' '
\ . ' -'
- \ , ale_linters#c#clang#GetCommand(bufnr(''))
+ \ , ale_linters#c#clang#GetCommand(bufnr(''), [])
Execute(The C Clang handler should include root directories for projects with .hpp files in them):
runtime! ale_linters/c/clang.vim
@@ -133,7 +133,7 @@ Execute(The C Clang handler should include root directories for projects with .h
\ . '-iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/hpp_file_project/subdir')) . ' '
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/hpp_file_project')) . ' '
\ . ' -'
- \ , ale_linters#c#clang#GetCommand(bufnr(''))
+ \ , ale_linters#c#clang#GetCommand(bufnr(''), [])
Execute(The C++ GCC handler should include 'include' directories for projects with a Makefile):
runtime! ale_linters/cpp/gcc.vim
diff --git a/test/test_c_parse_makefile.vader b/test/test_c_parse_makefile.vader
new file mode 100644
index 00000000..7c2fc21e
--- /dev/null
+++ b/test/test_c_parse_makefile.vader
@@ -0,0 +1,184 @@
+Before:
+ Save g:ale_c_parse_makefile
+ Save g:ale_c_gcc_options
+ Save g:ale_c_clang_options
+ Save g:ale_cpp_gcc_options
+ Save g:ale_cpp_clang_options
+
+ call ale#test#SetDirectory('/testplugin/test')
+
+ let g:ale_c_parse_makefile=1
+ let g:ale_c_gcc_options = ''
+ let g:ale_c_clang_options = ''
+ let g:ale_cpp_gcc_options = ''
+ let g:ale_cpp_clang_options = ''
+
+After:
+ Restore
+
+ call ale#test#RestoreDirectory()
+ call ale#linter#Reset()
+
+Execute(The CFlags parser should be able to parse include directives):
+ runtime! ale_linters/c/gcc.vim
+
+ call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
+
+ AssertEqual
+ \ [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):
+ runtime! ale_linters/c/gcc.vim
+
+ call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
+
+ AssertEqual
+ \ [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')
+
+Execute(The CFlags parser should be able to parse macro directives with spaces):
+ runtime! ale_linters/c/gcc.vim
+
+ call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
+
+ AssertEqual
+ \ [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')
+
+Execute(The CFlags parser should be able to parse shell directives with spaces):
+ runtime! ale_linters/c/gcc.vim
+
+ call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
+
+ AssertEqual
+ \ [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')
+
+Execute(The CFlagsToList parser should be able to parse multiple cflags):
+ runtime! ale_linters/c/gcc.vim
+
+ call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
+
+ AssertEqual
+ \ [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', '-'))
+
+Execute(The CFlagsToList parser should be able to parse multiple cflags #2):
+ runtime! ale_linters/c/gcc.vim
+
+ call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
+
+ AssertEqual
+ \ [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', '-'))
+
+Execute(The CFlagsToList parser should be able to parse multiple cflags #3):
+ 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/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', '-'))
+
+Execute(The CFlagsToList parser should be able to parse multiple cflags #4):
+ 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/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', '-'))
+
+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', '-'))
diff --git a/test/test_c_projects/makefile_project/subdir/file.c b/test/test_c_projects/makefile_project/subdir/file.c
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/test_c_projects/makefile_project/subdir/file.c