#! /bin/sh
# Bootstrap this package from checked-out sources.
# Copyright (C) 2003-2010 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .
# Written by Paul Eggert.
nl='
'
# Ensure file names are sorted consistently across platforms.
# Also, ensure diagnostics are in English, e.g., "wget --help" below.
LC_ALL=C
export LC_ALL
local_gl_dir=gl
# Temporary directory names.
bt='._bootmp'
bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
bt2=${bt}2
usage() {
  cat </dev/null 2>&1; then
       find_tool_res=$i
       break
      fi
    done
  else
    find_tool_error_prefix="\$$find_tool_envvar: "
  fi
  if test x"$find_tool_res" = x; then
    echo >&2 "$0: one of these is required: $find_tool_names"
    exit 1
  fi
  ($find_tool_res --version /dev/null 2>&1 || {
    echo >&2 "$0: ${find_tool_error_prefix}cannot run $find_tool_res --version"
    exit 1
  }
  eval "$find_tool_envvar=\$find_tool_res"
  eval "export $find_tool_envvar"
}
# Find sha1sum, named gsha1sum on MacPorts.
find_tool SHA1SUM sha1sum gsha1sum
# Override the default configuration, if necessary.
# Make sure that bootstrap.conf is sourced from the current directory
# if we were invoked as "sh bootstrap".
case "$0" in
  */*) test -r "$0.conf" && . "$0.conf" ;;
  *) test -r "$0.conf" && . ./"$0.conf" ;;
esac
if test "$vc_ignore" = auto; then
  vc_ignore=
  test -d .git && vc_ignore=.gitignore
  test -d CVS && vc_ignore="$vc_ignore .cvsignore"
fi
# Translate configuration into internal form.
# Parse options.
for option
do
  case $option in
  --help)
    usage
    exit;;
  --gnulib-srcdir=*)
    GNULIB_SRCDIR=`expr "X$option" : 'X--gnulib-srcdir=\(.*\)'`;;
  --skip-po)
    SKIP_PO=t;;
  --force)
    checkout_only_file=;;
  --copy)
    copy=true;;
  *)
    echo >&2 "$0: $option: unknown option"
    exit 1;;
  esac
done
if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
  echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
  exit 1
fi
# If $STR is not already on a line by itself in $FILE, insert it,
# sorting the new contents of the file and replacing $FILE with the result.
insert_sorted_if_absent() {
  file=$1
  str=$2
  test -f $file || touch $file
  echo "$str" | sort -u - $file | cmp - $file > /dev/null \
    || echo "$str" | sort -u - $file -o $file \
    || exit 1
}
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
# insert_sorted_if_absent.
insert_vc_ignore() {
  vc_ignore_file="$1"
  case $vc_ignore_file in
  *.gitignore)
    # A .gitignore entry that does not start with `/' applies recursively to
    # subdirectories, so prepend `/' to every .gitignore entry.
    pattern=`echo "$2" | sed s,^,/,`;;
  *)
    pattern="$2";;
  esac
  insert_sorted_if_absent "$vc_ignore_file" "$pattern"
}
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
found_aux_dir=no
grep '^[	 ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
    >/dev/null && found_aux_dir=yes
grep '^[	 ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
    >/dev/null && found_aux_dir=yes
if test $found_aux_dir = no; then
  echo "$0: expected line not found in configure.ac. Add the following:" >&2
  echo "  AC_CONFIG_AUX_DIR([$build_aux])" >&2
  exit 1
fi
# If $build_aux doesn't exist, create it now, otherwise some bits
# below will malfunction.  If creating it, also mark it as ignored.
if test ! -d $build_aux; then
  mkdir $build_aux
  for dot_ig in x $vc_ignore; do
    test $dot_ig = x && continue
    insert_vc_ignore $dot_ig $build_aux
  done
fi
# Note this deviates from the version comparison in automake
# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
# but this should suffice as we won't be specifying old
# version formats or redundant trailing .0 in bootstrap.conf.
# If we did want full compatibility then we should probably
# use m4_version_compare from autoconf.
sort_ver() { # sort -V is not generally available
  ver1="$1"
  ver2="$2"
  # split on '.' and compare each component
  i=1
  while : ; do
    p1=$(echo "$ver1" | cut -d. -f$i)
    p2=$(echo "$ver2" | cut -d. -f$i)
    if [ ! "$p1" ]; then
      echo "$1 $2"
      break
    elif [ ! "$p2" ]; then
      echo "$2 $1"
      break
    elif [ ! "$p1" = "$p2" ]; then
      if [ "$p1" -gt "$p2" ] 2>/dev/null; then # numeric comparison
        echo "$2 $1"
      elif [ "$p2" -gt "$p1" ] 2>/dev/null; then # numeric comparison
        echo "$1 $2"
      else # numeric, then lexicographic comparison
        lp=$(printf "$p1\n$p2\n" | LANG=C sort -n | tail -n1)
        if [ "$lp" = "$p2" ]; then
          echo "$1 $2"
        else
          echo "$2 $1"
        fi
      fi
      break
    fi
    i=$(($i+1))
  done
}
get_version() {
  app=$1
  $app --version >/dev/null 2>&1 || return 1
  $app --version 2>&1 |
  sed -n '# extract version within line
          s/.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*/\1/
          t done
          # extract version at start of line
          s/^\([0-9]\{1,\}\.[.a-z0-9-]*\).*/\1/
          t done
          d
          :done
          #the following essentially does s/5.005/5.5/
          s/\.0*\([1-9]\)/.\1/g
          p
          q'
}
check_versions() {
  ret=0
  while read app req_ver; do
    # Honor $APP variables ($TAR, $AUTOCONF, etc.)
    appvar=`echo $app | tr '[a-z]' '[A-Z]'`
    test "$appvar" = TAR && appvar=AMTAR
    eval "app=\${$appvar-$app}"
    inst_ver=$(get_version $app)
    if [ ! "$inst_ver" ]; then
      echo "Error: '$app' not found" >&2
      ret=1
    elif [ ! "$req_ver" = "-" ]; then
      latest_ver=$(sort_ver $req_ver $inst_ver | cut -d' ' -f2)
      if [ ! "$latest_ver" = "$inst_ver" ]; then
        echo "Error: '$app' version == $inst_ver is too old" >&2
        echo "       '$app' version >= $req_ver is required" >&2
        ret=1
      fi
    fi
  done
  return $ret
}
print_versions() {
  echo "Program    Min_version"
  echo "----------------------"
  printf "$buildreq"
  echo "----------------------"
  # can't depend on column -t
}
if ! printf "$buildreq" | check_versions; then
  test -f README-prereq &&
  echo "See README-prereq for notes on obtaining these prerequisite programs:" >&2
  echo
  print_versions
  exit 1
fi
echo "$0: Bootstrapping from checked-out $package sources..."
# See if we can use gnulib's git-merge-changelog merge driver.
if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
  if git config merge.merge-changelog.driver >/dev/null ; then
    :
  elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
    echo "initializing git-merge-changelog driver"
    git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
    git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
  else
    echo "consider installing git-merge-changelog from gnulib"
  fi
fi
cleanup_gnulib() {
  status=$?
  rm -fr gnulib
  exit $status
}
git_modules_config () {
  test -f .gitmodules && git config --file .gitmodules "$@"
}
# Get gnulib files.
case ${GNULIB_SRCDIR--} in
-)
  if git_modules_config submodule.gnulib.url >/dev/null; then
    echo "$0: getting gnulib files..."
    git submodule init || exit $?
    git submodule update || exit $?
  elif [ ! -d gnulib ]; then
    echo "$0: getting gnulib files..."
    trap cleanup_gnulib 1 2 13 15
    git clone --help|grep depth > /dev/null && shallow='--depth 2' || shallow=
    git clone $shallow git://git.sv.gnu.org/gnulib ||
      cleanup_gnulib
    trap - 1 2 13 15
  fi
  GNULIB_SRCDIR=gnulib
  ;;
*)
  # Redirect the gnulib submodule to the directory on the command line
  # if possible.
  if test -d "$GNULIB_SRCDIR"/.git && \
        git_modules_config submodule.gnulib.url >/dev/null; then
    git submodule init
    GNULIB_SRCDIR=`cd $GNULIB_SRCDIR && pwd`
    git_modules_config --replace-all submodule.gnulib.url $GNULIB_SRCDIR
    echo "$0: getting gnulib files..."
    git submodule update || exit $?
    GNULIB_SRCDIR=gnulib
  fi
  ;;
esac
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit
# Get translations.
download_po_files() {
  subdir=$1
  domain=$2
  echo "$0: getting translations into $subdir for $domain..."
  cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
  eval "$cmd"
}
# Download .po files to $po_dir/.reference and copy only the new
# or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
update_po_files() {
  # Directory containing primary .po files.
  # Overwrite them only when we're sure a .po file is new.
  po_dir=$1
  domain=$2
  # Download *.po files into this dir.
  # Usually contains *.s1 checksum files.
  ref_po_dir="$po_dir/.reference"
  test -d $ref_po_dir || mkdir $ref_po_dir || return
  download_po_files $ref_po_dir $domain \
    && ls "$ref_po_dir"/*.po 2>/dev/null |
      sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
  langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
  test "$langs" = '*' && langs=x
  for po in $langs; do
    case $po in x) continue;; esac
    new_po="$ref_po_dir/$po.po"
    cksum_file="$ref_po_dir/$po.s1"
    if ! test -f "$cksum_file" ||
        ! test -f "$po_dir/$po.po" ||
        ! $SHA1SUM -c --status "$cksum_file" \
            < "$new_po" > /dev/null; then
      echo "updated $po_dir/$po.po..."
      cp "$new_po" "$po_dir/$po.po" \
          && $SHA1SUM < "$new_po" > "$cksum_file"
    fi
  done
}
case $SKIP_PO in
'')
  if test -d po; then
    update_po_files po $package || exit
  fi
  if test -d runtime-po; then
    update_po_files runtime-po $package-runtime || exit
  fi;;
esac
check_dst_dir()
{
  dst=$1
  # If the destination directory doesn't exist, create it.
  # This is required at least for "lib/uniwidth/cjk.h".
  dst_dir=`dirname "$dst"`
  if ! test -d "$dst_dir"; then
    mkdir -p "$dst_dir"
    # If we've just created a directory like lib/uniwidth,
    # tell version control system(s) it's ignorable.
    # FIXME: for now, this does only one level
    parent=`dirname "$dst_dir"`
    for dot_ig in x $vc_ignore; do
      test $dot_ig = x && continue
      ig=$parent/$dot_ig
      insert_vc_ignore $ig `echo "$dst_dir"|sed 's,.*/,,'`
    done
  fi
}
symlink_to_dir()
{
  src=$1/$2
  dst=${3-$2}
  test -f "$src" && {
    check_dst_dir "$dst"
    if $copy; then
      {
        test ! -h "$dst" || {
          echo "$0: rm -f $dst" &&
          rm -f "$dst"
        }
      } &&
      test -f "$dst" &&
      cmp -s "$src" "$dst" || {
        echo "$0: cp -fp $src $dst" &&
        cp -fp "$src" "$dst"
      }
    else
      test -h "$dst" &&
      src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
      dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
      test "$src_i" = "$dst_i" || {
        dot_dots=
        case $src in
        /*) ;;
        *)
          case /$dst/ in
          *//* | */../* | */./* | /*/*/*/*/*/)
             echo >&2 "$0: invalid symlink calculation: $src -> $dst"
             exit 1;;
          /*/*/*/*/)	dot_dots=../../../;;
          /*/*/*/)	dot_dots=../../;;
          /*/*/)	dot_dots=../;;
          esac;;
        esac
        echo "$0: ln -fs $dot_dots$src $dst" &&
        ln -fs "$dot_dots$src" "$dst"
      }
    fi
  }
}
cp_mark_as_generated()
{
  cp_src=$1
  cp_dst=$2
  if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
    symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
  elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
    symlink_to_dir $local_gl_dir "$cp_dst"
  else
    case $cp_dst in
      *.[ch])             c1='/* '; c2=' */';;
      *.texi)             c1='@c '; c2=     ;;
      *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
      *)                  c1=     ; c2=     ;;
    esac
    if test -z "$c1"; then
      cmp -s "$cp_src" "$cp_dst" || {
        # Copy the file first to get proper permissions if it
        # doesn't already exist.  Then overwrite the copy.
        echo "$0: cp -f $cp_src $cp_dst" &&
        rm -f "$cp_dst" &&
        cp "$cp_src" "$cp_dst-t" &&
        sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst-t" &&
        mv -f "$cp_dst-t" "$cp_dst"
      }
    else
      check_dst_dir "$cp_dst"
      # Copy the file first to get proper permissions if it
      # doesn't already exist.  Then overwrite the copy.
      cp "$cp_src" "$cp_dst-t" &&
      (
        echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
        echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
        sed "s!$bt_regex/!!g" "$cp_src"
      ) > $cp_dst-t &&
      if cmp -s "$cp_dst-t" "$cp_dst"; then
        rm -f "$cp_dst-t"
      else
        echo "$0: cp $cp_src $cp_dst # with edits" &&
        mv -f "$cp_dst-t" "$cp_dst"
      fi
    fi
  fi
}
version_controlled_file() {
  dir=$1
  file=$2
  found=no
  if test -d CVS; then
    grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
             grep '^/[^/]*/[0-9]' > /dev/null && found=yes
  elif test -d .git; then
    git rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
  elif test -d .svn; then
    svn log -r HEAD "$dir/$file" > /dev/null 2>&1 && found=yes
  else
    echo "$0: no version control for $dir/$file?" >&2
  fi
  test $found = yes
}
slurp() {
  for dir in . `(cd $1 && find * -type d -print)`; do
    copied=
    sep=
    for file in `ls -a $1/$dir`; do
      case $file in
      .|..) continue;;
      .*) continue;; # FIXME: should all file names starting with "." be ignored?
      esac
      test -d $1/$dir/$file && continue
      for excluded_file in $excluded_files; do
        test "$dir/$file" = "$excluded_file" && continue 2
      done
      if test $file = Makefile.am; then
        copied=$copied${sep}$gnulib_mk; sep=$nl
        remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
        sed "$remove_intl" $1/$dir/$file | cmp - $dir/$gnulib_mk > /dev/null || {
          echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
          rm -f $dir/$gnulib_mk &&
          sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
        }
      elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
           version_controlled_file $dir $file; then
        echo "$0: $dir/$file overrides $1/$dir/$file"
      else
        copied=$copied$sep$file; sep=$nl
        if test $file = gettext.m4; then
          echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
          rm -f $dir/$file
          sed '
            /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
              AC_DEFUN([AM_INTL_SUBDIR], [
            /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
              AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
            $a\
              AC_DEFUN([gl_LOCK_EARLY], [])
          ' $1/$dir/$file >$dir/$file
        else
          cp_mark_as_generated $1/$dir/$file $dir/$file
        fi
      fi || exit
    done
    for dot_ig in x $vc_ignore; do
      test $dot_ig = x && continue
      ig=$dir/$dot_ig
      if test -n "$copied"; then
        insert_vc_ignore $ig "$copied"
        # If an ignored file name ends with .in.h, then also add
        # the name with just ".h".  Many gnulib headers are generated,
        # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
        # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
        f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
        insert_vc_ignore $ig "$f"
        # For files like sys_stat.in.h and sys_time.in.h, record as
        # ignorable the directory we might eventually create: sys/.
        f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
        insert_vc_ignore $ig "$f"
      fi
    done
  done
}
# Create boot temporary directories to import from gnulib and gettext.
rm -fr $bt $bt2 &&
mkdir $bt $bt2 || exit
# Import from gnulib.
gnulib_tool_options="\
 --import\
 --no-changelog\
 --aux-dir $bt/$build_aux\
 --doc-base $bt/$doc_base\
 --lib $gnulib_name\
 --m4-base $bt/$m4_base/\
 --source-base $bt/$source_base/\
 --tests-base $bt/$tests_base\
 --local-dir $local_gl_dir\
 $gnulib_tool_option_extras\
"
echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
$gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
slurp $bt || exit
for file in $gnulib_files; do
  symlink_to_dir "$GNULIB_SRCDIR" $file || exit
done
# Import from gettext.
with_gettext=yes
grep '^[	 ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
    with_gettext=no
if test $with_gettext = yes; then
  echo "$0: (cd $bt2; ${AUTOPOINT-autopoint}) ..."
  cp configure.ac $bt2 &&
  (cd $bt2 && ${AUTOPOINT-autopoint} && rm configure.ac) &&
  slurp $bt2 $bt || exit
fi
rm -fr $bt $bt2 || exit
# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
# gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
# The following requires GNU find 4.2.3 or newer.  Considering the usual
# portability constraints of this script, that may seem a very demanding
# requirement, but it should be ok.  Ignore any failure, which is fine,
# since this is only a convenience to help developers avoid the relatively
# unusual case in which a symlinked-to .m4 file is git-removed from gnulib
# between successive runs of this script.
find "$m4_base" "$source_base" \
  -depth \( -name '*.m4' -o -name '*.[ch]' \) \
  -type l -xtype l -delete > /dev/null 2>&1
# Reconfigure, getting other files.
# Skip autoheader if it's not needed.
grep -E '^[	 ]*AC_CONFIG_HEADERS?\>' configure.ac >/dev/null ||
  AUTOHEADER=true
for command in \
  libtool \
  "${ACLOCAL-aclocal} --force -I m4" \
  "${AUTOCONF-autoconf} --force" \
  "${AUTOHEADER-autoheader} --force" \
  "${AUTOMAKE-automake} --add-missing --copy --force-missing"
do
  if test "$command" = libtool; then
    use_libtool=0
    # We'd like to use grep -E, to see if any of LT_INIT,
    # AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
    # but that's not portable enough (e.g., for Solaris).
    grep '^[	 ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
      && use_libtool=1
    grep '^[	 ]*LT_INIT' configure.ac >/dev/null \
      && use_libtool=1
    test $use_libtool = 0 \
      && continue
    command="${LIBTOOLIZE-libtoolize} -c -f"
  fi
  echo "$0: $command ..."
  $command || exit
done
# Get some extra files from gnulib, overriding existing files.
for file in $gnulib_extra_files; do
  case $file in
  */INSTALL) dst=INSTALL;;
  build-aux/*) dst=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
  *) dst=$file;;
  esac
  symlink_to_dir "$GNULIB_SRCDIR" $file $dst || exit
done
if test $with_gettext = yes; then
  # Create gettext configuration.
  echo "$0: Creating po/Makevars from po/Makevars.template ..."
  rm -f po/Makevars
  sed '
    /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
    /^MSGID_BUGS_ADDRESS *=/s/=.*/= '"$MSGID_BUGS_ADDRESS"'/
    /^XGETTEXT_OPTIONS *=/{
      s/$/ \\/
      a\
          '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
    }
  ' po/Makevars.template >po/Makevars
  if test -d runtime-po; then
    # Similarly for runtime-po/Makevars, but not quite the same.
    rm -f runtime-po/Makevars
    sed '
      /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
      /^subdir *=.*/s/=.*/= runtime-po/
      /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
      /^XGETTEXT_OPTIONS *=/{
        s/$/ \\/
        a\
            '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
      }
    ' runtime-po/Makevars
    # Copy identical files from po to runtime-po.
    (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
  fi
fi
bootstrap_epilogue
echo "$0: done.  Now you can run './configure'."
# Local Variables:
# indent-tabs-mode: nil
# End: