#!/bin/sh

# This script generates:
# $2/libraries:
#	copies of the heirarchical libraries suitable for
#	use with Hugs.  Note that some of the libraries require extensions
#	to Haskell 98 and have to be run with the -98 flag.
# $2/oldlib:
#	compatibility stubs for old Hugs libraries
#
# A HUGSPATH consisting of both of these should approximate the old libs,
# and be fairly compatible with GHC.  If you're completely switched over,
# delete the second one.
#
# Usage:
#
#   ./convert_libraries <fptools directory> <build directory>
#
# NOTE: This script expects to be run in the top-level hugs98 directory,
# and contains paths relative to there.

case $# in
2)	;;
*)	echo "usage: $0 <fptools directory> <build directory>" >&2
	exit 1 ;;
esac

src=$1/libraries
if [ ! -d $src ]; then
	echo "Can't find libraries in directory '$1'" >&2
	exit 1
fi

hs_src=$1/hslibs
if [ ! -d $hs_src ]; then
	echo "Can't find hslibs in directory '$1'" >&2
	exit 1
fi

target="$2"
compat="$target/oldlib"

# parameters set by configure
case $0 in
*/*)	. `dirname $0`/config ;;
*)	. ./config ;;
esac

# Create a compatibility stub for a Hugs extension module

stub() {
	case $# in
	0)	echo "usage: stub module [module ...]" >&2
		exit 1 ;;
	esac

	stub_module=$1
	shift
	echo "Stub $stub_module -> $*"
	(
		echo "module $stub_module("
		for real
		do	echo "	module $real,"
		done
		echo '    ) where'
		echo
		for real
		do	echo "import $real"
		done
	) >$compat/$stub_module.hs
}

# Copy the Hugs version to the compatibility lib

libexts() {
	case $# in
	1)	;;
	*)	echo "usage: libexts module" >&2
		exit 1 ;;
	esac

	name="`ls lib/exts/$1.*hs`"
	echo "Copy `basename $name`"
	sed 's/import Prelude/import Hugs.Prelude/' $name >$compat/`basename $name`
}

libhugs() {
	case $# in
	1)	;;
	*)	echo "usage: libhugs module" >&2
		exit 1 ;;
	esac

	name="`ls lib/hugs/$1.*hs`"
	echo "Copy `basename $name`"
	sed 's/import Prelude/import Hugs.Prelude/' $name >$compat/`basename $name`
}

# Convert the hslibs version to the compatibility lib

hslibs() {
	case $# in
	2)	;;
	*)	echo "usage: hslibs dir file" >&2
		exit 1 ;;
	esac

	echo "Copy $2"
	cp $hs_src/$1/$2 $compat/$2
}

# Copy package examples (if any) to the demos directory

copy_examples() {
	from_dir=$1
	to_dir=$2
	if [ -d $from_dir/examples ]
	then	(cd $from_dir;
		 $FIND examples -follow -name CVS -prune -o \! -name .cvsignore \! -name Makefile \! -name makefile -type f -print) |
			sed 's:^examples/::' |
			while read name
			do
				target_file="$to_dir/$name"
				mkdir -p `dirname $target_file`
				cp $from_dir/examples/$name $target_file
			done
	fi
}

# Convert hierarchical modules

build_package() {
	source_dir=$1
	target_dir=$2
	cd $source_dir
	top_dir=`echo $source_dir | sed 's:[^/][^/]*:..:g'`

	HUGSDIR="$top_dir/$target"
	HUGSFLAGS="-P{Hugs}/libraries:{Hugs}/packages/*:$top_dir/libraries/bootlib"
	export HUGSDIR HUGSFLAGS

	runhugs=$top_dir/src/runhugs
	ffihugs=$top_dir/src/ffihugs
	HugsSetup="$runhugs -98 $top_dir/fptools/libraries/Cabal/examples/hapax.hs"

	case "$happy" in
	'')	happyflag= ;;
	/*)	happyflag="--with-happy=$happy" ;;
	*)	happyflag="--with-happy=$top_dir/$happy" ;;
	esac

	$HugsSetup configure --verbose --hugs \
			--builddir="$top_dir/$target_dir" \
			--with-hsc2hs="$top_dir/libraries/tools/hsc2hs" \
			--with-cpphs="$top_dir/libraries/tools/cpphs" \
			--with-compiler="$top_dir/src/ffihugs" $happyflag
	if $HugsSetup build --verbose; then
		for name in LICEN[CS]E* COPYING* COPYRIGHT* copyright; do
			if test -f $name; then
				cp $name $top_dir/$target_dir
			fi
		done
	else	echo "Skipping $package package"
	fi
	cd "$top_dir"
}

# Distinguish two classes of package:
# core_packages - released with Hugs and not independently updated
#	(these go in a unified hierarchy under {Hugs}/libraries)
# extra_packages - packaged with Hugs, but may also be independently updated
#	(each of these goes in a separate hierarchy under {Hugs}/packages)

core_packages='base haskell98 haskell-src network'
extra_packages='Cabal QuickCheck mtl fgl HaXml parsec HUnit'

#
# ToDo: fix -- cygwin supports 'unix' only when no -mno-cygwin is given to gcc
#
case `uname -a` in
CYGWIN*|MINGW32*)
	extra_packages="$extra_packages Win32" ;;
*)	core_packages="$core_packages unix" ;;
esac

extra_packages="$extra_packages X11 HGL OpenGL GLUT OpenAL"

build_package "libraries/hugsbase" $target/libraries

for package in $core_packages
do
	build_package $src/$package $target/libraries
	copy_examples $src/$package $target/demos/$package
done

for package in $extra_packages
do
	build_package $src/$package $target/packages/$package
	if test -d $target/packages/$package; then
		copy_examples $src/$package $target/demos/$package
	fi
done

# Compatibility with lib/exts:

mkdir -p $compat

# Hugs-only modules

  stub ConcBase		Hugs.ConcBase
  stub Memo		Hugs.Memo	# hslibs module is different
  stub Observe		Hugs.Observe	# hslibs module is different

# Stuff from hslibs (many of these are stubs)

  hslibs concurrent CVar.lhs		# superseded by MVars
  hslibs concurrent Chan.lhs		# -> Control.Concurrent.Chan
  hslibs concurrent Channel.lhs		# -> Control.Concurrent.Chan
  hslibs concurrent ChannelVar.lhs	# superseded by MVars
  hslibs concurrent Concurrent.lhs	# -> Control.Concurrent
  hslibs concurrent MVar.lhs		# -> Control.Concurrent.MVar
# hslibs concurrent Merge.lhs		# needs pre-emptive concurrency
  hslibs concurrent Parallel.lhs	# -> Control.Parallel
  hslibs concurrent QSem.lhs		# -> Control.Concurrent.QSem
  hslibs concurrent QSemN.lhs		# -> Control.Concurrent.QSemN
  hslibs concurrent SampleVar.lhs	# -> Control.Concurrent.SampleVar
  hslibs concurrent Semaphore.lhs	# -> Control.Concurrent.QSem Control.Concurrent.QSemN
# hslibs concurrent Strategies.lhs

  hslibs data FiniteMap.lhs		# -> Data.FiniteMap
  hslibs data Set.lhs			# -> Data.Set

  cp $hs_src/data/edison/COPYRIGHT $compat/COPYRIGHT.edison
  hslibs data/edison/Assoc Assoc.hs
  hslibs data/edison/Assoc AssocDefaults.hs
  hslibs data/edison/Assoc AssocList.hs
  hslibs data/edison/Assoc PatriciaLoMap.hs
  hslibs data/edison EdisonPrelude.hs
  hslibs data/edison/Coll Collection.hs
  hslibs data/edison/Coll CollectionDefaults.hs
  hslibs data/edison/Coll CollectionUtils.hs
  hslibs data/edison/Coll LazyPairingHeap.hs
  hslibs data/edison/Coll LeftistHeap.hs
  hslibs data/edison/Coll MinHeap.hs
  hslibs data/edison/Coll SkewHeap.hs
  hslibs data/edison/Coll SplayHeap.hs
  hslibs data/edison/Coll TestOrdBag.hs
  hslibs data/edison/Coll TestOrdSet.hs
  hslibs data/edison/Coll UnbalancedSet.hs
  hslibs data/edison/Seq BankersQueue.hs
  hslibs data/edison/Seq BinaryRandList.hs
  hslibs data/edison/Seq BraunSeq.hs
  hslibs data/edison/Seq JoinList.hs
  hslibs data/edison/Seq ListSeq.hs
  hslibs data/edison/Seq MyersStack.hs
  hslibs data/edison/Seq RandList.hs
  hslibs data/edison/Seq RevSeq.hs
  hslibs data/edison/Seq Sequence.hs
  hslibs data/edison/Seq SequenceDefaults.hs
  hslibs data/edison/Seq SimpleQueue.hs
  hslibs data/edison/Seq SizedSeq.hs
  hslibs data/edison/Seq TestSeq.hs

  hslibs hssource HsLexer.hs		# -> Language.Haskell.Lexer
  hslibs hssource HsParseMonad.hs	# -> Language.Haskell.ParseMonad
  hslibs hssource HsParseUtils.hs	# -> Language.Haskell.ParseUtils
  hslibs hssource HsParser.hs		# -> Language.Haskell.Parser
  hslibs hssource HsPretty.hs		# -> Language.Haskell.Pretty
  hslibs hssource HsSyn.hs		# -> Language.Haskell.Syntax

# hslibs lang Addr.lhs			# deprecated
 libexts Addr
  hslibs lang ArrayBase.hs		# -> Data.Array.Base
  hslibs lang Arrow.hs			# -> Control.Arrow
# hslibs lang ByteArray.lhs		# deprecated
# hslibs lang CTypesISO.hs		# uses C preprocessor
  hslibs lang DiffArray.hs		# -> Data.Array.Diff
# hslibs lang DirectoryExts.hs
  hslibs lang Dynamic.hs		# -> Data.Dynamic
  hslibs lang Exception.hs		# -> Control.Exception
# hslibs lang ForeignObj.lhs		# deprecated
 libexts ForeignObj			# uses Hugs primitives
# hslibs lang Generics.hs		# -> Data.Generics
# hslibs lang GlaExts.lhs		# deprecated
  hslibs lang IArray.hs			# -> Data.Array.IArray
# hslibs lang IOExts.hs
  stub IOExts		Hugs.IOExts Hugs.IORef Hugs.IOArray System.IO.Unsafe Debug.Trace
  hslibs lang IORef.hs			# -> Data.IORef
# hslibs lang LazyST.hs
  stub LazyST		Data.STRef.Lazy Control.Monad.ST.Lazy Hugs.LazyST
# hslibs lang MArray.hs			# lots of GHC stuff (and obsolete)
# hslibs lang MutableArray.lhs		# deprecated
  hslibs lang NativeInfo.hs		# -> System.Info
# hslibs lang NumExts.lhs		# uses C preprocessor
  hslibs lang PackedString.lhs		# -> Data.PackedString
# hslibs lang PrelByteArr.lhs		# GHC-specific
# hslibs lang ST.hs			# GHC-specific
  stub ST		Data.STRef.Strict Data.Array.ST Control.Monad.ST Hugs.ST
  hslibs lang ShowFunctions.hs		# -> Text.Show.Functions
  hslibs lang Stable.hs			# -> Foreign.StablePtr System.Mem.StableName
  hslibs lang StableName.hs		# -> System.Mem.StableName
  hslibs lang StorableArray.hs		# -> Data.Array.Storable
# hslibs lang SystemExts.lhs		# GHC-specific
# hslibs lang TimeExts.lhs
  hslibs lang Weak.hs			# -> System.Mem.Weak

  hslibs lang/monads MonadCont.lhs	# -> Control.Monad.Cont
  hslibs lang/monads MonadEither.lhs	# -> Control.Monad.Error
  hslibs lang/monads MonadError.lhs	# -> Control.Monad.Error
  hslibs lang/monads MonadFix.lhs	# -> Control.Monad.Fix
  hslibs lang/monads MonadIdentity.lhs	# -> Control.Monad.Identity
  hslibs lang/monads MonadList.lhs	# -> Control.Monad.List
  hslibs lang/monads MonadRWS.lhs	# -> Control.Monad.RWS
  hslibs lang/monads MonadReader.lhs	# -> Control.Monad.Reader
  hslibs lang/monads MonadState.lhs	# -> Control.Monad.State
  hslibs lang/monads MonadTrans.lhs	# -> Control.Monad.Trans
  hslibs lang/monads MonadWriter.lhs	# -> Control.Monad.Writer
  hslibs lang/monads Monoid.lhs		# -> Data.Monoid

  hslibs net BSD.hs			# -> Network.BSD
  hslibs net CGI.lhs			# -> Network.CGI
  hslibs net Socket.lhs			# -> Network.Socket
  hslibs net SocketPrim.hs		# -> Network.Socket
  hslibs net URI.hs			# -> Network.URI

# hslibs posix DL.hs
# hslibs posix DLPrim.hsc
# hslibs posix POpen.hs
# hslibs posix Posix.lhs
  hslibs posix PosixDB.lhs
# hslibs posix PosixErr.lhs
  hslibs posix PosixFiles.lhs
  hslibs posix PosixIO.lhs
# hslibs posix PosixProcEnv.lhs		# uses C preprocessor
# hslibs posix PosixProcPrim.lhs
  hslibs posix PosixTTY.lhs
# hslibs posix PosixUtil.lhs

  hslibs text Pretty.lhs		# -> Text.PrettyPrint.HughesPJ
  hslibs text RegexString.lhs		# -> Text.Regex

  hslibs text/html Html.lhs		# -> Text.Html
  hslibs text/html HtmlBlockTable.lhs	# -> Text.Html.BlockTable

  hslibs text/parsec Parsec.hs		# -> Text.ParserCombinators.Parsec
  hslibs text/parsec ParsecChar.hs	# -> Text.ParserCombinators.Parsec.Char
  hslibs text/parsec ParsecCombinator.hs # -> Text.ParserCombinators.Parsec.Combinator
  hslibs text/parsec ParsecError.hs	# -> Text.ParserCombinators.Parsec.Error
  hslibs text/parsec ParsecExpr.hs	# -> Text.ParserCombinators.Parsec.Expr
  hslibs text/parsec ParsecLanguage.hs	# -> Text.ParserCombinators.Parsec.Language
  hslibs text/parsec ParsecPerm.hs	# -> Text.ParserCombinators.Parsec.Perm
  hslibs text/parsec ParsecPos.hs	# -> Text.ParserCombinators.Parsec.Pos
  hslibs text/parsec ParsecPrim.hs	# -> Text.ParserCombinators.Parsec.Prim
  hslibs text/parsec ParsecToken.hs	# -> Text.ParserCombinators.Parsec.Token

  hslibs util GetOpt.lhs		# -> System.Console.GetOpt
# hslibs util Memo.lhs			# Hugs module is different
# hslibs util Observe.lhs		# Hugs module is different
# hslibs util Readline.hs		# -> System.Console.Readline
# hslibs util Select.lhs
  hslibs util Unique.lhs		# -> Data.Unique

  hslibs util/check QuickCheck.hs	# -> Debug.QuickCheck
# hslibs util/check QuickCheckBatch.hs	# -> Debug.QuickCheck.Batch
  hslibs util/check QuickCheckPoly.hs	# -> Debug.QuickCheck.Poly
  hslibs util/check QuickCheckUtils.hs	# -> Debug.QuickCheck.Utils

# Compatibility with lib/hugs:

  libhugs AnsiInteract
  libhugs AnsiScreen
     stub CVHAssert		Hugs.CVHAssert
     stub GenericPrint		Hugs.GenericPrint
     stub HugsInternals		Hugs.Internals
  libhugs HugsLibs				# only useful for testing
     stub IOExtensions		Hugs.IOExts
  libhugs Interact
  libhugs ListUtils
  libhugs Number
  libhugs ParseLib
     stub Quote			Hugs.Quote	# only hugs supports here docs
  libhugs StdLibs				# only useful for testing
     stub Trace			Debug.Trace
     stub Trex			Hugs.Trex	# only hugs supports Trex

# Graphics library

     stub SOEGraphics		Graphics.SOE
     stub GraphicsCore		Graphics.HGL.Core
     stub GraphicsUtils		Graphics.HGL
