#! /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.             #
###########################################################################

# -----------------------------------------------------------------------------
#
# FILE CONTENT DEFINITIONS
#
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# The content of the 'ccc-config' file.
# -----------------------------------------------------------------------------
CONTENT_CCC_CONFIG=$(cat <<EOF
#! /bin/bash

# -----------------------------------------------------------------------------
# Clear any existing configuration.
# -----------------------------------------------------------------------------
. ccc-unconfig


# -----------------------------------------------------------------------------
# Mandatory environment variables. These MUST be set to VALID values.
# -----------------------------------------------------------------------------

# Specify your project's root directory. If this file is located in your
# project's root directory (and it should), use '\$(pwd)' here. Do NOT add a
# trailing slash.
export CCC_PROJECT_DIR=\$(pwd)

# The directory in which the compiler wrapper scripts are located. Do NOT add a
# trailing slash.
export CCC_WRAPPERS_DIR="\$CCC_PROJECT_DIR/.ccc-wrappers"

# The cpp-callgraph-constructor's output directory. Do NOT add a trailing slash.
export CCC_OUTPUT_DIR="\$CCC_PROJECT_DIR/.ccc-output"

# The log file.
export CCC_LOG_FILE="\$CCC_OUTPUT_DIR/log"

# The arguments to be passed to ccie. This can be empty.
# Example: export CCC_CCIE_ARGS="-fc-filter-defn-conservative -fc-verbose -fc-no-print-consv-warnings"
export CCC_CCIE_ARGS=


# -----------------------------------------------------------------------------
# Prepend the PATH environment variable with the wrapper-scripts directory. That
# will cause the wrapper scripts to be called instead of the original compilers.
# -----------------------------------------------------------------------------
export PATH=\$CCC_WRAPPERS_DIR:\$PATH

EOF
)


# -----------------------------------------------------------------------------
# The content of the 'ccc-unconfig' file.
# -----------------------------------------------------------------------------
CONTENT_CCC_UNCONFIG=$( cat <<EOF
#! /bin/bash

# -----------------------------------------------------------------------------
# Remove the CCC_WRAPPERS_DIR from the PATH environment variable.
# -----------------------------------------------------------------------------

# If the CCC_WRAPPERS_DIR environment variable is set to a valid directory,
# remove that directory from the PATH environment variable.
if [ -n "\${CCC_WRAPPERS_DIR}" ]; then
	if [ -d \$CCC_WRAPPERS_DIR ]; then
		export PATH=\${PATH//\$CCC_WRAPPERS_DIR:/}
	fi
fi


# -----------------------------------------------------------------------------
# Unset all the ccc environment variables that were set in ccc-config.
# -----------------------------------------------------------------------------

# The project's root directory.
export CCC_PROJECT_DIR=

# The directory in which the compiler wrapper scripts are located.
export CCC_WRAPPERS_DIR=

# The cpp-callgraph-constructor's output directory.
export CCC_OUTPUT_DIR=

# The log file.
export CCC_LOG_FILE=

# The arguments to be passed to ccie.
export CCC_CCIE_ARGS=

EOF
)

# -----------------------------------------------------------------------------
# Retrieve the current working directory. This is the directory in which call
# information extraction needs to be initialized.
# -----------------------------------------------------------------------------
PROJECT_DIR=$(pwd)
OUTPUT_DIR="$PROJECT_DIR/.ccc-output"
WRAPPERS_DIR="$PROJECT_DIR/.ccc-wrappers"


# -----------------------------------------------------------------------------
# Install the 'ccc-config' and 'ccc-build' files in the directory from which
# 'ccc-init' was called.
# -----------------------------------------------------------------------------

# File copy function.
function copyFile
{
	echo "Copying '${1##*/}' to '$2'..."
	cp $1 $2
	
	if [ $? -ne 0 ]; then
		echo "An error occurred while copying '$1' to '$2'."
		exit 1
	fi
}

# Start the output with a newline.
echo ""

# Retrieve the installation directory of the compiler wrapper scripts.
CCC_WRAPPERS_PATH=$(whereis ccc-wrappers)
CCC_WRAPPERS_PATH=${CCC_WRAPPERS_PATH#*: }

# Create the ccc-config and ccc-unconfig files in the source directory.
echo "Creating 'ccc-config'..."
echo "$CONTENT_CCC_CONFIG" > $PROJECT_DIR/ccc-config
echo "Creating 'ccc-unconfig'..."
echo "$CONTENT_CCC_UNCONFIG" > $PROJECT_DIR/ccc-unconfig


# Make sure the output directory exists.
if [ ! -d "$OUTPUT_DIR" ]; then
	mkdir "$OUTPUT_DIR"
fi

# Make sure the wrappers directory exists.
if [ ! -d "$WRAPPERS_DIR" ]; then
	mkdir "$WRAPPERS_DIR"
fi

# Copy the wrapper scripts to the wrappers directory.
copyFile $CCC_WRAPPERS_PATH/gcc $WRAPPERS_DIR/gcc
copyFile $CCC_WRAPPERS_PATH/g++ $WRAPPERS_DIR/g++
copyFile $CCC_WRAPPERS_PATH/c++ $WRAPPERS_DIR/c++
copyFile $CCC_WRAPPERS_PATH/ld $WRAPPERS_DIR/ld
copyFile $CCC_WRAPPERS_PATH/ar $WRAPPERS_DIR/ar


# -----------------------------------------------------------------------------
# Inform the user what he should do next.
# -----------------------------------------------------------------------------
echo ""
echo "============================================================================="
echo ""
echo "The following files and directories were created:"
echo ""
echo "./ccc-config       : Configuration of ccc. Used to set your environment up"
echo "                     for call information extraction."
echo "./ccc-unconfig     : Unconfiguration of ccc. Used to restore your environment"
echo "                     when you no longer want call information extraction."
echo "./.ccc-wrappers/   : This directory contains the compiler wrapper scripts."
echo "./.ccc-wrappers/gcc: The wrapper script for the gcc compiler."
echo "./.ccc-wrappers/g++: The wrapper script for the g++ compiler."
echo "./.ccc-wrappers/c++: The wrapper script for the c++ compiler."
echo "./.ccc-wrappers/ld : The wrapper script for the linker."
echo "./.ccc-wrappers/ar : The wrapper script for the archiver."
echo "./.ccc-output/     : This directory will contain the output of the"
echo "                     extractor. The log file will also be stored here." 
echo ""
echo "To extract call information for your entire project, do the following:"
echo ""
echo "1. Set up your environment for extraction by doing:"
echo "   '. ccc-config'."
echo "   Note that the ccc-config file needs to be sourced, not executed, in your"
echo "   current shell."
echo "2. Clean your source tree ('make clean' will usually do the trick)."
echo "3. Build your source tree ('make')."
echo ""
echo "When you no longer want call information to be extracted, you can restore"
echo "your environment by doing:"
echo "'. ccc-unconfig'"
echo "This will make sure the wrapper scripts are no longer called. Instead, the"
echo "actual gcc, g++ and c++ compilers will again be called directly, as usual."
echo "Once more, the ccc-unconfig file needs to be sourced, not executed, in your"
echo "current shell."
echo ""
echo "To clean the output of the extraction system, execute:"
echo "'ccc-clean'"
echo "This will delete all the contents of the .ccc-output directory."
echo ""
echo "Note that the call information extraction system behaves just like your"
echo "build system. That is, if your build system only compiles files that have"
echo "changes, then the extractor will also be run just for those files."
echo ""
echo "Just remember: As long as your environment is set up for extraction, every"
echo "source file that is compiled by gcc, g++ or c++ will have its call"
echo "information extracted."
echo ""
echo "============================================================================="
echo ""


