diff options
author | w0rp <w0rp@users.noreply.github.com> | 2020-08-19 00:15:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-19 00:15:34 +0100 |
commit | e27d4377b5dec30a6510a8d45685a37681baaaf0 (patch) | |
tree | 890b7d6441598f5cbd40341accf7910a9441493a | |
parent | f8b3a43aab99af7abccde567c5912a12b9d4e0d9 (diff) | |
parent | b20931571484108d1ec29eaab5b731e754649664 (diff) | |
download | ale-e27d4377b5dec30a6510a8d45685a37681baaaf0.zip |
Merge pull request #3178 from sudobash1/expand_at
Fixes #3092 - Implement loading `@file` c arguments
-rw-r--r-- | autoload/ale/c.vim | 50 | ||||
-rw-r--r-- | test/test_c_flag_parsing.vader | 11 | ||||
-rw-r--r-- | test/test_c_projects/makefile_project/args | 3 | ||||
-rw-r--r-- | test/test_c_projects/makefile_project/subdir/args | 1 |
4 files changed, 64 insertions, 1 deletions
diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index 39892d42..be54cff1 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -61,10 +61,58 @@ function! ale#c#ShellSplit(line) abort return l:args endfunction +" Takes the path prefix and a list of cflags and expands @file arguments to +" the contents of the file. +" +" @file arguments are command line arguments recognised by gcc and clang. For +" instance, if @./path/to/file was given to gcc, it would load .path/to/file +" and use the contents of that file as arguments. +function! ale#c#ExpandAtArgs(path_prefix, raw_split_lines) abort + let l:out_lines = [] + + for l:option in a:raw_split_lines + if stridx(l:option, '@') == 0 + " This is an argument specifying a location of a file containing other arguments + let l:path = join(split(l:option, '\zs')[1:], '') + + " Make path absolute + if stridx(l:path, s:sep) != 0 && stridx(l:path, '/') != 0 + let l:rel_path = substitute(l:path, '"', '', 'g') + let l:rel_path = substitute(l:rel_path, '''', '', 'g') + let l:path = a:path_prefix . s:sep . l:rel_path + endif + + " Read the file and add all the arguments + try + let l:additional_args = readfile(l:path) + catch + continue " All we can really do is skip this argument + endtry + + let l:file_lines = [] + + for l:line in l:additional_args + let l:file_lines += ale#c#ShellSplit(l:line) + endfor + + " @file arguments can include other @file arguments, so we must + " recurse. + let l:out_lines += ale#c#ExpandAtArgs(a:path_prefix, l:file_lines) + else + " This is not an @file argument, so don't touch it. + let l:out_lines += [l:option] + endif + endfor + + return l:out_lines +endfunction + function! ale#c#ParseCFlags(path_prefix, cflag_line) abort let l:cflags_list = [] - let l:split_lines = ale#c#ShellSplit(a:cflag_line) + let l:raw_split_lines = ale#c#ShellSplit(a:cflag_line) + " Expand @file arguments now before parsing + let l:split_lines = ale#c#ExpandAtArgs(a:path_prefix, l:raw_split_lines) let l:option_index = 0 while l:option_index < len(l:split_lines) diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader index 8ae6f9dc..dff19aa3 100644 --- a/test/test_c_flag_parsing.vader +++ b/test/test_c_flag_parsing.vader @@ -366,3 +366,14 @@ Execute(CFlags we dont want to pass): \ 'gcc -Wl,option -Wa,option -Wp,option filename.c somelib.a ' \ . '-fdump-file=name -fdiagnostics-arg -fno-show-column' \ ) + +Execute(Expanding @file in CFlags): + AssertEqual + \ '-DARGS1 -DARGS2 -O2', + \ ale#c#ParseCFlags( + \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ 'gcc' + \ . ' -g' + \ . ' @./args' + \ . ' -O2', + \ ) diff --git a/test/test_c_projects/makefile_project/args b/test/test_c_projects/makefile_project/args new file mode 100644 index 00000000..ccaf82ad --- /dev/null +++ b/test/test_c_projects/makefile_project/args @@ -0,0 +1,3 @@ +foolib.a +-DARGS1 +@subdir/args diff --git a/test/test_c_projects/makefile_project/subdir/args b/test/test_c_projects/makefile_project/subdir/args new file mode 100644 index 00000000..3fe9c3fe --- /dev/null +++ b/test/test_c_projects/makefile_project/subdir/args @@ -0,0 +1 @@ +-DARGS2 |