#!/bin/sh
# $NetBSD: printindex,v 1.28 2005/11/28 01:14:35 rillig Exp $
#

# Copyright (c) 2001 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#        This product includes software developed by the NetBSD
#        Foundation, Inc. and its contributors.
# 4. Neither the name of The NetBSD Foundation nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

set -e

#
# Global variables
#

# The brokenfile_flag variable tells whether we want package-specific
# log files at all. If it is set to "yes", the mkdirs_flag
# variable tells whether the directories of the package-specific log
# files are created if necessary.
brokenfile_flag="yes"
mkdirs_flag="no"
pkgsrcdir="${PWD}"
bulkfilesdir="${pkgsrcdir}"
brokenfile=""

#
# Command line parsing
#

case $# in
0)	brokenfile_flag="no"
	;;
1)	brokenfile="$1"
	;;
2)	brokenfile="$1"
	bulkfilesdir="$2"
	if [ "${bulkfilesdir}" != "${pkgsrcdir}" ]; then
		mkdirs_flag="yes"
	fi
	;;
*)	echo "usage: $0 [brokenfile [bulkfilesdir]]" 1>&2
	exit 1
	;;
esac

#
# Sanity checks
#

case ${BMAKE-""} in
"")	echo "$0: error: BMAKE must be set and non-empty." 1>&2
	exit 1;;
esac
case ${bulkfilesdir} in
/*)	;;
*)	echo "$0: error: The <bulkfilesdir> argument must be absolute." 1>&2
	exit 1;;
esac
case ${brokenfile} in
*/*)	echo "$0: error: The <brokenfile> argument must not contain a slash." 1>&2
	exit 1;;
esac

#
# Get additional system information
#

cd "${pkgsrcdir}/pkgtools/pkglint"
BULK_PREREQ=`${BMAKE} show-var VARNAME=BULK_PREREQ`
GREP=`${BMAKE} show-var VARNAME=GREP USE_TOOLS=grep`
MKDIR=`${BMAKE} show-var VARNAME=MKDIR USE_TOOLS=mkdir`
SED=`${BMAKE} show-var VARNAME=SED USE_TOOLS=sed`
cd "${pkgsrcdir}"

case $mkdirs_flag in
yes)	mkbulkdir="${MKDIR}";;
*)	mkbulkdir=":";;
esac

case ${PKGLIST-""} in
"")	# List of all packages, from pkgsrc/*/Makefile
	list=`${GREP} '^[[:space:]]*'SUBDIR */Makefile | ${GREP} -v regress/ | ${SED} 's,/Makefile.*=[[:space:]]*,/,'`
	;;
*)	list="${PKGLIST}"
	;;
esac

#
# Sanity checks, part 2
#

allowed="
 +./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"
case $BULK_PREREQ in
*[!-"${allowed}"]*)
	inval=`echo "${BULK_PREREQ}" | tr -d " +\\\\-${allowed}"`
	echo "$0: error: BULK_PREREQ contains invalid characters (${inval})." 1>&2
	exit 1
esac
case $list in
*[!-"${allowed}"]*)
	inval=`echo "${list}" | tr -d " +\\\\-${allowed}"`
	echo "$0: error: The package list contains invalid characters (${inval})." 1>&2
	exit 1
esac

#
# Print the table of PKGPATH and PKGNAME.
#
# The check for duplicates is necessary to prevents double entries in
# the table. The use of the :detect_duplicates: delimiter prevents the
# inner "case" from occuring too often, as the $done_pkgs string grows
# to about 100k during one run of the program. This saves about
# 40 seconds on a 1 GHz Athlon.
#
done_pkgs=""
detect_duplicates=no
for pkgdir in $list :detect_duplicates: $BULK_PREREQ; do

	case $pkgdir in :detect_duplicates:)
		detect_duplicates=yes
		continue;;
	esac
	case $detect_duplicates in yes)
		case $done_pkgs in *="${pkgdir}"=*)
			continue;;
		esac;;
	esac

	if cd "${pkgsrcdir}/${pkgdir}"; then
		if pkgname=`${BMAKE} show-var VARNAME=PKGNAME`; then
			echo "${pkgdir}	${pkgname}"
			done_pkgs="${done_pkgs} =${pkgdir}="
		else
			echo "$0: error: could not extract PKGNAME for ${pkgdir} -- skipping." 1>&2

			case $brokenfile_flag in
			no)	continue;;
			esac

			${mkbulkdir} "${bulkfilesdir}/${pkgdir}"
			{ echo "[printindex] command failed: ${BMAKE} show-var VARNAME=PKGNAME"
			  ( ${BMAKE} show-var VARNAME=PKGNAME
			  ) || true
			} >> "${bulkfilesdir}/${pkgdir}/${brokenfile}" 2>&1
		fi
	else
		${mkbulkdir} "${bulkfilesdir}"
		{ echo "[printindex] command failed: cd ${pkgsrcdir}/${pkgdir}"
		  ( cd "${pkgsrcdir}/${pkgdir}"
		  ) || true
		} 1>&2
	fi
done