You can use tag facilities from shell command line. It is a big merit of GLOBAL compared with any other tag system.
First of all, you must execute gtags(1)(see section 5.2 gtags - create tag files for global.) at the root of source tree. For example, if you want to browse vi's source code:
$ cd /usr/src/usr.bin/vi $ gtags
Gtags traverse subdirectories and makes four databases at the root of the source tree.
$ ls G* GPATH GRTAGS GSYMS GTAGS
Consider the following source tree:
ROOT/ <- the root of source tree (GTAGS,GRTAGS,...) | |- DIR1/ | | | |- fileA.c ..... +---------------+ | | |main(){ | | | | func1();| | | | func2();| | | |} | | | +---------------+ | | | |- fileB.c ..... +---------------+ | |func1(){ ... } | | +---------------+ |- DIR2/ | |- fileC.c ..... +---------------+ |#ifdef X | |func2(){ i++; }| |#else | |func2(){ i--; }| |#endif | |func3(){ | | func1();| |} | +---------------+
$ cd ROOT $ global func1 DIR1/fileB.c # func1() is defined in fileB.c $ cd DIR1 $ global func1 fileB.c # relative path from DIR1 $ cd ../DIR2 $ global func1 ../DIR1/fileB.c # relative path from DIR2
$ global -r func2 ../DIR1/fileA.c # func2() is referred from fileA.c
$ cd ROOT $ global 'func[1-3]' DIR1/fileB.c # func1, func2 and func3 are matched DIR2/fileC.c
$ global func2 DIR2/fileC.c $ global -x func2 func2 2 DIR2/fileC.c func2(){ i++; } func2 4 DIR2/fileC.c func2(){ i--; }
$ global -a func1 /home/user/ROOT/DIR1/fileB.c
$ global -xs X X 1 DIR2/fileC.c #ifdef X
$ global -xg '#ifdef' #ifdef 1 DIR2/fileC.c #ifdef X
$ global -P fileB DIR1/fileB.c $ global -P '1/' DIR1/fileA.c DIR1/fileB.c $ global -P '\.c$' DIR1/fileA.c DIR1/fileB.c DIR2/fileC.c
$ global -f DIR2/fileC.c func2 2 DIR2/fileC.c func2(){ i++; } func2 4 DIR2/fileC.c func2(){ i--; } func3 6 DIR2/fileC.c func3(){
You can make multiple tag files. For example, you can execute gtags at ROOT/, version1.0/ and version2.0/.
ROOT/ <- the root of source tree (GTAGS,...) | |- version1.0/ <- the root of version1.0 (GTAGS,...) | | | |- file.c ..... +---------------+ | |func1(){ i++; }| | +---------------+ | |- version2.0/ <- the root of version2.0 (GTAGS,...) | |- file.c ..... +---------------+ |func1(){ i--; }| +---------------+
$ cd ROOT/version1.0 $ global -x func1 func1 1 file.c func1(){ i++; }
$ cd ROOT/version2.0 $ global -x func1 func1 1 file.c func1(){ i--; }
GTAGSROOT
environment variable to ROOT,
then global will locate objects in both directories.
$ cd ROOT $ global -x func1 func1 1 version1.0/file.c func1(){ i++; } func1 1 version2.0/file.c func1(){ i--; }
There is another usage of GTAGSROOT
.
$ mkdir /var/dbpath $ cd /cdrom/src # the root of source tree $ gtags /var/dbpath # make tag file in /var/dbpath $ export GTAGSROOT=`pwd` $ export GTAGSDBPATH=/var/dbpath $ global func
GTAGSLIBPATH
environment
variable.
You should execute gtags at each directory of the path.
If `GTAGS' is not found in a directory, global ignores that directory.
$ pwd /develop/src/mh # this is the source tree $ gtags $ ls G*TAGS GRTAGS GTAGS $ global mhl uip/mhlsbr.c # mhl() is found $ global strlen # strlen() is not found $ (cd /usr/src/lib; gtags) # library source $ (cd /usr/src/sys; gtags) # kernel source $ export GTAGSLIBPATH=/usr/src/lib:/usr/src/sys $ global strlen ../../../usr/src/lib/libc/string/strlen.c # found in library $ global access ../../../usr/src/sys/kern/vfs_syscalls.c # found in kernelOf course, the user program does not call kernel functions directly, but at least it is useful.
$ global -c kmem # maybe k..k.. kmem.. kmem_alloc kmem_alloc_pageable kmem_alloc_wait kmem_free kmem_free_wakeup kmem_init kmem_malloc kmem_suballoc # This is what I need! $ global kmem_suballoc ../vm/vm_kern.c
$ funcs() > { > local cur > cur=${COMP_WORDS[COMP_CWORD]} > COMPREPLY=(`global -c $cur`) > } $ complete -F funcs global $ global kmem_TABTAB kmem_alloc kmem_alloc_wait kmem_init kmem_alloc_nofault kmem_free kmem_malloc kmem_alloc_pageable kmem_free_wakeup kmem_suballoc $ global kmem_sTAB $ global kmem_suballoc ../vm/vm_kern.cIn tcsh:
% set funcs=(`global -c`) % complete global 'n/*/$funcs/' % global kmem_TAB kmem_alloc kmem_free_wakeup kmem_alloc_pageable kmem_init kmem_alloc_wait kmem_malloc kmem_free kmem_suballoc % global kmem_sTAB % global kmem_suballoc ../vm/vm_kern.c
$ vi `global func1` # edit fileB.c
$ global -xr fork | awk '{printf "view +%s %s\n",$2,$3}' view +650 ../dev/aic7xxx/aic7xxx_asm.c view +250 ibcs2/ibcs2_misc.c view +401 linux/linux_misc.c view +310 ../kern/init_main.c view +318 ../kern/init_main.c view +336 ../kern/init_main.c view +351 ../kern/init_main.c $ !! | sh # from now on, go to next tag with 'ZZ'.