]>
Commit | Line | Data |
---|---|---|
1 | if exists("g:loaded_syntastic_c_autoload") | |
2 | finish | |
3 | endif | |
4 | let g:loaded_syntastic_c_autoload = 1 | |
5 | ||
6 | let s:save_cpo = &cpo | |
7 | set cpo&vim | |
8 | ||
9 | " initialize c/cpp syntax checker handlers | |
10 | function! s:Init() | |
11 | let s:handlers = [] | |
12 | let s:cflags = {} | |
13 | ||
14 | call s:RegHandler('gtk', 'syntastic#c#CheckPKG', | |
15 | \ ['gtk', 'gtk+-2.0', 'gtk+', 'glib-2.0', 'glib']) | |
16 | call s:RegHandler('glib', 'syntastic#c#CheckPKG', | |
17 | \ ['glib', 'glib-2.0', 'glib']) | |
18 | call s:RegHandler('glade', 'syntastic#c#CheckPKG', | |
19 | \ ['glade', 'libglade-2.0', 'libglade']) | |
20 | call s:RegHandler('libsoup', 'syntastic#c#CheckPKG', | |
21 | \ ['libsoup', 'libsoup-2.4', 'libsoup-2.2']) | |
22 | call s:RegHandler('webkit', 'syntastic#c#CheckPKG', | |
23 | \ ['webkit', 'webkit-1.0']) | |
24 | call s:RegHandler('cairo', 'syntastic#c#CheckPKG', | |
25 | \ ['cairo', 'cairo']) | |
26 | call s:RegHandler('pango', 'syntastic#c#CheckPKG', | |
27 | \ ['pango', 'pango']) | |
28 | call s:RegHandler('libxml', 'syntastic#c#CheckPKG', | |
29 | \ ['libxml', 'libxml-2.0', 'libxml']) | |
30 | call s:RegHandler('freetype', 'syntastic#c#CheckPKG', | |
31 | \ ['freetype', 'freetype2', 'freetype']) | |
32 | call s:RegHandler('SDL', 'syntastic#c#CheckPKG', | |
33 | \ ['sdl', 'sdl']) | |
34 | call s:RegHandler('opengl', 'syntastic#c#CheckPKG', | |
35 | \ ['opengl', 'gl']) | |
36 | call s:RegHandler('ruby', 'syntastic#c#CheckRuby', []) | |
37 | call s:RegHandler('Python\.h', 'syntastic#c#CheckPython', []) | |
38 | call s:RegHandler('php\.h', 'syntastic#c#CheckPhp', []) | |
39 | endfunction | |
40 | ||
41 | " search the first 100 lines for include statements that are | |
42 | " given in the handlers dictionary | |
43 | function! syntastic#c#SearchHeaders() | |
44 | let includes = '' | |
45 | let files = [] | |
46 | let found = [] | |
47 | let lines = filter(getline(1, 100), 'v:val =~# "#\s*include"') | |
48 | ||
49 | " search current buffer | |
50 | for line in lines | |
51 | let file = matchstr(line, '"\zs\S\+\ze"') | |
52 | if file != '' | |
53 | call add(files, file) | |
54 | continue | |
55 | endif | |
56 | for handler in s:handlers | |
57 | if line =~# handler["regex"] | |
58 | let includes .= call(handler["func"], handler["args"]) | |
59 | call add(found, handler["regex"]) | |
60 | break | |
61 | endif | |
62 | endfor | |
63 | endfor | |
64 | ||
65 | " search included headers | |
66 | for hfile in files | |
67 | if hfile != '' | |
68 | let filename = expand('%:p:h') . ((has('win32') || has('win64')) ? | |
69 | \ '\' : '/') . hfile | |
70 | try | |
71 | let lines = readfile(filename, '', 100) | |
72 | catch /E484/ | |
73 | continue | |
74 | endtry | |
75 | let lines = filter(lines, 'v:val =~# "#\s*include"') | |
76 | for handler in s:handlers | |
77 | if index(found, handler["regex"]) != -1 | |
78 | continue | |
79 | endif | |
80 | for line in lines | |
81 | if line =~# handler["regex"] | |
82 | let includes .= call(handler["func"], handler["args"]) | |
83 | call add(found, handler["regex"]) | |
84 | break | |
85 | endif | |
86 | endfor | |
87 | endfor | |
88 | endif | |
89 | endfor | |
90 | ||
91 | return includes | |
92 | endfunction | |
93 | ||
94 | " try to find library with 'pkg-config' | |
95 | " search possible libraries from first to last given | |
96 | " argument until one is found | |
97 | function! syntastic#c#CheckPKG(name, ...) | |
98 | if executable('pkg-config') | |
99 | if !has_key(s:cflags, a:name) | |
100 | for i in range(a:0) | |
101 | let l:cflags = system('pkg-config --cflags '.a:000[i]) | |
102 | " since we cannot necessarily trust the pkg-config exit code | |
103 | " we have to check for an error output as well | |
104 | if v:shell_error == 0 && l:cflags !~? 'not found' | |
105 | let l:cflags = ' '.substitute(l:cflags, "\n", '', '') | |
106 | let s:cflags[a:name] = l:cflags | |
107 | return l:cflags | |
108 | endif | |
109 | endfor | |
110 | else | |
111 | return s:cflags[a:name] | |
112 | endif | |
113 | endif | |
114 | return '' | |
115 | endfunction | |
116 | ||
117 | " try to find PHP includes with 'php-config' | |
118 | function! syntastic#c#CheckPhp() | |
119 | if executable('php-config') | |
120 | if !exists('s:php_flags') | |
121 | let s:php_flags = system('php-config --includes') | |
122 | let s:php_flags = ' ' . substitute(s:php_flags, "\n", '', '') | |
123 | endif | |
124 | return s:php_flags | |
125 | endif | |
126 | return '' | |
127 | endfunction | |
128 | ||
129 | " try to find the ruby headers with 'rbconfig' | |
130 | function! syntastic#c#CheckRuby() | |
131 | if executable('ruby') | |
132 | if !exists('s:ruby_flags') | |
133 | let s:ruby_flags = system('ruby -r rbconfig -e ' | |
134 | \ . '''puts Config::CONFIG["archdir"]''') | |
135 | let s:ruby_flags = substitute(s:ruby_flags, "\n", '', '') | |
136 | let s:ruby_flags = ' -I' . s:ruby_flags | |
137 | endif | |
138 | return s:ruby_flags | |
139 | endif | |
140 | return '' | |
141 | endfunction | |
142 | ||
143 | " try to find the python headers with distutils | |
144 | function! syntastic#c#CheckPython() | |
145 | if executable('python') | |
146 | if !exists('s:python_flags') | |
147 | let s:python_flags = system('python -c ''from distutils import ' | |
148 | \ . 'sysconfig; import sys; sys.stdout.write(sysconfig.get_python_inc())''') | |
149 | let s:python_flags = substitute(s:python_flags, "\n", '', '') | |
150 | let s:python_flags = ' -I' . s:python_flags | |
151 | endif | |
152 | return s:python_flags | |
153 | endif | |
154 | return '' | |
155 | endfunction | |
156 | ||
157 | " return a handler dictionary object | |
158 | function! s:RegHandler(regex, function, args) | |
159 | let handler = {} | |
160 | let handler["regex"] = a:regex | |
161 | let handler["func"] = function(a:function) | |
162 | let handler["args"] = a:args | |
163 | call add(s:handlers, handler) | |
164 | endfunction | |
165 | ||
166 | call s:Init() | |
167 | ||
168 | let &cpo = s:save_cpo | |
169 | unlet s:save_cpo | |
170 | ||
171 | " vim: set et sts=4 sw=4: |