#!/bin/sh
#
# file fdfix.sh
# This file is part of LyX, the document processor.
# Licence details can be found in the file COPYING.
#
# author Angus Leeming
#
# Full author contact details are available in file CREDITS
#
# This shell script takes the dialog created with fdesign and generates the
# .C and .h files used by LyX from it.
# Note that the REAL magic is to be found in the sed scripts fdfixc.sed and
# fdfixh.sed used by this shell script.

INTRO_MESSAGE ()
{
test $# -eq 1 || {
	echo "Expected a file name!"
	exit 1
}

# Note that we can't create a variable containing this and then
# echo it across because some machines require -e to recognize \n et al.
# Other machines, of course output -e, it not being an option they
# recognise ;-)

cat - > $1 <<EOF
// File generated by fdesign from ${FDFILE}
// and modified by fdfix.sh for use by LyX.

// WARNING! All changes made to this file will be lost!

// This file is part of LyX, the document processor.
// Licence details can be found in the file COPYING.

EOF
}

#===============
# Initial checks
if [ ! -f $1 ]; then
	echo "Input file does not exist. Cannot continue"
	exit 1
fi

DIRNAME=`dirname $1`
BASENAME=`basename $1 .fd`

FDFIXH_SED=`dirname $0`/fdfixh.sed
FDFIXC_SED=`dirname $0`/fdfixc.sed
TMP_STR_SED=`dirname $0`/tmp_str.sed

if [ $1 = ${BASENAME} ]; then
	echo "Input file is not a .fd file. Cannot continue"
	exit 1
fi

#===================================
# Create the initial .c and .h files
FDESIGN=fdesign
FDFILE=${BASENAME}.fd

(cd ${DIRNAME} && ${FDESIGN} -convert ${FDFILE}) ||
{
	echo "\"${FDESIGN} -convert ${FDFILE}}\" failed. Please investigate."
	exit 1
}

#==================================
# Modify the .h file for use by LyX
HIN=${DIRNAME}/${BASENAME}.h
HPATCH=${DIRNAME}/${BASENAME}.h.patch
HOUT=${BASENAME}.hpp

# First clean up the "extern void func(arg);" declarations and
# put the sorted, unique list in file ${EXTERN_FUNCS}
# The contents of this file are used by ${FDFIXH} to replace the mess
# output by fdesign
# Note that we use unique file names for temp files to enable re-entrant
# builds with SMP machines
EXTERN_FUNCS=extern.$$
sed -n 's/extern void \(.*\)/void \1/p' ${HIN} > ${EXTERN_FUNCS}

if [ -s ${EXTERN_FUNCS} ]; then
	TMP=tmp.$$
	sort -u ${EXTERN_FUNCS} > ${TMP}
	echo "extern \"C\" {" > ${EXTERN_FUNCS}
	cat ${TMP} >> ${EXTERN_FUNCS}
	echo "}" >> ${EXTERN_FUNCS}
	rm -f ${TMP}
fi

# First ensure that the sed script knows where to find ${EXTERN_FUNCS}
FDFIXH=fdfixh.$$
sed "s/EXTERN_FUNCS/${EXTERN_FUNCS}/" ${FDFIXH_SED} > ${FDFIXH}

INTRO_MESSAGE ${HOUT}

sed -f ${FDFIXH} < ${HIN} >> ${HOUT}

# Don't forget to clean up the temporary files.
rm -f ${EXTERN_FUNCS} ${FDFIXH}

# Patch the .h file if a patch exists
if [ -f "${HPATCH}" ] ; then
	echo "Patching ${HOUT} with ${HPATCH}"
	patch -s ${HOUT} < ${HPATCH}
fi

# Clean up, to leave the finished .h file. We can be a little tricky here
# testing to see if the finished file exists already and if it does
# testing whether there are any differences.
# If there are no differences, then don't overwrite to prevent unnecessary
# compilation in the xforms directory.
rm -f ${HIN}
MOVE_H_FILE=1
if [ -r ${BASENAME}.h ]; then
	cmp -s ${HOUT} ${BASENAME}.h && MOVE_H_FILE=0
fi

if [ ${MOVE_H_FILE} -eq 1 ]; then
	mv ${HOUT} ${BASENAME}.h
else
	rm -f ${HOUT}
fi

#==================================
# Create the .C file for use by LyX
CIN=${DIRNAME}/${BASENAME}.c
CPATCH=${DIRNAME}/${BASENAME}.C.patch
COUT=${BASENAME}.cpp
FINAL_COUT=${BASENAME}.C

# We use a two pass algorithm to generate elegant C++ code whilst
# keeping the sed clean also.

# Pass 1. The bulk of the clean-up
TMP=tmp.$$
INTRO_MESSAGE ${TMP}

echo "#include <config.h>" >> ${TMP}
echo "#include \"forms_gettext.h\"" >> ${TMP}
echo "#include \"gettext.h\"" >> ${TMP}
echo "#include \"../lyx_forms.h\"" >> ${TMP}
grep bmtable ${CIN} > /dev/null &&
	echo "#include \"bmtable.h\"" >> ${TMP}
grep combox ${CIN} > /dev/null &&
	echo "#include \"combox.h\"" >> ${TMP}
echo "using std::string;" >> ${TMP}

sed -f ${FDFIXC_SED} < ${CIN} >> ${TMP}

# Pass 2. Ensure that any tmp_str variables inserted by fdfixc.sed
# are declared at the top of the appropriate function.
sed -f ${TMP_STR_SED} < ${TMP} > ${COUT}
rm -f ${TMP}

if [ -f "${CPATCH}" ] ; then
	echo "Patching ${COUT} with ${CPATCH}"
	patch -s ${COUT} < ${CPATCH}
fi

# Clean up, to leave the finished .C file
rm -f ${CIN}
mv ${COUT} ${FINAL_COUT}

#========================================
