@ -18,9 +18,17 @@ endfunction " }}}2
" read additional compiler flags from the given configuration file
" the file format and its parsing mechanism is inspired by clang_complete
function ! syntastic #c #ReadConfig ( file ) " {{{2
" search in the current file's directory upwards
call syntastic #log #debug ( g :_SYNTASTIC_DEBUG_CHECKERS , 'ReadConfig: looking for' , a :file )
" search upwards from the current file's directory
let config = findfile ( a :file , '.;' )
if config = = '' | | ! filereadable ( config )
if config = = ''
call syntastic #log #debug ( g :_SYNTASTIC_DEBUG_CHECKERS , 'ReadConfig: file not found' )
return ''
endif
call syntastic #log #debug ( g :_SYNTASTIC_DEBUG_CHECKERS , 'ReadConfig: config file:' , config )
if ! filereadable ( config )
call syntastic #log #debug ( g :_SYNTASTIC_DEBUG_CHECKERS , 'ReadConfig: file unreadable' )
return ''
endif
@ -31,6 +39,7 @@ function! syntastic#c#ReadConfig(file) " {{{2
try
let lines = readfile ( config )
catch /\m^Vim\%((\a\+)\)\=:E48[45]/
call syntastic #log #debug ( g :_SYNTASTIC_DEBUG_CHECKERS , 'ReadConfig: error reading file' )
return ''
endtry
@ -62,7 +71,7 @@ endfunction " }}}2
" GetLocList() for C-like compilers
function ! syntastic #c #GetLocList ( filetype , subchecker , options ) " {{{2
try
let flags = s :_getC flags ( a :filetype , a :subchecker , a :options )
let flags = s :_get_c flags ( a :filetype , a :subchecker , a :options )
catch /\m\C^Syntastic: skip checks$/
return []
endtry
@ -70,9 +79,9 @@ function! syntastic#c#GetLocList(filetype, subchecker, options) " {{{2
let makeprg = syntastic #util #shexpand ( g :syntastic_ {a :filetype }_compiler ) .
\ ' ' . flags . ' ' . syntastic #util #shexpand ( '%' )
let errorformat = s :_getCheckerV ar ( 'g' , a :filetype , a :subchecker , 'errorformat' , a :options ['errorformat' ])
let errorformat = s :_get_checker_v ar ( 'g' , a :filetype , a :subchecker , 'errorformat' , a :options ['errorformat' ])
let postprocess = s :_getCheckerV ar ( 'g' , a :filetype , a :subchecker , 'remove_include_errors' , 0 ) ?
let postprocess = s :_get_checker_v ar ( 'g' , a :filetype , a :subchecker , 'remove_include_errors' , 0 ) ?
\ ['filterForeignErrors' ] : []
" process makeprg
@ -91,25 +100,25 @@ function! s:_init() " {{{2
let s :handlers = []
let s :cflags = {}
call s :_regHandler ( '\m\<cairo' , 's:_check_pkg ' , ['cairo' , 'cairo' ])
call s :_regHandler ( '\m\<freetype' , 's:_check_pkg ' , ['freetype' , 'freetype2' , 'freetype' ])
call s :_regHandler ( '\m\<glade' , 's:_check_pkg ' , ['glade' , 'libglade-2.0' , 'libglade' ])
call s :_regHandler ( '\m\<glib' , 's:_check_pkg ' , ['glib' , 'glib-2.0' , 'glib' ])
call s :_regHandler ( '\m\<gtk' , 's:_check_pkg ' , ['gtk' , 'gtk+-2.0' , 'gtk+' , 'glib-2.0' , 'glib' ])
call s :_regHandler ( '\m\<libsoup' , 's:_check_pkg ' , ['libsoup' , 'libsoup-2.4' , 'libsoup-2.2' ])
call s :_regHandler ( '\m\<libxml' , 's:_check_pkg ' , ['libxml' , 'libxml-2.0' , 'libxml' ])
call s :_regHandler ( '\m\<pango' , 's:_check_pkg ' , ['pango' , 'pango' ])
call s :_regHandler ( '\m\<SDL' , 's:_check_pkg ' , ['sdl' , 'sdl' ])
call s :_regHandler ( '\m\<opengl' , 's:_check_pkg ' , ['opengl' , 'gl' ])
call s :_regHandler ( '\m\<webkit' , 's:_check_pkg ' , ['webkit' , 'webkit-1.0' ])
call s :_regHandler ( '\m\<php\.h\>' , 's:_check_p hp' , [])
call s :_regHandler ( '\m\<Python\.h\>' , 's:_check_p ython' , [])
call s :_regHandler ( '\m\<ruby' , 's:_check_r uby' , [])
call s :_register Handler ( '\m\<cairo' , 's:_checkPackage ' , ['cairo' , 'cairo' ])
call s :_register Handler ( '\m\<freetype' , 's:_checkPackage ' , ['freetype' , 'freetype2' , 'freetype' ])
call s :_register Handler ( '\m\<glade' , 's:_checkPackage ' , ['glade' , 'libglade-2.0' , 'libglade' ])
call s :_register Handler ( '\m\<glib' , 's:_checkPackage ' , ['glib' , 'glib-2.0' , 'glib' ])
call s :_register Handler ( '\m\<gtk' , 's:_checkPackage ' , ['gtk' , 'gtk+-2.0' , 'gtk+' , 'glib-2.0' , 'glib' ])
call s :_register Handler ( '\m\<libsoup' , 's:_checkPackage ' , ['libsoup' , 'libsoup-2.4' , 'libsoup-2.2' ])
call s :_register Handler ( '\m\<libxml' , 's:_checkPackage ' , ['libxml' , 'libxml-2.0' , 'libxml' ])
call s :_register Handler ( '\m\<pango' , 's:_checkPackage ' , ['pango' , 'pango' ])
call s :_register Handler ( '\m\<SDL' , 's:_checkPackage ' , ['sdl' , 'sdl' ])
call s :_register Handler ( '\m\<opengl' , 's:_checkPackage ' , ['opengl' , 'gl' ])
call s :_register Handler ( '\m\<webkit' , 's:_checkPackage ' , ['webkit' , 'webkit-1.0' ])
call s :_register Handler ( '\m\<php\.h\>' , 's:_checkP hp' , [])
call s :_register Handler ( '\m\<Python\.h\>' , 's:_checkP ython' , [])
call s :_register Handler ( '\m\<ruby' , 's:_checkR uby' , [])
endfunction " }}}2
" return a handler dictionary object
function ! s :_regHandler ( regex , function , args ) " {{{2
" register a handler dictionary object
function ! s :_register Handler ( regex , function , args ) " {{{2
let handler = {}
let handler ["regex" ] = a :regex
let handler ["func" ] = function ( a :function )
@ -117,8 +126,75 @@ function! s:_regHandler(regex, function, args) " {{{2
call add ( s :handlers , handler )
endfunction " }}}2
" try to find library with 'pkg-config'
" search possible libraries from first to last given
" argument until one is found
function ! s :_checkPackage ( name , ...) " {{{2
if executable ( 'pkg-config' )
if ! has_key ( s :cflags , a :name )
for pkg in a :000
let pkg_flags = system ( 'pkg-config --cflags ' . pkg )
" 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 && pkg_flags ! ~ ? 'not found'
let pkg_flags = ' ' . substitute ( pkg_flags , "\n" , '' , '' )
let s :cflags [a :name ] = pkg_flags
return pkg_flags
endif
endfor
else
return s :cflags [a :name ]
endif
endif
return ''
endfunction " }}}2
" try to find PHP includes with 'php-config'
function ! s :_checkPhp ( ) " {{{2
if executable ( 'php-config' )
if ! has_key ( s :cflags , 'php' )
let s :cflags ['php' ] = system ( 'php-config --includes' )
let s :cflags ['php' ] = ' ' . substitute ( s :cflags ['php' ], "\n" , '' , '' )
endif
return s :cflags ['php' ]
endif
return ''
endfunction " }}}2
" try to find the python headers with distutils
function ! s :_checkPython ( ) " {{{2
if executable ( 'python' )
if ! has_key ( s :cflags , 'python' )
let s :cflags ['python' ] = system ( 'python -c ''from distutils import ' .
\ 'sysconfig; import sys; sys.stdout.write(sysconfig.get_python_inc())''' )
let s :cflags ['python' ] = substitute ( s :cflags ['python' ], "\n" , '' , '' )
let s :cflags ['python' ] = ' -I' . s :cflags ['python' ]
endif
return s :cflags ['python' ]
endif
return ''
endfunction " }}}2
" try to find the ruby headers with 'rbconfig'
function ! s :_checkRuby ( ) " {{{2
if executable ( 'ruby' )
if ! has_key ( s :cflags , 'ruby' )
let s :cflags ['ruby' ] = system ( 'ruby -r rbconfig -e ' .
\ '''puts RbConfig::CONFIG["rubyhdrdir"] || RbConfig::CONFIG["archdir"]''' )
let s :cflags ['ruby' ] = substitute ( s :cflags ['ruby' ], "\n" , '' , '' )
let s :cflags ['ruby' ] = ' -I' . s :cflags ['ruby' ]
endif
return s :cflags ['ruby' ]
endif
return ''
endfunction " }}}2
" }}}1
" Utilities {{{1
" resolve checker-related user variables
function ! s :_getCheckerVar ( scope , filetype , subchecker , name , default ) " {{{2
function ! s :_get_checker_v ar ( scope , filetype , subchecker , name , default ) " {{{2
let prefix = a :scope . ':' . 'syntastic_'
if exists ( prefix . a :filetype . '_' . a :subchecker . '_' . a :name )
return {a :scope }:syntastic_ {a :filetype }_ {a :subchecker }_ {a :name }
@ -130,10 +206,10 @@ function! s:_getCheckerVar(scope, filetype, subchecker, name, default) " {{{2
endfunction " }}}2
" resolve user CFLAGS
function ! s :_getC flags ( ft , ck , opts ) " {{{2
function ! s :_get_c flags ( ft , ck , opts ) " {{{2
" determine whether to parse header files as well
if has_key ( a :opts , 'header_names' ) && expand ( '%' ) = ~ ? a :opts ['header_names' ]
if s :_getCheckerV ar ( 'g' , a :ft , a :ck , 'check_header' , 0 )
if has_key ( a :opts , 'header_names' ) && expand ( '%' , 1 ) = ~ ? a :opts ['header_names' ]
if s :_get_checker_v ar ( 'g' , a :ft , a :ck , 'check_header' , 0 )
let flags = get ( a :opts , 'header_flags' , '' ) . ' -c ' . syntastic #c #NullOutput ( )
else
" checking headers when check_header is unset: bail out
@ -143,21 +219,21 @@ function! s:_getCflags(ft, ck, opts) " {{{2
let flags = get ( a :opts , 'main_flags' , '' )
endif
let flags .= ' ' . s :_getCheckerV ar ( 'g' , a :ft , a :ck , 'compiler_options' , '' ) . ' ' . s :_getIncludeD irs ( a :ft )
let flags .= ' ' . s :_get_checker_v ar ( 'g' , a :ft , a :ck , 'compiler_options' , '' ) . ' ' . s :_get_include_d irs ( a :ft )
" check if the user manually set some cflags
let b_cflags = s :_getCheckerV ar ( 'b' , a :ft , a :ck , 'cflags' , '' )
let b_cflags = s :_get_checker_v ar ( 'b' , a :ft , a :ck , 'cflags' , '' )
if b_cflags = = ''
" check whether to search for include files at all
if ! s :_getCheckerV ar ( 'g' , a :ft , a :ck , 'no_include_search' , 0 )
if ! s :_get_checker_v ar ( 'g' , a :ft , a :ck , 'no_include_search' , 0 )
if a :ft = = # 'c' | | a :ft = = # 'cpp'
" refresh the include file search if desired
if s :_getCheckerV ar ( 'g' , a :ft , a :ck , 'auto_refresh_includes' , 0 )
let flags .= ' ' . s :_searchH eaders ( )
if s :_get_checker_v ar ( 'g' , a :ft , a :ck , 'auto_refresh_includes' , 0 )
let flags .= ' ' . s :_search_h eaders ( )
else
" search for header includes if not cached already
if ! exists ( 'b:syntastic_' . a :ft . '_includes' )
let b :syntastic_ {a :ft }_includes = s :_searchH eaders ( )
let b :syntastic_ {a :ft }_includes = s :_search_h eaders ( )
endif
let flags .= ' ' . b :syntastic_ {a :ft }_includes
endif
@ -169,7 +245,7 @@ function! s:_getCflags(ft, ck, opts) " {{{2
endif
" add optional config file parameters
let config_file = s :_getCheckerV ar ( 'g' , a :ft , a :ck , 'config_file' , '.syntastic_' . a :ft . '_config' )
let config_file = s :_get_checker_v ar ( 'g' , a :ft , a :ck , 'config_file' , '.syntastic_' . a :ft . '_config' )
let flags .= ' ' . syntastic #c #ReadConfig ( config_file )
return flags
@ -177,7 +253,7 @@ endfunction " }}}2
" get the gcc include directory argument depending on the default
" includes and the optional user-defined 'g:syntastic_c_include_dirs'
function ! s :_getIncludeD irs ( filetype ) " {{{2
function ! s :_get_include_d irs ( filetype ) " {{{2
let include_dirs = []
if a :filetype = ~ # '\v^%(c|cpp|objc|objcpp)$' &&
@ -195,7 +271,7 @@ endfunction " }}}2
" search the first 100 lines for include statements that are
" given in the handlers dictionary
function ! s :_searchH eaders ( ) " {{{2
function ! s :_search_h eaders ( ) " {{{2
let includes = ''
let files = []
let found = []
@ -221,7 +297,7 @@ function! s:_searchHeaders() " {{{2
" search included headers
for hfile in files
if hfile ! = ''
let filename = expand ( '%:p:h' ) . syntastic #util #Slash ( ) . hfile
let filename = expand ( '%:p:h' , 1 ) . syntastic #util #Slash ( ) . hfile
try
let lines = readfile ( filename , '' , 100 )
@ -250,69 +326,6 @@ function! s:_searchHeaders() " {{{2
return includes
endfunction " }}}2
" try to find library with 'pkg-config'
" search possible libraries from first to last given
" argument until one is found
function ! s :_check_pkg ( name , ...) " {{{2
if executable ( 'pkg-config' )
if ! has_key ( s :cflags , a :name )
for pkg in a :000
let pkg_flags = system ( 'pkg-config --cflags ' . pkg )
" 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 && pkg_flags ! ~ ? 'not found'
let pkg_flags = ' ' . substitute ( pkg_flags , "\n" , '' , '' )
let s :cflags [a :name ] = pkg_flags
return pkg_flags
endif
endfor
else
return s :cflags [a :name ]
endif
endif
return ''
endfunction " }}}2
" try to find PHP includes with 'php-config'
function ! s :_check_php ( ) " {{{2
if executable ( 'php-config' )
if ! has_key ( s :cflags , 'php' )
let s :cflags ['php' ] = system ( 'php-config --includes' )
let s :cflags ['php' ] = ' ' . substitute ( s :cflags ['php' ], "\n" , '' , '' )
endif
return s :cflags ['php' ]
endif
return ''
endfunction " }}}2
" try to find the ruby headers with 'rbconfig'
function ! s :_check_ruby ( ) " {{{2
if executable ( 'ruby' )
if ! has_key ( s :cflags , 'ruby' )
let s :cflags ['ruby' ] = system ( 'ruby -r rbconfig -e ' .
\ '''puts RbConfig::CONFIG["rubyhdrdir"] || RbConfig::CONFIG["archdir"]''' )
let s :cflags ['ruby' ] = substitute ( s :cflags ['ruby' ], "\n" , '' , '' )
let s :cflags ['ruby' ] = ' -I' . s :cflags ['ruby' ]
endif
return s :cflags ['ruby' ]
endif
return ''
endfunction " }}}2
" try to find the python headers with distutils
function ! s :_check_python ( ) " {{{2
if executable ( 'python' )
if ! has_key ( s :cflags , 'python' )
let s :cflags ['python' ] = system ( 'python -c ''from distutils import ' .
\ 'sysconfig; import sys; sys.stdout.write(sysconfig.get_python_inc())''' )
let s :cflags ['python' ] = substitute ( s :cflags ['python' ], "\n" , '' , '' )
let s :cflags ['python' ] = ' -I' . s :cflags ['python' ]
endif
return s :cflags ['python' ]
endif
return ''
endfunction " }}}2
" }}}1
" default include directories