Shigio Yamaguchi's global tags package. The infrastructure support

for this is already in place, so "make tags" (or "make tags HTML=yes")
should work after your next make world.
Submitted by:	Shigio Yamaguchi <shigio@wafu.netgate.net>
This commit is contained in:
Jordan K. Hubbard 1997-04-15 12:30:38 +00:00
parent ebcf3d327b
commit f8fc522a77
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/GLOBAL/; revision=24959
31 changed files with 5260 additions and 0 deletions

131
usr.bin/global/HISTORY Normal file
View File

@ -0,0 +1,131 @@
GLOBAL history
--------------
version 1.0 initial version [21-Apr-96]
version 1.1 only bugfix [2-May-96]
[fixed bug]
global - makes corrupted path name by conversion error.
- description of exit code in online manual is mistaken.
btreeop - cannot treat a long line over BUFSIZ. With the result
that gtags fails.
extended ctags - when using -r option, considers a reserved word
to be a function name. With the result that GRTAGS becomes
too large.
version 1.2 mainly unification of files [7-Jun-96]
[changed]
extended ctags
- change to use bsearch(3) for searching reserved words.
- change to consider '__P' as a reserved word.
- unify the original patch (included in version1.0) and
the bugfix patch (included in version1.1).
extended vi
- unify the VI entended patch.
version 1.3 support of GTAGSLIBPATH [28-Jul-96]
[changed]
global - search in not only a source tree but also library paths
specified by environment variable GTAGSLIBPATH.
extended ctags
- change print format a little when -x option
version 1.4 support of yacc source file [26-Oct-96]
[changed]
extended ctags
- support of yacc source file.
- this version of ctags is NOT COMPATIBLE with original one.
* search all part of a yacc file for C functions.
(original only 3rd part)
* no longer considers a yacc rule to be an object.
version 1.5 hypertext generator [12-Dec-96]
[fixed bug]
gtags - doesn't skip 'y.tab.c'.(we should treat only *.y)
extended vi
- free stack memory. free(3) in FreeBSD 2.1.5R seems to
show a warning message when receive stack address.
So it spoils the screen.
[added]
htags - new command (hypertext generator of C source file)
gtags - error check code added.
version 1.6 support of 1.76 nvi and reconstruction for other OS [21-Jan-97]
[changed]
htags - cease using <BLOCKQUOTE> because lynx doesn't understand it.
global,htags
- replace 'sort -u' with 'sort | uniq' for compatibility reason.
[fixed bug]
global - makes illegal path name when using GTAGSLIBPATH.
gtags - error message mistaken.
[added]
nvi-1.76.diff
- patch for nvi 1.76 to make extended vi.
gctags - this is the same with extended ctags in older version.
now GLOBAL includes BSD ctags in it. so no longer has
patch file (ctags.diff).
(I brought original ctags from FreeBSD 2.1.5R)
global - -a option added.
version 1.7 make suitable for large project (mainly FreeBSD kernel) [17-Feb-97]
[changed]
htags - htags no longer makes frame.html. Index.html offers frame
function too.
- works MUCH faster than previous version.
[fixed bug]
htags - string 'param' follows '&' means specific charactor in hypertext.
So, changed internal separator from '&' to '|'.
[added]
gtags - -s option added. If specified, gtags extract ENTRY() and
ALTENTRY() from *.[sS] files.
htags - supports one level nested index. It's always valid for file
index when directories found, and valid for function index
only when -a option specified.
- -v and -t option added.
systags.sh
- script to make all tags (GTAGS,GRTAGS,HTML) for kernel source.
(it is only for FreeBSD and Linux)
version 1.8 fix some bugs, add options and make more portable [5-Apr-97]
[changed]
gctags, btreeop, Makefile
- modify for generic UNIX (Linux, Solaris)
- modify to quiet compiler.
Many thanks to
A.E. Brouwer
Oleg Checkulaev
Emile Heyns
gctags - modify to treat '\r' at the end of line.
htags - changed internal separator from '|' to ' '.
because some OS cannot treat '|' in a path.
[fixed bug]
htags - regard a part of path in #include as a reserved word.
- generate illegal links when same tags exist in a line.
- insufficient comment detection.
gctags - regard function name as a definition in extern statement.
- skip macro(no argment) body when -r specified.
gctags, htags
- regard 'entry' as a reserved word.
[added]
global - -c (complete) option added.
htags - -d tagdir option added.
- -w option added.
version 1.81 make global to understand 'obj' directory and bug fix. [14-Apr-97]
[fixed bug]
extended vi
- doesn't hand '\' in a pattern to global.
[changed]
global
- can find tag file in obj directory.

16
usr.bin/global/MANIFEST Normal file
View File

@ -0,0 +1,16 @@
HISTORY Histroy of GLOBAL.
INSTALL Installation method
MANIFEST This file.
Makefile Makefile for generic UNIX(including BSD).
Makefile.bsd Makefile for BSD.
Makefile.inc A part of Makefile for BSD.
README Readme (introduction and usage).
VERSION Version number.
btreeop/ Btreeop command directory.
gctags/ Gctags command directory (extended ctags).
global/ Global command directory.
gtags/ Gtags command directory.
htags/ Htags command directory.
systags/ Script for kernel.
nvi-1.34.diff Patch for nvi 1.34.
nvi-1.76.diff Patch for nvi 1.76.

3
usr.bin/global/Makefile Normal file
View File

@ -0,0 +1,3 @@
SUBDIR= gctags global gtags btreeop htags systags
.include <bsd.subdir.mk>

View File

@ -0,0 +1 @@
BINDIR?= /usr/bin

527
usr.bin/global/README Normal file
View File

@ -0,0 +1,527 @@
@@@@@@@-
@- @-
@- @-
@- @- @@@@@- @@@@@@- @@- @-
@- F o r a l l h a c h e r s. version 1.8
@- @@@@@@-@- @- @- @@@@@- @- @- @-
@- @- @- @- @- @- @- @@@@@- @-
@- @- @- @- @- @- @-@- @- @-
@@@@@@@@- @@@@- @@@@@- @@@@@@-@@@- @@@@- @@@@@@-
Shigio Yamaguchi 5-Apr-97
Copyright 1996, 1997 Shigio Yamaguchi All right resereved.
GLOBAL is a browsing system for C and Yacc source code.
It brings benefits to all hackers. Enjoy!
Contents
--------------------------------
0. Introduction
1. Global
1.1. Features
1.2. Preparation
1.3. Basic usage
1.4. Applied usage
2. Extended vi using global
2.1. Features
2.2. Preparation
2.3. Basic usage
2.4. Applied usage
3. Hypertext generator
3.1. Features
3.2. Preparation
3.3. Usage
3.4. To make hypertext of kernel
--------------------------------
0. Introduction
GLOBAL is a browsing system for C and Yacc source files.
You can locate the specified function in C source files and move there easily.
It is useful to hack a large project containing many subdirectories,
many '#ifdef' and many main() functions like MH, X or BSD kernel.
It supports following environments.
o shell command line(see '1. Global')
o vi editor(see '2. Extended vi using global')
o web browser(see '3. Hypertext generator')
GLOBAL is consist of global(1), gtags(1), btreeop(1), gctags(1), htags(1)
and extended vi(1).
* 'extended' means being entended for GLOBAL.
* Btreeop and gctags are used internally, so you need not
understand about them.
The extended vi is completely upper compatible with original one.
All the functions for GLOBAL are enabled only in 'gtagsmode'.
------------------------------------------------------------------------------
1. Global
1.1. Features
o Global can find the locations of a specified function quickly.
o Global can locate not only function definitions but also function references.
o Global allows duplicate entries.
o Global can treat a source tree containing subdirectories and you can
get relative path of objects from anywhere within the tree.
o Global can understand perl's regular expression.
o Global can search in not only a source tree but also library paths.
o Global can treat yacc source file.
I think these features are useful for a large project containing many
subdirectories, many '#ifdef' and many main() functions like MH.
1.2. Preparation
First of all, you must execute gtags(1) at the root of source tree.
For example, if you want to browse vi's source code, please do like this.
% cd /usr/src/usr.bin/vi
% gtags
Gtags traverse subdirectories and makes
two database at the root of source tree.
% ls G*TAGS
GRTAGS GTAGS
GTAGS - database for function definition
GRTAGS - database for function reference
If you cannot find functions that should exist, please try -e option.
% gtags -e
1.3. Basic usage
Please think of 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();|
|} |
+---------------+
You can get the relative path of your object from anywhere within
the source tree.
% 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
-r option locates function references.
% global -r func2
../DIR1/fileA.c <- func2() is referred from fileA.c
You can use perl's regular expression.
% cd ROOT
% global 'func[1-3]'
DIR1/fileB.c <- func1, func2 and func3 are matched
DIR2/fileC.c
-x option shows the detail. It's similar to ctags's -x option.
% global func2
DIR2/fileC.c
% global -x func2
func2 2 DIR2/fileC.c func2(){ i++; }
func2 4 DIR2/fileC.c func2(){ i--; }
-a option produces the absolute path name.
% global -a func1
/home/user/ROOT/DIR1/fileB.c
You can edit files including specified function directly like this.
% vi `global func1` <- edit fileB.c
1.4. Applied usage
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,GRTAGS)
|
|- version1.0/ <- the root of version1.0 (GTAGS,GRTAGS)
| |
| |- file.c ..... +---------------+
| |func1(){ i++; }|
| +---------------+
|
|- version2.0/ <- the root of version2.0 (GTAGS,GRTAGS)
|
|- file.c ..... +---------------+
|func1(){ i--; }|
+---------------+
When you are walking in version1.0 directory, global locates functions
only in version1.0.
% cd ROOT/version1.0
% global -x func1
func1 1 file.c func1(){ i++; }
When you are walking in version2.0, global locates functions only in
version2.0.
% cd ROOT/version2.0
% global -x func1
func1 1 file.c func1(){ i--; }
If you are at ROOT/ or you set GTAGSROOT environment variable to ROOT,
global locates functions in both version1.0 and version2.0 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.
If your source files are on a read only device like CDROM, you cannot
make database on the root of source tree.
In such case, please do the following.
% mkdir /var/dbpath
% cd /cdrom/src <- the root of source tree
% gtags /var/dbpath <- make tag file in /var/dbpath
% setenv GTAGSROOT `pwd`
% setenv GTAGSDBPATH /var/dbpath
% global func
=-=-=-=
If you want to treat the references to a function that is not defined
in the source tree like a library function or system call, you can specify
library directories with the GTAGSLIBPATH environment variable.
You should execute gtags at each directory of the path.
If GTAGS is not found in a directory, global ignores it.
% 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
% setenv GTAGSLIBPATH /usr/src/lib:/usr/src/sys
% global strlen
../../../usr/src/lib/libc/string/strlen.c <- strlen() is found in library
% global access
../../../usr/src/sys/kern/vfs_syscalls.c <- access() is found in kernel
Of course, user program doesn't call kernel function directly, but
at least it is useful.
=-=-=-=
If you forget function name, you can use -c (complete) option.
% 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
You can use -c option with tcsh's complete command.
% set funcs=(`global -c`)
% complete global 'n/*/$funcs/'
% global kmem_<TAB>
kmem_alloc kmem_alloc_wait kmem_free_wakeup kmem_malloc
kmem_alloc_pageable kmem_free kmem_init kmem_suballoc
% global kmem_s<TAB>
% global kmem_suballoc
../vm/vm_kern.c
* <TAB> means tab key or Ctrl-I.
=-=-=-=
If you want to browse many files in order, do the followings.
% global -xr fork | awk '{printf "view +%s %s\n",$2,$3}' | tee /tmp/list
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'.
2. Extended vi using global
2.1. Features
o Tag function of extended vi can locate not only function definitions
but also function references.
o Extended vi allows duplicate tag entries.
o Extended vi can understand perl's regular expression as a tag name
for search.
o Extended vi is completely upper compatible with original one.
Above functions are available only in 'gtags mode'.
2.2. Preparation
First do the preparation of global. (Please see "1.2. Preparation").
Second, to use global from vi, you need to get into 'gtagsmode'.
There are some ways to do it.
(a) Start vi with -G option
% vi -G file.c
(b) Start vi and execute "set gtagsmode"
% vi file.c
~
~
~
:set gtagsmode
(c) Previously write the set command to .exrc or .nexrc file and start vi
$HOME/.exrc
+----------------------------
|set gtagsmode
You must start vi under the source tree described in "1.2. Preparation".
2.3. Basic usage
o To go to func1, you can say
:tag func1
It seemes same with original vi, but extended vi use GTAGS
instead of tags.
o To go to referenced point of func1, add prefix 'r'
:rtag func1
Extended vi use GRTAGS.
o If a number of functions located, the action of extended vi differs
up to your nvi's version.
[Extended vi based 1.34 nvi]
Vi goes into 'GTAGS SELECT MODE' like this.
+-------------------------------------------------------------
|main 347 i386/isa/ultra14f.c main()
|main 128 kern/init_main.c main(framep)
|main 104 netiso/clnp_debug.c main()
|main 164 netiso/xebec/main.c main(argc, argv)
|~
|~
|~
|~
|~
|[GTAGS SELECT MODE] 4 lines
+-------------------------------------------------------------
You can select a tag line by any vi command and press [RETURN],
and you can go to the tag's point. In ex mode, type "select"
instead of [RETURN]. When you want to go to next or previous tag,
you can return to 'GTAGS SELECT MODE' with <control-T> and reselect.
Suggested .nexrc:
set gtagsmode
set leftright
[Extended vi based 1.76 nvi]
Vi goes to the first tag.
Then you can go to next tag by ':tagnext' or back by ':tagprev'.
Suggested .nexrc:
set gtagsmode
map ^N :tagnext^M
map ^P :tagprev^M
== WHY TWO STYLE EXIST ? ==
1.34 nvi cannot treat duplicate tag entries, so I made 'GTAGS SELECT MODE'
in it. But 1.76 nvi (1.61 and later) can treat them, so I adapted GLOBAL
tags to nvi's tag structure.
o <control-]> command is available.
In gtagsmode, if you are on the first column of line, it is identical to
":rtag <current token>[RETURN]", otherwise ":tag <current token>[RETURN]".
o Other tag commands are available too.
<control-T>
":tagpop"
":tagtop"
":display tags"
Please read online manual.
2.4. Applied usage
o In large project which include many main() function like MH,
you can start vi like this.
% vi -G -t main
You can browse all commands sequentially.
o When you want to check functions the name of which start with
"set" or "get",
% vi -G -t '^[sg]et'
Of cause, following command is available too.
:tag ^[sg]et
o If your source files are on a read only device like CDROM, please do
the followings.
% mkdir /var/dbpath <- directory for tag file
% cd /cdrom/src <- the root of source tree
% gtags /var/dbpath <- make tag files in /var/dbpath
% setenv GTAGSROOT `pwd`
% setenv GTAGSDBPATH /var/dbpath
% vi -G -t main
o If you want to treat the references to the function that is not defined
in the source tree like library functions or system calls,
do the followings.
% cd /usr/src/lib
% gtags <- probably as a root
% cd /usr/src/sys
% gtags
% setenv GTAGSLIBPATH /usr/src/lib:/usr/src/sys
If you examine vi's source,
% cd /usr/src/usr.bin/vi
% gtags
% vi -G -t main
You can start from vi and trip the whole unix world as if using
hypertext.
3. Hypertext generator
3.1. Features
o Htags makes hypertext from C source files.
o Once the hypertext generated, you need nothing other than WWW browser.
o You can use all of your browser's functions, for example, search,
history, bookmark, save, frame, windows and so on.
3.2. Preparation
At first, you must prepare much disk space. Hypertext needs so much
disk space. For example, the source code of FreeBSD kernel needs the
following disk space.
source code(/usr/src/sys) 14MB
tag database(GTAGS,GRTAGS) 9MB(!)
hypertext(HTML/*) 42MB(!!!)
Please do the followings.
(at your source directory)
% gtags <- make tag database
% htags <- make hypertext
Then you will find 'HTML' directory in the current directory.
3.3. Usage
Please start a web browser like this.
% lynx HTML/index.html
You can use any browsers, for example, Lynx, Chimera, Mosaic,
Netscape Navigator, Internet Explorer and so on.
(But IE3.0 doesn't work well about index.)
You will understand the usage for the looking.
You can move HTML directory to anywhere. It is independent of
the source code.
3.4. To make hypertext of kernel
If you would like to make hypertext of FreeBSD or Linux kernel source,
it is convenient to use systags script in this package.
% cd /usr/src/sys
% systags
then
% netscape HTML/index.html
You can use one level nested index and browse assembler source file too.
Thank you for your reading of my poor english.
And of course, thank you Keith Bostic (the author of nvi(1) and db(3)).
----------------------------------------------------------------------------
E-Mail: <shigio@wafu.netgate.net>
WWW: <http://wafu.netgate.net/tama/unix/indexe.html>
(You can find the latest version here.)
----------------------------------------------------------------------------

1
usr.bin/global/VERSION Normal file
View File

@ -0,0 +1 @@
1.81

View File

@ -0,0 +1,5 @@
# @(#)Makefile 1.0 (Berkeley) 4/21/96
PROG= btreeop
.include <bsd.prog.mk>

View File

@ -0,0 +1,142 @@
.\"
.\" Copyright (c) 1996, 1997 Shigio Yamaguchi. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Shigio Yamaguchi.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd April 21, 1996
.Dt BTREEOP 1
.Os BSD 4
.Sh NAME
.Nm btreeop
.Nd btree database maintenance tool
.Sh SYNOPSIS
.Nm btreeop
.Op Fl C
.Op Fl K Ar key
.Op Fl b
.Op Fl c Ar cashesize
.Op Fl l
.Op Fl p Ar psize
.Op Ar dbname
.Sh DESCRIPTION
.Nm Btreeop
execute simple operations for
.Xr btree 3
database.
.Nm Btreeop
can create database and read (sequential or index) from it .
Duplicate entries are allowed.
.Sh OPTIONS
A capital letter means a command. If no command specified
then it assume sequential read operation.
.Bl -tag -width Ds
.It Fl C
create database.
.It Fl K Ar key
search data by the key.
.It Fl b
assume BIG_ENDIAN byte order. default is LITTLE_ENDIAN.
.It Fl c Ar cashesize
specify cashesize. It's identical to
.Nm info.cachesize
of BTREEINFO. (see btree(3))
.It Fl l
assume LITTLE_ENDIAN byte order. (the default)
.It Fl p Ar psize
specify page size. It's identical to
.Nm info.psize
of BTREEINFO. (see btree(3))
.It Ar dbname
database name. default is 'btree'.
.Sh DATA FORMAT
To creat database,
.Nm btreeop
read data from stdin.
The format of the data is the following.
Key Data\\n
Key Data\\n
.
.
.
.El
.Bl -enum -offset indent
.It
Key and Data are separated by blank('\\t' or ' ').
.It
Key cannot include blank.
.It
Data can include blank.
.It
Null Data not allowed.
.El
.Sh EXAMPLES
Create database.
% btreeop -C
key1 data1
key2 data2
key2 data2-2
key3 data3
^D
%
Sequential read.
% btreeop
key2 data2
key3 data3
key2 data2-2
key1 data1
%
Indexed read.
% btreeop -K key2
key2 data2-2
key2 data2
%
.Sh FILES
.Bl -tag -width tags -compact
.It Pa btree
default database name.
.El
.Sh DIAGNOSTICS
.Nm Btreeop
exits with a value of 1 if an error occurred, 0 otherwise.
.Sh SEE ALSO
.Xr btree 3 ,
.Sh BUGS
.Nm btreeop
cannot utilize all features of
.Xr btree 3
.Sh AUTHOR
Shigio Yamaguchi (shigio@wafu.netgate.net)

View File

@ -0,0 +1,308 @@
/*
* Copyright (c) 1996, 1997 Shigio Yamaguchi. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Shigio Yamaguchi.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* btreeop.c 5-Apr-97
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h>
#include <db.h>
#include <fcntl.h>
char *dbdefault = "btree"; /* default database name */
char *progname = "btreeop"; /* command name */
char *dbname;
char buf[BUFSIZ+1];
#ifndef __P
#if defined(__STDC__)
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
void die __P((char *));
void usage __P((void));
void entab __P((char *));
void main __P((int, char **));
int dbcreate __P((DB *));
int dbkey __P((DB *, char *));
int dbscan __P((DB *));
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
void
die(s)
char *s;
{
fprintf(stderr, "%s: %s\n", progname, s);
exit(1);
}
void
usage() {
fprintf(stderr,
"usage: %s [-C][-K key][-b][-c cachesize][-l][-p psize][dbname]\n",
progname);
exit(1);
}
#define TABPOS(i) ((i)%8 == 0)
/*
* entab: convert spaces into tabs
*
* io) buf string buffer
*/
void
entab(buf)
char *buf;
{
int blanks = 0;
int pos, src, dst;
char c;
pos = src = dst = 0;
while ((c = buf[src++]) != 0) {
if (c == ' ') {
if (!TABPOS(++pos)) {
blanks++; /* count blanks */
continue;
}
buf[dst++] = '\t';
} else if (c == '\t') {
while (!TABPOS(++pos))
;
buf[dst++] = '\t';
} else {
++pos;
while (blanks--)
buf[dst++] = ' ';
buf[dst++] = c;
}
blanks = 0;
}
buf[dst] = 0;
}
#include <errno.h>
void
main(argc, argv)
int argc;
char *argv[];
{
char command = 0;
char *key = NULL;
DB *db;
BTREEINFO info;
int c;
info.flags = R_DUP; /* allow duplicate entries */
info.cachesize = 500000;
info.maxkeypage = 0;
info.minkeypage = 0;
info.psize = 0;
info.compare = NULL;
info.prefix = NULL;
info.lorder = LITTLE_ENDIAN;
while ((c = getopt(argc, argv, "CK:bc:lp:")) != EOF) {
switch (c) {
case 'K':
key = optarg;
case 'C':
command = c;
break;
case 'b':
info.lorder = BIG_ENDIAN;
break;
case 'c':
info.cachesize = atoi(optarg);
break;
case 'l':
info.lorder = LITTLE_ENDIAN;
break;
case 'p':
info.psize = atoi(optarg);
break;
default:
usage();
}
}
dbname = (optind < argc) ? argv[optind] : dbdefault;
db = dbopen(dbname, command == 'C' ?
O_RDWR|O_CREAT|O_TRUNC : O_RDONLY,
0644, DB_BTREE, &info);
if (db == NULL) {
die("dbopen failed.");
}
switch (command) {
case 'C': /* Create database */
dbcreate(db);
break;
case 'K': /* Keyed search */
dbkey(db, key);
break;
default: /* Scan all data */
dbscan(db);
break;
}
if (db->close(db)) {
die("db->close failed.");
}
exit(0);
}
/*
* dbcreate: create database
*
* i) db
* r) 0: normal
*/
int
dbcreate(db)
DB *db;
{
DBT key, dat;
int status;
#define IDENTLEN 80
char keybuf[IDENTLEN+1];
char *c;
/*
* Input file format:
* +------------------
* |Key Data\n
* |Key Data\n
* .
* .
* - Key and Data are separated by blank('\t' or ' ').
* - Key cannot include blank.
* - Data can include blank.
* - Null Data not allowed.
*/
while (fgets(buf, BUFSIZ, stdin)) {
if (buf[strlen(buf)-1] == '\n') /* chop(buf) */
buf[strlen(buf)-1] = 0;
else
while (fgetc(stdin) != '\n')
;
for (c = buf; *c && !isspace(*c); c++) /* skip key part */
;
if (*c == 0)
die("data part not found.");
if (c - buf > IDENTLEN)
die("key too long.");
strncpy(keybuf, buf, c - buf); /* make key string */
keybuf[c - buf] = 0;
for (; *c && isspace(*c); c++) /* skip blanks */
;
if (*c == 0)
die("data part is null.");
entab(buf);
key.data = keybuf;
key.size = strlen(keybuf)+1;
dat.data = buf;
dat.size = strlen(buf)+1;
status = (db->put)(db, &key, &dat, 0);
switch (status) {
case RET_SUCCESS:
break;
case RET_ERROR:
case RET_SPECIAL:
die("db->put: failed.");
}
}
return(0);
}
/*
* dbkey: Keyed search
*
* i) db
* i) skey
* r) 0: normal
* 1: not found
*/
int
dbkey(db, skey)
DB *db;
char *skey;
{
DBT dat, key;
int status;
key.data = skey;
key.size = strlen(skey)+1;
for (status = (*db->seq)(db, &key, &dat, R_CURSOR);
status == RET_SUCCESS && !strcmp(key.data, skey);
status = (*db->seq)(db, &key, &dat, R_NEXT)) {
(void)fprintf(stdout, "%s\n", (char *)dat.data);
}
if (status == RET_ERROR)
die("db->seq failed.");
return (0);
}
/*
* dbscan: Scan all data
*
* i) db
* r) 0: normal
* 1: not found
*/
int
dbscan(db)
DB *db;
{
DBT dat, key;
int status;
for (status = (*db->seq)(db, &key, &dat, R_FIRST);
status == RET_SUCCESS;
status = (*db->seq)(db, &key, &dat, R_NEXT)) {
(void)fprintf(stdout, "%s\n", (char *)dat.data);
}
if (status == RET_ERROR)
die("db->seq failed.");
return (0);
}

840
usr.bin/global/gctags/C.c Normal file
View File

@ -0,0 +1,840 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)C.c 8.4 (Berkeley) 4/2/94";
#endif /* LIBC_SCCS and not lint */
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ctags.h"
static int func_entry __P((void));
static void hash_entry __P((void));
static void skip_string __P((int));
static int str_entry __P((int));
#ifdef GTAGS
static int cmp __P((const void *, const void *));
static int isstatement __P((char *));
static void define_line __P((void));
#endif
#ifdef YACC
extern int yaccfile; /* true when *.y file */
#endif
/*
* c_entries --
* read .c and .h files and call appropriate routines
*/
void
c_entries()
{
int c; /* current character */
int level; /* brace level */
int token; /* if reading a token */
int t_def; /* if reading a typedef */
int t_level; /* typedef's brace level */
char *sp; /* buffer pointer */
char tok[MAXTOKEN]; /* token buffer */
#ifdef YACC
/*
* yacc file format is like the following.
*
* declarations
* %%
* rules
* %%
* programs
*
*/
#define DECLARATIONS 0
#define RULES 1
#define PROGRAMS 2
int yaccstatus = (yaccfile) ? DECLARATIONS : PROGRAMS;
int inyacc = (yaccfile) ? YES : NO; /* NO while C source */
#endif
lineftell = ftell(inf);
sp = tok; token = t_def = NO; t_level = -1; level = 0; lineno = 1;
while (GETC(!=, EOF)) {
switch (c) {
/*
* Here's where it DOESN'T handle: {
* foo(a)
* {
* #ifdef notdef
* }
* #endif
* if (a)
* puts("hello, world");
* }
*/
case '{':
#ifdef YACC
if (yaccstatus == RULES && level == 0)
inyacc = NO;
#endif
++level;
goto endtok;
case '}':
/*
* if level goes below zero, try and fix
* it, even though we've already messed up
*/
if (--level < 0)
level = 0;
#ifdef GTAGS
/*
* -e flag force a function to end when a '}' appear
* at column 0. If -e flag not specified, all functions
* after funcA() would be lost.
*
* funcA() {
* #ifdef A
* if (a) {
* ...
* #else
* if (nota) {
* ...
* #endif
* }
* }
*/
if (eflag && ftell(inf) == lineftell+1) {
level = 0;
}
#endif
#if YACC
if (yaccstatus == RULES && level == 0)
inyacc = YES;
#endif
goto endtok;
case '\n':
SETLINE;
/*
* the above 3 cases are similar in that they
* are special characters that also end tokens.
*/
endtok: if (sp > tok) {
*sp = EOS;
token = YES;
sp = tok;
}
else
token = NO;
continue;
/*
* We ignore quoted strings and character constants
* completely.
*/
case '"':
case '\'':
(void)skip_string(c);
break;
/*
* comments can be fun; note the state is unchanged after
* return, in case we found:
* "foo() XX comment XX { int bar; }"
*/
case '/':
if (GETC(==, '*')) {
skip_comment();
continue;
}
(void)ungetc(c, inf);
c = '/';
goto storec;
/* hash marks flag #define's. */
case '#':
if (sp == tok) {
hash_entry();
break;
}
goto storec;
/*
* if we have a current token, parenthesis on
* level zero indicates a function.
#ifdef GTAGS
* in the case of rflag == 1, if we have a current token,
* parenthesis on level > zero indicates a function reference.
#endif
#ifdef YACC
* inyacc == NO while C source.
#endif
*/
case '(':
#ifdef YACC
if (inyacc == NO)
#endif
#ifdef GTAGS
if (!rflag && !level && token)
#else
if (!level && token)
#endif
{
int curline;
if (sp != tok)
*sp = EOS;
/*
* grab the line immediately, we may
* already be wrong, for example,
* foo\n
* (arg1,
*/
getline();
curline = lineno;
#ifdef GTAGS
/* to make sure. */
if (!isstatement(tok))
#endif
if (func_entry()) {
++level;
pfnote(tok, curline);
}
break;
}
#ifdef GTAGS
else if (rflag && level && token) {
if (sp != tok)
*sp = EOS;
getline();
if (!isstatement(tok) && isdefined(tok))
pfnote(tok, lineno);
break;
}
#endif
goto storec;
/*
* semi-colons indicate the end of a typedef; if we find a
* typedef we search for the next semi-colon of the same
* level as the typedef. Ignoring "structs", they are
* tricky, since you can find:
*
* "typedef long time_t;"
* "typedef unsigned int u_int;"
* "typedef unsigned int u_int [10];"
*
* If looking at a typedef, we save a copy of the last token
* found. Then, when we find the ';' we take the current
* token if it starts with a valid token name, else we take
* the one we saved. There's probably some reasonable
* alternative to this...
*/
case ';':
if (t_def && level == t_level) {
t_def = NO;
getline();
if (sp != tok)
*sp = EOS;
pfnote(tok, lineno);
break;
}
goto storec;
#if YACC
case '%':
if (yaccstatus == DECLARATIONS || yaccstatus == RULES) {
if (GETC(==, '%')) {
level = 0;
if (yaccstatus == DECLARATIONS) {
if (!rflag) {
getline();
pfnote("yyparse", lineno);
}
yaccstatus = RULES;
} else if (yaccstatus == RULES) {
yaccstatus = PROGRAMS;
}
inyacc = (yaccstatus == PROGRAMS) ? NO : YES;
} else if (c == '{') {
level = 0;
inyacc = NO;
} else if (c == '}') {
level = 0;
inyacc = YES;
} else {
(void)ungetc(c, inf);
}
break;
}
/* else fall throuth */
#endif
/*
* store characters until one that can't be part of a token
* comes along; check the current token against certain
* reserved words.
*/
default:
#ifdef BUGFIX
/*
* to treat following function.
* func (arg) {
* ....
* }
*/
if (c == ' ' || c == '\t') {
int save = c;
while (GETC(!=, EOF) && (c == ' ' || c == '\t'))
;
if (c == EOF)
return;
(void)ungetc(c, inf);
c = save;
}
#endif
storec: if (!intoken(c)) {
if (sp == tok)
break;
*sp = EOS;
#ifdef GTAGS
if (!memcmp(tok, "extern",7)) {
while (GETC(!=, EOF) && c != ';') {
if (c == '\n')
SETLINE;
}
if (c == EOF)
return;
break;
}
#endif
if (tflag) {
/* no typedefs inside typedefs */
if (!t_def &&
!memcmp(tok, "typedef",8)) {
t_def = YES;
t_level = level;
break;
}
/* catch "typedef struct" */
if ((!t_def || t_level < level)
&& (!memcmp(tok, "struct", 7)
|| !memcmp(tok, "union", 6)
|| !memcmp(tok, "enum", 5))) {
/*
* get line immediately;
* may change before '{'
*/
getline();
if (str_entry(c))
++level;
break;
/* } */
}
}
sp = tok;
}
else if (sp != tok || begtoken(c)) {
*sp++ = c;
token = YES;
}
continue;
/* end of default */
} /* end of switch */
/*
* 'break' statement in switch block come here.
*/
sp = tok;
token = NO;
} /* end of while */
}
/*
* func_entry --
* handle a function reference
*/
static int
func_entry()
{
int c; /* current character */
int level = 0; /* for matching '()' */
/*
* Find the end of the assumed function declaration.
* Note that ANSI C functions can have type definitions so keep
* track of the parentheses nesting level.
*/
while (GETC(!=, EOF)) {
switch (c) {
case '\'':
case '"':
/* skip strings and character constants */
skip_string(c);
break;
case '/':
/* skip comments */
if (GETC(==, '*'))
skip_comment();
break;
case '(':
level++;
break;
case ')':
if (level == 0)
goto fnd;
level--;
break;
case '\n':
SETLINE;
}
}
return (NO);
fnd:
/*
* we assume that the character after a function's right paren
* is a token character if it's a function and a non-token
* character if it's a declaration. Comments don't count...
*/
for (;;) {
while (GETC(!=, EOF) && iswhite(c))
if (c == '\n')
SETLINE;
if (intoken(c) || c == '{')
break;
if (c == '/' && GETC(==, '*'))
skip_comment();
else { /* don't ever "read" '/' */
(void)ungetc(c, inf);
return (NO);
}
}
if (c != '{')
(void)skip_key('{');
return (YES);
}
/*
* hash_entry --
* handle a line starting with a '#'
*/
static void
hash_entry()
{
int c; /* character read */
int curline; /* line started on */
char *sp; /* buffer pointer */
char tok[MAXTOKEN]; /* storage buffer */
#ifdef BUGFIX
/*
* to treat following macro.
* # macro(arg) ....
*/
while (GETC(!=, EOF) && (c == ' ' || c == '\t'))
;
(void)ungetc(c, inf);
#endif
curline = lineno;
for (sp = tok;;) { /* get next token */
if (GETC(==, EOF))
return;
if (iswhite(c))
break;
*sp++ = c;
}
*sp = EOS;
if (memcmp(tok, "define", 6)) /* only interested in #define's */
goto skip;
for (;;) { /* this doesn't handle "#define \n" */
if (GETC(==, EOF))
return;
if (!iswhite(c))
break;
}
for (sp = tok;;) { /* get next token */
*sp++ = c;
if (GETC(==, EOF))
return;
/*
* this is where it DOESN'T handle
* "#define \n"
*/
if (!intoken(c))
break;
}
*sp = EOS;
#ifdef GTAGS
if (rflag) {
/*
* #define XXX\n
*/
if (c == '\n' || (c == '\r' && GETC(==, '\n'))) {
SETLINE;
return;
}
/*
* v
* #define XXX(X) XXXXXX
*/
if (c == '(')
(void)skip_key(')');
/*
* v
* #define XXX(X) XXXXXX
*/
while (GETC(!=, EOF)) {
if (c != ' ' && c != '\t') {
(void)ungetc(c, inf);
break;
}
}
/*
* v
* #define XXX(X) XXXXXX
*/
define_line();
return;
}
#endif
if (dflag || c == '(') { /* only want macros */
getline();
pfnote(tok, curline);
}
skip: if (c == '\n') { /* get rid of rest of define */
SETLINE
#ifdef MODIFY
if (*(sp - 1) == '\r') {
if (*(sp - 2) != '\\')
return;
} else
#endif
if (*(sp - 1) != '\\')
return;
}
(void)skip_key('\n');
}
#ifdef GTAGS
/* sorted by alphabet */
static struct words {
char *name;
} words[] = {
{"__P"},
{"auto"},
{"break"},
{"case"},
{"char"},
{"continue"},
{"default"},
{"do"},
{"double"},
{"else"},
{"extern"},
{"float"},
{"for"},
{"goto"},
{"if"},
{"int"},
{"long"},
{"register"},
{"return"},
{"short"},
{"sizeof"},
{"static"},
{"struct"},
{"switch"},
{"typedef"},
{"union"},
{"unsigned"},
{"void"},
{"while"},
};
static int
cmp(s1, s2)
const void *s1, *s2;
{
return strcmp(((struct words *)s1)->name, ((struct words *)s2)->name);
}
static int
isstatement(token)
char *token;
{
struct words tmp;
tmp.name = token;
if (bsearch(&tmp, words, sizeof(words)/sizeof(struct words), sizeof(struct words), cmp))
return YES;
return NO;
}
static void
define_line()
{
int c; /* character read */
int level; /* brace level */
int token; /* if reading a token */
char *sp; /* buffer pointer */
char tok[MAXTOKEN]; /* storage buffer */
sp = tok; token = NO; level = 0;
while (GETC(!=, EOF)) {
switch (c) {
case '{':
++level;
goto endtok;
case '}':
if (--level < 0)
level = 0;
goto endtok;
case '\\':
if (GETC(==, '\n') || (c == '\r' && GETC(==, '\n'))) {
SETLINE;
}
continue;
case '\n':
SETLINE;
return;
endtok: if (sp > tok) {
*sp = EOS;
token = YES;
sp = tok;
}
else
token = NO;
continue;
case '"':
case '\'':
(void)skip_string(c);
break;
case '/':
if (GETC(==, '*')) {
skip_comment();
continue;
}
(void)ungetc(c, inf);
c = '/';
goto storec;
case '(':
if (token) {
if (sp != tok)
*sp = EOS;
getline();
if (!isstatement(tok) && isdefined(tok))
pfnote(tok, lineno);
break;
}
goto storec;
case ';':
goto storec;
default:
storec: if (!intoken(c)) {
if (sp == tok)
break;
*sp = EOS;
sp = tok;
}
else if (sp != tok || begtoken(c)) {
*sp++ = c;
token = YES;
}
continue;
}
sp = tok;
token = NO;
}
}
#endif
/*
* str_entry --
* handle a struct, union or enum entry
*/
static int
str_entry(c)
int c; /* current character */
{
int curline; /* line started on */
char *sp; /* buffer pointer */
char tok[LINE_MAX]; /* storage buffer */
curline = lineno;
while (iswhite(c))
if (GETC(==, EOF))
return (NO);
if (c == '{') /* it was "struct {" */
return (YES);
for (sp = tok;;) { /* get next token */
*sp++ = c;
if (GETC(==, EOF))
return (NO);
if (!intoken(c))
break;
}
switch (c) {
case '{': /* it was "struct foo{" */
--sp;
break;
case '\n': /* it was "struct foo\n" */
SETLINE;
/*FALLTHROUGH*/
default: /* probably "struct foo " */
while (GETC(!=, EOF))
if (!iswhite(c))
break;
if (c != '{') {
(void)ungetc(c, inf);
return (NO);
}
}
*sp = EOS;
pfnote(tok, curline);
return (YES);
}
/*
* skip_comment --
* skip over comment
*/
void
skip_comment()
{
int c; /* character read */
int star; /* '*' flag */
for (star = 0; GETC(!=, EOF);)
switch(c) {
/* comments don't nest, nor can they be escaped. */
case '*':
star = YES;
break;
case '/':
if (star)
return;
break;
case '\n':
SETLINE;
/*FALLTHROUGH*/
default:
star = NO;
break;
}
}
/*
* skip_string --
* skip to the end of a string or character constant.
*/
static void
skip_string(key)
int key;
{
int c,
skip;
for (skip = NO; GETC(!=, EOF); )
switch (c) {
case '\\': /* a backslash escapes anything */
skip = !skip; /* we toggle in case it's "\\" */
break;
#ifdef MODIFY
case '\r':
break;
#endif
case '\n':
SETLINE;
/*FALLTHROUGH*/
default:
if (c == key && !skip)
return;
skip = NO;
}
}
/*
* skip_key --
* skip to next char "key"
*/
int
skip_key(key)
int key;
{
int c,
skip,
retval;
for (skip = retval = NO; GETC(!=, EOF);)
switch(c) {
case '\\': /* a backslash escapes anything */
skip = !skip; /* we toggle in case it's "\\" */
break;
case ';': /* special case for yacc; if one */
case '|': /* of these chars occurs, we may */
retval = YES; /* have moved out of the rule */
break; /* not used by C */
case '\'':
case '"':
/* skip strings and character constants */
skip_string(c);
break;
case '/':
/* skip comments */
if (GETC(==, '*')) {
skip_comment();
break;
}
(void)ungetc(c, inf);
c = '/';
goto norm;
#ifdef MODIFY
case '\r':
break;
#endif
case '\n':
SETLINE;
/*FALLTHROUGH*/
default:
norm:
if (c == key && !skip)
return (retval);
skip = NO;
}
return (retval);
}

View File

@ -0,0 +1,7 @@
# @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= gctags
CFLAGS+=-I${.CURDIR} -DGTAGS -DBUGFIX -DMODIFY -DYACC
SRCS= C.c ctags.c fortran.c lisp.c print.c tree.c yacc.c
.include <bsd.prog.mk>

View File

@ -0,0 +1,402 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1987, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)ctags.c 8.3 (Berkeley) 4/2/94";
#endif /* LIBC_SCCS and not lint */
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "ctags.h"
/*
* ctags: create a tags file
*/
NODE *head; /* head of the sorted binary tree */
/* boolean "func" (see init()) */
bool _wht[256], _etk[256], _itk[256], _btk[256], _gd[256];
FILE *inf; /* ioptr for current input file */
FILE *outf; /* ioptr for tags file */
long lineftell; /* ftell after getc( inf ) == '\n' */
int lineno; /* line number of current line */
int dflag; /* -d: non-macro defines */
#ifdef GTAGS
int eflag; /* -e: '{' at 0 column force function end */
#endif
int tflag; /* -t: create tags for typedefs */
int vflag; /* -v: vgrind style index output */
int wflag; /* -w: suppress warnings */
int xflag; /* -x: cxref style output */
#ifdef GTAGS
int Dflag; /* -D: allow duplicate entrys */
int rflag; /* -r: function reference */
#endif
#ifdef YACC
int yaccfile; /* yacc file */
#endif
char *curfile; /* current input file name */
char searchar = '/'; /* use /.../ searches by default */
char lbuf[LINE_MAX];
void init __P((void));
void find_entries __P((char *));
int main __P((int, char **));
int
main(argc, argv)
int argc;
char **argv;
{
static char *outfile = "tags"; /* output file */
int aflag; /* -a: append to tags */
int uflag; /* -u: update tags */
int exit_val; /* exit value */
int step; /* step through args */
int ch; /* getopts char */
char cmd[100]; /* too ugly to explain */
#ifndef lint
copyright[0] = copyright[0]; /* to satisfy compiler */
#endif
aflag = uflag = NO;
#ifdef GTAGS
while ((ch = getopt(argc, argv, "BDFadef:rtuwvxy")) != EOF)
#else
while ((ch = getopt(argc, argv, "BFadf:tuwvx")) != EOF)
#endif
switch(ch) {
case 'B':
searchar = '?';
break;
#ifdef GTAGS
case 'D':
Dflag++;
break;
#endif
case 'F':
searchar = '/';
break;
case 'a':
aflag++;
break;
case 'd':
dflag++;
break;
#ifdef GTAGS
case 'e':
eflag++;
break;
#endif
case 'f':
outfile = optarg;
break;
#ifdef GTAGS
case 'r':
rflag++;
break;
#endif
case 't':
tflag++;
break;
case 'u':
uflag++;
break;
case 'w':
wflag++;
break;
case 'v':
vflag++;
case 'x':
xflag++;
break;
case '?':
default:
goto usage;
}
argv += optind;
argc -= optind;
if (!argc) {
usage: (void)fprintf(stderr,
#ifdef GTAGS
"usage: ctags [-BDFadrtuwvx] [-f tagsfile] file ...\n");
#else
"usage: ctags [-BFadtuwvx] [-f tagsfile] file ...\n");
#endif
exit(1);
}
#ifdef GTAGS
if (rflag)
gtagopen();
#endif
init();
for (exit_val = step = 0; step < argc; ++step)
if (!(inf = fopen(argv[step], "r"))) {
fprintf(stderr, "gctags: %s cannot open\n", argv[step]);
exit_val = 1;
}
else {
curfile = argv[step];
find_entries(argv[step]);
(void)fclose(inf);
}
if (head)
if (xflag)
put_entries(head);
else {
if (uflag) {
for (step = 0; step < argc; step++) {
(void)sprintf(cmd,
"mv %s OTAGS; fgrep -v '\t%s\t' OTAGS >%s; rm OTAGS",
outfile, argv[step],
outfile);
system(cmd);
}
++aflag;
}
if (!(outf = fopen(outfile, aflag ? "a" : "w"))) {
fprintf(stderr, "gctags: %s cannot open\n", outfile);
exit(exit_val);
}
put_entries(head);
(void)fclose(outf);
if (uflag) {
(void)sprintf(cmd, "sort -o %s %s",
outfile, outfile);
system(cmd);
}
}
#ifdef GTAGS
if (rflag)
gtagclose();
#endif
exit(exit_val);
}
/*
* init --
* this routine sets up the boolean psuedo-functions which work by
* setting boolean flags dependent upon the corresponding character.
* Every char which is NOT in that string is false with respect to
* the pseudo-function. Therefore, all of the array "_wht" is NO
* by default and then the elements subscripted by the chars in
* CWHITE are set to YES. Thus, "_wht" of a char is YES if it is in
* the string CWHITE, else NO.
*/
void
init()
{
int i;
unsigned char *sp;
for (i = 0; i < 256; i++) {
_wht[i] = _etk[i] = _itk[i] = _btk[i] = NO;
_gd[i] = YES;
}
#define CWHITE " \f\t\n"
for (sp = (unsigned char *)CWHITE; *sp; sp++) /* white space chars */
_wht[*sp] = YES;
#define CTOKEN " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?"
for (sp = (unsigned char *)CTOKEN; *sp; sp++) /* token ending chars */
_etk[*sp] = YES;
#define CINTOK "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789"
for (sp = (unsigned char *)CINTOK; *sp; sp++) /* valid in-token chars */
_itk[*sp] = YES;
#define CBEGIN "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
for (sp = (unsigned char *)CBEGIN; *sp; sp++) /* token starting chars */
_btk[*sp] = YES;
#define CNOTGD ",;"
for (sp = (unsigned char *)CNOTGD; *sp; sp++) /* invalid after-function chars */
_gd[*sp] = NO;
}
/*
* find_entries --
* this routine opens the specified file and calls the function
* which searches the file.
*/
void
find_entries(file)
char *file;
{
char *cp;
lineno = 0; /* should be 1 ?? KB */
if ((cp = strrchr(file, '.')) != NULL) {
if (cp[1] == 'l' && !cp[2]) {
int c;
#ifdef GTAGS
if (rflag)
fprintf(stderr, "-r option is ignored in lisp file (Warning only)\n");
#endif
for (;;) {
if (GETC(==, EOF))
return;
if (!iswhite(c)) {
rewind(inf);
break;
}
}
#define LISPCHR ";(["
/* lisp */ if (strchr(LISPCHR, c)) {
l_entries();
return;
}
/* lex */ else {
/*
* we search all 3 parts of a lex file
* for C references. This may be wrong.
*/
toss_yysec();
(void)strcpy(lbuf, "%%$");
pfnote("yylex", lineno);
rewind(inf);
}
}
/* yacc */ else if (cp[1] == 'y' && !cp[2]) {
#ifdef YACC
/*
* we search all part of a yacc file for C references.
* but ignore yacc rule tags.
*/
yaccfile = YES;
c_entries();
return;
#endif
/*
* we search only the 3rd part of a yacc file
* for C references. This may be wrong.
*/
toss_yysec();
(void)strcpy(lbuf, "%%$");
pfnote("yyparse", lineno);
y_entries();
}
/* fortran */ else if ((cp[1] != 'c' && cp[1] != 'h') && !cp[2]) {
#ifdef GTAGS
if (rflag)
fprintf(stderr, "-r option is ignored in fortran file (Warning only)\n");
#endif
if (PF_funcs())
return;
rewind(inf);
}
}
#ifdef YACC
yaccfile = NO;
#endif
/* C */ c_entries();
}
#ifdef GTAGS
#include <db.h>
DB *db;
void
gtagopen()
{
BTREEINFO info;
char *env;
char dbname[200];
strcpy(dbname, ".");
if ((env = getenv("GTAGDBPATH"))) {
strcpy(dbname, env);
}
strcat(dbname, "/GTAGS");
info.flags = 0;
info.cachesize = 500000;
info.maxkeypage = 0;
info.minkeypage = 0;
info.psize = 0;
info.compare = 0;
info.prefix = 0;
info.lorder = 0;
#define O_RDONLY 0x0000 /* open for reading only */
db = dbopen(dbname, O_RDONLY, 0, DB_BTREE, &info);
if (db == 0) {
fprintf(stderr, "GTAGS file needed.\n");
exit(1);
}
}
int
isdefined(skey)
char *skey;
{
DBT dat, key;
int status;
key.data = skey;
key.size = strlen(skey)+1;
status = (*db->get)(db, &key, &dat, 0);
switch (status) {
case RET_SUCCESS:
return(1); /* exist */
case RET_ERROR:
fprintf(stderr, "db->get failed.\n");
exit(1);
case RET_SPECIAL: /* not exist */
break;
}
return 0;
}
void
gtagclose()
{
if (db->close(db)) {
fprintf(stderr, "GTAGS cannot close.(dbclose)\n");
exit(1);
}
}
#endif

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ctags.h 8.3 (Berkeley) 4/2/94
*/
#define bool char
#define YES 1
#define NO 0
#define EOS '\0'
#define ENDLINE 50 /* max length of pattern */
#define MAXTOKEN 250 /* max size of single token */
#ifndef LINE_MAX
#define LINE_MAX 2048
#endif
#define SETLINE {++lineno;lineftell = ftell(inf);}
#define GETC(op,exp) ((c = getc(inf)) op (int)exp)
#define iswhite(arg) (_wht[(unsigned)arg]) /* T if char is white */
#define begtoken(arg) (_btk[(unsigned)arg]) /* T if char can start token */
#define intoken(arg) (_itk[(unsigned)arg]) /* T if char can be in token */
#define endtoken(arg) (_etk[(unsigned)arg]) /* T if char ends tokens */
#define isgood(arg) (_gd[(unsigned)arg]) /* T if char can be after ')' */
typedef struct nd_st { /* sorting structure */
struct nd_st *left,
*right; /* left and right sons */
char *entry, /* function or type name */
*file, /* file name */
*pat; /* search pattern */
int lno; /* for -x option */
bool been_warned; /* set if noticed dup */
} NODE;
extern char *curfile; /* current input file name */
extern NODE *head; /* head of the sorted binary tree */
extern FILE *inf; /* ioptr for current input file */
extern FILE *outf; /* ioptr for current output file */
extern long lineftell; /* ftell after getc( inf ) == '\n' */
extern int lineno; /* line number of current line */
#ifdef GTAGS
extern int eflag; /* -e: '{' at 0 column force function end */
extern int Dflag; /* -D: allow duplicate entrys */
extern int rflag; /* -r: function reference */
#endif /* GTAGS */
extern int dflag; /* -d: non-macro defines */
extern int tflag; /* -t: create tags for typedefs */
extern int vflag; /* -v: vgrind style index output */
extern int wflag; /* -w: suppress warnings */
extern int xflag; /* -x: cxref style output */
extern bool _wht[], _etk[], _itk[], _btk[], _gd[];
extern char lbuf[LINE_MAX];
extern char *lbp;
extern char searchar; /* ex search character */
#ifndef __P
#ifdef __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
int cicmp __P((char *));
void getline __P((void));
void pfnote __P((char *, int));
int skip_key __P((int));
void put_entries __P((NODE *));
void toss_yysec __P((void));
void l_entries __P((void));
void y_entries __P((void));
int PF_funcs __P((void));
void c_entries __P((void));
void skip_comment __P((void));
void gtagopen __P((void));
int isdefined __P((char *));
void gtagclose __P((void));

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)fortran.c 8.3 (Berkeley) 4/2/94";
#endif /* LIBC_SCCS and not lint */
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "ctags.h"
static void takeprec __P((void));
char *lbp; /* line buffer pointer */
int
PF_funcs()
{
bool pfcnt; /* pascal/fortran functions found */
char *cp;
char tok[MAXTOKEN];
for (pfcnt = NO;;) {
lineftell = ftell(inf);
if (!fgets(lbuf, sizeof(lbuf), inf))
return (pfcnt);
++lineno;
lbp = lbuf;
if (*lbp == '%') /* Ratfor escape to fortran */
++lbp;
for (; isspace(*lbp); ++lbp)
continue;
if (!*lbp)
continue;
switch (*lbp | ' ') { /* convert to lower-case */
case 'c':
if (cicmp("complex") || cicmp("character"))
takeprec();
break;
case 'd':
if (cicmp("double")) {
for (; isspace(*lbp); ++lbp)
continue;
if (!*lbp)
continue;
if (cicmp("precision"))
break;
continue;
}
break;
case 'i':
if (cicmp("integer"))
takeprec();
break;
case 'l':
if (cicmp("logical"))
takeprec();
break;
case 'r':
if (cicmp("real"))
takeprec();
break;
}
for (; isspace(*lbp); ++lbp)
continue;
if (!*lbp)
continue;
switch (*lbp | ' ') {
case 'f':
if (cicmp("function"))
break;
continue;
case 'p':
if (cicmp("program") || cicmp("procedure"))
break;
continue;
case 's':
if (cicmp("subroutine"))
break;
default:
continue;
}
for (; isspace(*lbp); ++lbp)
continue;
if (!*lbp)
continue;
for (cp = lbp + 1; *cp && intoken(*cp); ++cp)
continue;
if (cp == lbp + 1)
continue;
*cp = EOS;
(void)strcpy(tok, lbp);
getline(); /* process line for ex(1) */
pfnote(tok, lineno);
pfcnt = YES;
}
/*NOTREACHED*/
}
/*
* cicmp --
* do case-independent strcmp
*/
int
cicmp(cp)
char *cp;
{
int len;
char *bp;
for (len = 0, bp = lbp; *cp && (*cp &~ ' ') == (*bp++ &~ ' ');
++cp, ++len)
continue;
if (!*cp) {
lbp += len;
return (YES);
}
return (NO);
}
static void
takeprec()
{
for (; isspace(*lbp); ++lbp)
continue;
if (*lbp == '*') {
for (++lbp; isspace(*lbp); ++lbp)
continue;
if (!isdigit(*lbp))
--lbp; /* force failure */
else
while (isdigit(*++lbp))
continue;
}
}

View File

@ -0,0 +1,228 @@
.\" Copyright (c) 1987, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)gctags.1 8.1 (Berkeley) 6/6/93
.\"
.Dd June 6, 1993
.Dt GCTAGS 1
.Os BSD 4
.Sh NAME
.Nm gctags
.Nd create a tags file (special command for GLOBAL)
.Sh SYNOPSIS
.Nm gctags
.Op Fl BDFadertuwvx
.Op Fl f Ar tagsfile
.Ar name ...
.Sh DESCRIPTION
.Nm Gctags
makes a tags file for
.Xr ex 1
from the specified C,
Pascal, Fortran,
.Tn YACC ,
lex, and lisp sources.
A tags file gives the locations of specified objects in a group of files.
Each line of the tags file contains the object name, the file in which it
is defined, and a search pattern for the object definition, separated by
white-space.
Using the
.Ar tags
file,
.Xr ex 1
can quickly locate these object definitions.
Depending upon the options provided to
.Nm gctags ,
objects will consist of subroutines, typedefs, defines, structs,
enums and unions.
.Bl -tag -width Ds
.It Fl B
use backward searching patterns
.Pq Li ?...? .
.It Fl D
allow duplicate object names.
.It Fl F
use forward searching patterns
.Pq Li /.../
(the default).
.It Fl a
append to
.Ar tags
file.
.It Fl d
create tags for
.Li #defines
that don't take arguments;
.Li #defines
that take arguments are tagged automatically.
.It Fl e
forece a function to end when reach a '}' at the first column. (C source only)
.It Fl f
Places the tag descriptions in a file called
.Ar tagsfile .
The default behavior is to place them in a file called
.Ar tags .
.It Fl r
locate function references instead of function definitions. GTAGS file is
needed at the current directory. (C source only)
.It Fl t
create tags for typedefs, structs, unions, and enums.
.It Fl u
update the specified files in the
.Ar tags
file, that is, all
references to them are deleted, and the new values are appended to the
file. (Beware: this option is implemented in a way which is rather
slow; it is usually faster to simply rebuild the
.Ar tags
file.)
.It Fl v
An index of the form expected by
.Xr vgrind 1
is produced on the standard output. This listing
contains the object name, file name, and page number (assuming 64
line pages). Since the output will be sorted into lexicographic order,
it may be desired to run the output through
.Xr sort 1 .
Sample use:
.Bd -literal -offset indent
gctags \-v files \&| sort \-f > index
vgrind \-x index
.Ed
.It Fl w
suppress warning diagnostics.
.It Fl x
.Nm gctags
produces a list of object
names, the line number and file name on which each is defined, as well
as the text of that line and prints this on the standard output. This
is a simple index which can be printed out as an off-line readable
function index.
.El
.Pp
Files whose names end in
.Nm \&.c
or
.Nm \&.h
are assumed to be C
source files and are searched for C style routine and macro definitions.
Files whose names end in
.Nm \&.y
are assumed to be
.Tn YACC
source files.
Files whose names end in
.Nm \&.l
are assumed to be lisp files if their
first non-blank character is `;', `(', or `[',
otherwise, they are
treated as lex files. Other files are first examined to see if they
contain any Pascal or Fortran routine definitions, and, if not, are
searched for C style definitions.
.Pp
The tag
.Li main
is treated specially in C programs. The tag formed
is created by prepending
.Ar M
to the name of the file, with the
trailing
.Nm \&.c
and any leading pathname components removed. This
makes use of
.Nm gctags
practical in directories with more than one
program.
.Pp
Yacc and lex files each have a special tag.
.Ar Yyparse
is the start
of the second section of the yacc file, and
.Ar yylex
is the start of
the second section of the lex file.
.Sh FILES
.Bl -tag -width tags -compact
.It Pa tags
default output tags file
.It Pa GTAGS
tags file for GLOBAL
.El
.Sh DIAGNOSTICS
.Nm Gctags
exits with a value of 1 if an error occurred, 0 otherwise.
Duplicate objects are not considered errors.
.Sh SEE ALSO
.Xr ex 1 ,
.Xr vi 1 ,
.Xr gtags 1
.Sh BUGS
.Pp
Recognition of
.Nm functions ,
.Nm subroutines
and
.Nm procedures
for
.Tn FORTRAN
and Pascal is done is a very simpleminded way. No attempt
is made to deal with block structure; if you have two Pascal procedures
in different blocks with the same name you lose.
.Nm Gctags
doesn't
understand about Pascal types.
.Pp
The method of deciding whether to look for C, Pascal or
.Tn FORTRAN
functions is a hack.
.Pp
.Nm Gctags
relies on the input being well formed, and any syntactical
errors will completely confuse it. It also finds some legal syntax
confusing; for example, since it doesn't understand
.Li #ifdef Ns 's
(incidentally, that's a feature, not a bug), any code with unbalanced
braces inside
.Li #ifdef Ns 's
will cause it to become somewhat disoriented.
In a similar fashion, multiple line changes within a definition will
cause it to enter the last line of the object, rather than the first, as
the searching pattern. The last line of multiple line
.Li typedef Ns 's
will similarly be noted.
.Sh HISTORY
The
.Nm Ctags
command appeared in
.Bx 3.0 .
The
.Nm
command appeared in GLOBAL 1.6 .

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)lisp.c 8.3 (Berkeley) 4/2/94";
#endif /* LIBC_SCCS and not lint */
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "ctags.h"
/*
* lisp tag functions
* just look for (def or (DEF
*/
void
l_entries()
{
int special;
char *cp;
char savedc;
char tok[MAXTOKEN];
for (;;) {
lineftell = ftell(inf);
if (!fgets(lbuf, sizeof(lbuf), inf))
return;
++lineno;
lbp = lbuf;
if (!cicmp("(def"))
continue;
special = NO;
switch(*lbp | ' ') {
case 'm':
if (cicmp("method"))
special = YES;
break;
case 'w':
if (cicmp("wrapper") || cicmp("whopper"))
special = YES;
}
for (; !isspace(*lbp); ++lbp)
continue;
for (; isspace(*lbp); ++lbp)
continue;
for (cp = lbp; *cp && *cp != '\n'; ++cp)
continue;
*cp = EOS;
if (special) {
if (!(cp = strchr(lbp, ')')))
continue;
for (; cp >= lbp && *cp != ':'; --cp)
continue;
if (cp < lbp)
continue;
lbp = cp;
for (; *cp && *cp != ')' && *cp != ' '; ++cp)
continue;
}
else
for (cp = lbp + 1;
*cp && *cp != '(' && *cp != ' '; ++cp)
continue;
savedc = *cp;
*cp = EOS;
(void)strcpy(tok, lbp);
*cp = savedc;
getline();
pfnote(tok, lineno);
}
/*NOTREACHED*/
}

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)print.c 8.3 (Berkeley) 4/2/94";
#endif /* LIBC_SCCS and not lint */
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ctags.h"
/*
* getline --
* get the line the token of interest occurred on,
* prepare it for printing.
*/
void
getline()
{
long saveftell;
int c;
int cnt;
char *cp;
saveftell = ftell(inf);
(void)fseek(inf, lineftell, SEEK_SET);
if (xflag)
for (cp = lbuf; GETC(!=, '\n'); *cp++ = c)
continue;
/*
* do all processing here, so we don't step through the
* line more than once; means you don't call this routine
* unless you're sure you've got a keeper.
*/
else for (cnt = 0, cp = lbuf; GETC(!=, EOF) && cnt < ENDLINE; ++cnt) {
if (c == '\\') { /* backslashes */
if (cnt > ENDLINE - 2)
break;
*cp++ = '\\'; *cp++ = '\\';
++cnt;
}
else if (c == (int)searchar) { /* search character */
if (cnt > ENDLINE - 2)
break;
*cp++ = '\\'; *cp++ = c;
++cnt;
}
else if (c == '\n') { /* end of keep */
*cp++ = '$'; /* can find whole line */
break;
}
else
*cp++ = c;
}
*cp = EOS;
(void)fseek(inf, saveftell, SEEK_SET);
}
/*
* put_entries --
* write out the tags
*/
void
put_entries(node)
NODE *node;
{
if (node->left)
put_entries(node->left);
if (vflag)
printf("%s %s %d\n",
node->entry, node->file, (node->lno + 63) / 64);
else if (xflag)
#ifdef MODIFY
/* separate 'entry' and 'lno' */
if (strlen(node->entry) >= 16 && node->lno >= 1000)
printf("%-16s %4d %-16s %s\n",
node->entry, node->lno, node->file, node->pat);
else /* for compatibility */
#endif
printf("%-16s%4d %-16s %s\n",
node->entry, node->lno, node->file, node->pat);
else
fprintf(outf, "%s\t%s\t%c^%s%c\n",
node->entry, node->file, searchar, node->pat, searchar);
if (node->right)
put_entries(node->right);
}

View File

@ -0,0 +1,67 @@
int bar = (1 + 5);
FOO("here is a #define test: ) {");
char sysent[20];
int nsysent = sizeof (sysent) / sizeof (sysent[0]);
/*
* now is the time for a comment.
* four lines in length...
*/struct struct_xtra{int list;};r4(x,y){};typedef struct{int bar;}struct_xxe;
#define FOO BAR
struct struct_three {
int list;
};
#define SINGLE
int BAD();
enum color {red, green, gold, brown};
char qq[] = " quote(one,two) {int bar;} ";
typedef struct {
int bar;
struct struct_two {
int foo;
union union_3 {
struct struct_three entry;
char size[25];
};
struct last {
struct struct_three xentry;
char list[34];
};
};
} struct_one;
#define TWOLINE ((MAXLIST + FUTURE + 15) \
/ (time_to_live ? 3 : 4))
#if (defined(BAR))
int bar;
#endif
#define MULTIPLE {\
multiple(one,two); \
lineno++; \
callroute(one,two); \
}
#if defined(BAR)
int bar;
#endif
union union_one {
struct struct_three s3;
char foo[25];
};
#define XYZ(A,B) (A + B / 2) * (3 - 26 + l_lineno)
routine1(one,two) /* comments here are fun... */
struct {
int entry;
char bar[34];
} *one;
char two[10];
{
typedef unsigned char u_char;
register struct buf *bp;
five(one,two);
}
routine2 (one,two) { puts("hello\n"); }
routine3
(one,
two) { puts("world\n"); }
routine4(int one, char (*two)(void)) /* test ANSI arguments */
{
}

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)tree.c 8.3 (Berkeley) 4/2/94";
#endif /* LIBC_SCCS and not lint */
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ctags.h"
static void add_node __P((NODE *, NODE *));
static void free_tree __P((NODE *));
/*
* pfnote --
* enter a new node in the tree
*/
void
pfnote(name, ln)
char *name;
int ln;
{
NODE *np;
char *fp;
char nbuf[MAXTOKEN];
/*NOSTRICT*/
if (!(np = (NODE *)malloc(sizeof(NODE)))) {
fprintf(stderr, "too many entries to sort");
put_entries(head);
free_tree(head);
/*NOSTRICT*/
if (!(head = np = (NODE *)malloc(sizeof(NODE)))) {
fprintf(stderr, "gctags: out of space\n");
exit(1);
}
}
if (!xflag && !strcmp(name, "main")) {
if (!(fp = strrchr(curfile, '/')))
fp = curfile;
else
++fp;
(void)sprintf(nbuf, "M%s", fp);
fp = strrchr(nbuf, '.');
if (fp && !fp[2])
*fp = EOS;
name = nbuf;
}
if (!(np->entry = strdup(name))) {
fprintf(stderr, "gctags: out of space\n");
exit(1);
}
np->file = curfile;
np->lno = ln;
np->left = np->right = 0;
if (!(np->pat = strdup(lbuf))) {
fprintf(stderr, "gctags: out of space\n");
exit(1);
}
if (!head)
head = np;
else
add_node(np, head);
}
static void
add_node(node, cur_node)
NODE *node,
*cur_node;
{
int dif;
dif = strcmp(node->entry, cur_node->entry);
#ifdef GTAGS
if (!Dflag && !dif) /* -D option allows duplicate entries. */
#else
if (!dif)
#endif
{
if (node->file == cur_node->file) {
if (!wflag)
fprintf(stderr, "Duplicate entry in file %s, line %d: %s\nSecond entry ignored\n", node->file, lineno, node->entry);
return;
}
if (!cur_node->been_warned)
if (!wflag)
fprintf(stderr, "Duplicate entry in files %s and %s: %s (Warning only)\n", node->file, cur_node->file, node->entry);
cur_node->been_warned = YES;
}
else if (dif < 0)
if (cur_node->left)
add_node(node, cur_node->left);
else
cur_node->left = node;
else if (cur_node->right)
add_node(node, cur_node->right);
else
cur_node->right = node;
}
static void
free_tree(node)
NODE *node;
{
while (node) {
if (node->right)
free_tree(node->right);
free(node);
node = node->left;
}
}

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)yacc.c 8.3 (Berkeley) 4/2/94";
#endif /* LIBC_SCCS and not lint */
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "ctags.h"
/*
* y_entries:
* find the yacc tags and put them in.
*/
void
y_entries()
{
int c;
char *sp;
bool in_rule;
char tok[MAXTOKEN];
in_rule = NO;
while (GETC(!=, EOF))
switch (c) {
case '\n':
SETLINE;
/* FALLTHROUGH */
case ' ':
case '\f':
case '\r':
case '\t':
break;
case '{':
if (skip_key('}'))
in_rule = NO;
break;
case '\'':
case '"':
if (skip_key(c))
in_rule = NO;
break;
case '%':
if (GETC(==, '%'))
return;
(void)ungetc(c, inf);
break;
case '/':
if (GETC(==, '*'))
skip_comment();
else
(void)ungetc(c, inf);
break;
case '|':
case ';':
in_rule = NO;
break;
default:
if (in_rule || (!isalpha(c) && c != '.' && c != '_'))
break;
sp = tok;
*sp++ = c;
while (GETC(!=, EOF) && (intoken(c) || c == '.'))
*sp++ = c;
*sp = EOS;
getline(); /* may change before ':' */
while (iswhite(c)) {
if (c == '\n')
SETLINE;
if (GETC(==, EOF))
return;
}
if (c == ':') {
pfnote(tok, lineno);
in_rule = YES;
}
else
(void)ungetc(c, inf);
}
}
/*
* toss_yysec --
* throw away lines up to the next "\n%%\n"
*/
void
toss_yysec()
{
int c; /* read character */
int state;
/*
* state == 0 : waiting
* state == 1 : received a newline
* state == 2 : received first %
* state == 3 : recieved second %
*/
lineftell = ftell(inf);
for (state = 0; GETC(!=, EOF);)
switch (c) {
case '\n':
++lineno;
lineftell = ftell(inf);
if (state == 3) /* done! */
return;
state = 1; /* start over */
break;
case '%':
if (state) /* if 1 or 2 */
++state; /* goto 3 */
break;
default:
state = 0; /* reset */
break;
}
}

View File

@ -0,0 +1,9 @@
# @(#)Makefile 1.0 (Berkeley) 4/21/96
MAN1= global.1
beforeinstall:
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/global.pl ${DESTDIR}/usr/bin/global
.include <bsd.prog.mk>

View File

@ -0,0 +1,130 @@
.\"
.\" Copyright (c) 1996, 1997 Shigio Yamaguchi. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Shigio Yamaguchi.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd Jul 28, 1996
.Dt GLOBAL 1
.Os BSD 4
.Sh NAME
.Nm global
.Nd print the locations of specified function in C and Yacc source files.
.Sh SYNOPSIS
.Nm global
.Op Fl acrx
.Ar name
.Sh DESCRIPTION
.Nm Global
find the locatins of specified function in C and Yacc source files.
.Nm Global
can treat a source tree, that is, a directory that has subdirectories and
source files.
You can get the relative path of objects from anywhere within the tree.
.Nm Global
can locate not only function definitions but also function references and
allow duplicate entries too.
.Pp
In advance of using this command, you must execute
.Xr gtags 1
at the root directory of the source tree.
.Pp
The following options are available:
.Bl -tag -width Ds
.It Fl a
print absolute path name. By default, print relative path name.
.It Fl c
print candidate function names which start with specified string.
If string is not specified, print all function names.
.It Fl r
print the locations of function references. By default, print function
definitions.
.It Fl x
In addition to the default output, produce the line number and
the line contents.
.It Ar name
function name. It can include perl's regular expression.
.Sh FILES
.Bl -tag -width tags -compact
.It Pa GTAGS
tags file for function definitions.
.It Pa GRTAGS
tags file for function references.
.El
.Sh ENVIRONMENT
The following environment variables affect the execution of global.
.Pp
.Bl -tag -width indent
.It Ev GTAGSROOT
The directory which is the root of source tree.
.It Ev GTAGSDBPATH
The directory on which gtags database exist. This value is ignored
when GTAGSROOT is not defined.
.It Ev GTAGSLIBPATH
If this variable is set, its value is used as the path to search for library
functions. If specified function is not found in a source tree,
global search in these path too.
.Sh EXAMPLES
% ls -F
Makefile src/ lib/
% gtags
% global main
src/main.c
% global -x main
main 10 src/main.c main (argc, argv) {
% global -x '^[sg]et'
set_num 20 lib/util.c set_num(values)
get_num 30 lib/util.c get_num() {
% global -rx '^[sg]et'
set_num 113 src/op.c set_num(32);
set_num 225 src/opop.c if (set_num(0) > 0) {
get_num 90 src/op.c while (get_num() > 0) {
% cd lib
% global -rx '^[sg]et'
set_num 113 ../src/op.c set_num(32);
set_num 225 ../src/opop.c if (set_num(0) > 0) {
get_num 90 ../src/op.c while (get_num() > 0) {
% global strlen
% (cd /usr/src/sys; gtags)
% setenv GTAGSLIBPATH /usr/src/sys
% global strlen
../../../usr/src/sys/libkern/strlen.c
% (cd /usr/src/lib; gtags)
% setenv GTAGSLIBPATH /usr/src/lib:/usr/src/sys
% global strlen
../../../usr/src/lib/libc/string/strlen.c
.Sh DIAGNOSTICS
.Nm Global
exits with a non 0 value if an error occurred, 0 otherwise.
.Sh SEE ALSO
.Xr gtags 1 ,
.Xr btreeop 1
.Sh AUTHORS
Shigio Yamaguchi (shigio@wafu.netgate.net)

View File

@ -0,0 +1,213 @@
#!/usr/bin/perl
#
# Copyright (c) 1996, 1997 Shigio Yamaguchi. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Shigio Yamaguchi.
# 4. Neither the name of the author nor the names of any co-contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# global.pl 14-Apr-97
#
sub getcwd {
local($dir);
chop($dir = `/bin/pwd`);
$dir;
}
$com = $0;
$com =~ s/.*\///;
$usage = "usage:\t$com [-a][-r][-x] pattern\n\t$com -c [name]\n";
#
# options check
#
while ($ARGV[0] =~ /^-/) {
$opt = shift;
if ($opt =~ /a/) { $aflag = 1; }
if ($opt =~ /c/) { $cflag = 1; }
if ($opt =~ /r/) { $rflag = 1; }
if ($opt =~ /x/) { $xflag = 1; }
}
if (@ARGV == 0) {
die($usage) if (! $cflag);
} elsif ($ARGV[0] =~ /[][.*\^\$+?|(){}\\]/) { # include regular expression ?
$regex = 1;
}
if ($cflag) {
die($usage) if ($aflag || $rflag || $xflag);
die("$com: regular expression not allowed with -c option.\n") if ($regex);
}
$current = &getcwd;
#
# get $dbpath and $root
#
if (defined($ENV{'GTAGSROOT'})) {
$root = $ENV{'GTAGSROOT'};
if (defined($ENV{'GTAGSDBPATH'})) {
$dbpath = $ENV{'GTAGSDBPATH'};
} else {
$dbpath = $root;
}
unless ($current =~ /$root/) {
die("$com: illegal GTAGSROOT.\n");
}
chdir($dbpath) || die("$com: directory $dbpath not found.\n");
$dbpath = &getcwd;
chdir($current);
chdir($root) || die("$com: directory $root not found.\n");
$root = &getcwd;
}
chdir($current) || die("$com: cannot return current directory.\n");
$gtagsname = ($rflag) ? 'GRTAGS' : 'GTAGS';
#
# make a sed command to make paths into relative
#
if (! defined($root)) {
chdir($current);
while (! -r $gtagsname && ! -r "obj/$gtagsname") {
if (&getcwd =~ m!^/$!) { die "$com: $gtagsname not found.\n"; }
chdir('..');
}
$dbpath = $root = &getcwd;
$dbpath = "$dbpath/obj" if (! -r $gtagsname);
}
$cur = $current;
$cur =~ s!$root!!;
$cur =~ s!^/!!;
@step = split('/', $cur);
$downpath = '\\.\\./' x @step;
push(@com, "-e 's!\\./!$downpath!'");
foreach $step (@step) {
push(@com, "-e 's!\\.\\./$step/!!'");
}
#
# complete function name
#
if ($cflag) {
open(PIPEIN, "btreeop $dbpath/GTAGS | awk '{print \$1}' | sort | uniq |") || die("$com: btreeop cannot exec.\n");
while (<PIPEIN>) {
print if (@ARGV == 0 || $_ =~ /^$ARGV[0]/o);
}
close(PIPEIN);
exit(0);
}
#
# search in current source tree.
#
$cnt = &search($ARGV[0], $dbpath, $gtagsname, @com);
#
# search in library path.
#
if ($cnt == 0 && ! $regex && ! $rflag && defined($ENV{'GTAGSLIBPATH'})) {
foreach $lib (split(':', $ENV{'GTAGSLIBPATH'})) {
next unless (-f "$lib/GTAGS");
next if ($dbpath eq $lib);
chdir($lib) || die("$com: cannot chdir to $lib.\n");
$dbpath = &getcwd;
$common = &common($dbpath, $current);
$up = $dbpath;
$up =~ s/$common//;
$down = $current;
$down =~ s/$common//;
$down =~ s![^/]+!..!g;
next if ($down eq '' || $up eq '');
$cnt = &search($ARGV[0], $dbpath, 'GTAGS', ("-e 's!\\./!$down/$up/!'"));
last if ($cnt > 0);
}
}
exit(0);
#
# common: extract a common part of two paths.
#
# i) $p1, $p2 paths
# r) common part
#
sub common {
local($p1, $p2) = @_;
local(@p1, @p2, @common, $common);
@p1 = split('/', $p1);
@p2 = split('/', $p2);
while (@p1 && @p2 && $p1[0] eq $p2[0]) {
push(@common, shift @p1);
shift @p2;
}
$common = join('/', @common);
$common .= '/';
$common;
}
#
# search: search specified function
#
# i) $pattern search pattern
# i) $dbpath where GTAGS exist
# i) $gtagsname gtags name (GTAGS or GRTAGS)
# i) @com sed's command
# gi) $xflag -x option
# gi) $rflag -r option
# gi) $regex regular expression
# r) count of output lines
#
sub search {
local($pattern, $dbpath, $gtagsname, @com) = @_;
local($cnt);
#
# make input filter
#
if ($regex) { # regular expression
$infilter = "btreeop $dbpath/$gtagsname |";
} else {
$infilter = "btreeop -K '$pattern' $dbpath/$gtagsname |";
}
#
# make output filter
# gtags fields is same to ctags -x format.
# 0:tag, 1:lineno, 2:filename, 3: pattern.
#
if ($xflag) {
$outfilter = "| sort +0b -1 +2b -3 +1n -2";
} else {
$outfilter = "| awk '{print \$3}' | sort | uniq";
}
#
# if absolute path needed
#
if ($aflag) {
@com = ("-e 's!\\.!$dbpath!'");
}
$outfilter .= "| sed @com";
open(PIPEIN, $infilter) || die("$com: database not found.\n");
open(PIPEOUT, $outfilter) || die("$com: pipe cannot open.\n");
$cnt = 0;
while (<PIPEIN>) {
($tag) = split;
if (! $regex || $tag =~ /$pattern/o) {
$cnt++;
print PIPEOUT $_;
}
}
close(PIPEIN);
close(PIPEOUT);
$cnt;
}

View File

@ -0,0 +1,9 @@
# @(#)Makefile 1.0 (Berkeley) 4/21/96
MAN1= gtags.1
beforeinstall:
install -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/gtags.sh ${DESTDIR}/${BINDIR}/gtags
.include <bsd.prog.mk>

View File

@ -0,0 +1,81 @@
.\"
.\" Copyright (c) 1996, 1997 Shigio Yamaguchi. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Shigio Yamaguchi.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd Feb 17, 1997
.Dt GTAGS 1
.Os BSD 4
.Sh NAME
.Nm gtags
.Nd create GTAGS, GRTAGS file
.Sh SYNOPSIS
.Nm gtags
.Op Fl e
.Op Fl s
.Op Ar dbpath
.Sh DESCRIPTION
.Nm Gtags
makes GTAGS, GRTAGS files for global(1).
.Nm Gtags
trace subdirectories, read source files,
locate the functions and save the information into tag files.
C, yacc and assembler source files are supported.
You should execute this command at the root of the source tree.
.Pp
If your source directory is on a read only device like CDROM, specify
.Ar dbpath
of the directory on which make tags files.
.Pp
.Bl -tag -width Ds
.It Fl e
force a function to end when reach a '}' at the first column in C source file.
.It Fl s
treat assembler source file (*.s, *.S).
.Sh FILES
.Bl -tag -width tags -compact
.It Pa GTAGS
tags file for function definitions.
.It Pa GRTAGS
tags file for function references.
.El
.Sh DIAGNOSTICS
.Nm Gtags
exits with a value of 1 if an error occurred, 0 otherwise.
.Sh SEE ALSO
.Xr global 1 ,
.Xr btreeop 1 ,
.Xr gctags 1
.Sh BUG
GTAGS, GRTAGS are very large. In advance, check the space of your disk.
Assembler support is far from completeness. It extracts only ENTRY()
and ALTENTRY() from source file. Probably valid only for FreeBSD and Linux
kernel source.
.Sh AUTHORS
Shigio Yamaguchi (shigio@wafu.netgate.net)

View File

@ -0,0 +1,98 @@
#!/bin/sh
#
# Copyright (c) 1996, 1997 Shigio Yamaguchi. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Shigio Yamaguchi.
# 4. Neither the name of the author nor the names of any co-contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# gtags.sh 17-Feb-97
#
com=`echo $0 | sed 's/.*\///'` # command name
usage="usage: $com [-e][-s][dbpath]"
#
# ctags flag
#
eflag=
sflag=
while :; do
case $1 in
-*)
if echo $1 | grep '[^-es]' >/dev/null; then
echo $usage >/dev/tty; exit 1
fi
case $1 in
-*e*) eflag=e;;
esac
case $1 in
-*s*) sflag=1;;
esac
shift;;
*)
break;;
esac
done
export eflag sflag
case $1 in
"") dbpath=".";;
*) dbpath=$1;;
esac
if [ -f $dbpath/GTAGS -a -f $dbpath/GRTAGS ]; then
if [ ! -w $dbpath/GTAGS ]; then
echo "$com: cannot write to GTAGS."
exit 1
elif [ ! -w $dbpath/GRTAGS ]; then
echo "$com: cannot write to GRTAGS."
exit 1
fi
elif [ ! -w $dbpath ]; then
echo "$com: cannot write to the directory $dbpath."
exit 1
fi
#
# make global database
#
for db in GTAGS GRTAGS; do
# currently only *.c *.h *.y are supported.
# *.s *.S is valid only when -s option specified.
find . -type f -name "*.[chysS]" -print | while read f; do
case $f in
*y.tab.c|*y.tab.h)
continue;;
*.s|*.S)
[ ${sflag}x = x -o $db = GRTAGS ] && continue
perl -ne '($nouse, $tag) = /^(ENTRY|ALTENTRY)\((\w+)\)/;
if ($tag) {printf("%-16s%4d %-16s %s", $tag, $., $ARGV, $_)} ' $f
continue;;
esac
case $db in
GRTAGS) flag=${eflag}Dxr;;
GTAGS) flag=${eflag}Dx;;
esac
GTAGDBPATH=$dbpath gctags -$flag $f || exit 1
done | btreeop -C $dbpath/$db
done
exit 0

View File

@ -0,0 +1,9 @@
# @(#)Makefile 1.0 (Berkeley) 4/21/96
MAN1= htags.1
beforeinstall:
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/htags.pl ${DESTDIR}/usr/bin/htags
.include <bsd.prog.mk>

View File

@ -0,0 +1,99 @@
.\"
.\" Copyright (c) 1996, 1997 Shigio Yamaguchi. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Shigio Yamaguchi.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd Feb 17, 1997
.Dt HTAGS 1
.Os BSD 4
.Sh NAME
.Nm htags
.Nd generate hypertext from C and Yacc source code
.Sh SYNOPSIS
.Nm htags
.Op Fl a
.Op Fl v
.Op Fl w
.Op Fl d Ar tagdir
.Op Fl t Ar title
.Op Ar dir
.Sh DESCRIPTION
.Nm Htags
makes hypertext from C and Yacc source code using GLOBAL database.
.Pp
In advance of using this command, you must execute
.Xr gtags 1
at the root directory of the source tree.
Then you can execute
.Nm htags
at the same place.
.Nm Htags
makes HTML directory and generate hypertext in it.
.Pp
You can start browsing from 'HTML/index.html'.
Once hypertext generated, you can move it anywhere and browse it
by any browsers.
.Pp
.br
.Bl -tag -width Ds
.It Fl a
make alphabetical function index. It's suitable to large project.
.It Fl v
verbose mode.
.It Fl w
print warning message.
.It Fl d Ar tagdir
the directory in which GTAGS and GRTAGS exist. Default is current directory.
.It Fl t Ar title
Tile of this hypertext. Default is the last conponent of current path.
.It Ar dir
the directory in which hypertext generated. Default is current directory.
.Sh EXAMPLES
% cd /usr/src/sys
# gtags -se
# htags -vat 'Welcom to FreeBSD kernel source tour!'
% lynx HTML/index.html
.Sh FILES
.Bl -tag -width tags -compact
.It Pa HTML/index.html
Index file.
.It Pa GTAGS
tags file for function definitions.
.It Pa GRTAGS
tags file for function references.
.El
.Sh DIAGNOSTICS
.Nm Htags
exits with a value of 1 if an error occurred, 0 otherwise.
.Sh SEE ALSO
.Xr gtags 1 ,
.Xr btreeop 1
.Sh BUG
Generated hypertext is VERY LARGE. In advance, check the space of your disk.
.Sh AUTHORS
Shigio Yamaguchi (shigio@wafu.netgate.net)

1043
usr.bin/global/htags/htags.pl Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
# @(#)Makefile 1.0 (Berkeley) 4/21/96
beforeinstall:
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/systags.sh ${DESTDIR}/usr/bin/systags
.include <bsd.prog.mk>

View File

@ -0,0 +1,83 @@
#!/bin/sh
#
# Copyright (c) 1997 Shigio Yamaguchi. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Shigio Yamaguchi.
# 4. Neither the name of the author nor the names of any co-contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# systags.sh 17-Feb-97
#
# script to make hypertext of kernel source.
# supporting FreeBSD and Linux.
#
case $1 in
-n) nflag=1; shift;;
esac
case $1 in
"") dir=.;;
*) dir=$1;;
esac
#
# get release number from source tree.
#
if [ -f conf/newvers.sh ]; then
os=FreeBSD
release=`awk -F= '/^RELEASE=/ {print $2}' < conf/newvers.sh`
elif [ -f Makefile ] && grep '^vmlinux:' Makefile >/dev/null; then
os=Linux
version=`awk -F= '/^VERSION *=/ {print $2}' < Makefile`
patchlevel=`awk -F= '/^PATCHLEVEL *=/ {print $2}' < Makefile`
sublevel=`awk -F= '/^SUBLEVEL *=/ {print $2}' < Makefile`
release=`echo "$version.$patchlevel.$sublevel" | tr -d ' '`
fi
#
# remove old files
#
case $nflag in
1) echo "rm -rf $dir/htags.log $dir/GTAGS $dir/GRTAGS $dir/HTML";;
*) rm -rf $dir/htags.log $dir/GTAGS $dir/GRTAGS $dir/HTML;;
esac
#
# make global database(GTAGS, GRTAGS).
#
case $nflag in
1) echo "gtags -se $dir";;
*) gtags -se $dir;;
esac
#
# make hypertext.
# (please replace this title with a suitable one.)
#
case $os$release in
"") program=`/bin/pwd | sed 's/.*\///'`
title="Welcome to $program source tour!";;
*) title="Welcome to $os $release kernel source tour!";;
esac
case $nflag in
1) echo "htags -vwat '$title' -d $dir $dir > $dir/htags.log 2>&1";;
*) htags -vwat "$title" -d $dir $dir> $dir/htags.log 2>&1;;
esac