#! /bin/sh

test -f /bin/ksh && test -z "$RUNNING_KSH" \
  && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
  && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
unset RUNNING_KSH

# No failure shall remain unpunished.
set -e

me=$(basename "$0")
medir=$(dirname "$0")

# We have to initialize IFS to space tab newline since we save and
# restore IFS and apparently POSIX allows stupid/broken behavior with
# empty-but-set IFS.
# http://lists.gnu.org/archive/html/automake-patches/2006-05/msg00008.html
# We need space, tab and new line, in precisely that order.  And don't
# leave trailing blanks.
space=' '
tab='	'
newline='
'
IFS="$space$tab$newline"

# Pacify verbose cds.
CDPATH=${ZSH_VERSION+.}$path_sep

# In case someone crazy insists on using grep -E.
: ${EGREP=egrep}

debug=false
quiet=false     # by default let the tools' message be displayed
verb=false      # true for verbose mode

## --------------------- ##
## Auxiliary functions.  ##
## --------------------- ##

# In case `local' is not supported by the shell.
(
  foo=bar
  test_local () {
    local foo="foo"
  }
  test_local
  test $foo = bar
) || local () {
  case $1 in
    *=*) eval "$1";;
  esac
}


# stderr LINE1 LINE2...
# ---------------------
# Report some information on stderr.
stderr ()
{
  for i
  do
    echo >&2 "$me: $i"
  done
}

# verbose WORD1 WORD2
# -------------------
# Report some verbose information.
verbose ()
{
  if $verb; then
    stderr "$@"
  fi
}

# run COMMAND-LINE
# ----------------
# Run the COMMAND-LINE verbosely, and catching errors as failures.
run ()
{
  if $verb; then
    first=true
    for i
    do
      if $first; then
	stderr "Running: $i"
	first=false
      else
	stderr "       : $i"
      fi
    done
  fi
  "$@" 1>&5 ||
     error 1 "$1 failed"
}


# error EXIT_STATUS LINE1 LINE2...
# --------------------------------
# Report an error and exit with EXIT_STATUS.
error ()
{
  local s="$1"
  shift
  stderr "$@"
  exit $s
}


# fata LINE1 LINE2...
# -------------------
# Report an error and exit 1.
fatal ()
{
  error 1 "$@"
}


# dirlist_error EXIT_STATUS WHAT WHERE WHICH
# ------------------------------------------
# Report an error and exit with failure if WHICH, of type WHAT
# does not exist in WHERE.
# This function tests only directories
dirlist_error ()
{
  local err="$1"
  local type="$2"
  local base="$3"
  local val="$4"

  if test ! -d $base/$val; then
    stderr "no such $type $val, possible choices are :"
    for d in $base/*; do
      if test -d $d; then
	stderr "  - $(basename $d)"
      fi
    done
    exit $err
  fi
}

# exist_error EXIT_STATUS WHAT WHERE OPTION
# -----------------------------------------
# Report an error and exit with failure if WHERE is not found
# or is not of type WHAT.
# OPTION indicates which umake option to set for this value.
# This function tests only directories
exist_error ()
{
  local err="$1"
  local type="$2"
  local base="$3"
  local option="$4"
  local longtype="$2"

  case $type in
    d) longtype=directory;;
    f) longtype=file;;
  esac

  test "$type" = d -a -n "$base" &&
    base=$(dirname $base/.)

  if test ! -$type "$base"; then
    stderr "no such $longtype $base"
    if test -n "$option"; then
      stderr "  use option --$option to set to an alternative value."
    fi
    exit $err
  fi
}

# Initialize the common set up.  Should be done when $debug and
# $quiet are set.
initialize ()
{
  # File descriptor usage:
  # 0 standard input
  # 1 standard output (--verbose messages)
  # 2 standard error
  # 3 some systems may open it to /dev/tty
  # 4 used on the Kubota Titan
  # 5 tools output (turned off by --quiet)
  # 6 tracing/debugging (set -x output, etc.)

  # Main tools' output (TeX, etc.) that TeX users are used to seeing.
  #
  # If quiet, discard, else redirect to the error flow.
  if $quiet; then
    exec 5>/dev/null
  else
    exec 5>&2
  fi

  # Enable tracing, and auxiliary tools output.
  #
  # Should be used where you'd typically use /dev/null to throw output
  # away.  But sometimes it is convenient to see that output (e.g., from
  # a grep) to aid debugging.  Especially debugging at distance, via the
  # user.
  if $debug || test x"$VERBOSE" = xx; then
    exec 6>&1
    set -x
  else
    exec 6>/dev/null
  fi

  verbose "$0 running."
}

# append VARIABLE CONTENT [SEPARATOR=' ']
# ---------------------------------------
append ()
{
  local var="$1"
  local content="$2"
  local sep
  sep=${3-' '}
  eval "$var=\$$var\${$var:+$sep}\$content"
}

: ${URBI_HOST=i686-pc-linux-gnu}

dir=$medir

usage ()
{
cat <<EOF
Usage: $me [OPTION]... -- ARGUMENTS

Invoke libtool with magic to pass --whole-archive where/when needed.
Hopefully this tool will be obsolete some day --- the day Libtool
supports --whole-archive appropriately.

General options:
  -D, --debug         turn on shell debugging (set -x)
  -h, --help          display this help and exit successfully
  -q, --quiet         no output unless errors (implies --batch)
  -V, --version       display version information and exit successfully
  -v, --verbose       report on what is done

Specific options:
  -L, --libtool=PATH    path to libtool
  -E, --env=URBI-ENV    urbi environment name (e.g., engine)

Report bugs to sdk-remote-bugs@gostai.com.
EOF

  exit 0
}

version ()
{
    cat <<\EOF
umake-link UNDEFINED (Urbi SDK Remote UNDEFINED)
Copyright (C) 2004-2010, Gostai S.A.S.
EOF
    exit 0
}

## ---------------------- ##
## Command line parsing.  ##
## ---------------------- ##

# This is not a function, since we want to manipulate the script's $@,
# not the function's local copy.

# Push a token among the arguments that will be used to notice when we
# ended options/arguments parsing.
# Use "set dummy ...; shift" rather than 'set - ..." because on
# Solaris set - turns off set -x (but keeps set -e).
# Use ${1+"$@"} rather than "$@" because Digital Unix and Ultrix 4.3
# still expand "$@" to a single argument (the empty string) rather
# than nothing at all.
arg_sep="$$--$$"
set dummy ${1+"$@"} "$arg_sep"; shift

# Parse command line arguments.
while test x"$1" != x"$arg_sep"
do
  # Handle --option=value by splitting apart and putting back on argv.
  case "$1" in
    (--*=*)
      opt=`echo "$1" | sed -e 's/=.*//'`
      val=`echo "$1" | sed -e 's/[^=]*=//'`
      shift
      set dummy "$opt" "$val" ${1+"$@"}; shift
      ;;
  esac

  case "$1" in
    (-D | --debug  ) debug=true;;
    (-v | --verbose) verb=true;;
    (-h | --help   ) usage;;
    (-q | --quiet  ) quiet=true;;
    (-V | --version) version;;

    (-L | --libtool) shift; libtool=$1;;
    (-E | --env)     shift; urbi_env=$1;;

    (--) # What remains are not options.
      shift
      while test x"$1" != x"$arg_sep"
      do
	  set dummy ${1+"$@"} "$1"; shift
	  shift
      done
      break
      ;;
    (-*)
      error 2 "Unknown or ambiguous option \`$1'." \
	      "Try \`--help' for more information."
      ;;
    (*) set dummy ${1+"$@"} "$1"; shift;;
   esac
   shift
done
# Pop the token
shift

initialize

# Check that these are defined.
for i in libtool urbi_env urbi_host
do
  if eval test -z "\$$i"; then
    fatal "$i is not defined"
  fi
done

if $verb; then
  echo >&2 "$libtool --config:"
  $libtool --config | sed  >&2 's/^/> /'
fi

set -x

case $($libtool --config) in
  (*build_old_libs=no*)
  # shared library mode, nothing special required
  command="$libtool --tag=CXX --mode=link $@"
  ;;

  (*)
  # Static mode: we need to insert a --whole-archive or similar.
  command=$($libtool -n --tag=CXX --mode=link "$@" |
      # libtool 2.2 outputs additional prefixes.
      sed -e 's/^libtool: link: //')
  case $URBI_HOST in
    (*darwin*)
      command=$(echo "$command" |
        sed -e 's/ \([a-zA-Z0-9.\/_-]*\.a\( \|$\)\)/ -Wl,-all_load \1 /g')
      ;;
    (*)
      command=$(echo "$command" |
        sed -e 's/ \([a-zA-Z0-9.\/_-]*\.a\( \|$\)\)/ -Wl,-whole-archive \1 -Wl,-no-whole-archive /')
      ;;
  esac
  ;;
esac

stderr "$command"
eval "$command"
exit $?

# Local variables:
# mode: shell-script
# End:
