@ -1,4 +1,4 @@
if exists ( "g:loaded_syntastic_c_autoload" )
if exists ( "g:loaded_syntastic_c_autoload" ) | | ! exists ( "g:loaded_syntastic_plugin" )
finish
endif
let g :loaded_syntastic_c_autoload = 1
@ -10,14 +10,14 @@ set cpo&vim
" convenience function to determine the 'null device' parameter
" based on the current operating system
function ! syntastic #c #NullOutput ( )
function ! syntastic #c #NullOutput ( ) " {{{2
let known_os = has ( 'unix' ) | | has ( 'mac' ) | | syntastic #util #isRunningWindows ( )
return known_os ? '-o ' . syntastic #util #DevNull ( ) : ''
endfunction
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 )
function ! syntastic #c #ReadConfig ( file ) " {{{2
" search in the current file's directory upwards
let config = findfile ( a :file , '.;' )
if config = = '' | | ! filereadable ( config )
@ -30,7 +30,7 @@ function! syntastic#c#ReadConfig(file)
" try to read config file
try
let lines = readfile ( config )
catch /^Vim\%((\a\+)\)\=:E48[45]/
catch /\m ^Vim\%((\a\+)\)\=:E48[45]/
return ''
endtry
@ -57,12 +57,12 @@ function! syntastic#c#ReadConfig(file)
endfor
return join ( map ( parameters , 'syntastic#util#shescape(v:val)' ) )
endfunction
endfunction " }}}2
" GetLocList() for C-like compilers
function ! syntastic #c #GetLocList ( filetype , subchecker , options )
function ! syntastic #c #GetLocList ( filetype , subchecker , options ) " {{{2
try
let flags = s :G etCflags( a :filetype , a :subchecker , a :options )
let flags = s :g etCflags( a :filetype , a :subchecker , a :options )
catch /\m\C^Syntastic: skip checks$/
return []
endtry
@ -70,9 +70,9 @@ function! syntastic#c#GetLocList(filetype, subchecker, options)
let makeprg = syntastic #util #shexpand ( g :syntastic_ {a :filetype }_compiler ) .
\ ' ' . flags . ' ' . syntastic #util #shexpand ( '%' )
let errorformat = s :G etCheckerVar( 'g' , a :filetype , a :subchecker , 'errorformat' , a :options ['errorformat' ])
let errorformat = s :g etCheckerVar( 'g' , a :filetype , a :subchecker , 'errorformat' , a :options ['errorformat' ])
let postprocess = s :G etCheckerVar( 'g' , a :filetype , a :subchecker , 'remove_include_errors' , 0 ) ?
let postprocess = s :g etCheckerVar( 'g' , a :filetype , a :subchecker , 'remove_include_errors' , 0 ) ?
\ ['filterForeignErrors' ] : []
" process makeprg
@ -80,34 +80,45 @@ function! syntastic#c#GetLocList(filetype, subchecker, options)
\ 'makeprg' : makeprg ,
\ 'errorformat' : errorformat ,
\ 'postprocess' : postprocess })
endfunction
endfunction " }}}2
" }}}1
" Private functions {{{1
" initialize c/cpp syntax checker handlers
function ! s :I nit( )
function ! s :i nit( ) " {{{2
let s :handlers = []
let s :cflags = {}
call s :RegHandler ( '\m\<cairo' , 'syntastic#c#CheckPKG' , ['cairo' , 'cairo' ])
call s :RegHandler ( '\m\<freetype' , 'syntastic#c#CheckPKG' , ['freetype' , 'freetype2' , 'freetype' ])
call s :RegHandler ( '\m\<glade' , 'syntastic#c#CheckPKG' , ['glade' , 'libglade-2.0' , 'libglade' ])
call s :RegHandler ( '\m\<glib' , 'syntastic#c#CheckPKG' , ['glib' , 'glib-2.0' , 'glib' ])
call s :RegHandler ( '\m\<gtk' , 'syntastic#c#CheckPKG' , ['gtk' , 'gtk+-2.0' , 'gtk+' , 'glib-2.0' , 'glib' ])
call s :RegHandler ( '\m\<libsoup' , 'syntastic#c#CheckPKG' , ['libsoup' , 'libsoup-2.4' , 'libsoup-2.2' ])
call s :RegHandler ( '\m\<libxml' , 'syntastic#c#CheckPKG' , ['libxml' , 'libxml-2.0' , 'libxml' ])
call s :RegHandler ( '\m\<pango' , 'syntastic#c#CheckPKG' , ['pango' , 'pango' ])
call s :RegHandler ( '\m\<SDL' , 'syntastic#c#CheckPKG' , ['sdl' , 'sdl' ])
call s :RegHandler ( '\m\<opengl' , 'syntastic#c#CheckPKG' , ['opengl' , 'gl' ])
call s :RegHandler ( '\m\<webkit' , 'syntastic#c#CheckPKG' , ['webkit' , 'webkit-1.0' ])
call s :RegHandler ( '\m\<php\.h\>' , 'syntastic#c#CheckPhp' , [])
call s :RegHandler ( '\m\<Python\.h\>' , 'syntastic#c#CheckPython' , [])
call s :RegHandler ( '\m\<ruby' , 'syntastic#c#CheckRuby' , [])
endfunction
call s :regHandler ( '\m\<cairo' , 'syntastic#c#checkPKG' , ['cairo' , 'cairo' ])
call s :regHandler ( '\m\<freetype' , 'syntastic#c#checkPKG' , ['freetype' , 'freetype2' , 'freetype' ])
call s :regHandler ( '\m\<glade' , 'syntastic#c#checkPKG' , ['glade' , 'libglade-2.0' , 'libglade' ])
call s :regHandler ( '\m\<glib' , 'syntastic#c#checkPKG' , ['glib' , 'glib-2.0' , 'glib' ])
call s :regHandler ( '\m\<gtk' , 'syntastic#c#checkPKG' , ['gtk' , 'gtk+-2.0' , 'gtk+' , 'glib-2.0' , 'glib' ])
call s :regHandler ( '\m\<libsoup' , 'syntastic#c#checkPKG' , ['libsoup' , 'libsoup-2.4' , 'libsoup-2.2' ])
call s :regHandler ( '\m\<libxml' , 'syntastic#c#checkPKG' , ['libxml' , 'libxml-2.0' , 'libxml' ])
call s :regHandler ( '\m\<pango' , 'syntastic#c#checkPKG' , ['pango' , 'pango' ])
call s :regHandler ( '\m\<SDL' , 'syntastic#c#checkPKG' , ['sdl' , 'sdl' ])
call s :regHandler ( '\m\<opengl' , 'syntastic#c#checkPKG' , ['opengl' , 'gl' ])
call s :regHandler ( '\m\<webkit' , 'syntastic#c#checkPKG' , ['webkit' , 'webkit-1.0' ])
call s :regHandler ( '\m\<php\.h\>' , 'syntastic#c#checkPHP' , [])
call s :regHandler ( '\m\<Python\.h\>' , 'syntastic#c#checkPython' , [])
call s :regHandler ( '\m\<ruby' , 'syntastic#c#checkRuby' , [])
endfunction " }}}2
" return a handler dictionary object
function ! s :regHandler ( regex , function , args ) " {{{2
let handler = {}
let handler ["regex" ] = a :regex
let handler ["func" ] = function ( a :function )
let handler ["args" ] = a :args
call add ( s :handlers , handler )
endfunction " }}}2
" resolve checker-related user variables
function ! s :GetCheckerVar ( scope , filetype , subchecker , name , default )
function ! s :g etCheckerVar( 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 }
@ -116,13 +127,13 @@ function! s:GetCheckerVar(scope, filetype, subchecker, name, default)
else
return a :default
endif
endfunction
endfunction " }}}2
" resolve user CFLAGS
function ! s :G etCflags( ft , ck , opts )
function ! s :g etCflags( 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 :G etCheckerVar( 'g' , a :ft , a :ck , 'check_header' , 0 )
if s :g etCheckerVar( '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
@ -132,21 +143,21 @@ function! s:GetCflags(ft, ck, opts)
let flags = get ( a :opts , 'main_flags' , '' )
endif
let flags .= ' ' . s :G etCheckerVar( 'g' , a :ft , a :ck , 'compiler_options' , '' ) . ' ' . s :G etIncludeDirs( a :ft )
let flags .= ' ' . s :g etCheckerVar( 'g' , a :ft , a :ck , 'compiler_options' , '' ) . ' ' . s :g etIncludeDirs( a :ft )
" check if the user manually set some cflags
let b_cflags = s :G etCheckerVar( 'b' , a :ft , a :ck , 'cflags' , '' )
let b_cflags = s :g etCheckerVar( 'b' , a :ft , a :ck , 'cflags' , '' )
if b_cflags = = ''
" check whether to search for include files at all
if ! s :G etCheckerVar( 'g' , a :ft , a :ck , 'no_include_search' , 0 )
if ! s :g etCheckerVar( '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 :G etCheckerVar( 'g' , a :ft , a :ck , 'auto_refresh_includes' , 0 )
let flags .= ' ' . s :S earchHeaders( )
if s :g etCheckerVar( 'g' , a :ft , a :ck , 'auto_refresh_includes' , 0 )
let flags .= ' ' . s :s earchHeaders( )
else
" search for header includes if not cached already
if ! exists ( 'b:syntastic_' . a :ft . '_includes' )
let b :syntastic_ {a :ft }_includes = s :S earchHeaders( )
let b :syntastic_ {a :ft }_includes = s :s earchHeaders( )
endif
let flags .= ' ' . b :syntastic_ {a :ft }_includes
endif
@ -158,15 +169,15 @@ function! s:GetCflags(ft, ck, opts)
endif
" add optional config file parameters
let config_file = s :G etCheckerVar( 'g' , a :ft , a :ck , 'config_file' , '.syntastic_' . a :ft . '_config' )
let config_file = s :g etCheckerVar( 'g' , a :ft , a :ck , 'config_file' , '.syntastic_' . a :ft . '_config' )
let flags .= ' ' . syntastic #c #ReadConfig ( config_file )
return flags
endfunction
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 :G etIncludeDirs( filetype )
function ! s :g etIncludeDirs( filetype ) " {{{2
let include_dirs = []
if a :filetype = ~ # '\v^%(c|cpp|d|objc|objcpp)$' &&
@ -180,11 +191,11 @@ function! s:GetIncludeDirs(filetype)
endif
return join ( map ( syntastic #util #unique ( include_dirs ) , 'syntastic#util#shescape("-I" . v:val)' ) )
endfunction
endfunction " }}}2
" search the first 100 lines for include statements that are
" given in the handlers dictionary
function ! s :S earchHeaders( )
function ! s :s earchHeaders( ) " {{{2
let includes = ''
let files = []
let found = []
@ -214,7 +225,7 @@ function! s:SearchHeaders()
try
let lines = readfile ( filename , '' , 100 )
catch /^Vim\%((\a\+)\)\=:E484/
catch /\m ^Vim\%((\a\+)\)\=:E484/
continue
endtry
@ -237,12 +248,12 @@ function! s:SearchHeaders()
endfor
return includes
endfunction
endfunction " }}}2
" try to find library with 'pkg-config'
" search possible libraries from first to last given
" argument until one is found
function ! syntastic #c #C heckPKG( name , ...)
function ! syntastic #c #c heckPKG( name , ...) " {{{2
if executable ( 'pkg-config' )
if ! has_key ( s :cflags , a :name )
for pkg in a :000
@ -260,10 +271,10 @@ function! syntastic#c#CheckPKG(name, ...)
endif
endif
return ''
endfunction
endfunction " }}}2
" try to find PHP includes with 'php-config'
function ! syntastic #c #CheckPhp ( )
function ! syntastic #c #checkPHP ( ) " {{{2
if executable ( 'php-config' )
if ! has_key ( s :cflags , 'php' )
let s :cflags ['php' ] = system ( 'php-config --includes' )
@ -272,10 +283,10 @@ function! syntastic#c#CheckPhp()
return s :cflags ['php' ]
endif
return ''
endfunction
endfunction " }}}2
" try to find the ruby headers with 'rbconfig'
function ! syntastic #c #C heckRuby( )
function ! syntastic #c #c heckRuby( ) " {{{2
if executable ( 'ruby' )
if ! has_key ( s :cflags , 'ruby' )
let s :cflags ['ruby' ] = system ( 'ruby -r rbconfig -e ' .
@ -286,10 +297,10 @@ function! syntastic#c#CheckRuby()
return s :cflags ['ruby' ]
endif
return ''
endfunction
endfunction " }}}2
" try to find the python headers with distutils
function ! syntastic #c #C heckPython( )
function ! syntastic #c #c heckPython( ) " {{{2
if executable ( 'python' )
if ! has_key ( s :cflags , 'python' )
let s :cflags ['python' ] = system ( 'python -c ''from distutils import ' .
@ -300,16 +311,7 @@ function! syntastic#c#CheckPython()
return s :cflags ['python' ]
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
endfunction " }}}2
" }}}1
@ -322,9 +324,9 @@ let s:default_includes = [
\ '..' . syntastic #util #Slash ( ) . 'include' ,
\ '..' . syntastic #util #Slash ( ) . 'includes' ]
call s :I nit( )
call s :i nit( )
let &cpo = s :save_cpo
unlet s :save_cpo
" vim: set et sts=4 sw=4 fdm=marker:
" vim: set sw=4 sts=4 et fdm=marker: