Next Previous Contents

5. 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++.

5.1 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

5.2 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

5.3 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.

Memory leak tools -


Next Previous Contents