ale/autoload/ale/handlers/gcc.vim

126 lines
4.4 KiB
VimL
Raw Normal View History

scriptencoding utf-8
" Author: w0rp <devw0rp@gmail.com>
" Description: This file defines a handler function which ought to work for
" any program which outputs errors in the format that GCC uses.
let s:pragma_error = '#pragma once in main file'
function! s:AddIncludedErrors(output, include_lnum, include_lines) abort
if a:include_lnum > 0
call add(a:output, {
\ 'lnum': a:include_lnum,
\ 'type': 'E',
\ 'text': 'Problems were found in the header (See :ALEDetail)',
\ 'detail': join(a:include_lines, "\n"),
\})
endif
endfunction
2017-04-11 20:05:41 +00:00
function! s:IsHeaderFile(filename) abort
return a:filename =~? '\v\.(h|hpp)$'
endfunction
function! s:RemoveUnicodeQuotes(text) abort
let l:text = a:text
let l:text = substitute(l:text, '[`´]', '''', 'g')
let l:text = substitute(l:text, '\v\\u2018([^\\]+)\\u2019', '''\1''', 'g')
let l:text = substitute(l:text, '[“”]', '"', 'g')
return l:text
endfunction
function! ale#handlers#gcc#ParseGCCVersion(lines) abort
for l:line in a:lines
let l:match = matchstr(l:line, '\d\.\d\.\d')
if !empty(l:match)
return ale#semver#Parse(l:match)
endif
endfor
return []
endfunction
function! ale#handlers#gcc#HandleGCCFormat(buffer, lines) abort
2017-04-11 20:05:41 +00:00
let l:include_pattern = '\v^(In file included | *)from ([^:]*):(\d+)'
" Include pattern looks for lines like :
"
" In file included from test.h:1:0,
" from test.cpp:1:
let l:include_lnum = 0
let l:include_lines = []
let l:included_filename = ''
" Look for lines like the following.
"
" <stdin>:8:5: warning: conversion lacks type at end of format [-Wformat=]
" <stdin>:10:27: error: invalid operands to binary - (have int and char *)
" -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+)$'
let l:output = []
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if empty(l:match)
let l:include_match = matchlist(l:line, l:include_pattern)
" If the line has an 'included from' pattern, store the line to
" create a gutter sign at the appropriate location in linted file
if !empty(l:include_match)
" We don't check if l:include_match[2] is linted filename
" because the last line matching include_pattern in a group
" of contiguous lines is probably concerning the linted file
" anyway
let l:include_lnum = l:include_match[3]
endif
else
" Filter out the pragma errors
if s:IsHeaderFile(bufname(bufnr('')))
\&& l:match[5][:len(s:pragma_error) - 1] is# s:pragma_error
continue
endif
" If the 'error type' is a note, make it detail related to
" the previous error parsed in output
if l:match[4] is# 'note'
if !empty(l:output)
let l:output[-1]['detail'] =
\ get(l:output[-1], 'detail', '')
\ . s:RemoveUnicodeQuotes(l:match[0]) . "\n"
endif
continue
endif
" If l:include_lnum is non-null, then the error relates to
" an included file and l:include_lnum is the line number
" where a gutter sign would be needed in linted file
" The ternary operator in filename filters out the 'dummy'
" filenames like <nopath> or <stdin> and leave the location
" handling to engine#FixLocList
let l:item = {
\ 'filename': (l:match[1][:0] is# '<') ? '' : l:match[1],
\ 'lnum': str2nr(l:match[2]),
\ 'type': l:match[4] is# 'error' ? 'E' : 'W',
\ 'text': s:RemoveUnicodeQuotes(l:match[5]),
\}
if !empty(l:match[3])
let l:item.col = str2nr(l:match[3])
endif
" Finish filtering out filename : if the key exists but is empty,
" unlet it.
if get(l:item, 'filename', 'dummy_no_key_to_unlet') is# ''
unlet l:item['filename']
endif
call add(l:output, l:item)
" Reset include_lnum after an error has been added
let l:include_lnum = 0
endif
endfor
return l:output
endfunction