#! /bin/sh
#! -*- coding:utf-8; mode:shell-script; -*-

# Download some prerequisites needed by GCC.
# Run this from the top level of the GCC source tree and the GCC build will do
# the right thing.  Run it with the `--help` option for more information.
#
# (C) 2010-2021 Free Software Foundation
#
# 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 http://www.gnu.org/licenses/.

program='download_prerequisites'
version='(unversioned)'

# MAINTAINERS: If you update the package versions below, please
# remember to also update the files `contrib/prerequisites.sha512` and
# `contrib/prerequisites.md5` with the new checksums.

gmp='gmp-6.2.1.tar.bz2'
mpfr='mpfr-4.1.0.tar.bz2'
mpc='mpc-1.2.1.tar.gz'
isl='isl-0.24.tar.bz2'

base_url='http://gcc.gnu.org/pub/gcc/infrastructure/'

echo_archives() {
    echo "${gmp}"
    echo "${mpfr}"
    echo "${mpc}"
    if [ ${graphite} -gt 0 ]; then echo "${isl}"; fi
}

graphite=1
verify=1
force=0
OS=$(uname)

if type wget > /dev/null ; then
  fetch='wget'
else
  fetch='curl -LO'
fi
chksum_extension='sha512'
directory='.'

helptext="usage: ${program} [OPTION...]

Downloads some prerequisites needed by GCC.  Run this from the top level of the
GCC source tree and the GCC build will do the right thing.

The following options are available:

 --directory=DIR  download and unpack packages into DIR instead of '.'
 --force          download again overwriting existing packages
 --no-force       do not download existing packages again (default)
 --isl            download ISL, needed for Graphite loop optimizations (default)
 --graphite       same as --isl
 --no-isl         don't download ISL
 --no-graphite    same as --no-isl
 --verify         verify package integrity after download (default)
 --no-verify      don't verify package integrity
 --sha512         use SHA512 checksum to verify package integrity (default)
 --md5            use MD5 checksum to verify package integrity
 --help           show this text and exit
 --version        show version information and exit
"

versiontext="${program} ${version}
Copyright (C) 2016-2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."

die() {
    echo "error: $@" >&2
    exit 1
}

for arg in "$@"
do
    case "${arg}" in
        --help)
            echo "${helptext}"
            exit
            ;;
        --version)
            echo "${versiontext}"
            exit
            ;;
    esac
done
unset arg

# Emulate Linux's 'md5sum --check' on macOS
md5_check() {
  # Store the standard input: a line from contrib/prerequisites.md5:
  md5_checksum_line=$(cat -)
  # Grab the text before the first space
  md5_checksum_expected="${md5_checksum_line%% *}"
  # Grab the text after the first space
  file_to_check="${md5_checksum_line##* }"
  # Calculate the md5 checksum for the downloaded file
  md5_checksum_output=$(md5 -r "${file_to_check}")
  # Grab the text before the first space
  md5_checksum_detected="${md5_checksum_output%% *}"
  [ "${md5_checksum_expected}" = "${md5_checksum_detected}" ] \
    || die "Cannot verify integrity of possibly corrupted file ${file_to_check}"
  echo "${file_to_check}: OK"
}


argnext=
for arg in "$@"
do
    if [ "x${argnext}" = x ]
    then
        case "${arg}" in
            --directory)
                argnext='directory'
                ;;
            --directory=*)
                directory="${arg#--directory=}"
                ;;
            --force)
                force=1
                ;;
            --no-force)
                force=0
                ;;
            --isl|--graphite)
                graphite=1
                ;;
            --no-isl|--no-graphite)
                graphite=0
                ;;
            --verify)
                verify=1
                ;;
            --no-verify)
                verify=0
                ;;
            --sha512)
                chksum_extension='sha512'
                verify=1
                ;;
            --md5)
                chksum_extension='md5'
                verify=1
                ;;
            -*)
                die "unknown option: ${arg}"
                ;;
            *)
                die "too many arguments"
                ;;
        esac
    else
        case "${arg}" in
            -*)
                die "Missing argument for option --${argnext}"
                ;;
        esac
        case "${argnext}" in
            directory)
                directory="${arg}"
                ;;
            *)
                die "The impossible has happened"
                ;;
        esac
        argnext=
    fi
done
[ "x${argnext}" = x ] || die "Missing argument for option --${argnext}"
unset arg argnext

case $chksum_extension in
  sha512)
    case $OS in
      "Darwin"|"FreeBSD"|"DragonFly"|"AIX")
        chksum='shasum -a 512 --check'
      ;;
      "OpenBSD")
        chksum='sha512 -c'
      ;;
      *)
        chksum='sha512sum -c'
      ;;
    esac
  ;;
  md5)
    case $OS in
      "Darwin")
        chksum='md5_check'
      ;;
      *)
        chksum='md5sum -c'
      ;;
    esac
    ;;
  *)
    die "Unkown checksum $chksum_extension"
  ;;
esac

[ -e ./gcc/BASE-VER ]                                                         \
    || die "You must run this script in the top-level GCC source directory"

[ -d "${directory}" ]                                                         \
    || die "No such directory: ${directory}"

for ar in $(echo_archives)
do
    if [ ${force} -gt 0 ]; then rm -f "${directory}/${ar}"; fi
    [ -e "${directory}/${ar}" ]                                               \
        || ( cd "${directory}" && ${fetch} --no-verbose "${base_url}${ar}" )  \
        || die "Cannot download ${ar} from ${base_url}"
done
unset ar

if [ ${verify} -gt 0 ]
then
    chksumfile="contrib/prerequisites.${chksum_extension}"
    [ -r "${chksumfile}" ] || die "No checksums available"
    for ar in $(echo_archives)
    do
        grep "${ar}" "${chksumfile}"                                          \
            | ( cd "${directory}" && ${chksum} )                              \
            || die "Cannot verify integrity of possibly corrupted file ${ar}"
    done
    unset chksumfile
fi
unset ar

for ar in $(echo_archives)
do
    package="${ar%.tar*}"
    if [ ${force} -gt 0 ]; then rm -rf "${directory}/${package}"; fi
    case $ar in
    *.gz)
	uncompress='gzip -d'
	;;
    *.bz2)
	uncompress='bzip2 -d'
	;;
    *)
	uncompress='cat'
	;;
    esac
    [ -e "${directory}/${package}" ]                                          \
        || ( cd "${directory}" && $uncompress <"${ar}" | tar -xf - )          \
        || die "Cannot extract package from ${ar}"
    unset package
done
unset ar

for ar in $(echo_archives)
do
    target="${directory}/${ar%.tar*}/"
    linkname="${ar%-*}"
    if [ ${force} -gt 0 ]; then rm -f "${linkname}"; fi
    [ -e "${linkname}" ]                                                      \
        || ln -s "${target}" "${linkname}"                                    \
        || die "Cannot create symbolic link ${linkname} --> ${target}"
    unset target linkname
done
unset ar

echo "All prerequisites downloaded successfully."
