#!/bin/bash
# =============================================================================
# 
# @(#) check_headers,v openss7-0_9_2_F(0.9.2.29) 2007/02/26 07:24:59
#
# -----------------------------------------------------------------------------
#
# Copyright (c) 2001-2006  OpenSS7 Corporation <http://www.openss7.com>
# Copyright (c) 1997-2000  Brian F. G. Bidulock <bidulock@openss7.org>
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 675 Mass
# Ave, Cambridge, MA 02139, USA.
#
# -----------------------------------------------------------------------------
#
# U.S. GOVERNMENT RESTRICTED RIGHTS.  If you are licensing this Software on
# behalf of the U.S. Government ("Government"), the following provisions apply
# to you.  If the Software is supplied by the Department of Defense ("DoD"), it
# is classified as "Commercial Computer Software" under paragraph 252.227-7014
# of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any
# successor regulations) and the Government is acquiring only the license rights
# granted herein (the license rights customarily provided to non-Government
# users).  If the Software is supplied to any unit or agency of the Government
# other than DoD, it is classified as "Restricted Computer Software" and the
# Government's rights in the Software are defined in paragraph 52.227-19 of the
# Federal Acquisition Regulations ("FAR") (or any successor regulations) or, in
# the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR
# (or any successor regulations).
#
# -----------------------------------------------------------------------------
#
# Commercial licensing and support of this software is available from OpenSS7
# Corporation at a fee.  See http://www.openss7.com/
#
# -----------------------------------------------------------------------------
#
# Last Modified 2007/02/26 07:24:59 by brian
#
# =============================================================================

me=`basename $0`
errors=0
warnings=0

abs_top_builddir=`(cd $top_builddir; pwd)`
abs_builddir=`(cd $builddir; pwd)`
abs_top_srcdir=`(cd $top_srcdir; pwd)`
abs_srcdir=`(cd $srcdir; pwd)`

exec 5>>$top_builddir/$me.log

export -p >&5

function echo_v()
{
	echo "$me:  : $1"
}
function echo_t()
{
	echo "$me: T: $1"
}
function echo_s()
{
	case :"${MAINTAINER_MODE:-no}" in
	(:verbose|:continue) echo "$me: S: $1" ;;
	esac
	echo "$me:$2: S: $1" >&5
}
function echo_d()
{
	echo "$me:$2: D: $1" >&5
}
function echo_e()
{
	echo "$me: E: --- $1" >&2
	echo "$me:$2: E: $1" >&5
	((errors++))
}
function echo_w()
{
#	if test :"${MAINTAINER_MODE:-no}" != :no ; then
		echo "$me: W: --- $1" >&2
#	fi
	echo "$me:$2: W: $1" >&5
	((warnings++))
}
function echo_fls()
{
	echo_s "$3" "$4"
}
function echo_flw()
{
	echo "$1:$2: warning: $3" >&2
	echo "$me:$4: W: $3" >&5
	((warnings++))
}
function echo_fle()
{
	echo "$1:$2: error: $3" >&2
	echo "$me:$4: E: $3" >&5
	((errors++))
}

export -p | while read line
do
	echo_d "$line" $LINENO
done

#
# Skip test if we have nothing to test
#
if test -z "$PKG_HEADERS"
then
	echo_d "nothing to check, skipping test" $LINENO
	exit 77
fi

#
# Find all the headers
#
headers=
for f in $PKG_HEADERS ; do
	case $f in
	(/*)
		if test -f $f ; then
			header=$f
		else
			header=
			echo_d "file $f does not exit" $LINENO
		fi
		;;
	(*)
		if test -f ./$f ; then
			header=`pwd`/$f
		elif test -f $abs_srcdir/$f ; then
			header=$abs_srcdir/$f
		else
			header=
			echo_d "file $f does not exist" $LINENO
		fi
		;;
	esac
	headers="${headers:+$headers${header:+ }}${header}"
done
if test -z "$headers"
then
	echo_d "nothing to check, skipping test" $LINENO
	exit 77
fi

echo_d "actual headers are:" $LINENO
for header in $headers ; do
	echo_d "$header" $LINENO
done

#
# Create ctags output
#
rm -f ${top_builddir}/check_ctags.log

echo "$headers" | xargs ctags -x --c-kinds=defgpstuvx ${CTAGS} \
	| sed -e 's|\\$|\\ |' > ${top_builddir}/check_ctags.log

if test :"${MAINTAINER_MODE:-no}" != :no
then
	if test -n "$PKG_MANPATH" ; then
		manpath="$PKG_MANPATH"
	else
		manpath="${abs_top_builddir}/doc/man:${abs_top_builddir}/man:${abs_top_builddir}:./doc/man:./man:.${mandir:+:${mandir}}"
	fi
	srcpath="${abs_top_srcdir}/doc/man:${abs_top_srcdir}/man:${abs_top_srcdir}:${abs_srcdir}/doc/man:${abs_srcdir}/man:${abs_srcdir}${mandir:+:$mandir}"
	searchpath=`echo "$manpath" | sed -e 's|:| |g'`
	sourcepath=`echo "$srcpath" | sed -e 's|:| |g'`
	sections="3 5 9"
	on_error='echo_s'
	for header in $headers ; do
		base=`basename $header .h`
		string="$base in sections $sections"
		echo_t "testing for $string"
		list=
		for n in $sections ; do list="${list:+$list }man${n}/$base.${n} man${n}/$base.h.${n}" ; done
		for page in $list; do
			for dir in $searchpath ; do
				test -d $dir || continue
				files=`ls $dir/$page* 2>/dev/null`
				for file in $files ; do
					if test -f $file ; then
						echo_s "manual page $file exists" $LINENO
						dirmask=`echo $dir | sed -e's|.|.|g'`
						page=`echo $file | sed -e 's|^'$dirmask'/||'`
						echo "$page" >> ${top_builddir}/check_used.log
						found=yes
					fi
				done
			done
		done
		if test :$found = :yes ; then
			echo_s "found $string" $LINENO
		else
			#
			# one additional check here: we check if there is a source manual page in
			# the source directories that matches the object, if so, we warn as well
			# because there is no reason why the manual page should not be included
			#
			for page in $list; do
				for dir in $sourcepath ; do
					test -d $dir || continue
					files=`ls $dir/$page*.man 2>/dev/null`
					for file in $files ; do
						if test -f $file ; then
							echo_flw "$file" "1" "manual source page for $string" $LINENO
						fi
					done
				done
			done
			eval "$on_error \"cannot find \$string\" \$LINENO"
		fi
	done
	while read -a tokens ; do
		found=no
		sections=
		case ${tokens[0]} in
		(_*)	on_error='echo_flw' ; sections="3 9 7" ;;
		(*)	case ${tokens[1]} in
			(function)	on_error='echo_fle' ; sections="2 3 9"
					echo "${tokens[0]}" >> ${top_builddir}/check_symbols.log ;;
			(prototype)	on_error='echo_fle' ; sections="2 3 9" ;;
			(variable)	on_error='echo_fls' ; sections="2 3 9"
					echo "${tokens[0]}" >> ${top_builddir}/check_symbols.log ;;
			(externvar)	on_error='echo_fls' ; sections="2 3 9" ;;
			(macro)		on_error='echo_fls' ; sections="3 9 7" ;;
			(enumerate)	on_error='echo_fls' ; sections="3 9 7" ;;
			(enum)		on_error='echo_flw' ; sections="3 9" ;;
			(struct)	on_error='echo_flw' ; sections="3 9 7" ;;
			(union)		on_error='echo_flw' ; sections="3 9 7" ;;
			(typedef)	on_error='echo_flw' ; sections="3 9 7" ;;
			(member)	continue ;;
			(*)		on_error='echo_flw' ; sections="3 9 7" ;;
			esac ;;
		esac
		string="${tokens[1]} ${tokens[0]} in sections $sections"
		echo_t "testing for $string"
		list=
		for n in $sections ; do list="${list:+$list }man${n}/${tokens[0]}.${n}" ; done
		for page in $list; do
			for dir in $searchpath ; do
				test -d $dir || continue
				files=`ls $dir/$page* 2>/dev/null`
				for file in $files ; do
					if test -f $file ; then
						echo_s "manual page $file exists" $LINENO
						dirmask=`echo $dir | sed -e's|.|.|g'`
						page=`echo $file | sed -e 's|^'$dirmask'/||'`
						echo "$page" >> ${top_builddir}/check_used.log
						found=yes
					fi
				done
			done
		done
		if test :$found = :yes ; then
			echo_s "found $string" $LINENO
		else
			#
			# one additional check here: we check if there is a source manual page in
			# the source directories that matches the object, if so, we warn as well
			# because there is no reason why the manual page should not be included
			#
			for page in $list; do
				for dir in $sourcepath ; do
					test -d $dir || continue
					files=`ls $dir/$page*.man 2>/dev/null`
					for file in $files ; do
						if test -f $file ; then
							echo_flw "${tokens[3]}" "${tokens[2]}" "manual source page for $string" $LINENO
						fi
					done
				done
			done
			eval "$on_error \${tokens[3]} \${tokens[2]} \"cannot find \$string\" \$LINENO"
		fi
	done < ${top_builddir}/check_ctags.log
fi

retval=0
if test $warnings -gt 0
then
	echo_v "--------------"
	echo_v "Warning summary:"
	echo_v "--------------"
	egrep -- '\<W:' $top_builddir/$me.log >&2
	echo_v "--------------"
	retval=77
fi
if test $errors -gt 0
then
	echo_v "--------------"
	echo_v "Error summary:"
	echo_v "--------------"
	egrep -- '\<E:' $top_builddir/$me.log >&2
	echo_v "--------------"
	if test :"${MAINTAINER_MODE:-no}" = :continue
	then
		retval=77
	else
		retval=1
	fi
fi

exit $retval
