#!/bin/sh
# $Id: manifest,v 1.30 2024/04/21 17:59:35 tom Exp $
# -----------------------------------------------------------------------------
# Copyright 1994-2023,2024 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
#
# Construct a manifest from the RCS description lines for the selected
# (symbolic) version.  The script assumes that the following files are
# automatically generated from scripts:
#
#	MANIFEST - from this script
#	configure - from autoconf (configure.in, aclocal.m4)
#	config.h - from configure
#
# Other files are all managed via RCS, and are present in a release only if
# they have had symbolic revisions added for that release.
#
failed() {
	echo "? $*"
	exit 1
}

unset LC_ALL
DOIT="eval"
DIRS=no
ECHO=
LINE=yes
OUTPUT=MANIFEST.tmp
if [ $# = 0 ]
then
	failed 'this requires a revision name (-r option)'
fi

while test $# != 0
do
	case $1 in
	-d)
		DIRS=yes
		;;
	-n)
		DOIT="echo"
		;;
	-p)
		DIRS=no
		LINE=no
		;;
	-r*)
		REV="`echo "$1" | sed -e 's/^-r//'`"
		;;
	-v)	ECHO="echo"
		;;
	-*)
		failed 'expected an "-r" option'
		;;
	*)
		break;
		;;
	esac
	shift
done

if test -z "$REV" ; then
	failed 'expected an "-r" option'
fi

# The remaining arguments are the names of files that we don't lookup in RCS
# (i.e., automatically-generated files that are useful in a distribution).

MYTMP=`mktemp -d`
ALL=$MYTMP/find
ANY=$MYTMP/keep
WD=`pwd`
trap "rm -rf $MYTMP; exit" EXIT INT QUIT TERM HUP

echo >"$ANY"

test "$#" != 0 && shift
while [ $# != 0 ]
do
	if [ -f "$1" ]
	then
		echo "$1" >>"$ANY"
	fi
	shift
done

##############################################################################
#
# Construct a list of the files that are present in the given release.  This
# would be faster, but the rcs programs don't have an easy way to find if a
# file has a specific version.  We do this by looking for the version in the
# list of symbolic revisions.
#
find . -type f | awk '
function dirname(path) {
	if (match(path, "/") > 0) {
		sub("/[^/]*$","",path);
	} else {
		path = ".";
	}
	return path;
}
function basename(path) {
	sub("^.*/","",path);
	return path;
} 
{
	sub("^[.]/","",$0);
	head=dirname($1);
	tail=basename($1);
	printf "%s\001%s\n", head, tail;
}' | csort | tr '\001' '/' >"$ALL"

BASE=`basename "$WD" | sed -e 's,-[0-9.-][0-9.-]*$,,'`
echo "Generating MANIFEST for $BASE, version $REV"

if [ -f $OUTPUT ]
then
	rm -f $OUTPUT
fi

if test $LINE = yes
then
cat >$OUTPUT <<EOF
MANIFEST for $BASE, version $REV
--------------------------------------------------------------------------------
EOF
fi

TAB=32
echo "MANIFEST	this file" | expand -t $TAB >>$OUTPUT

HAD_CFG=no
last=""
odir="."
while true
do
	TAB=32
	read -r name
	[ -z "$name" ] && break
	[ "$name" = "$last" ] && break

	leaf=`basename "$name"`
	ndir=`dirname "$name"`
	[ "$ndir" = . ] && name=$leaf
	temp=`(rlog -h "$name" \
		| sed -e '1,/symbolic names:/d' \
		| sed -e '/^[^ 	]/,$d' \
		| grep -F "${REV}":) 2>/dev/null`
	if [ -z "$temp" ]
	then
		if  ( grep -E '^'"$name"'$' "$ANY" >/dev/null 2>&1 )
		then
			echo "auto:$name"
			echo "$name" >>$OUTPUT
		elif [ -f configure.in ] && [ "$name" = config.guess ]
		then
			echo "$name	configure utility-script" | expand -t $TAB >>$OUTPUT
		elif [ -f configure.in ] && [ "$name" = config.sub ]
		then
			echo "$name	configure utility-script" | expand -t $TAB >>$OUTPUT
		elif [ "$name" = CHANGES ]
		then
			echo "$name	generated changelog" | expand -t $TAB >>$OUTPUT
		else
			[ -n "$ECHO" ] && echo "skip $name"
			last=$name
		fi
		continue
	fi
	CHR=`echo "$name" | wc -c | sed -e 's/[ 	]//g'`
	if test -n "$CHR" && test "$CHR" -gt "$TAB"
	then
		TAB=`expr "$CHR" + 1`
	fi
	[ -n "$ECHO" ] && echo "...>>$name"
	if [ "$name" = configure ]
	then
		HAD_CFG=yes
	fi
	if [ "$ndir" != "$odir" ]
	then
		if [ $DIRS = yes ]
		then
			echo "$ndir	subdirectory" | expand -t "$TAB" >>$OUTPUT
			odir=$ndir
		fi
	fi
	if [ "$leaf" = "config.h" ] && [ -f configure ] && [ -z "`rlog -t "$name"`" ]
	then
		[ -n "$ECHO" ] && echo '...ignored config.h (generated)'
	elif [ "$name" != "MANIFEST" ]
	then
		text=`rlog -t "$name" | sed -e '1,/description:/d' | head -1`
		echo "$name	$text" | expand -t "$TAB" >>$OUTPUT
	fi
	if [ "$name" = "configure.in" ] && [ -f configure ] && [ $HAD_CFG = no ]
	then
		# Postpone til after the files that generate 'configure' are
		# listed, so we can use this as an input list for 'shar'.
		echo "configure	Configuration script for UNIX" | expand -t "$TAB" >>$OUTPUT
	fi
	last=$name
done < "$ALL"

if [ -f "$OUTPUT" ]
then
	[ -n "$ECHO" ] && diff -u MANIFEST $OUTPUT
	$DOIT rm -f MANIFEST
	$DOIT mv $OUTPUT MANIFEST
else
	failed "no output-file was created"
fi
