ale/autoload/ale/handlers/gcc.vim

122 lines
4.4 KiB
VimL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
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
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'
let l:output[-1]['detail'] = get(l:output[-1], 'detail', '')
\ . s:RemoveUnicodeQuotes(l:match[0]) . "\n"
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