
#===============================================================
#
# This shell script emulates the behaviour of the 'cmt buid dependencies' operation
# but using the tool specified by the $(c_pp) macro (or cpp -M) instead
#
#===============================================================

function compute_dependencies ()
{
  file=$1

  # Generate the expected format:
  #  one single line
  #  prefix is a make macro
  #  ends with a dependency to the stamp file

if [ -z "$c_pp" ]; then
    c_pp="cpp -M"
fi

  a=`eval ${c_pp} ${allflags} ${file} | \
    sed -e 's#[.]o:#_'"${suffix}"'_dependencies = #' -e 's#[\\]$##'`

  if test ! `echo ${a} | wc -w` = "0"; then
    line="`echo ${a}`"
  else
    line="${file_name}_${suffix}_dependencies = ${file}"
  fi

if [ "$no_stamps" != yes ]; then
    stamp_output_base=${constituent}_deps/${file_name}_${suffix}.stamp
    stamp_output=${bin}${stamp_output_base}
    line="${line} \$(bin)${stamp_output_base}"

  # create or update the stamp file
    if [ -f "${stamp_output}" ]; then
	read old_stamp <${stamp_output}
	if [ "${line}" != "${old_stamp}" ]; then
	    /bin/rm -f ${stamp_output}
	    printf "${line}\n" >${stamp_output}
	fi
    else
	printf "${line}\n" >${stamp_output}
    fi

  #touch ${bin}/${constituent}_deps/${file_name}_${suffix}.stamp
fi
printf "${line}\n"
}

#--------------------------------------------
macro_value ()
{
  name=$1
  shift
  sed -n '/^'${name}'=/{s#^'${name}'=##p;q}' ${tempmacros}
#  grep "^${name}=" ${tempmacros} | sed -e "s#^${name}=##"
}

#-----------------------------------------------------
# Pre-compute all configuration parameters from CMT queries
#-----------------------------------------------------
function prepare_context ()
{
  /bin/rm -f ${tempmacros}
  cmt -quiet build tag_makefile > ${tempmacros}
  cmt -quiet filter ${tempmacros} ${tempmacros}A; mv ${tempmacros}A ${tempmacros}

  # /bin/rm -f ${tempconstituents}
  # cmt -quiet show constituents > ${tempconstituents}
  # cmt -quiet filter ${tempconstituents} ${tempconstituents}A; mv ${tempconstituents}A ${tempconstituents}
}

#------------------------------------------------------------------------------------------
# Main
#
#  Expected arguments:
#    1    : <constituent name>
#    2    : [ options: -all_sources | -no_stamps | -out=<dependencies file> ]
#    3... : <source file list>
#
#------------------------------------------------------------------------------------------

[ $# -gt 0 ] || exit
constituent=$1
shift

n=0
for f; do
    case ${f} in
	-all_sources) all_sources=yes; n=`expr $n + 1` ;;
	-no_stamps) no_stamps=yes; n=`expr $n + 1` ;;
	-out=*) output=`expr "$f" : '-out=\(.*\)'`; n=`expr $n + 1` ;;
	*) break ;;
    esac
done
shift $n

#---------------
# Prepare temporary file management
#
tempprefix=/tmp/CMT$$
if test ! "${TMPDIR}" = ""; then
  tempprefix=${TMPDIR}/CMT$$
fi

tempmacros=${tempprefix}/macros$$
tempconstituents=${tempprefix}/constituents$$

trap "if test -d ${tempprefix} ; then chmod -R +w ${tempprefix}; fi; /bin/rm -rf ${tempprefix}" 0 1 2 15

if test -d ${tempprefix} ; then chmod -R +w ${tempprefix}; fi
/bin/rm -rf ${tempprefix}
mkdir -p ${tempprefix}
#---------------

#---------------
# prepare the context from CMT
#
prepare_context

type=`cmt show constituent ${constituent} | cut -d' ' -f1`
case "${type}" in
    application) type=app ;;
    library) type=lib ;;
    document) type=doc ;;
esac

incl=`macro_value includes`

cflags=`macro_value cflags`
pp_cflags=`macro_value pp_cflags`
use_pp_cflags=`macro_value use_pp_cflags`
const_pp_cflags=`macro_value ${constituent}_pp_cflags`
type_pp_cflags=`macro_value ${type}_${constituent}_pp_cflags`
use_cflags=`macro_value use_cflags`
const_cflags=`macro_value ${constituent}_cflags`
type_const_cflags=`macro_value ${type}_${constituent}_cflags`

cppflags=`macro_value cppflags`
pp_cppflags=`macro_value pp_cppflags`
use_pp_cppflags=`macro_value use_pp_cppflags`
const_pp_cppflags=`macro_value ${constituent}_pp_cppflags`
type_pp_cppflags=`macro_value ${type}_${constituent}_pp_cppflags`
use_cppflags=`macro_value use_cppflags`
const_cppflags=`macro_value ${constituent}_cppflags`
type_const_cppflags=`macro_value ${type}_${constituent}_cppflags`

c_pp=`macro_value c_pp`

if [ "$output" ]; then
    bin=`dirname $output`/
elif [ -z "$bin" ]; then
    bin=`macro_value bin`
fi
#--------------

#--------------
# Prepare the directory for the stamp files
#
if [ "$no_stamps" != yes ]; then
mkdir -p ${bin}/${constituent}_deps
fi
#--------------

#--------------
# Prepare the dependency file
#
if [ -z "$output" ]; then
output=${bin}${constituent}_dependencies.make
fi
#--------------

#--------------
# Loop over source files (if any)
#
for f; do
  suffix=`echo ${f} | sed -e 's#.*[.]##'`
  file_name=`basename ${f} .${suffix}`

  # First remove the old dependency line from the output

if [ "$all_sources" != yes ]; then
  if test -f ${output}; then
    grep -v "${file_name}_${suffix}_dependencies" ${output} >${tempprefix}/t$$
    mv ${tempprefix}/t$$ ${output}
  fi
fi
#  echo "computing dependencies for ${file_name}.${suffix}"

  case ${suffix} in
    c ) allflags="${incl} ${cflags} ${pp_cflags} ${use_pp_cflags} ${const_pp_cflags} ${type_pp_cflags} ${use_cflags} ${const_cflags} ${type_const_cflags}" ;;
    C|cc|cxx|cpp ) allflags="${incl} ${cppflags} ${pp_cppflags} ${use_pp_cppflags} ${const_pp_cppflags} ${type_pp_cppflags} ${use_cppflags} ${const_cppflags} ${type_const_cppflags}" ;;
    * ) allflags="-x c++ ${incl} ${cppflags} ${pp_cppflags} ${use_pp_cppflags} ${const_pp_cppflags} ${type_pp_cppflags} ${use_cppflags} ${const_cppflags} ${type_const_cppflags}" ;;
#    c ) allflags="${incl} ${cflags} ${const_cflags} ${const_cpp_cflags}";;
#    C|cc|cxx|cpp ) allflags="${incl} ${cppflags} ${const_cppflags} ${const_cpp_cppflags}";;
  esac

  compute_dependencies ${f} >>${output}
done
#--------------
