Converting long variable names to names <8 characters

Jean-Pierre Radley jpr at jpradley.uucp
Sun Oct 14 09:31:22 AEST 1990


In article <1091 at ria.ccs.uwo.ca> peter at ria.ccs.uwo.ca (Peter Marshall) writes:
>
>Most code these days uses variables that have more than 8 significant
>characters.  I recently purchased a system (a convergent CG1000
>Miniframe -- a Motorola 68010 based system) that has a compiler that
>has the original 8 character limit on variable names.  I haven't been
>able to find a conversion routine that would systematically convert
>long names to shorter ones.  Is there such a beast?
>
>One of the primary candidates for conversion would be the gcc
>compiler.  Once it is running, I suspect that file name problems would
>be either eliminated or at least reduced (I have not yet determined
>the limitations of the linker).  Is there either a version of gcc that
>has been hand converted to 8 character names or a binary that would be
>compatible with my machine available?


By our late friend Fred Buck:


:
# Name: unique_nms
#
# Usage: unique_nms [ -y ] [ -v ] [ tagfilename ]
#
# Description: from the set of C source files in the current directory
# (i.e., *.c and *.h), detects function names that aren't unique within
# their first seven characters, and rewrites each reference to such
# functions (including their definitions) with a unique prefix.
#
# If a tagfilename is specified, then the specified tagfilename is
# taken to be a file created by 'ctags', representing the contents of
# the C source files in the current directory, and up to date.  If no
# tagfilename is specified, "tags" is assumed to be the tagfilename.
# The script prompts for whether to restrict the edit to the files
# specifically mentioned in the tagfile, regardless of whether a
# tagfilename is specified on the command line.
#
# If the "-y" (for "yes" or "affirmative") switch is present, no
# prompting will occur; the responses to all ordinary prompts will be
# assumed to be "yes".
#
# If the "-v" (for "void") switch is present, then if a tags file must
# be built, it will be built from copies of the specified source files
# with references to the "void" type removed.  This is for versions of
# 'ctags' that don't know about the "void" data type.  The implementation
# is crude, requiring a physical copy of each source file so as not to
# disturb the original.  The Tandy 6000 requires this switch for any
# source fileset that contains "void" functions.
#
# Notes: this script generates a 'sed' scriptfile called "sedfile$$"
# where "$$" is the current process number.  This file can be referred
# to to keep track of changes made in the original source files; it's
# pretty easy to reverse the changes made by this script with simple
# massaging of the sedfile and re-running 'sed'.
#
# Copyright: this script was written by Fred Buck, who hereby releases
# it into the public domain and expressly waives all copyright or
# similar rights with respect to it.  This script is public property.
# However, liability is disclaimed for any consequences of use of
# this script.

trap "rm -f TEMP$$ *@ tags$$ /tmp/tag$$; exit 1" 1 2 15

# affirmative mode?
if [ $# -gt 0 -a "$1" = "-y" ]
then
	AFFIRM="yes"
	shift
else
	AFFIRM="no"
fi

# anti-void mode?
if [ $# -gt 0 -a "$1" = "-v" ]
then
	VOID="yes"
	shift
else
	VOID="no"
fi


# usage section
case $# in
0)
	TAGFILE="tags"				;;
1)	if [ ! -r $1 ]
	then
		echo "$0: can't open $1"
		exit 1
	else
		TAGFILE="$1"
	fi					;;
*)	echo "usage: $0 [ -y ] [ -v ] [ tagfilename ]"
	exit 1					;;
esac

# check for readability of specified tags file
if [ ! -r "$TAGFILE" ]
then
	if [ "$AFFIRM" = "no" ]
	then
		echo -n "'tags' file doesn't exist; generate it? "
		read yesno
		case $yesno in
			[Yy]*)					;;
			*)	echo "can't work without a tags file"
			exit 1					;;
		esac
	fi
	echo "calling 'ctags'....."
	if [ "$VOID" = "no" ]
	then
		ctags *.c *.h
	else
		for SFILE in *.c *.h
		do
			0<$SFILE sed \
				-e 's/^void//'\
				-e 's/^static void/static/'\
			1>$SFILE@
		done
		ctags *.c@ *.h@
		mv tags tags$$
		TAGFILE=/tmp/tag$$
		0<tags$$ sed 's/@//' 1>$TAGFILE
		rm tags$$
	fi
else
	echo "The tags file is stamped as follows:"
	echo
	ls -l ./$TAGFILE
	echo
	if [ "$AFFIRM" = "no" ]
	then
		echo -n "Use it? "
		read yesno
		case $yesno in
		[Yy]*)		echo "OK."				;;
		*)		echo "can't work without a tags file"
				exit 1					;;
		esac
	fi
fi

# get to work

				# first, find names ambiguous in 1st 7 chars;
				# and build a sed scriptfile to disambiguate 'em
				# (scriptfile will be sedfile$$).  This logic
				# will accommodate up to about seventeen
				# thousand ambiguous function names, with
				# gradually increasing probability that
				# some "[A-Z][A-Z][A-Z]_*" names may become
				# ambiguous.
echo "Building edit scriptfile for ambiguous function names....."
0<$TAGFILE awk '
	BEGIN {
		a = "ABCDEFGFHIJKLMNOPQRSTUVWXYZ"
		i1 = 1
		i2 = 0
		i3 = 0
		l1 = 1
		l2 = 0
		l3 = 0
	}
	{ if (substr($1,1,7) == prevsub) {
		prefix = substr(a,i3,l3) substr(a,i2,l2) substr(a,i1,l1)
		printf "s/^%s(/%s_&/\n", $1, prefix
		printf "s/\\([^_]\\)\\(%s(\\)/\\1%s_\\2/g\n", $1, prefix
		printf "s/\\([, \t]\\)\\(%s[^A-Za-z0-9_]\\)/\\1%s_\\2/g\n", \
			$1, prefix
		++i1
		if (i1 > 26) {
			i1 = 1
			++i2
			l2 = 1
		}
		if (i2 > 26) {
			i2 = 1
			++i3
			l3 = 1
		}
		if (i3 > 26) exit(1)
	  }
	}
	{ prevsub = substr($1,1,7)
	}'				1>sedfile$$

	if [ $? -gt 0 ]
	then
		echo "Fatal error: 'awk' failure" 1>&2
		exit 1
	fi

				# if the sedfile is empty, bail out
if [ ! -s sedfile$$ ]
then
	echo "All names in '$TAGFILE' are unique within the first 7 characters."
	rm -f sedfile$$ /tmp/tag$$
	exit 0
fi

				# let the user look over the sedfile first
if [ "$AFFIRM" = "no" ]
then
	echo "Sed command file contains:"
	/usr/bin/less sedfile$$
	echo -n " -- go ahead with edit? "
	read yesno
	case $yesno in
		[Yy]*) echo ;;
		*)     exit 1 ;;
	esac
	echo -n "Restrict edit to files mentioned in '$TAGFILE'? "
	read yesno
	case $yesno in
		[Yy]*) TARGETS=`0<$TAGFILE awk '{ print $2 }' | sort -u` ;;
		*)     TARGETS=`echo *.c *.h`				 ;;
	esac
else
	echo "Restricting edit to files mentioned in '$TAGFILE'."
	TARGETS=`0<$TAGFILE awk '{ print $2 }' | sort -u`
fi
echo "About to edit: $TARGETS" | tr '\012' ' '
echo

				# finally, run the 'sed' commandfile on
				# the files mentioned in $TAGFILE
for FILE in $TARGETS
do
	echo "Editing $FILE:"
	0<$FILE sed -f sedfile$$ 1>TEMP$$
	if [ $? -eq 0 ]
	then
		mv TEMP$$ $FILE
		echo "	$FILE successfully edited"
	else
		echo "  Can't edit $FILE!"
	fi
done
rm -f TEMP$$
-- 
 Jean-Pierre Radley          HIGH-Q	     jpr at jpradley	CIS: 72160,1341



More information about the Comp.lang.c mailing list