#! /bin/sh

# importify: a debugging utility script, which induces static inclusion of
# S-Lang importable module code into slsh.  This makes the module code
# available to the debugger at process startup (instead of deferring such
# until after the module has been imported), which simplifies debugging.
#
# $1, $2, ... $N are the module names (unquoted).  For example,
#
#	./importify gtk xpa
#
# will generate C code which pulls in the S-Lang gtk and xpa moduies.
#
# The generated code is written to stdout.  Typically the script would
# be invoked w/in a Makefile, with its output captured to a .c file and
# compiled into a suitably-named <something>slsh executable.
#
# The script searches for slsh.c first in $PWD, then in a default location.
# It would be useful to support the generation of stubs for programs other
# than slsh.
#
# The generated code will also create an S-Lang #define named
#
#			__NO_<modulename>_IMPORT__
#
# which, again using the xpa module as an example , can be referenced in
# your primary/starter/bootstrap .sl script as
#
#		#ifndef __NO_XPA_IMPORT__
#		import("xpa");
#		#endif
#
# to enable the module to be used either within a "vanilla" slsh or in 
# the module-enhanced slsh produced by this script (while avoiding any
# duplicate definition errors).  Another way to achieve the same effect
# would be to have your primary .sl check for the existence of a function
# or variable defined within the module itself, as in
#
#		#ifnexists xpaget
#		import("xpa");
#		#endif
#
# CAVEATS:
#
# Only supports namespace-extended module initialization semantics, via
#
#		init_<modulename>_module_ns 
#
# If your code provides an older-style
#
#		init_<modulename>_module
#
# initializer it should be upgraded, since the older semantics only 
# permit the module to be loaded into the Global namespace.
#
# This file is part of SLgtk, the S-Lang bindings for GTK+.
# Copyright (C) 2002-2004 Michael S. Noble <mnoble@space.mit.edu>
# 
# This script is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
# 
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.

name=`basename $0`
version="0.9"

instruct()
{
   echo ""
   echo "${name}, version ${version} (mnoble@space.mit.edu)"
   echo "Emits to stdout a copy of slsh.c, modified to facilitate static"
   echo "loading of one or more embedded S-Lang modules."
   echo ""
   echo "Usage: $name [options] module_name [ module_name ...]"
   echo ""
   echo "Options:"
   echo "-h                   generate this message"
   echo "-m symbol            allow main() to be overridden, by renaming it to symbol()"
   echo "-p                   do not generate prototype for module init func"
   echo "-q                   generate quiet code (no startup messages)"
   echo "-s path_to_slsh.c    useful when slsh.c is not in \$PWD"
   echo ""
   exit 1
}

set -- `getopt hm:pqs: $* `
if [ $? != 0 ] ; then
   Instruct
fi

ProtoInit=1;
while [ $1 != -- ] ; do
   case $1 in
	-h) instruct ;;
	-m) DefineMain="#define main $2" ;;
	-p) ProtoInit=0 ;;
	-q) Quiet=1 ;;
	-s) if [ -n "$2" ] && [ -r $2 ] ; then
		slsh_source=$2
	    else
		echo "Warning: $2 not found, will look for slsh.c in ." >&2
	    fi
	    shift
	    ;;

   esac
   shift
done
shift

if [ -z "$slsh_source" ] ; then
   slsh_source="slsh.c"
fi

if [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then
   instruct
fi

if [ ! -r $slsh_source ] ; then
   echo "Error: could not locate slsh.c sourcecode"
   instruct
fi

echo "/* auto-generated by importify script - DO NOT EDIT!!  */"
echo "/* Written by Michael S. Noble (mnoble@space.mit.edu)  */"
echo ""
echo "static int statically_load_modules(void);"
echo ""
echo $DefineMain

cat $slsh_source | sed 's/== load_startup_file/== statically_load_modules/'
echo ""

if [ -z "$Quiet" ] ; then
  VersionMsg="printf(\"${name}, version ${version} (mnoble@space.mit.edu)\n\");"
fi

# Use cat -- rather than echo -- to emit content with embedded newlines
# (even though strict ANSI C forbids such, they are nonetheless convenient)
cat <<EOT
int statically_load_modules(void) {
$VersionMsg
EOT
echo ""

for module in $* ; do
  modules="${modules} \"${module}\","
  upcase=`echo $module | tr a-z A-Z`
  if [ -z "$Quiet" ] ; then
	InitMsg="printf(\"statically loaded ${module} module\n\");"
  else
	InitMsg=""
  fi
  if [ $ProtoInit -eq 1 ] ; then
     InitProto="int init_${module}_module_ns(char *);"
  else
     InitProto=""
  fi
  cat <<EOT
   {
   $InitProto
   if (init_${module}_module_ns(NULL) != 0)
      return -1;
   $InitMsg
   (void)SLdefine_for_ifdef("__NO_${upcase}_IMPORT__");
   }
EOT

done
echo ""
echo "   return load_startup_file();"
echo "}"
