blob: 9524152794de35a3758b660e83558e12c7e971d7 [file] [log] [blame]
#!/bin/sh
# vim:ts=4:
# Generates a tag file for TCL code. Slow, but gets the job done.
#
# Written by Darren Hiebert <darren@hiebert.com>
program_name=`basename $0`
program_version="0.3"
program_author="Darren Hiebert"
author_email="darren@hiebert.com"
tmp_tagfile=/tmp/${program_name}.$$
usage="\
Usage: $program_name [-au] [-{f|o} tagfile] [--format=n] file(s)
-a append to current tag file
-f tagfile specify output tag file name (default=tags)
-o alternative for -f
-u unsorted
--format=n specify tag file format (default=2)
--help print this help message
"
# defaults
#
append=0
format=2
sorted=1
tagfile=tags
filelist=
# read options
#
getparam()
{
if [ -n "$1" ]; then
# set variable to word passed in
echo "$2='$1'; opt="
else
# set variable to next word on command line
echo "$2="'$1'"; shift"
fi
}
finished=0
while [ $# -gt 0 -a $finished -eq 0 ]
do
case "$1" in
--*)
opt=`echo "$1" | cut -c 3-`
shift
opt_name=`echo "$opt" | awk -F= '{print $1}'`
opt_value=`echo "$opt" | awk -F= '{print $2}'`
case "$opt_name" in
format) case "$opt_value" in
1|2) format=$opt_value;;
*) echo "--$opt: unsupported value" >&2; exit 1;;
esac
;;
help) echo "$usage"; exit 0;;
*) echo "$opt_name: unsupported option" >&2; exit 1;;
esac
;;
-*)
# chop off leading '-'
opt=`echo "$1" | cut -c 2-`
shift
while [ -n "$opt" ]
do
opt_char=`echo "$opt" | cut -c 1`
opt=`echo "$opt" | cut -c 2-`
case "$opt_char" in
a) append=1;;
u) sorted=0;;
o|f) eval `getparam "$opt" tagfile`;;
*) echo "$opt: unsupported option" >&2; exit 1;;
esac
done
;;
*) filelist="$*"; break;;
esac
done
if [ -z "$filelist" ] ;then
echo "$usage" >&2; exit 1
fi
# awk program for generating tags
#
ext_flags=""
ttype=""
if [ $format -eq 2 ] ;then
ext_flags=';\" %s'
ttype=", type"
fi
awkprg='
function trim_comment(string) {
comment = index(string, "#")
if (comment != 0)
string = substr(string, 0, comment-1)
return string
}
function maketag(tagname, pattern, type, line_end) {
gsub(/\\/, "\\\\", pattern)
gsub(/\//, "\\/", pattern)
if (line_end)
terminator="$"
else
terminator=""
printf("%s\t%s\t/^%s%s/'"$ext_flags"'\n", \
tagname, FILENAME, pattern, terminator'"$ttype"')
}
$1 == "proc" && $3 ~ /^{/ {
pattern = substr($0, 0, index($0, "{"))
maketag($2, pattern, "f", 0)
}
/^set[ \t]/ && $2 !~ /\(/ {
pattern = substr($0, 0, index($0, $2) + length($2))
maketag($2, pattern, "v", 0)
}
/^array[ \t]*set[ \t]/ && $3 !~ /\(/ {
pattern = substr($0, 0, index($0, $3) + length($3))
maketag($3, pattern, "v", 0)
}'
# add or correct the pseudo tags
#
if [ "$tagfile" != "-" ] ;then
if [ $append -eq 1 ]; then
# ensure existing sort flag is correct
sed -e "/^!_TAG_FILE_SORTED/s/ [01] / $sorted /" \
-e "/^!_TAG_FILE_FORMAT/s/ 1 / $format /" \
$tagfile > $tmp_tagfile
else
echo -ne "\
!_TAG_FILE_FORMAT $format /extended format; --format=1 will not append ;\" to lines/
!_TAG_FILE_SORTED $sorted /0=unsorted, 1=sorted/
!_TAG_PROGRAM_AUTHOR $program_author /$author_email/
!_TAG_PROGRAM_NAME $program_name //
!_TAG_PROGRAM_VERSION $program_version //
" > $tmp_tagfile
fi
fi
# generate tags
#
awk "$awkprg" $filelist >> $tmp_tagfile
if [ $sorted -eq 1 ] ;then
sort -u -o $tmp_tagfile $tmp_tagfile
fi
if [ "$tagfile" = '-' ] ;then
cat $tmp_tagfile
else
cp $tmp_tagfile $tagfile
fi
rm $tmp_tagfile
exit 0