#!/bin/bash

#< Fix perl Makefiles for modules that fail to compile under Solaris

# This fairly rigid script is used to fix the Makefiles of Perl modules that
# fail to compile under Solaris

# It replaces the following parameters in the Makefile, and prompts if
# any one of them doesn't exist.

# Parameter		Looks for		Changes to
# CC			cc			gcc
# LD			cc			gcc
# CCCDLFLAGS		-KPIC			-fPIC
# OPTIMIZE		-xO3 -xdepend		-O2

BASENAME="/usr/bin/basename"
CP="/usr/bin/cp"
ECHO="/usr/bin/echo"
GCC="/usr/local/bin/gcc"
GREP="/usr/bin/grep"
MV="/usr/bin/mv"
RM="/bin/rm"
SED="/usr/bin/sed"

THIS_PROG=$( ${BASENAME} $0 )
TMPFILE_1="/tmp/Makefile.$$"
TMPFILE_2="/tmp/Makefile.$$.working"

ERROR=1
SUCCESS=0

function print_error {
   ${ECHO} "Error: $@" >&2
}

function print_message {
   ${ECHO} "--> $@"
}

function print_warning {
   ${ECHO} "Warning: $@"
}

function print_usage {
   ${ECHO} "Usage: ${THIS_PROG} <Makefile>"
}

function check_gcc {
   print_message "Checking for gcc"
   if [ ! -e "${GCC}" ]; then
      print_error "gcc not found"
      exit ${ERROR}
   fi
}

function check_makefile_exists {
   print_message "Checking for Makefile"
   if [ "${MAKEFILE##*/}" != "Makefile" ]; then
      print_error "Makefiles are usually named \"Makefile\""
      exit ${ERROR}
   fi
   if [ ! -e "${MAKEFILE}" ]; then
      print_error "${MAKEFILE} does not exist"
      exit ${ERROR}
   fi
   BACKUP="${MAKEFILE}.$$"
}

function check_required_parameters {
   print_message "Calculating which changes are required"
   ERROR_COUNT=0
   ${GREP} '^CC = cc$' ${MAKEFILE} >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      print_error "Cannot find line \"CC = cc\" in ${MAKEFILE}"
      (( ERROR_COUNT = ERROR_COUNT + 1 ))
   else
      CC_CONFIRM=1
   fi
   ${GREP} '^LD = cc$' ${MAKEFILE} >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      print_error "Cannot find line \"LD = cc\" in ${MAKEFILE}"
      (( ERROR_COUNT = ERROR_COUNT + 1 ))
   else
      LD_CONFIRM=1
   fi
   ${GREP} '^CCCDLFLAGS = -KPIC$' ${MAKEFILE} >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      print_error "Cannot find line \"CCCDLFLAGS = -KPIC\" in ${MAKEFILE}"
      (( ERROR_COUNT = ERROR_COUNT + 1 ))
   else
      CCCDLFLAGS_CONFIRM=1
   fi
   ${GREP} '^OPTIMIZE = -xO3 -xdepend$' ${MAKEFILE} >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      print_error "Cannot find line \"OPTIMIZE = -xO3 -xdepend\" in ${MAKEFILE}"
      (( ERROR_COUNT = ERROR_COUNT + 1 ))
   else
      OPTIMIZE_CONFIRM=1
   fi
   if [ "${ERROR_COUNT}" -gt "0" -a "${ERROR_COUNT}" -lt "4" ]; then
      print_warning "${ERROR_COUNT} error(s) found when checking for parameters"
      ${ECHO} "You can proceed, and only lines that match EXACTLY will be"
      ${ECHO} "replaced. This is normally sufficient - would you like to"
      ${ECHO} "continue (y or n): \c"
      read RESPONSE
      case "${RESPONSE}" in
         y|Y|[yY][eE][sS]  ) ;;
         n|N|[nN][oO]      ) ${ECHO} "Aborting..." 
                              exit ${SUCCESS} ;;
         *                 ) print_error "Just type y or n, idiot. Exiting!"
                             exit ${ERROR} ;;
      esac
   fi
   if [ "${ERROR_COUNT}" -eq "4" ]; then
      print_error "Nothing to be done"
      exit ${ERROR}
   fi
}

function backup_makefile {
   print_message "Creating backup of Makefile as ${BACKUP}"
   ${CP} -p ${MAKEFILE} ${BACKUP}
   print_message "Creating working file"
   ${CP} -p ${MAKEFILE} ${TMPFILE_1}
}

function convert_makefile {
   if [ -n "${CC_CONFIRM}" ]; then
      print_message "Replacing value of CC in Makefile"
      ${SED} 's/^CC = cc$/CC = gcc/' ${TMPFILE_1} > ${TMPFILE_2} 
      ${MV} ${TMPFILE_2} ${TMPFILE_1}
   fi
   if [ -n "${LD_CONFIRM}" ]; then
      print_message "Replacing value of LD in Makefile"
      ${SED} 's/^LD = cc$/LD = gcc/' ${TMPFILE_1} > ${TMPFILE_2} 
      ${MV} ${TMPFILE_2} ${TMPFILE_1}
   fi
   if [ -n "${CCCDLFLAGS_CONFIRM}" ]; then
      print_message "Replacing value of CCCDLFLAGS in Makefile"
      ${SED} 's/^CCCDLFLAGS = -KPIC$/CCCDLFLAGS = -fPIC/' ${TMPFILE_1} > ${TMPFILE_2} 
      ${MV} ${TMPFILE_2} ${TMPFILE_1}
   fi
   if [ -n "${OPTIMIZE_CONFIRM}" ]; then
      print_message "Replacing value of OPTIMIZE in Makefile"
      ${SED} 's/^OPTIMIZE = -xO3 -xdepend$/OPTIMIZE = -O2/' ${TMPFILE_1} > ${TMPFILE_2} 
      ${MV} ${TMPFILE_2} ${TMPFILE_1}
   fi
}

function restore_makefile {
   print_message "Replacing Makefile with fixed copy"
   ${MV} ${TMPFILE_1} ${MAKEFILE}
}

function cleanup {
   print_message "Cleaning up..."
   ${RM} -f ${TMPFILE_1} ${TMPFILE_2}
}

if [ "$#" -ne "1" ]; then
   print_usage
   exit ${ERROR}
else
   MAKEFILE=$1
fi

trap "cleanup; exit ${ERROR}" 1 2 3 15

check_gcc
check_makefile_exists
check_required_parameters
backup_makefile
convert_makefile
restore_makefile
cleanup

print_message "All done. Now run make"

exit 0