#!/bin/sh

if [ $# -lt 4 ]; then

    echo "Usage: $0 <working dir> <input dir> <global mk> <arch [arch [arch ...]]"
    exit 1

fi

workingdir=$1
input=$2
globalmk=$3

shift 3

OLDPWD=$PWD

MAKEFILE_TMP=gencode.mk.tmp
MAKEFILE_EXT=gencode.mk

cd ${workingdir}

echo=`which echo`

rm -f ${MAKEFILE_TMP}
$echo >> ${MAKEFILE_TMP}


$echo "include ${globalmk}" >> ${MAKEFILE_TMP}
$echo >> ${MAKEFILE_TMP}

if [ "$1" = "-" ]; then
    OPCODES=`find ${input} -name '*c' -and -not -name '*.tmpl.c' -exec basename {} \; | cut -d. -f2 | sort | uniq`
else
    OPCODES=`find ${input} -name '*c' -and -not -name '*.tmpl.c' -exec basename {} \; | cut -d. -f3 | sort | uniq`
fi

# Génération des en-têtes de décodage

for arch in $*;
do
    if [ ${arch} = "-" ]; then
        arch_name=""
        arch_name_dotted=""
    else
        arch_name="${arch}_"
        arch_name_dotted="${arch}_."
    fi

    $echo -n "${arch_name}HEADER_FILES =" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}

    has_header=""

    for op in $OPCODES;
    do
        template="${input}/*.${arch_name_dotted}${op}.c"

        sources=`ls $template 2> /dev/null`

        if [ -z "${sources}" ]; then
            continue
        fi

        for src in ${sources};
        do
            has_header="yes"
            $echo -ne " \\" >> ${MAKEFILE_TMP}
            $echo -ne "\n\t" >> ${MAKEFILE_TMP}
            $echo -n ${src} | sed "s/${op}.c$/opcodes.h/" >> ${MAKEFILE_TMP}
        done

    done

    $echo >> ${MAKEFILE_TMP}
    $echo >> ${MAKEFILE_TMP}

    $echo -n "${arch_name}opcodes.h: " >> ${MAKEFILE_TMP}
    $echo "\$(${arch_name}HEADER_FILES)" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}

    if [ -z "${has_header}" ]; then

        $echo -e "\techo > \$@" >> ${MAKEFILE_TMP}

    else

        $echo -e "\t\$(cini_verbose)cat ${input}/${arch_name_dotted}opcodes.tmpl.h > \$@" >> ${MAKEFILE_TMP}
        $echo -e "\t\$(cgen_verbose)cat \$^ >> \$@" >> ${MAKEFILE_TMP}
        $echo -e "\t\$(cfini_verbose)echo >> \$@" >> ${MAKEFILE_TMP}
        $echo -en "\t\$(cfini_verbose)echo \"#endif\t /* " >> ${MAKEFILE_TMP}
        $echo -en '`cat \$@ | grep "#define" | cut -d " " -f 2`' >> ${MAKEFILE_TMP}
        $echo -e " */\" >> \$@" >> ${MAKEFILE_TMP}

    fi

    $echo >> ${MAKEFILE_TMP}

done

$echo >> ${MAKEFILE_TMP}

# Génération des codes d'instructions

for op in $OPCODES;
do
    for arch in $*;
    do
        if [ ${arch} = "-" ]; then
            arch_name=""
            arch_name_dotted=""
        else
            arch_name="${arch}_"
            arch_name_dotted="${arch}_."
        fi

        template="${input}/*.${arch_name_dotted}${op}.c"

        sources=`ls $template 2> /dev/null`

        if [ -z "${sources}" ]; then
            continue
        fi

        $echo -n "${op}_${arch_name}FILES =" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}

        for src in ${sources};
        do
            $echo -ne " \\" >> ${MAKEFILE_TMP}
            $echo -ne "\n\t${src}" >> ${MAKEFILE_TMP}
        done

        $echo >> ${MAKEFILE_TMP}
        $echo >> ${MAKEFILE_TMP}

        $echo -n "${arch_name}${op}.c: " >> ${MAKEFILE_TMP}
        $echo -n "\$(${op}_${arch_name}FILES)" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}
        $echo " ${arch_name}opcodes.h" >> ${MAKEFILE_TMP}

        $echo -e "\t\$(cini_verbose)cat ${input}/${arch_name_dotted}${op}.tmpl.c > \$@" >> ${MAKEFILE_TMP}
        $echo -ne "\t\$(cgen_verbose)cat \$(" >> ${MAKEFILE_TMP}
        $echo -ne "${op}_${arch_name}FILES" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}
        $echo -e ") >> \$@" >> ${MAKEFILE_TMP}

        $echo >> ${MAKEFILE_TMP}

    done

done

$echo >> ${MAKEFILE_TMP}

# Génération de la liste des sources

$echo -n "GENERATED_FILES =" >> ${MAKEFILE_TMP}

for arch in $*;
do
    if [ ${arch} = "-" ]; then
        arch_name=""
        arch_name_dotted=""
    else
        arch_name="${arch}_"
        arch_name_dotted="${arch}_."
    fi

    $echo -ne " \\" >> ${MAKEFILE_TMP}
    $echo -ne "\n\t${arch_name}opcodes.h" >> ${MAKEFILE_TMP}

    for op in $OPCODES;
    do
        template="${input}/*.${arch_name_dotted}${op}.c"

        sources=`ls $template 2> /dev/null`

        if [ ! -z "${sources}" ]; then
            $echo -ne " \\" >> ${MAKEFILE_TMP}
            $echo -ne "\n\t${arch_name}${op}.c" >> ${MAKEFILE_TMP}
            continue
        fi

    done

done

$echo >> ${MAKEFILE_TMP}

$echo >> ${MAKEFILE_TMP}

# Validation finale

if [ ! -f  ]; then

    rm -rf ${MAKEFILE_EXT}
    mv ${MAKEFILE_TMP} ${MAKEFILE_EXT}

else

    hash_tmp=`md5sum ${MAKEFILE_TMP} | cut -d ' ' -f 1`
    hash_ext=`md5sum ${MAKEFILE_EXT} | cut -d ' ' -f 1`

    if [ "${hash_tmp}" = "${hash_ext}" ]; then

        rm -f ${MAKEFILE_TMP}

        echo "${MAKEFILE_EXT} is up to date."

    else

        rm -f ${MAKEFILE_EXT}
        mv ${MAKEFILE_TMP} ${MAKEFILE_EXT}

        echo "${MAKEFILE_EXT} is updated."

    fi

fi

cd ${OLDPWD}