#!/bin/sh # vim:ts=4: # Generates a tag file for TCL code. Slow, but gets the job done. # # Written by Darren Hiebert program_name=`basename $0` program_version="0.3" program_author="Darren Hiebert" author_email="darren@hiebert.com" tmp_tagfile=`mktemp -t tcltagXXXXXX` || exit 1 trap "rm -rf $tmp_tagfile" 0 1 2 3 9 11 13 15 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