[net.sources] making 'ctags -x' useful

rgenter@Diamond.BBN.COM (Rick Genter) (01/15/87)

The program 'ctags' distributed on BSD and SunOS systems (and maybe System V;
I don't know) has an option '-x' which produces an alphabetized cross-reference
listing.  Unfortunately, it assumes that names of routines are going to be
pretty short, so quite often the cross-reference looks like:

	short_name	245 foo.c	int short_name ()
	a_long_and_descriptive_name2965 foo.d int a_long_and_descriptive_name()

Also, unless you have a really condensed coding style, the part of the listing
which shows the defining line (the "int short_name ()" in the above example)
is usually truncated and/or useless.  I have a shell script and awk script 
which gets around this, allowing 40 columns for the name and deleting the
"descriptive" text.

The shell script is a one-liner, consisting of:

	ctags -x $* | sort -f | awk -f /usr/rgenter/lib/fixtags.awk

Obviously the work is done in the awk script "fixtags.awk".  Here it is,
unshar'd.  Real Men edit news articles (preferably with sed) to extract the
scripts/programs contained therein :-).

*start*of*fixtags.awk*
BEGIN {
	prev_first = ""
	upper[ "a" ] = "A" ; upper[ "b" ] = "B" ; upper[ "c" ] = "C"
	upper[ "d" ] = "D" ; upper[ "e" ] = "E" ; upper[ "f" ] = "F"
	upper[ "g" ] = "G" ; upper[ "h" ] = "H" ; upper[ "i" ] = "I"
	upper[ "j" ] = "J" ; upper[ "k" ] = "K" ; upper[ "l" ] = "L"
	upper[ "m" ] = "M" ; upper[ "n" ] = "N" ; upper[ "o" ] = "O"
	upper[ "p" ] = "P" ; upper[ "q" ] = "Q" ; upper[ "r" ] = "R"
	upper[ "s" ] = "S" ; upper[ "t" ] = "T" ; upper[ "u" ] = "U"
	upper[ "v" ] = "V" ; upper[ "w" ] = "W" ; upper[ "x" ] = "X"
	upper[ "y" ] = "Y" ; upper[ "z" ] = "Z"
}

{
	first_letter = substr ($1, 1, 1)
	if ( first_letter >= "a" && first_letter <= "z" )
		first_letter = upper[ first_letter ]

	if ( first_letter != prev_first ) {
		prev_first = first_letter
		print " "
		print prev_first
	}

	if ( substr ($2, length ($2), 1) < "0" || \
	     substr ($2, length ($2), 1) > "9" ) {
		for ( i = length ($1) ; i > 0 ; i-- ) {
			if ( substr ($1, i, 1) < "0" || \
			     substr ($1, i, 1) > "9" ) {
				printf ("%-40s%5.5s   %s\n", \
					substr ($1, 1, i), \
					substr ($1, i + 1, length ($1) - i), \
					$2)
				next
			}
		}

		printf ("fixtags: botch '%s'\n", $0)
		next
	}

	printf ("%-40s%5d   %s\n", $1, $2, $3)
}
*end*of*fixtags.awk*

Enjoy.  The only case it won't fix (and there is no way to fix it) is the one
that shows as:

	a_long_and_descriptive_name2965 foo.c

where the name of the routine is "a_long_and_descriptive_name2".
-- 
Rick Genter 				BBN Laboratories Inc.
(617) 497-3848				10 Moulton St.  6/512
rgenter@bbn.COM  (Internet new)		Cambridge, MA   02238
rgenter@bbnj.ARPA (Internet old)	seismo!bbn.com!rgenter (UUCP)