[comp.lang.vhdl] vhdl tags generator

battle@prang.TEST.Vitalink.COM (Jim Battle) (01/24/91)

Included below is a small script to generate a "tags" file for vhdl source.
I wrote it for my own purposes and so isn't very general, but I've posted
it since it is easy to modify to your own liking.  If someone can present
a better solution (generalized parsing, better support for overloads, etc)
please pass it on.

In case you don't know about the tags concept read the "TAGS INFO" section,
otherwise skip on to the next section, "SHORTCOMINGS."

***TAGS INFO***

For example, say you are editing a file and see the line:

    SOMEVAR <= MYFUNC(ARG1,ARG2);

and you want to take a quick look at MYFUNC.  Usually you'd have to remember
what file it is in and then type ":e myfunc_bod.vhd" and then scroll through
the file until you see the function MYFUNC.

If you have a "tags" database in the directory, there is a 1-keystroke way
to do all this.  Simply place the cursor on the "M" of "MYFUNC" and then
hit the '^]' key.  VI consults the database, loads in the file where MYFUNC
is located, and jumps the cursor to the line where MYFUNC is defined.  You
can also use the command line by typing ":tag MYFUNC".

One other nice feature of tags is that every time you make a link to a new
file, vi keeps track of where you came from on the "tag stack."  So if you
see something, and ":tag" to it, and while poking around you ":tag" to
something else, you can move back by typing ":pop", which puts you back
in the previous file on the line you were editing.  You can the ":pop" again
until you get back to the original.

For the format of the tags database, see "man ctags".  Consult a vi guide
for more tag-related commands (vi -t, :set tags=...).

***SHORTCOMINGS***

The tags mechanism is used mostly with C programs, although others are
supported.  One fundamental problem is that vhdl has the ability to overload,
but the tags mechanism is too simple to distinguish two functions with the
same name.

The script below works only for my style of coding; you will probably have to
change the embedded awk program to make it work with your source.

***USAGE***

Note that the "ctags" program usually just builds a database of functions,
whereas my script below also includes type and subtype definitions.  This
is handy for looking up the meaning of global constants and such.

To use it,
   cut out the script below (& modify it if necessary)
      (note there is an embedded tab)
   save it as 'vtags' somewhere in your path
   chmod +x vtags
   cd <vhdl working directory>
   vtags *.vhdl (or vtags *.vhd, whatever your suffix is)

This should produce a file named "tags" in the directory.  You make want
to look at it to see if it has what you want.  Then try

   vi -t <function name>

and see if vi comes up editing the file containing the named function.

***SOURCE***

--- cut here ---
#!/bin/csh -f

# simple program to generate a tags file for VHDL code
# this only understands my format for VHDL code
# (i.e., assumes entity name immediately follows word "entity")
#
# also, overloaded functions and operators don't work

set tfile = /tmp/vtag_$$

onintr cleanup

if ($#argv == 0) goto usage
set first=`echo $argv[1] | awk '{print substr($0,1,1) }'`
if ("$first" == "-") goto usage

# erase tags file
cat /dev/null > $tfile

# process each tag file in the list
foreach fln ( $* )
if (! -e $fln) then
	echo "Can't open file '$fln'"
	continue
endif
awk 'BEGIN { OFS="	" } # a tab \
#    /^ *entity / { print $2,FILENAME,"/^" $0 "$/"; } \
    /^ *architecture / { print $4,FILENAME,"/^" $0 "$/"; } \
    /^ *type / { print $2,FILENAME,"/^" $0 "$/"; } \
    /^ *subtype / { print $2,FILENAME,"/^" $0 "$/"; } \
    /^ *constant / { print $2,FILENAME,"/^" $0 "$/"; } \
    /^ *function .* is/ {for(i=1;substr($2,i,1)!="(" && i<length($2);i++); \
			  print substr($2,1,i-1),FILENAME,"/^" $0 "$/"; } \
    /^ *procedure .* is/ {for(i=1;substr($2,i,1)!="(" && i<length($2);i++); \
			  print substr($2,1,i-1),FILENAME,"/^" $0 "$/"; } \
	' $fln >> $tfile
end

sort $tfile > tags

cleanup:
	rm -f $tfile
	exit 0

usage:
	echo "usage: $0 filename1 [ filename2 [ ... ] ]"
	exit 1

--- end of script ---

I can supposedly be reached at battle@eng.vitalink.com.