" if compiled with --enable-cscope
if has("cscope")
	if exists("g:loaded_cscope_plus") || &cp
    		finish
	endif
	let g:loaded_cscope_plus   = 1.0
	
	" cat Makefile | grep '\-I\/' | tr '[:space:]' '\n' | grep '\-I/' | sort -u | tr '\n' ' '
	" build tags database with shift+F8 or alt+F8 to ignore /usr/include
	"        --c++-kinds=+p  : Adds prototypes in the database for C/C++ files.
	"        --fields=+iaS   : Adds inheritance (i), access (a) and function 
	"                          signatures (S) information.
	"        --extra=+q      : Adds context to the tag name. Note: Without this
	"                          option, the script cannot get class members.
	
	command! CtagsBuild
	    \ :!echo 'building ctags database...' ;
	    \   ctags --fields=+iaS --extra=+q --totals -R --c++-kinds=+p &&
	    \   echo 'adding system headers...' ;
	    \   find -exec gcc -M  '{}' \; 2>&- | tr '[:space:]' '\n' | grep '^/.*' | sort -u |
	    \   ctags --c-kinds=+px --c++-kinds=+px --fields=+iaS --extra=+q -aL-
	command! CtagsKernelBuild
	    \ :!echo 'building ctags database in kernel mode...' ;
	    \   ctags --fields=+iaS --extra=+q --totals -R --c++-kinds=+p
	command! CscopeBuild
	    \ :!echo 'building cscope database...' ;
	    \   cscope -bR
	command! CscopeKernelBuild
	    \ :!echo 'building cscope database in kernel mode...' ;
	    \   cscope -bkR
	command! CscopeFileBuild
		\ :!echo 'building cscope database for all language';
		\ find . -name '*.py' -o -name '*.java' -o -iname '*.[ch]' -o -name '[*.cpp]' -o -name '[*.hpp]' > cscope.files

	if has("cscope")
	    map <S-F8> :CtagsBuild<CR><CR>:CscopeBuild<CR><CR>:cscope reset<CR><CR>:cscope add cscope.out<CR><CR>
	    map <M-F8> :CtagsKernelBuild<CR><CR>:CscopeKernelBuild<CR><CR>:cscope reset<CR><CR>:cscope add cscope.out<CR><CR>
	else
	    map <S-F8> :CtagsBuild<CR><CR>
	    map <M-F8> :CtagsKernelBuild<CR><CR>
	endif

	function! GetLocalCscopeDb(pathname)
		if !isdirectory(a:pathname) ||  a:pathname == $HOME || a:pathname == '/'
			return
		endif
		let s:cscopefile = a:pathname."/cscope.out"
		if filereadable(s:cscopefile)
			echo "Add cscope db for ".a:pathname
			execute "cscope add ".s:cscopefile." ".a:pathname
		endif
		unlet s:cscopefile
		call GetLocalCscopeDb(fnamemodify(a:pathname, ":h"))
	endfunction
	command! LoadLocalCscopeDb :call GetLocalCscopeDb(expand("%:p:h"))

	function! GetCscopeDb(pathname)
		if !isdirectory(a:pathname) ||  a:pathname == $HOME || a:pathname == '/'
			return
		endif

		let l:has_link  = 0
		let l:tag_found = 0
		if resolve(a:pathname) != a:pathname
			let l:has_link = 1
		endif

		let s:cscopefile = $HOME."/.vim/cscope/".substitute(a:pathname, '/', '_', 'g').".cscope"
		if filereadable(s:cscopefile)
			execute "cscope add ".s:cscopefile
			let l:tag_found = 1
		endif

		if l:tag_found == 0 && l:has_link == 1
			let s:cscopefile = $HOME."/.vim/cscope/".substitute(resolve(a:pathname), '/', '_', 'g').".cscope"
			if filereadable(s:cscopefile)
				execute "cscope add ".s:cscopefile
				let l:tag_found = 1
			endif
		endif

		unlet s:cscopefile

		call GetCscopeDb(fnamemodify(a:pathname, ":h"))
	endfunction

	function! GenerateCscopeDb()
		let path = input('Create cscope db for: ', getcwd(), 'dir')

		echohl WarningMsg
		echo "Please wait, generating cscope db..."

		let file = tempname()
		let cscopefile = $HOME."/.vim/cscope/".substitute(path, '/', '_', 'g').".cscope"
		call system("cd ".path."; find . -name '*.c' -or -name '*.h' > ".file."; cscope -b -i ".file." -f ".cscopefile)
		call delete(file)

		redraw
		echo "Please wait, generating cscope db... Done"
		echohl None

		call GetCscopeDb(path)
	endfunction
	command! GenerateCscopeDb :call GenerateCscopeDb()

	if has("cscope")
	    map <F9>   :call GetCscopeDb(expand("%:p:h")) <CR><CR>
	    map <S-F9> :call GenerateCscopeDb() <CR><CR>
	    map <M-F9> :call GetLocalCscopeDb(expand("%:p:h"))  <CR><CR>
	endif

endif
