#!/bin/ksh
##
## AIX ld(1) wrapper to do hacks and emulate GNU and SVR4 ld(1)
## Copyright (c) 2009-2010 SATOH Fumiyasu @ OSS Technology Corp.
##               <http://www.osstech.co.jp/>
##
## License: GNU General Public License version 2 or later
## Date: 2010-01-20, since 2009-01-22
##

set -u
PS4="$0: "

function match_csv {
  typeset csv="$1"; shift
  typeset item="$1"; shift
  typeset sep="${1-,}"

  case "$sep$csv$sep" in
  *"$sep$item$sep"*)
    return 0
    ;;
  *)
    return 1
    ;;
  esac
}

ld_cmd="${LDWRAPPER_LD:-/usr/ccs/bin/ld}"
verbose_flag="${LDWRAPPER_VERBOSE+set}"
no_echo="${LDWRAPPER_NO_ECHO+set}"
no_run_flag="${LDWRAPPER_NO_RUN+set}"
no_wrap_flag="${LDWRAPPER_NO_WRAP+set}"

if [ -n "$verbose_flag" ]; then
  echo "${PS4}orignal argv: $@" 1>&2
  set -x
fi

if [ -n "$no_wrap_flag" ]; then
  ${no_run_flag:+echo} exec "$ld_cmd" ${1+"$@"}
  exit 1
fi

## ----------------------------------------------------------------------

## NOTE: Do NOT use -bsvr4 option because AIX 6.1 ld(1) sometimes
## fails by SIGSEGV or the following mysterious error:
## "ld: 0706-005 Cannot find or open file: NULL-OR-RANDOM-STRING"

set -A ld_argv --

output="a.out"
dso_flag=""
rpath=""

while [ $# -gt 0 ]; do
  argv="$1"; shift
  case X"$argv" in
  X-o*)
    if [ X"$argv" != X"-o" ]; then
      output="${argv#-o}"
    elif [ $# -ge 1 ]; then
      output="$1"
    fi
    ;;
  X-G)
    dso_flag="yes"
    ;;
  X-blibpath:*)
    ## AIX ld(1)
    rpath="$rpath:${argv#-blibpath:}"
    continue
    ;;
  X-rpath)
    ## GNU ld(1)
    if [ $# -ge 1 ]; then
      rpath="$rpath:$1"; shift
      continue
    fi
    ;;
  X-R/*)
    ## SVR4 ld(1)
    rpath="$rpath:${argv#-R}"
    continue
    ;;
  esac

  set -A ld_argv -- ${ld_argv+"${ld_argv[@]}"} "$argv"
done

## ----------------------------------------------------------------------

rtl_flag="yes"

case X"$output" in
X*.so|*.so.*)
  rtl_flag=""
  if [ -z "$dso_flag" ]; then
    set -A ld_argv -- -G ${ld_argv+"${ld_argv[@]}"}
  fi
  ;;
esac

if [ -n "$dso_flag" ]; then
  rtl_flag=""
fi

if [ -n "$rtl_flag" ]; then
  set -A ld_argv -- -brtl ${ld_argv+"${ld_argv[@]}"}
fi

## ----------------------------------------------------------------------

if [ -n "$rpath" ]; then
  IFS_save="$IFS"; IFS=":"; set -f
  set -A rpath_list -- ${rpath#:}
  IFS="$IFS_save"; set +f

  rpath=""
  for rpath_tmp in "${rpath_list[@]}"; do
    [ -z "$rpath_tmp" ] && continue
    match_csv "$rpath" "$rpath_tmp" ":" && continue
    rpath="$rpath:$rpath_tmp"
  done \

  match_csv "$rpath" "/usr/lib" ":" || rpath="$rpath:/usr/lib"
  match_csv "$rpath" "/lib" ":" || rpath="$rpath:/lib"

  set -A ld_argv -- ${ld_argv+"${ld_argv[@]}"} -blibpath"$rpath"
fi

## ----------------------------------------------------------------------

set -- "$ld_cmd" ${ld_argv+"${ld_argv[@]}"}

if [ -z "$verbose_flag" ] && [ -z "$no_echo" ]; then
  echo "$0: $@" 1>&2
fi

${no_run_flag:+echo} exec "$@"

exit 1

