#! /bin/sh
### ====================================================================
### This is a simple wrapper for ghostscript to provide an extended and
### enhanced search path that eliminates the need for ghostscript
### build-time local search path customization, and to allow ghostscript
### version number selection on the command line, for sites that
### preserve multiple versions.
###
### Usage:
###	gs-wrapper [-x.yz] [ghostscript-options-and-files]
###
### The -x.yz option, where at least x is a decimal digit, if specified
### must be first: it identifies a particular installed version of
### ghostscript as gs-x.yz.  Otherwise, the default version is set below
### by the local installer, generally to the latest stable ghostscript
### version.
###
### The optional user-defined GS_LIB environment variable is a
### colon-separated list of directories to search for fonts and input
### PostScript library files.  All empty components (initial, embedded,
### or final) in that path are replaced by a local-site-dependent search
### path.  If GS_LIB is not defined, it is set to :, which will then be
### replaced by the local default.
###
### Typical user settings of GS_LIB might be something like these:
###
###	GS_LIB=:$HOME/fonts//			# user font directory tree last
###	GS_LIB=$HOME/fonts//:			# user font directory tree first
###	GS_LIB=$HOME/newfonts::$HOME/fonts//	# system default in middle
###
### After creating the augmented GS_LIB environment variable by
### default-path substitution, any directories in that new path list
### which end in two (or more) slashes will be replaced with a sorted
### list of that directory and all of the subdirectories recursively
### nested below it.  Any nonexistant or nonexecutable directories are
### discarded from the list.
###
### To aid in debugging, if the environment variable GS_DEBUG is set to
### a nonempty value, debug output for variable setting will be written
### to stdout.
###
### ====================================================================
###
###                          INSTALLATION NOTE
###
### This script is typically stored in a central shared file system, and
### then symlinked to the gs executable in the shell search path, so
### that all changes to the master copy are immediately available the
### next time a user invokes gs.  In particular, this script provides a
### default ghostscript version and search path, so that system managers
### can change these instantly if necessary.
###
### ====================================================================
###
###                               LICENSE
###
### This script is made available for use under the same terms
### as ghostscript:
###
###	the Aladdin Free Public License (AFPL) [Version 9, September 18,
###	2000, or later: see the file ${gsdatadir}/doc/PUBLIC],
###
### or
###
###	the GNU General Public License (GPL) [Version 2, June 1991, or
###	later: see the file ${gsdatadir}/doc/COPYING]
###
### depending on the ghostscript version and code source (Aladdin or
### GNU).
###
### ====================================================================
###
###                             WARNING
###
### Because of outdated draconian limits on the size of the environment
### string space in many UNIX implementations (ARG_MAX, _SC_ARG_MAX, and
### _POSIX_ARG_MAX in system header files, accessible in C as
### sysconf(_SC_ARG_MAX)), and an even smaller ghostscript-imposed limit
### (25, the value of GS_MAX_LIB_DIRS in src/imainarg.c for ghostscript
### versions up to and including 7.20, but changeable at compile time)
### on the number of directories in the path, if the expanded GS_LIB
### path is too long, ghostscript will exit immediately with a return
### code of 255.  You should therefore test whether ghostscript will run
### with GS_LIB paths typical of your site before making this script the
### default interface to ghostscript!
###
### ====================================================================
###
###                              NOTE
###
### This script will require local customization from time to time as
### new stable versions of ghostscript are installed, or additional font
### directories are added.  Search for "**CUSTOMIZE**" below.
###
### Please log your customizations here, in reverse chronological order:
###
### [17-May-2002] -- Original version by Nelson H. F. Beebe
###                  <beebe@math.utah.edu>
### ====================================================================

### **CUSTOMIZE** the system-default version of ghostscript here:
version=7.20

### Programs that we need below; some site may wish to **CUSTOMIZE**
### them with, for example, absolute paths:
dirname=dirname
echo=echo
find=find
ls=ls
sed=sed
sort=sort
test=test
tr=tr

gs_debug_trace()
{
    ## -----------------------------------------------------------------
    ## Display a message on stdout if GS_DEBUG is nonempty.
    ##
    ## Usage:
    ##	gs_debug_trace message text
    ## -----------------------------------------------------------------

    ${test} -n "${GS_DEBUG}" && ${echo} "## DEBUG:" "$@"
    ## ${test} -n "${GS_DEBUG}" && ${echo} DEBUG: environment size = `env | wc -c`
}

gs_expand_dir()
{
    ## -----------------------------------------------------------------
    ## Given a colon-separated directory path on the command line, split
    ## it into separate directories, and then expand any that end in two
    ## (or more) slashes to a sorted list of that directory and all of
    ## its recursively nested subdirectories.
    ##
    ## Usage:
    ##		gs_expand_dir dir1:dir2:dir3:...:dirn
    ##		gs_expand_dir dir1//:dir2:dir3:...:dirn//
    ##
    ## -----------------------------------------------------------------

    ## NB: We intentionally avoid using IFS=: for field splitting, since
    ## that unnecessarily complicates construction of newpath, and can
    ## introduce nasty security holes as well.
    dirs=`${echo} $1 | ${sed} -e 's@:@ @g'`

    newpath=
    for d in ${dirs}
    do
	${test} -d ${d} || continue	# discard nonexistant directories
	${test} -x ${d} || continue	# discard nonexecutable directories
	case ${d} in
	*//)
	    e=`${echo} ${d} | ${sed} -e 's@//*$@@g'`
	    newpath=${newpath}:`${find} ${e} -type d |
			    ${sort} |
				    ${tr} '\n' ':' |
					    ${sed} -e 's@:$@@g' `
	    ;;
	*)
	    newpath=${newpath}:${d}
	    ;;
	esac
    done

    ## Remove the initial colon
    newpath=`${echo} ${newpath} | ${sed} -e 's@^:@@'`

    ${echo} ${newpath}
}

### Reduce the environment size by removing common, but unneeded
### variables, to try to work around the ridiculously low and
### arbitrary limits on environment string space in many UNIX systems.

gs_debug_trace environment size = `env | wc -c`

unset	A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
unset	AB2_DEFAULTSERVER AFMPATH BIBINPUTS CLASSPATH DVIPSHEADERS EDITOR \
	GROUP HELPPATH HZDIR HZINPUTDIR LCCTOP LESS LESSOPEN LS_COLORS MAIL \
	MFINPUTS NNTPSERVER OPENWINHOME PGPPATH PLT PROCDIR PVM_ROOT QTDIR \
	TEX TEXCONFIG TEXFONTS TEXINPUTS TEXPKS THOTDIR STEX VENDOR VFFONTS \
	XDVIFONTS

gs_debug_trace environment size = `env | wc -c`

### Handle any command-line version option:

if ${test} $# -gt 0
then
	case $1 in
	-[0-9]*)
		version=`${echo} $1 | ${sed} -e 's@^-@@'`
		shift
		;;
	*)
		;;
	esac
fi

### Assume the usual GNU directory structure
###
###	${prefix}/{bin,share/ghostscript}
###
### computing it from the location of this script.

### The directory of the ghostscript executable:
bindir=`${dirname} $0`

### The root of the local installation (often /usr/local):
prefix=`${dirname} ${bindir}`

### The basename of the requested ghostscript executable:
gs=${bindir}/gs-${version}

### The root of the ghostscript installation tree:
gsdir=${prefix}/share/ghostscript

### The version-specific ghostscript installation tree:
gsdatadir=${gsdir}/${version}

### The TeX directory tree:
texdir=${prefix}/share/lib/tex

### The root of the local TeX fonts tree:
texfontdir=${texdir}/fonts

### The root of the local TeX Live n (**CUSTOMIZE**) tree:
texlivedir=${texdir}/texlive6

gs_debug_trace bindir = ${bindir}
gs_debug_trace prefix = ${prefix}
gs_debug_trace gsdir = ${gsdir}
gs_debug_trace gsdatadir = ${gsdatadir}
gs_debug_trace texdir = ${texdir}
gs_debug_trace texfontdir = ${texfontdir}
gs_debug_trace texlivedir = ${texlivedir}

if ${test} ! -f "${gs}"
then
	${echo} ${gs} does not exist
	${echo} Perhaps you want one of these versions: `cd ${bindir}; ${ls} gs-[0-9]*`
	exit 1
fi

if ${test} ! -d "${gsdatadir}"
then
	${echo} ${gsdatadir} does not exist
	${echo} Perhaps you want one of these versions: `cd ${gsdir}; ${ls} [0-9]*`
	exit 1
fi

### **CUSTOMIZE** this list of directories according to local site
### requirements.  Generally, the lib directory should be first, then
### the version-specific fonts and examples directories, then the
### version-independent font directory, followed by local directories
### that contain fonts.

GS_LIB_DEFAULT=${gsdatadir}/lib
GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${gsdatadir}/fonts
GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${gsdatadir}/examples
GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${gsdir}/fonts
GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${prefix}/share/sys/fonts/postscript
GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${texfontdir}/lucida
GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${texfontdir}/mathtime
GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${texfontdir}/postscript/bakoma/pfb
GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${texfontdir}/vf

### Because of the very small GS_MAX_LIB_DIRS value in previously-built
### ghostscript versions, we do not include the long TeX Live path
### component in versions up to 7.20.
${test} `${echo} ${version} | ${sed} -e 's@[.]@@'` -gt 720 && \
	GS_LIB_DEFAULT=${GS_LIB_DEFAULT}:${texlivedir}/texmf/fonts/type1//

### Set default search path if GS_LIB is not set by user
${test} -z "${GS_LIB}" && GS_LIB=:

gs_debug_trace BEFORE default substitution and subdirectory expansion: GS_LIB = ${GS_LIB}

### Handle any default directory substitution, treating more than two
### consecutive colons as equivalent to two:
GS_LIB=`${echo} ${GS_LIB} |
	${sed} -e "s@^:@${GS_LIB_DEFAULT}:@" |
	${sed} -e 's@:$@:'"${GS_LIB_DEFAULT}@" |
	${sed} -e "s@:::*@:${GS_LIB_DEFAULT}:@"`

gs_debug_trace AFTER default substitution and BEFORE subdirectory expansion: GS_LIB = ${GS_LIB}

### Finally, handle any recursive path expansion:
GS_LIB=`gs_expand_dir ${GS_LIB}`

export GS_LIB

gs_debug_trace AFTER default substitution and subdirectory expansion: GS_LIB = ${GS_LIB}

gs_debug_trace ${gs} "$@"

${gs} "$@"
