summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrançois-Xavier Carton <fx.carton91@gmail.com>2019-01-09 16:00:10 +0100
committerFrançois-Xavier Carton <fx.carton91@gmail.com>2019-01-09 16:53:36 +0100
commit4bbb10b46aae7cb3f0657c981715c4abd4376412 (patch)
treeb0acf966e302320e01a25bce43435d7eff091383
parentf23811770a8104346b7e9ccc6e586da828c8f41d (diff)
downloadale-4bbb10b46aae7cb3f0657c981715c4abd4376412.zip
Cflags parser: fix special chars matching algorithm
-rw-r--r--autoload/ale/c.vim45
1 files changed, 34 insertions, 11 deletions
diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim
index 746d19b0..dd5cb08a 100644
--- a/autoload/ale/c.vim
+++ b/autoload/ale/c.vim
@@ -46,6 +46,38 @@ function! ale#c#FindProjectRoot(buffer) abort
return ''
endfunction
+function! ale#c#AreSpecialCharsBalanced(option) abort
+ " Escape \"
+ let l:option_escaped = substitute(a:option, '\\"', '', 'g')
+
+ " Retain special chars only
+ let l:special_chars = substitute(l:option_escaped, '[^"''()`]', '', 'g')
+ let l:special_chars = split(l:special_chars, '\zs')
+
+ " Check if they are balanced
+ let l:stack = []
+
+ for l:char in l:special_chars
+ if l:char is# ')'
+ if len(l:stack) == 0 || get(l:stack, -1) isnot# '('
+ return 0
+ endif
+
+ call remove(l:stack, -1)
+ elseif l:char is# '('
+ call add(l:stack, l:char)
+ else
+ if len(l:stack) > 0 && get(l:stack, -1) is# l:char
+ call remove(l:stack, -1)
+ else
+ call add(l:stack, l:char)
+ endif
+ endif
+ endfor
+
+ return len(l:stack) == 0
+endfunction
+
function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
let l:cflags_list = []
let l:previous_options = ''
@@ -57,17 +89,8 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
let l:option = l:previous_options . l:split_lines[l:option_index]
let l:option_index = l:option_index + 1
- " Check if cflag contained an unmatched characters and should not have been splitted
- let l:option_special = substitute(l:option, '\\"', '', 'g')
- let l:option_special = substitute(l:option_special, '[^"''()`]', '', 'g')
- let l:option_special = substitute(l:option_special, '""', '', 'g')
- let l:option_special = substitute(l:option_special, '''''', '', 'g')
- let l:option_special = substitute(l:option_special, '``', '', 'g')
- let l:option_special = substitute(l:option_special, '((', '(', 'g')
- let l:option_special = substitute(l:option_special, '))', ')', 'g')
- let l:option_special = substitute(l:option_special, '()', '', 'g')
-
- if len(l:option_special) > 0 && l:option_index < len(l:split_lines)
+ " Check if cflag contained an unmatched special character and should not have been splitted
+ if ale#c#AreSpecialCharsBalanced(l:option) == 0 && l:option_index < len(l:split_lines)
let l:previous_options = l:option . ' '
continue
endif