8.  Vi companions

Generally Vim is used in conjunction with other powerful tools like ctags and gdb . ctags is for very rapid navigation through millions of lines of "C/C++" code and gdb is for debugging the "C/C++" code. A brief introduction of these two indispensable commands will be given in this chapter.

ctags is the most powerful command available for coding C, C++, Java, Perl, Korn/Bourne shell scripts or Fortran. Developers very extensively use ctags to navigate through thousands of functions within C/C++ programs. See 'man ctags' on Unix. It is very important that you learn how to use ctags to develop programs in C or C++, Java, etc.. Navigation is the single most important task while doing development of C or C++ code. Using ctags you can very quickly read the code by jumping from a calling line to the called function, drill down deeper into nested function calls, and unwind back all the way up to the top. You can go back and forth from function to function very quickly.

Without NAVIGATION you will be completely lost! ctags is like the magnetic COMPASS needle for the programmers.

Usage of ctags :

	ctags *.cpp
	gvim -t foo_function
	gvim -t main

This will edit the C++ program file which contains the function foo_function() and will automatically place the cursor on the first line of the function foo_function(). The second command takes you to the line with the main() function definition.

Inside the Vim editor, you can jump to a function by typing : (colon) tag < function name > as below -

	:tag sample_function

This will place the cursor on first line of sample_function()

If you want to jump into the function from a line in file which contains the function name, place the cursor just before the function name and press CTRL+] (press control key and left-square-bracket key simultaneously).

		// example code
		switch(id_number) {
			Case 1:
				if ( foo_function( 22, "abcef") == 3 )
				    ^
				    |
				    |
				    |
		  Place the cursor here (just before foo_function) and press CTRL+]
		  This takes you to the function named "foo_function". 
		  To come back to this line press CTRL+t

To go back to the calling line press CTRL+t (Control key and letter 't' together). Keep pressing CTRL+t to unwind and go to the first line where you started the navigation. That is you can keep pressing CTRL+] and then keep pressing CTRL+t to go back. You can repeat these as many times as you want to have complete navigation through all the functions of C or C++.

8.1.  Directory Tree 'tags'

To recursively process the tags file for the entire directory :

$ cd $HOME
$ ctags -R

This will recurse the directory underneath and create a tag file all the files under the directory and beneath. But to use this tag file you must set the following in the vim session or modify .gvimrc file

$ vi ~/.gvimrc
" Set the tag file search order
set tags=./tags,tags,~/tags,/home/john/ccplus/tags

Or in the Vim session you set the tags with colon command:

$ vi somefile.cpp
:set tags=./tags,tags,~/tags,/home/john/ccplus/tags

8.2.  Ctags for ESQL

Since ctags does not directly support the Embedded SQL/C (ESQL) language, the following shell script can be used to create tags for esql. ESQL/C is database SQL commands embedded inside the "C" programs. Oracle's ESQL/C is called Pro*C and Sybase, Informix have ESQL/C and PostgreSQL has product "ecpg".

Save this file as "sqltags.sh" and do chmod a+rx tags_gen.sh.

#!/bin/sh
# Program to create ctags for ESQL, C++ and C files
ESQL_EXTN=pc
tag_file1=tags_file.1
tag_file2=tags_file.2
which_tag=ctags
rm -f $tag_file1 $tag_file2 tags
aa=`ls *.$ESQL_EXTN`
#echo $aa
for ii in $aa 
do
	#echo $ii
	jj=`echo $ii | cut -d'.' -f1`
	#echo $jj
	if [ ! -f $jj.cpp ]; then
		echo " "
		echo " "
		echo "***********************************************"
		echo "ESQL *.cpp files does not exist.. "
		echo "You must generate the *.cpp from *.pc file"
		echo "using the Oracle Pro*C pre-compiler or Sybase"
		echo "or Informix esql/c pre-compiler."
		echo "And then re-run this command"
		echo "***********************************************"
		echo " "
		exit
	fi
	rm -f tags
	$which_tag $jj.cpp
	kk=s/$jj\.cpp/$jj\.pc/g
	#echo $kk > sed.tmp
	#sed -f sed.tmp tags >> $tag_file1
	#sed -e's/sample\.cpp/sample\.pc/g' tags >> $tag_file1
	sed -e $kk tags >> $tag_file1
done
# Now handle all the C++/C files - exclude the ESQL *.cpp files
rm -f tags $tag_file2
bb=`ls *.cpp *.c`
aa=`ls *.$ESQL_EXTN`
for mm in $bb 
do
	ee=`echo $mm | cut -d'.' -f1`
	file_type="NOT_ESQL"
	# Exclude the ESQL *.cpp and *.c files
	for nn in $aa 
	do
		dd=`echo $nn | cut -d'.' -f1`
		if [ "$dd" = "$ee" ]; then
			file_type="ESQL"
			break
		fi
	done
	if [ "$file_type" = "ESQL" ]; then
		continue
	fi
	rm -f tags
	$which_tag $mm
	cat tags >> $tag_file2
done
mv -f $tag_file2 tags
cat  $tag_file1 >> tags
rm -f $tag_file1
# Must sort tags file for it work properly ....
sort tags > $tag_file1
mv $tag_file1 tags

8.3.  Ctags for JavaScript programs, Korn, Bourne shells

The shell script given below can be used to generate tags for a very large variety of programs written in JavaScript, PHP/FI scripts, Korn shell, C shell, Bourne shell and many others. This is a very generic module.

Save this file as tags_gen.sh and do chmod a+rx tags_gen.sh.

#!/bin/sh
tmp_tag=tags_file
tmp_tag2=tags_file2
echo " "
echo " "
echo " "
echo " "
echo " "
echo "Generate tags for ...."
while :
do
	echo "    Enter file extension for which you want to generate tags."
	echo -n "    File-extension should be like sh, js, ksh, etc... : "
	read ans
	if [ "$ans" == "" ]; then
		echo " "
		echo "Wrong entry. Try again!"
	else
		break
	fi
done
\rm -f $tmp_tag
aa=`ls *.$ans`
for ii in $aa
do
	jj=`echo $ii | cut -d'.' -f1`
	#echo $jj
	cp $ii $jj.c
	ctags $jj.c
	echo "s/$jj.c/$ii/g" > $tmp_tag2
	sed -f $tmp_tag2 tags >> $tmp_tag
	\rm -f tags $jj.c
done
sort $tmp_tag > tags
\rm -f $tmp_tag $tmp_tag2

8.4.  Debugger gdb

You would be using gdb extensively along with Vi. Debugging is the most important aspect of programming as the major cost of software projects goes into debugging and testing.

To debug C++/C programs use 'gdb' tool. See 'man gdb' . You must compile your programs with -g3 option like

          gcc -g3 foo.c foo_another.c sample.c 
        

To set up easy aliases do -

          Setup an alias in your ~/.bash_profile alias gdb='gdb 
          -directory=/home/src -directory=/usr/myname/src ' Give - gdb foo.cpp 
          gdb> dir /hom2/another_src This will add to file search path 
          gdb> break 'some_class::func<TAB><TAB> This will 
          complete the function name saving you typing time... and will output 
          like - gdb> break 'some_class::function_foo_some_where(int aa, 
          float bb)' 
        

Pressing TAB key twice is the command line completion, which will save you lots of typing time. This is one of the most important technique of using gdb.

To get online help do -

          gdb> help Gives online help gdb> help breakpoints Gives more 
          details about breakpoints. 
        

To set breakpoints and do debugging

          unixprompt> gdb exe_filename gdb> b main This will put 
          breakpoint in main() function gdb> b 123 This will put breakpoint 
          in line 123 of the current file gdb> help breakpoints Gives more 
          details about breakpoints. 
        

To analyze the core dumps do

          unixprompt> gdb exe_filename core gdb> bt Gives backtrace of 
          functions and line numbers where the program failed gdb> help 
          backtrace Gives more details about backtrace. 
        

You can also use GUI version of gdb called xxgdb.

See also gdb interface to Vim at "http://www.lxlinux.com/gdbvim.tgz" .

Memory leak tools -