diff --git a/autoload/syntastic.vim b/autoload/syntastic.vim index a4777365..7e3dc14a 100644 --- a/autoload/syntastic.vim +++ b/autoload/syntastic.vim @@ -22,3 +22,161 @@ function! syntastic#HighlightErrors(errors, termfunc, ...) endfor endfunction +" initialize c/cpp syntax checker handlers +function! s:Init() + let s:handlers = [] + let s:cflags = {} + + call syntastic#RegHandler('gtk', 'syntastic#CheckPKG', + \ ['gtk', 'gtk+-2.0', 'gtk+', 'glib-2.0', 'glib']) + call syntastic#RegHandler('glib', 'syntastic#CheckPKG', + \ ['glib', 'glib-2.0', 'glib']) + call syntastic#RegHandler('glade', 'syntastic#CheckPKG', + \ ['glade', 'libglade-2.0', 'libglade']) + call syntastic#RegHandler('libsoup', 'syntastic#CheckPKG', + \ ['libsoup', 'libsoup-2.4', 'libsoup-2.2']) + call syntastic#RegHandler('webkit', 'syntastic#CheckPKG', + \ ['webkit', 'webkit-1.0']) + call syntastic#RegHandler('cairo', 'syntastic#CheckPKG', + \ ['cairo', 'cairo']) + call syntastic#RegHandler('pango', 'syntastic#CheckPKG', + \ ['pango', 'pango']) + call syntastic#RegHandler('libxml', 'syntastic#CheckPKG', + \ ['libxml', 'libxml-2.0', 'libxml']) + call syntastic#RegHandler('freetype', 'syntastic#CheckPKG', + \ ['freetype', 'freetype2', 'freetype']) + call syntastic#RegHandler('SDL', 'syntastic#CheckPKG', + \ ['sdl', 'sdl']) + call syntastic#RegHandler('opengl', 'syntastic#CheckPKG', + \ ['opengl', 'gl']) + call syntastic#RegHandler('ruby', 'syntastic#CheckRuby', []) + call syntastic#RegHandler('Python\.h', 'syntastic#CheckPython', []) + call syntastic#RegHandler('php\.h', 'syntastic#CheckPhp', []) +endfunction + +" search the first 100 lines for include statements that are +" given in the handlers dictionary +function! syntastic#SearchHeaders() + let includes = '' + let files = [] + let found = [] + let lines = filter(getline(1, 100), 'v:val =~# "#\s*include"') + + " search current buffer + for line in lines + let file = matchstr(line, '"\zs\S\+\ze"') + if file != '' + call add(files, file) + continue + endif + for handler in s:handlers + if line =~# handler["regex"] + let includes .= call(handler["func"], handler["args"]) + call add(found, handler["regex"]) + break + endif + endfor + endfor + + " search included headers + for hfile in files + if hfile != '' + let filename = expand('%:p:h') . ((has('win32') || has('win64')) ? + \ '\' : '/') . hfile + try + let lines = readfile(filename, '', 100) + catch /E484/ + continue + endtry + let lines = filter(lines, 'v:val =~# "#\s*include"') + for handler in s:handlers + if index(found, handler["regex"]) != -1 + continue + endif + for line in lines + if line =~# handler["regex"] + let includes .= call(handler["func"], handler["args"]) + call add(found, handler["regex"]) + break + endif + endfor + endfor + endif + endfor + + return includes +endfunction + +" try to find library with 'pkg-config' +" search possible libraries from first to last given +" argument until one is found +function! syntastic#CheckPKG(name, ...) + if executable('pkg-config') + if !has_key(s:cflags, a:name) + for i in range(a:0) + let l:cflags = system('pkg-config --cflags '.a:000[i]) + " since we cannot necessarily trust the pkg-config exit code + " we have to check for an error output as well + if v:shell_error == 0 && l:cflags !~? 'not found' + let l:cflags = ' '.substitute(l:cflags, "\n", '', '') + let s:cflags[a:name] = l:cflags + return l:cflags + endif + endfor + else + return s:cflags[a:name] + endif + endif + return '' +endfunction + +" try to find PHP includes with 'php-config' +function! syntastic#CheckPhp() + if executable('php-config') + if !exists('s:php_flags') + let s:php_flags = system('php-config --includes') + let s:php_flags = ' ' . substitute(s:php_flags, "\n", '', '') + endif + return s:php_flags + endif + return '' +endfunction + +" try to find the ruby headers with 'rbconfig' +function! syntastic#CheckRuby() + if executable('ruby') + if !exists('s:ruby_flags') + let s:ruby_flags = system('ruby -r rbconfig -e ' + \ . '''puts Config::CONFIG["archdir"]''') + let s:ruby_flags = substitute(s:ruby_flags, "\n", '', '') + let s:ruby_flags = ' -I' . s:ruby_flags + endif + return s:ruby_flags + endif + return '' +endfunction + +" try to find the python headers with distutils +function! syntastic#CheckPython() + if executable('python') + if !exists('s:python_flags') + let s:python_flags = system('python -c ''from distutils import ' + \ . 'sysconfig; print sysconfig.get_python_inc()''') + let s:python_flags = substitute(s:python_flags, "\n", '', '') + let s:python_flags = ' -I' . s:python_flags + endif + return s:python_flags + endif + return '' +endfunction + +" return a handler dictionary object +function! syntastic#RegHandler(regex, function, args) + let handler = {} + let handler["regex"] = a:regex + let handler["func"] = function(a:function) + let handler["args"] = a:args + call add(s:handlers, handler) +endfunction + +call s:Init() diff --git a/syntax_checkers/c.vim b/syntax_checkers/c.vim index f6e2e07a..59a4df2f 100644 --- a/syntax_checkers/c.vim +++ b/syntax_checkers/c.vim @@ -47,40 +47,6 @@ endif let s:save_cpo = &cpo set cpo&vim -" initialize handlers -function! s:Init() - let s:handlers = [] - let s:cflags = {} - - call s:RegHandler('gtk', 's:CheckPKG', - \ ['gtk', 'gtk+-2.0', 'gtk+', 'glib-2.0', 'glib']) - call s:RegHandler('glib', 's:CheckPKG', - \ ['glib', 'glib-2.0', 'glib']) - call s:RegHandler('glade', 's:CheckPKG', - \ ['glade', 'libglade-2.0', 'libglade']) - call s:RegHandler('libsoup', 's:CheckPKG', - \ ['libsoup', 'libsoup-2.4', 'libsoup-2.2']) - call s:RegHandler('webkit', 's:CheckPKG', - \ ['webkit', 'webkit-1.0']) - call s:RegHandler('cairo', 's:CheckPKG', - \ ['cairo', 'cairo']) - call s:RegHandler('pango', 's:CheckPKG', - \ ['pango', 'pango']) - call s:RegHandler('libxml', 's:CheckPKG', - \ ['libxml', 'libxml-2.0', 'libxml']) - call s:RegHandler('freetype', 's:CheckPKG', - \ ['freetype', 'freetype2', 'freetype']) - call s:RegHandler('SDL', 's:CheckPKG', - \ ['sdl', 'sdl']) - call s:RegHandler('opengl', 's:CheckPKG', - \ ['opengl', 'gl']) - call s:RegHandler('ruby', 's:CheckRuby', []) - call s:RegHandler('Python\.h', 's:CheckPython', []) - call s:RegHandler('php\.h', 's:CheckPhp', []) - - unlet! s:RegHandler -endfunction - function! SyntaxCheckers_c_GetLocList() let makeprg = 'gcc -fsyntax-only '.shellescape(expand('%')).' -I. -I..' let errorformat = '%-G%f:%s:,%-G%f:%l: %#error: %#(Each undeclared '. @@ -101,10 +67,10 @@ function! SyntaxCheckers_c_GetLocList() \ g:syntastic_c_no_include_search != 1 if exists('g:syntastic_c_auto_refresh_includes') && \ g:syntastic_c_auto_refresh_includes != 0 - let makeprg .= s:SearchHeaders() + let makeprg .= syntastic#SearchHeaders() else if !exists('b:syntastic_c_includes') - let b:syntastic_c_includes = s:SearchHeaders() + let b:syntastic_c_includes = syntastic#SearchHeaders() endif let makeprg .= b:syntastic_c_includes endif @@ -116,132 +82,5 @@ function! SyntaxCheckers_c_GetLocList() return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) endfunction -" search the first 100 lines for include statements that are -" given in the s:handlers dictionary -function! s:SearchHeaders() - let includes = '' - let files = [] - let found = [] - let lines = filter(getline(1, 100), 'v:val =~# "#\s*include"') - - " search current buffer - for line in lines - let file = matchstr(line, '"\zs\S\+\ze"') - if file != '' - call add(files, file) - continue - endif - for handler in s:handlers - if line =~# handler["regex"] - let includes .= call(handler["func"], handler["args"]) - call add(found, handler["regex"]) - break - endif - endfor - endfor - - " search included headers - for hfile in files - if hfile != '' - let filename = expand('%:p:h') . ((has('win32') || has('win64')) ? - \ '\' : '/') . hfile - try - let lines = readfile(filename, '', 100) - catch /E484/ - continue - endtry - let lines = filter(lines, 'v:val =~# "#\s*include"') - for handler in s:handlers - if index(found, handler["regex"]) != -1 - continue - endif - for line in lines - if line =~# handler["regex"] - let includes .= call(handler["func"], handler["args"]) - call add(found, handler["regex"]) - break - endif - endfor - endfor - endif - endfor - - return includes -endfunction - -" try to find library with 'pkg-config' -" search possible libraries from first to last given -" argument until one is found -function! s:CheckPKG(name, ...) - if executable('pkg-config') - if !has_key(s:cflags, a:name) - for i in range(a:0) - let l:cflags = system('pkg-config --cflags '.a:000[i]) - " since we cannot necessarily trust the pkg-config exit code - " we have to check for an error output as well - if v:shell_error == 0 && l:cflags !~? 'not found' - let l:cflags = ' '.substitute(l:cflags, "\n", '', '') - let s:cflags[a:name] = l:cflags - return l:cflags - endif - endfor - else - return s:cflags[a:name] - endif - endif - return '' -endfunction - -" try to find PHP includes with 'php-config' -function! s:CheckPhp() - if executable('php-config') - if !exists('s:php_flags') - let s:php_flags = system('php-config --includes') - let s:php_flags = ' ' . substitute(s:php_flags, "\n", '', '') - endif - return s:php_flags - endif - return '' -endfunction - -" try to find the ruby headers with 'rbconfig' -function! s:CheckRuby() - if executable('ruby') - if !exists('s:ruby_flags') - let s:ruby_flags = system('ruby -r rbconfig -e ' - \ . '''puts Config::CONFIG["archdir"]''') - let s:ruby_flags = substitute(s:ruby_flags, "\n", '', '') - let s:ruby_flags = ' -I' . s:ruby_flags - endif - return s:ruby_flags - endif - return '' -endfunction - -" try to find the python headers with distutils -function! s:CheckPython() - if executable('python') - if !exists('s:python_flags') - let s:python_flags = system('python -c ''from distutils import ' - \ . 'sysconfig; print sysconfig.get_python_inc()''') - let s:python_flags = substitute(s:python_flags, "\n", '', '') - let s:python_flags = ' -I' . s:python_flags - endif - return s:python_flags - endif - return '' -endfunction - -" return a handler dictionary object -function! s:RegHandler(regex, function, args) - let handler = {} - let handler["regex"] = a:regex - let handler["func"] = function(a:function) - let handler["args"] = a:args - call add(s:handlers, handler) -endfunction - -call s:Init() - let &cpo = s:save_cpo unlet s:save_cpo