#! /bin/bash -norc

#	Copyright (C) 2021	Paul F. Markfort
#	License:	GPLv3: https://www.gnu.org/licenses/
#
#	2021/09/27 - paulfm - created
#	2024/02/17 - paulfm - updated to use name+ext, and added comments
#
#
# Purpose:  To make it possible to use c/c++ (and other) code like you would scripts.
#
# This script conditionally compiles $1 and sends the rest of the arguments to the resulting binary.
# Note: if first argument is "-v", it is verbose about what it is doing.
#
#  EXAMPLE, how to use it in a c or c++ file (put the below at the top of the file):
#
#	#if 0	/*
#		compile-and-run-file.sh -v "${0}" "${@}"
#		exit
#		#	End of C comment	*/
#	#endif
#


# : is a noop command
_echo=":"	

if [ -n "${1}" -a "${1}" == "-v" ] ; then
	# verbose output   
	_echo="echo"
	shift
fi

_source_file="${1}"
shift

if [ -z "${_source_file}" ] ; then
	echo "	ERROR: Missing Source"
	exit 1
elif [ ! -r "${_source_file}" ] ; then
	echo "	ERROR: Unable to Read: ${_source_file}"
	exit 1
fi

# These are buit-in ways of doing what uname does:

#	Reduce to file name only (everything after last /)
_source_file_name_ext="${_source_file##*/}"

#	Extension (everthing after last .)
_source_file_ext="${_source_file_name_ext##*.}"

#	Name only (file name up to last .) - not used
# _source_file_name="${_source_file_name_ext%.*}"


# set/create _run_folder

if [ -z "${TMP}" ] ; then
        TMP="/tmp/${USER}.tmp"
        if [ -w "/usr/tmp" ] ; then
                TMP="/usr/tmp/${USER}.tmp"
        fi
fi

_run_folder="${TMP}/run"
mkdir -p "${_run_folder}"
chmod 700 "${_run_folder}"

# Use full filename so .cpp and .c bin files are different
_bin_file="${_run_folder}/${_source_file_name_ext}.bin"


#  Select compiler
_compile_command=""
_do_compile=""
_do_run=""

case ${_source_file_ext} in
	"C"|"cc"|"cp"|"c++"|"C++"|"cpp"|"cxx")
		# gnu c++ compiler on linux (you could use c++ or g++ as well)
		# note - I have found that gcc -xc++ does not seem to work.
		_compile_command="g++ -o \"${_bin_file}\" \"${_source_file}\" "
		;;
	"c")
		# gnu c compiler on linux
		_compile_command="gcc  -o \"${_bin_file}\" \"${_source_file}\" "
		;;
	*)
		echo "	ERROR: Unknown extension:  ${_source_file_ext}"
		exit 1
		;;
esac


# Determine if Compile is needed
if [ -x "${_bin_file}" ] ; then 
	_do_run="1"
	if [ "${_source_file}" -nt "${_bin_file}" ] ; then
		# source is newer than bin
		_do_compile="1"
		_do_run=""
	fi
else
		# bin cannot be run
		_do_compile="1"
		_do_run=""
fi


# Run Compile if needed
if [ -n "${_do_compile}" ] ; then
	${_echo} "	COMPILING:  ${_compile_command}"
	if eval "${_compile_command}" ; then
		_do_run="1"
	fi
fi

# Run binary if suggested
if [ -n "${_do_run}" ] ; then
	${_echo} "	RUNNING:  ${_bin_file} ${*}
"
	"${_bin_file}" "${@}"
fi
