#! /bin/bash
#
# C'ish source code beautifier
# (uses sed, awk, and indent)
#
# Jan 06, 2000 Andrew E. Mileski <andrewm@netwinder.org>
# - Written to save my eyes, nerves, brain cells, hair, and time.
#

TYPES=yes

if [ "$1" = "-types" ] ; then
	TYPES=no
	shift
fi

if [ ! -f "$1" ] ; then
	echo 'usage: aem [-types] filename'
	exit 1;
fi

cp -a $1 $1.orig

#
# Change C++ // comments into /* C comments */
#
sed -n -e '
# Remove consecutive blank lines
/^[ 	]*$/{
	p
	: blank
	n
	/^[ 	]*$/b blank
}

#
# Change imbedded // comments // like this line //
# to // nice comments -- like this line --
#
: comment1
\#[^;]*//[^;]*//)#{
	s#\(.*\)//\(.*\)//\(.*\)#\1//\2--\3#
}
\#[^;]*//[^;]*//)#b comment1

#
# // Change dead code; // comments
# #if 0
#  Change dead code; // comments
# Eendif
#
\#^[ 	]*//.[^;]*;.*//#{
	s#^[ 	]*//[ 	]*\(.*\)[ 	]*$#\1#
	i\
#if 0
	p
	i\
#endif
	d
}

# Handle // without leading text
s#^//\(.*\)]*[ 	]*$#/* \1 */#

# Handle // with leading text
s#^\(.*\)[ 	]*//[ 	]*\(.*\)[ 	]*$#\1 /* \2 */#

# Print and delete
p
d
' < $1.orig |

#
# All the real work is done here
#
indent -kr -i8 -ts8 -l132 -lc80 |

#
# No partial tabs
#
sed -e 's/^\(	*\) \{2,\}/\1	/' |

#
# Remove annoying type prefixes UI_ UC_ UL_ I_ C_ L_ (optional)
# Warning: this can be dangerous!
#
if [ "$TYPES" = "no" ] ; then
	sed -e 's#\([ 	\*\(\[\.\>\"]\)[SU]\?[ICLZ]_\([a-zA-Z0-9_]\+\)#\1\2#g'
else
	cat
fi |

#
# Take consecutive single line comments
# and put them in a single comment box.
#
awk '
BEGIN {
	started = 0;
	tab = "";
	old = "";
	m = 0;

	while (getline) {

		# Start box if two consecutive lines are comments
		m = match($0, /^[ 	]*\/\*.*\*\//);
		if (m == 0) {
			print $0;
			continue;
		}
		old = $0;
		getline;
		m = match($0, /^[ 	]*\/\*.*\*\//);
		if (m == 0) {
			print old;
			print $0;
			continue;
		}
		started = 1;

		# Open a box and print the lines already read
		m = match(old, /\/\*/);
		tab = substr(old, 1, m - 1);
		old = substr(old, m + 3)
		printf("%s/*\n%s * %s\n", tab, tab, substr(old, 1, length(old) - 3));
		m = match($0, /\/\*/);
		$0 = substr($0, m + 3);
		printf("%s * %s\n", tab, substr($0, 1, length($0) - 3));

		# Look for more lines to add to the box
		while (getline) {

			# Close the box if next line is not a comment
			m = match($0, /^[ 	]*\/\*.*\*\//);
			if (m == 0) {
				printf("%s */\n%s\n", tab, $0);
				started = 0;
				break;
			}

			# Add line to the box
			m = match($0, /\/\*/);
			$0 = substr($0, m + 3);
			printf("%s * %s\n", tab, substr($0, 1, length($0) - 3));
			
		}
	}

	# Close a box that is still open (end of file)
	if (started == 1) {
		printf("%s */\n", tab);
	}
}
' > $1
