#! /bin/bash
###########################################################################
#   Copyright (C) 2009 by Hessel Hoogendorp                               #
#   bugs.ccc@gmail.com                                                    #
#                                                                         #
#   This program is free software; you can redistribute it and/or modify  #
#   it under the terms of the GNU General Public License as published by  #
#   the Free Software Foundation; either version 2 of the License, or     #
#   (at your option) any later version.                                   #
#                                                                         #
#   This program is distributed in the hope that it will be useful,       #
#   but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#   GNU General Public License for more details.                          #
#                                                                         #
#   You should have received a copy of the GNU General Public License     #
#   along with this program; if not, write to the                         #
#   Free Software Foundation, Inc.,                                       #
#   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
###########################################################################

# -----------------------------------------------------------------------------
# This script wraps g++.
#
# First, it makes the original call to g++, and, if that succeeds, then calls
# the call information extractor with the same parameters.
# -----------------------------------------------------------------------------


# -----------------------------------------------------------------------------
# Call the original g++ compiler.
# -----------------------------------------------------------------------------

# Find the installation path of g++.
CXX=$(whereis g++)
CXX=${CXX#*: }         # Strip off 'g++: '.
CXX=${CXX%% *}         # Strip off any secondary paths.

# Test whether we found an existing, executable program.
if [ ! -x $CXX ]; then
	echo "ERROR: The g++ wrapper script could not find a usable C++ compiler."
	exit 1
fi

# Reconstruct the arguments passed to this script; sometimes a -D option is
# passed to the compiler, with escaped quotes in the argument. The original
# command line may look like this:
# -DSOMENAME="\"SomeText to be quoted in the source file.\""
# To make sure this gets passed properly to the actual compiler, we need to
# reconstruct such arguments. That is, we need to manually put back the outer
# pair of quotes, since they have been interpreted by the shell (to form a
# single argument). The next step will be to write out the reconstructed command
# line to a temporary file and source that file. This will then properly call
# the compiler.
NEWARGS=
EXECBYSOURCING=0
for ARG in "$@"; do
	case $ARG in
		-D*=\"*\")
			EXECBYSOURCING=1
			ARG="${ARG/=\"/=}"
			ARG="${ARG/\"/\\\"\"}"
			ARG="${ARG/=/=\"\\\"}"
			;;
	esac
	NEWARGS="$NEWARGS ""${ARG}"
done

# Supply the compiler with all arguments passed to this script, but add the
# -save-temps switch. This will cause the compiler to save the preprocessed
# source code. The extractor will then use this preprocessed source code to
# extract the call information.

if [ $EXECBYSOURCING -eq 0 ]; then

	CMD="$CXX $@ -save-temps"
	$CMD
	exitCode=$?

else

	CMD="$CXX"" ""$NEWARGS"" -save-temps"

	# Generate and store the name of a temporary file.
	TMPFILE="ccc-$RANDOM.$RANDOM.$RANDOM-ccc"

	# Output the command line to the temporary file.
	echo "$CMD" > $TMPFILE

	# Source the temporary file.
	. $TMPFILE

	exitCode=$?

	# Remove the temporary file.
	rm $TMPFILE

fi

# Check whether the call to g++ was successful. If not, return with the
# compiler's exit code.
if [ $exitCode -ne 0 ]; then
	exit $exitCode
fi


# -----------------------------------------------------------------------------
# Extract call information.
# -----------------------------------------------------------------------------

# Call the call information extractor with the same arguments that were
# supplied to this script.
CMD="ccc-extract $@"
$CMD

# The compiler returned success, so return success regardless of the output of
# the extraction script.
exit 0

