#!/bin/bash
#
# File generated			out of		and directory
#--------------------------------------------------------------------
# local.h	Local Includes		local.alt	~root/include
# own.h		Own Includes		own.alt		~/include
# augusta.h	Augusta Includes	augusta.alt	this directory
# includes.h	System Includes		includes.alt	/usr/include
# X11.h		X11 Includes		X11.alt		/usr/include/X11
#
# I am using nawk for on my system:
# 1) awk is not working correctly
# 2) gawk is not working correctly either
# If you got no nawk, and
# if your gawk is working correctly:	ln -s gawk nawk
# elif your awk is fully implemented:	ln -s awk nawk
# else get gawk.
#
# @PublicShellScript(Valentin Hilbig)@

AWK=awk
SCRIPT=$0
DEF=alt

#set -x

# Called with:	<name> <directory> <awk-script>
# Recoursively searches the given directory and creates file tmp.tmp.
# Places for all found *.h-files one line tag and filename in it.
# (The tag is the filename in CAPS modified for #define's macro name usage.)
# Finally all those data is fed through the awk-script and must look like:
# x	<tag>	<include-filename>
# where <include-filename> is either "name" or <name>.
# All other lines not starting with "x" are treated as comments and
# lines starting with "x" followed by non-whitespace are switched off lines.
step1()
{
if [ -d $2 ]
then
	find $2 -name '*.h' -type f -follow -print |
		$AWK "{sub(\"^$2/\",\"\");print}" > tmp.tmp
	# no tee to avoid side-effects
	cat tmp.tmp | dd conv=ucase 2>/dev/null |
		sed -e 's/\//_/g' -e 's/\./_/g' -e 's/-/_/g' |
		paste - tmp.tmp |
		$AWK "$3" > $1.tmp
fi
}

# Called with:	<name>
# Creates a sorted <name>.in from <name>.$DEF, <name>.in and <name>.tmp
# Double tags are elliminated using awk's associative memory,
# but all comments are preserved (but sorted with the other lines, too).
step2()
{
if [ -f $1.in ]
then
	[ -f $1.inO ] && rm -f $1.inO
	mv $1.in $1.inO
fi
cat >$1.h <<~~END~~ 
/* Generated definition file
 *
 * ! To protect your data against irregular changes, keep it in $1.$DEF !
 *
 * You may enter temporary rules in this file. This rules should survive the
 * call of $SCRIPT if no corresponding rule exists in $1.$DEF
 */

~~END~~
files=""
[ -f $1.tmp ] && files="$1.tmp"
[ -f $1.inO ] && files="$1.inO $files"
[ -f $1.$DEF ] && files="$1.$DEF $files"
[ -n "$files" ] &&
$AWK '/^x/ { if (hold[$2] == "") hold[$2]=$0 }
END { for (a in hold) print hold[a] }' $files | sort >> $1.in
}

# Called with:	<name>
# Creates <name>.h out of <name>.in
step3()
{
if [ ! -f $1.in ]
then
	echo "$1.in missing, $1.h not changed"
	return
fi
if [ -f $1.h ]
then
	rm -f $1.hO
	mv $1.h $1.hO
fi
cat > $1.h <<~~END~~ 
/* Generated Includefile
 *
 * !! _NEVER_ CHANGE, or all data will be lost. !! Change $1.$DEF instead.
 */

~~END~~
$AWK '
$1=="x"	{ var="_INC_" $2; print "#ifndef " var; e=0
	for (i=4; NF>=i; i+=2)
	{
		if (e)	print "#elif	defined(" $i ")"
		else	print "#if	defined(" $i ")"
		print "#define " var "\t" $(i+1); e=1
	}
	if (e)	print "#else"
	print "#define " var "\t" $3
	if (e)	print "#endif"
	print "#endif" }' $1.in >> $1.h
}

enter()
{
step1 "$1" "$2" "$3"
step2 "$1"
step3 "$1"
echo "done $1.h"
}

enter augusta .. '$2!~/^includes(\/|\.h)/ && $2!~/\/SCCS\// && $2!~/\/RCS\// {
			print "x\t" $1 "\t\"" $2 "\"" }'
enter X11 /usr/include/X11 '{ if ($2~/^X[^\/]*\//) print "x\t"$1"\t<X11/"$2">";
				   else print "x\tX11_"$1"\t<X11/"$2">" }'
enter includes /usr/include '$2!~/^X(11|m|aw)\// { print "x\t"$1"\t<"$2">" }'
enter own	$HOME/include	'{ print "x\t" $1 "\t\"" $2 "\"" }'
enter local	~root/include	'{ print "x\t" $1 "\t\"" $2 "\"" }'

rm *.tmp
