#! /bin/sh

# Bootstrap this package from checked-out sources.

# Copyright (C) 2003, 2004, 2005, 2006, 2007 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 2, 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

# 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

# Temporary directory names.
bt='._bootmp'
bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
bt2=${bt}2

usage() {
  echo >&2 "\
Usage: $0 [OPTION]...
Bootstrap this package from the checked-out sources.

Options:
 --gnulib-srcdir=DIRNAME  Specify the local directory where gnulib
                          sources reside.  Use this if you already
                          have gnulib sources on your machine, and
                          do not want to waste your bandwidth downloading
                          them again.
 --copy                   Copy files instead of creating symbolic links.
 --force                  Attempt to bootstrap even if the sources seem
                          not to have been checked out.
 --skip-po                Do not download po files.
 --cvs-user=USERNAME      Set the username to use when checking out
                          sources from the gnulib repository.

If the file .bootstrap.conf exists in the current working directory, its
contents are read as shell variables to configure the bootstrap.

Running without arguments will suffice in most cases.
"
}

# Configuration.

# List of gnulib modules needed.
gnulib_modules=

# Any gnulib files needed that are not in modules.
gnulib_files=

# Translation Project URL, for the registry of all projects
# and for the translation-team master directory.
TP_URL='http://www.iro.umontreal.ca/translation/registry.cgi?domain='
TP_PO_URL='http://www.iro.umontreal.ca/translation/teams/PO/'

extract_package_name='
  /^AC_INIT(/{
     /.*,.*,.*,/{
       s///
       s/[][]//g
       p
       q
     }
     s/AC_INIT(\[*//
     s/]*,.*//
     s/^GNU //
     y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
     s/[^A-Za-z0-9_]/-/g
     p
  }
'
package=`sed -n "$extract_package_name" configure.ac` || exit
gnulib_name=lib$package

build_aux=build-aux
# Extra files from gnulib, which override files from other sources.
gnulib_extra_files="
	$build_aux/install-sh
	$build_aux/missing
	$build_aux/mdate-sh
	$build_aux/texinfo.tex
	$build_aux/depcomp
	$build_aux/config.guess
	$build_aux/config.sub
	doc/INSTALL
"

# Other locale categories that need message catalogs.
EXTRA_LOCALE_CATEGORIES=

# Additional xgettext options to use.  Use "\\\newline" to break lines.
XGETTEXT_OPTIONS='\\\
 --flag=_:1:pass-c-format\\\
 --flag=N_:1:pass-c-format\\\
 --flag=error:3:c-format --flag=error_at_line:5:c-format\\\
'

# Files we don't want to import.
excluded_files=

# File that should exist in the top directory of a checked out hierarchy,
# but not in a distribution tarball.
checkout_only_file=README-hacking

# Whether to use copies instead of symlinks.
copy=false

# Override the default configuration, if necessary.
test -r bootstrap.conf && . ./bootstrap.conf

# Translate configuration into internal form.

# Parse options.

for option
do
  case $option in
  --help)
    usage
    exit;;
  --gnulib-srcdir=*)
    GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
  --cvs-user=*)
    CVS_USER=`expr "$option" : '--cvs-user=\(.*\)'`;;
  --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
  echo "$str" | sort -u - $file | cmp -s - $file \
    || echo "$str" | sort -u - $file -o $file \
    || exit 1
}

# 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.
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 ig in .cvsignore .gitignore; do
    test -f $ig && insert_sorted_if_absent $ig $build_aux
  done
fi

echo "$0: Bootstrapping from checked-out $package sources..."

cleanup_gnulib() {
  status=$?
  rm -fr gnulib
  exit $status
}

# Get gnulib files.

case ${GNULIB_SRCDIR--} in
-)
  if [ ! -d gnulib ]; then
    echo "$0: getting gnulib files..."

    case ${CVS_AUTH-pserver} in
    pserver)
      CVS_PREFIX=':pserver:anonymous@';;
    ssh)
      CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
    *)
      echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
      exit 1;;
    esac

    case $CVS_RSH in
    '') CVS_RSH=ssh; export CVS_RSH;;
    esac

    trap cleanup_gnulib 1 2 13 15

    cvs -z3 -q -d ${CVS_PREFIX}cvs.savannah.gnu.org:/cvsroot/gnulib co gnulib ||
      cleanup_gnulib

    trap - 1 2 13 15
  fi
  GNULIB_SRCDIR=gnulib
esac

gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit

# Get translations.

get_translations() {
  subdir=$1
  domain=$2

  case $WGET_COMMAND in
  '')
    echo "$0: wget not available; skipping translations";;
  ?*)
    echo "$0: getting translations into $subdir for $domain..." &&

    (cd $subdir && rm -f dummy `ls | sed -n '/\.gmo$/p; /\.po/p'`) &&
    $WGET_COMMAND -O "$subdir/$domain.html" "$TP_URL$domain" &&

    sed -n 's|.*"http://[^"]*/translation/teams/PO/\([^/"]*\)/'"$domain"'-\([^/"]*\)\.[^."]*\.po".*|\1.\2|p' <"$subdir/$domain.html" |
    sort -k 1,1 -k 2,2n -k2,2 -k3,3n -k3,3 -k4,4n -k4,4 -k5,5n -k5.5 |
    awk -F. '
      { if (lang && $1 != lang) print lang, ver }
      { lang = $1; ver = substr($0, index($0, ".") + 1) }
      END { if (lang) print lang, ver }
    ' | awk -v domain="$domain" -v subdir="$subdir" '
      {
	lang = $1
	ver = $2
	urlfmt = ""
	printf "{ $WGET_COMMAND -O %s/%s.po '\'"$TP_PO_URL"'/%s/%s-%s.%s.po'\'' &&\n", subdir, lang, lang, domain, ver, lang
	printf "  msgfmt -c -o /dev/null %s/%s.po || {\n", subdir, lang
	printf "    echo >&2 '\'"$0"': omitting translation for %s'\''\n", lang
	printf "    rm -f %s/%s.po; }; } &&\n", subdir, lang
      }
      END { print ":" }
    ' | WGET_COMMAND="$WGET_COMMAND" sh;;
  esac &&
  ls "$subdir"/*.po 2>/dev/null |
    sed 's|.*/||; s|\.po$||' >"$subdir/LINGUAS" &&
  rm -f "$subdir/$domain.html"
}

case $SKIP_PO in
'')
  case `wget --help` in
  *'--no-cache'*)
    WGET_COMMAND='wget -nv --no-cache';;
  *'--cache=on/off'*)
    WGET_COMMAND='wget -nv --cache=off';;
  *'--non-verbose'*)
    WGET_COMMAND='wget -nv';;
  *)
    WGET_COMMAND='';;
  esac

  if test -d po; then
    get_translations po $package || exit
  fi

  if test -d runtime-po; then
    get_translations runtime-po $package-runtime || exit
  fi;;
esac

symlink_to_gnulib()
{
  src=$GNULIB_SRCDIR/$1
  dst=${2-$1}

  test -f "$src" && {
    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_gnulib "$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" || {
	echo "$0: cp -f $cp_src $cp_dst" &&
	rm -f "$cp_dst" &&
	sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
      }
    else
      # 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
  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 $1/$dir`; do
      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 -s - $dir/gnulib.mk || {
	  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 .cvsignore .gitignore; do
      ig=$dir/$dot_ig
      if test -n "$copied" && test -f $ig; then
	insert_sorted_if_absent $ig "$copied"
	# If an ignored file name ends with _.h, then also add
	# the name with just ".h".  Many gnulib headers are generated,
	# e.g., stdint_.h -> stdint.h, dirent_.h ->..., etc.
	f=`echo "$copied"|sed 's/_\.h$/.h/'`
	insert_sorted_if_absent $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\
 --lib $gnulib_name\
 --m4-base $bt/m4/\
 --source-base $bt/lib/\
 --tests-base $bt/tests\
 --local-dir gl\
"
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_gnulib $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) ..."
  cp configure.ac $bt2 &&
  (cd $bt2 && autopoint && rm configure.ac) &&
  slurp $bt2 $bt || exit

  rm -fr $bt $bt2 || exit
fi


# Reconfigure, getting other files.

for command in \
  libtool \
  'aclocal --force -I m4' \
  'autoconf --force' \
  'autoheader --force' \
  'automake --add-missing --copy --force-missing';
do
  if test "$command" = libtool; then
    grep '^[	 ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
      continue
    command='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;;
  *) dst=$file;;
  esac
  symlink_to_gnulib $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/=.*/= bug-'"$package"'@gnu.org/
    /^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+}
      }
    ' <po/Makevars.template >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

echo "$0: done.  Now you can run './configure'."
