#!/bin/sh
# @(#)CHAPTER version 3.25 created 5/22/95
# @(#)Copyright (c), 1987, 1995 StatSci, Inc.  All rights reserved.

# Splus version of CHAPTER command
# Old S used to have a CHAPTER command, too, but nobody would be
# foolish enough to try making old S interface routines at this late date
# would they?
# 
# This script creates a Makefile which should be used to compile, load and
# install the chapter code. The name of the directory from which CHAPTER is
# run becomes the name of the chapter; this will be hardcoded into the
# Makefile. Avoid using characters like '.' in the directory name which have
# special meaning in C.
# 
# Splus CHAPTER [<files>.{cfrqsdo} ...]  \
# 		[lib="S-libsect ..." ...]  \
# 		[CFLAGS="<flags ...>"]  \
# 		[FFLAGS="<flags ...>"] \
# 		["<compile_flags_for_Splus_LOAD>"] \
# 		[fun="dumpfile ..." ...] \
# 		[<directory> ...]  
# 
# The file suffixes cfr refer to C, Fortran, Ratfor source. Both q and s are
# for S-language files, such as those produced by dump().  d is for nroff
# helpfiles, such as produced by prompt(). o is for object files.
# 
# <S-libsect> is the name of a standard S-PLUS library section, eg Slib=examples
# 
# In CFLAGS="<flags>" and FFLAGS="<flags>", <flags> means a list of C resp.
# Fortran compile flags.
# 
# <compile_flags_for_Splus_LOAD> and fun=<dumpfile> are for historical 
# compatibility and are not recommended. The same is true of <directory>;
# if <directory> begins with a slash, LOAD will tack on a ".a" and assume
# this points to an archive; if it is a relative pathname, LOAD will assume
# it leads to an $SHOME/library library or to another chapter.
# This will probably produce a Makefile that is not portable.

. $SHOME/adm/cmd/DIRNAMES

chapter=`basename \`pwd\``
C_specials=".,:+%=-"	# subset of characters nonalphanumeric in C which are 
			# remotely plausible in a directory name
if `echo x$chapter | grep "[${C_specials}]" >/dev/null`; then
	echo "Don't use these characters in a chapter name: $C_specials"
	exit 1
fi

if test -r Makefile
then
	echo "Splus CHAPTER: Makefile already exists -- will not overwrite"; exit 1
fi

CFLAGS="-O"
FFLAGS="-O2"
FLAGS=
LIB=\$\${SHOME}/newfun/lib
CHAPTERS=../$chapter
SRC=
OBJ=
FUNS=force_ld.q
HELPS=

for i
do
	case $i in
	lib*=*)
		x=`(IFS="="
		set $i
		shift
		echo " $1" | sed 's! !:$${SHOME}/newfun/lib/!g')`
		CHAPTERS="${CHAPTERS}$x"
		# backed out of lib= for dyn load target; idea was to 
		# add <sect>_init to EXTRA_C_NAMES with $extra_C_names, then
		# add $SHOME/newfun/lib/<sect>.a to FLAGS for ld -r.
		# (Would that break anything in static load target?)
		# y=`(IFS="="
		# set $i
		# shift
		# echo "$1 " | sed 's! !_init !g')`
		# extra_C_names="$extra_C_names $y"
		;;
	fun*=*)
		x=`(IFS="="
		set $i
		echo $2)`  # all of them
		FUNS="$FUNS $x"
		;;
	CFLAGS=*)
		# eval $i won't work with CFLAGS="flag1 flag2"
		# And want to support CFLAGS="-Dvar=value", with two ='s.
		CFLAGS="$CFLAGS `echo $i | sed 's:CFLAGS=::'`"
		;;
	FFLAGS=*)
		FFLAGS="$FFLAGS `echo $i | sed 's:FFLAGS=::'`"
		;;
	*.q|*.s) FUNS="$FUNS $i"
		;;
	*.d)	HELPS="$HELPS $i"
		;;
	*.c)
		SRC="$SRC $i"
		OBJ="$OBJ `basename $i .c`.o"
		;;
	*.f)
		SRC="$SRC $i"
		OBJ="$OBJ `basename $i .f`.o"
		;;
	*.r)
		SRC="$SRC $i"
		OBJ="$OBJ `basename $i .r`.o"
		;;
	*.o)
		OBJ="$OBJ $i"
		;;
	*)
		if test -d $i
		then
			# if $i is under this SHOME, substitute in $${SHOME}
			# for the local SHOME so it will work on a remote
			# machine too. Otherwise pass it thru unchanged.
			# This probably won't work anyway, since if the path
			# name starts with a slash then LOAD tacks on ".a" !
			irel=`echo $i | sed "s:$SHOME:\\$\\${SHOME}:"`
			CHAPTERS="$CHAPTERS:$irel"
# 			CHAPTERS="$CHAPTERS:$i"
		else
			FLAGS="$FLAGS $i"
		fi
	esac
done

( echo Makefile created by S-PLUS utility CHAPTER, version 3.25
  VERSION | grep S-PLUS
) | sed 's/^/# /' > Makefile

cat >>Makefile <<!

SHOME=$SHOME

WHICH_LOAD=static.load
# WHICH_LOAD=dyn.load
# WHICH_LOAD=dyn.load.shared

EXTRA_OBJ_FILES=
EXTRA_C_NAMES=
EXTRA_F_NAMES=

# This is a Makefile produced by the S-PLUS utility CHAPTER. It guides
# compilation of C, Ratfor and Fortran source code, loading of the resulting
# object code, and installation of functions and helpfiles.
# 
# Overview: 
# ========
# 
# You will need to attend to a few 'make' macro settings at the top of this
# file first.  See the Detailed Instructions below for these. Then, if you
# want to compile and load the default set of C and Fortran routines, type
# (1) 'make install' to install functions on ${DATA_DIR} and thereby enable
# building of the default list of compiled routine names, then (2) 'make
# load' to compile the object code, build the set of names to load, and load
# this object code.  Other, secondary, 'make' targets are 'install.funs' and
# 'install.help' ('install' makes both of those), 'clean' (remove only
# intermediate object code) and 'virgin' (remove object code, the local
# standalone S-PLUS executable if you built it, and the directory
# ${DATA_DIR}).
# 
# Detailed Instructions:
# =====================
# 
# 1. On the line near the top that starts with "SHOME=", change the
# directory pathname on the right of the equals sign to the pathname of the
# top S-PLUS directory on your machine; use Splus SHOME to get this
# pathname.
# 
# 2. Near the top, the macro WHICH_LOAD specifies whether 'make' targets
# 'load' and 'all' should make
# (a) a standalone S-PLUS binary executable named
# "local.Sqpe" which includes the local C and Fortran code, or
# (b) a dyn.loadable file "${chapter}_l.o" containing only this local code, or
# (c) a shared library "${chapter}.so" containing this local code
# and loadable with the dyn.load.shared function (this is the only form
# of dynamic loading available on Splus 3.3 for the Iris and Dec Alpha).
# To make a complete standalone executable, WHICH_LOAD should be set to
# "static.load"; the other possible values are "dyn.load" and
# "dyn.load.shared".  Make sure a # comment symbol (#) appears in front
# of the setting you DON'T want.
# The default has been set to "static.load".
# 
# Incidentally, you can always make targets 'static.load', 'dyn.load',
# and 'dyn.load.shared' regardless of the value of WHICH_LOAD.
# The macro just specifies what the generic targets 'load' and 'all'
# should make.
# 
# 3. Near the top, the macro EXTRA_OBJ_FILES names object files (ending in
# ".o") which should be loaded in addition to those which are part of this
# chapter.  Add any additional object file names you want to load, separated
# by spaces, on the right hand side of the equals sign.  There MUST be
# corresponding C (".c"), Ratfor (".r") or Fortran (".f") files present in
# this directory.
# 
# If you add file names to EXTRA_OBJ_FILES, you must also add the names of
# the corresponding C functions or Fortran subroutines to the macros
# EXTRA_C_NAMES and EXTRA_F_NAMES respectively, underneath EXTRA_OBJ_FILES.
# The names added should be as they appear at the source-code level; do not
# add leading or trailing underscores unless these are present in the
# source-level name.
# 
# You won't generally need to change any more 'make' macros, or indeed
# anything else in this Makefile.
# 
# 4. The file ${chapter}_i.c is a C language source file which will ensure
# that the make target 'load' will load C and Fortran routines referenced
# only through .C or .Fortran calls in S functions. If ${chapter}_i.c does
# not exist, it will be made during 'make load' based on the objects in
# $DATA_DIR. If ${chapter}_i.c exists already and you have since added new C
# or Fortran routine names to EXTRA_C_NAMES and EXTRA_F_NAMES, you must
# remove ${chapter}_i.c so that it will get remade using this new
# information. Do this now.
# 
# 5. Type 'make install.funs' to create the S functions on $DATA_DIR.  This
# must precede 'make load' in Step 6. (You can install the helpfiles at
# this point as well by typing making 'install' instead of 'install.funs'.)
# 
# 6. Type 'make load'. This will build the list of routines to load, then
# compile the C, Ratfor and Fortran source files specified by this Makefile,
# and lastly load the routines named on the list into either a standalone
# S-PLUS executable or a dyn.loadable file or a shared library.
# 
# 7. To remove unnecessary object files, type 'make clean'. This will not
# remove the dyn.loadable file ${chapter}_l.o, the shared library
# ${chapter}.so, or the standalone local.Sqpe.  To clean out everything
# including $DATA_DIR and start over, use 'make virgin'.
# 
# 8. See the helpfile for the "library" function in S-PLUS for hints on
# how to install the new code as a library section.


# ========================= End instructions. =============================

default : all
include $(SHOME)/newfun/lib/S_makefile
chapters=$CHAPTERS
SRC=$SRC
OBJ=$OBJ \$(EXTRA_OBJ_FILES)
CFLAGS=$CFLAGS
FFLAGS=$FFLAGS
FUNS=$FUNS
HELPS=$HELPS
FLAGS=$FLAGS
RM=-rm

all load: $(WHICH_LOAD)

static.load: ${chapter}.a
	Splus LOAD \$(FLAGS) CHAPTERS='"\$(chapters)"'

dyn.load ${chapter}_l.o: ${chapter}.a
	ld -r -o ${chapter}_l.o ${chapter}_i.o ${chapter}.a \$(FLAGS)
	@echo dynamically loadable file in ${chapter}_l.o

dyn.load.shared ${chapter}.so: \$(SRC)
	Splus SHLIB -o ${chapter}.so \$(SRC)

${chapter}.a: ${chapter}_i.o \$(OBJ) 
	Splus LIBRARY ${chapter}.a ${chapter}_i.o \$(OBJ)

${chapter}_i.c:
	-mkdir $DATA_DIR
	Splus make.init $chapter $DATA_DIR

install : install.funs install.help

funs install.funs : \$(FUNS) $DATA_DIR
	Splus QINSTALL $DATA_DIR \$(FUNS)

force_ld.q :
	( echo "force.loading <- function(){" ;\\
	set \$(EXTRA_C_NAMES) terminator ;\\
	while test \$\$1 != terminator ;\\
	do \\
		echo \$\$1 | sed 's:.*:.C("&"):' ;\\
		shift ;\\
	done ;\\
	set \$(EXTRA_F_NAMES) terminator ;\\
	while test \$\$1 != terminator ;\\
	do \\
		echo \$\$1 | sed 's:.*:.Fortran("&"):' ;\\
		shift ;\\
	done ;\\
	echo } \\
	) > \$@


# force_ld.q :
# 	echo "force.loading <- function(){ X\\
# 		stop(\"should not be executed\") X\\
# 		# Add .C and .Fortran calls here to force routines to  X\\
# 		# be loaded. For example, .C(\"fun1\"), .Fortran(\"fun2\"). X\\
# 	}" | tr X \\\\012  > \$@

help install.help : \$(HELPS) $DATA_DIR/$HELP_DIR
	Splus HINSTALL $DATA_DIR/$HELP_DIR \$(HELPS)
	Splus help.findsum $DATA_DIR

$DATA_DIR :
	-mkdir \$@
$DATA_DIR/$HELP_DIR : $DATA_DIR
	-mkdir \$@

virgin : clean virgin.std
# add additional cleanup rules/targets above here for target 'virgin'
clean :
	\$(RM) -f \$(OBJ) ${chapter}_i.o S_load_time.[oc] core
virgin.std :
	\$(RM) -rf $DATA_DIR
	\$(RM) -f $chapter.a local.Sqpe ${chapter}_l.o ${chapter}.so ${chapter}_i.c force_ld.q
!
