Home | History | Annotate | Line # | Download | only in maintainer-scripts
gcc_release revision 1.1.1.6
      1 #! /bin/sh
      2 
      3 ########################################################################
      4 #
      5 # File:   gcc_release
      6 # Author: Jeffrey Law, Bernd Schmidt, Mark Mitchell
      7 # Date:   2001-05-25
      8 #
      9 # Contents:
     10 #   Script to create a GCC release.
     11 #
     12 # Copyright (c) 2001-2015 Free Software Foundation.
     13 #
     14 # This file is part of GCC.
     15 #
     16 # GCC is free software; you can redistribute it and/or modify
     17 # it under the terms of the GNU General Public License as published by
     18 # the Free Software Foundation; either version 3, or (at your option)
     19 # any later version.
     20 #
     21 # GCC is distributed in the hope that it will be useful,
     22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     24 # GNU General Public License for more details.
     25 #
     26 # You should have received a copy of the GNU General Public License
     27 # along with GCC; see the file COPYING3.  If not see
     28 # <http://www.gnu.org/licenses/>.
     29 #
     30 ########################################################################
     31 
     32 ########################################################################
     33 # Notes
     34 ########################################################################
     35 
     36 # Here is an example usage of this script, to create a GCC 3.0.2
     37 # prerelease:
     38 #
     39 #   gcc_release -r 3.0.2
     40 #
     41 # This script will automatically use the head of the release branch
     42 # to generate the release.
     43 
     44 ########################################################################
     45 # Functions
     46 ########################################################################
     47 
     48 # Issue the error message given by $1 and exit with a non-zero
     49 # exit code.
     50 
     51 error() {
     52     echo "gcc_release: error: $1"
     53     exit 1
     54 }
     55 
     56 # Issue the informational message given by $1.
     57 
     58 inform() {
     59     echo "gcc_release: $1"
     60 }
     61 
     62 # Issue a usage message explaining how to use this script.
     63 
     64 usage() {
     65 cat <<EOF
     66 gcc_release -r release [-f] [further options]
     67 gcc_release -s name:svnbranch [further options]
     68 
     69 Options:
     70 
     71   -r release           Version of the form X.Y or X.Y.Z.
     72   -s name:svnbranch    Create a snapshot, not a real release.
     73 
     74   -d destination       Local working directory where we will build the release
     75                        (default=${HOME}).
     76   -f                   Create a final release (and update ChangeLogs,...).
     77   -l                   Indicate that we are running on gcc.gnu.org.
     78   -p previous-tarball  Location of a previous tarball (to generate diff files).
     79   -t tag               Tag to mark the release in SVN.
     80   -u username          Username for upload operations.
     81 EOF
     82     exit 1
     83 }
     84 
     85 # Change to the directory given by $1.
     86 
     87 changedir() {
     88   cd $1 || \
     89     error "Could not change directory to $1"
     90 }
     91 
     92 # Build the source tree that will be the basis for the release
     93 # in ${WORKING_DIRECTORY}/gcc-${RELEASE}.
     94 
     95 build_sources() {
     96   # If the WORKING_DIRECTORY already exists, do not risk destroying it.
     97   if [ -r ${WORKING_DIRECTORY} ]; then
     98     error "\`${WORKING_DIRECTORY}' already exists"
     99   fi
    100   # Create the WORKING_DIRECTORY.
    101   mkdir "${WORKING_DIRECTORY}" \
    102     || error "Could not create \`${WORKING_DIRECTORY}'"
    103   changedir "${WORKING_DIRECTORY}"
    104 
    105   # If this is a final release, make sure that the ChangeLogs
    106   # and version strings are updated.
    107   if [ ${FINAL} -ne 0 ]; then
    108     inform "Updating ChangeLogs and version files"
    109 
    110     ${SVN} -q co "${SVNROOT}/${SVNBRANCH}" "`basename ${SOURCE_DIRECTORY}`" ||\
    111            error "Could not check out release sources"
    112     svnciargs=""
    113     for x in `changedir ${SOURCE_DIRECTORY} && \
    114 	      find . -name ChangeLog`; do
    115       # Update this ChangeLog file only if it does not yet contain the
    116       # entry we are going to add.  (This is a safety net for repeated
    117       # runs of this script for the same release.)
    118       if ! grep "GCC ${RELEASE} released." ${SOURCE_DIRECTORY}/${x} > /dev/null ; then       
    119 	cat - ${SOURCE_DIRECTORY}/${x} > ${SOURCE_DIRECTORY}/${x}.new <<EOF
    120 ${LONG_DATE}  Release Manager
    121 
    122 	* GCC ${RELEASE} released.
    123 
    124 EOF
    125 	mv ${SOURCE_DIRECTORY}/${x}.new ${SOURCE_DIRECTORY}/${x} \
    126 	  || error "Could not update ${x}"
    127 	svnciargs="${svnciargs} ${x}"
    128       fi
    129     done
    130 
    131     # Update gcc/DEV-PHASE.
    132 
    133     if [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` != ${RELEASE} ]; then
    134       [ ${RELEASE_MAJOR} -lt 5 ] && \
    135 	error "Release number ${RELEASE} does not match BASE-VER"
    136       if [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` \
    137 	   = ${RELEASE_MAJOR}.`expr ${RELEASE_MINOR} - 1`.1 \
    138 	   -a x${RELEASE_REVISION} = x0 ]; then
    139 	(changedir ${SOURCE_DIRECTORY}/gcc && \
    140 	 echo ${RELEASE} > BASE-VER) || \
    141 	error "Could not update BASE-VER"
    142 	svnciargs="${svnciargs} gcc/BASE-VER"
    143       else
    144 	error "Release number ${RELEASE} does not immediately follow BASE-VER"
    145       fi
    146     fi
    147     (changedir ${SOURCE_DIRECTORY}/gcc && \
    148      : > DEV-PHASE) || \
    149     error "Could not update DEV-PHASE"
    150     svnciargs="${svnciargs} gcc/DEV-PHASE"
    151 
    152     (changedir ${SOURCE_DIRECTORY} && \
    153      ${SVN} -q ci -m 'Update ChangeLog and version files for release' ${svnciargs}) || \
    154     error "Could not commit ChangeLog and version file updates"
    155 
    156     # Make sure we tag the sources for a final release.
    157     TAG="tags/gcc_`echo ${RELEASE} | tr . _`_release"
    158 
    159     rm -rf ${SOURCE_DIRECTORY}
    160   fi
    161 
    162   # Tag the sources.
    163   if [ -n "${TAG}" ]; then
    164     inform "Tagging sources as ${TAG}"
    165     # We don't want to overwrite an existing tag.  So, if the tag
    166     # already exists, issue an error message; the release manager can
    167     # manually remove the tag if appropriate.
    168     echo "${SVN} ls ${SVNROOT}/${TAG}/ChangeLog" 
    169     if ${SVN} ls "${SVNROOT}/${TAG}/ChangeLog"; then 
    170       error "Tag ${TAG} already exists"
    171     fi
    172     ${SVN} -m "Tagging source as ${TAG}" cp "${SVNROOT}/${SVNBRANCH}" "${SVNROOT}/${TAG}" || \
    173       error "Could not tag sources"
    174     SVNBRANCH=${TAG}
    175   fi
    176   SVNREV=`${SVN} info "${SVNROOT}/${SVNBRANCH}"|awk '/Revision:/ {print $2}'`
    177 
    178   # Export the current sources.
    179   inform "Retrieving sources (svn export -r ${SVNREV} ${SVNROOT}/${SVNBRANCH})"
    180 
    181   ${SVN} -q export -r${SVNREV} "${SVNROOT}/${SVNBRANCH}" "`basename ${SOURCE_DIRECTORY}`" ||\
    182     error "Could not retrieve sources"
    183 
    184   # Run gcc_update on them to set up the timestamps nicely, and (re)write
    185   # the LAST_UPDATED file containing the SVN tag/revision used.
    186   changedir "gcc-${RELEASE}"
    187   contrib/gcc_update --touch
    188   echo "Obtained from SVN: ${SVNBRANCH} revision ${SVNREV}" > LAST_UPDATED
    189 
    190   # For a prerelease or real release, we need to generate additional
    191   # files not present in SVN.
    192   changedir "${SOURCE_DIRECTORY}"
    193   if [ $SNAPSHOT -ne 1 ]; then
    194     # Generate the documentation.
    195     inform "Building install docs"
    196     SOURCEDIR=${SOURCE_DIRECTORY}/gcc/doc
    197     DESTDIR=${SOURCE_DIRECTORY}/INSTALL
    198     export SOURCEDIR
    199     export DESTDIR
    200     ${SOURCE_DIRECTORY}/gcc/doc/install.texi2html
    201 
    202     # Regenerate the NEWS file.
    203     contrib/gennews > NEWS || \
    204       error "Could not regenerate NEWS files"
    205 
    206     # Now, we must build the compiler in order to create any generated
    207     # files that are supposed to go in the source directory.  This is
    208     # also a good sanity check to make sure that the release builds
    209     # on at least one platform.
    210     inform "Building compiler"
    211     OBJECT_DIRECTORY=../objdir
    212     num_cpus=1
    213     if type -p getconf 2>/dev/null; then
    214       num_cpus=`getconf _NPROCESSORS_ONLN 2>/dev/null`
    215       case "$num_cpus" in
    216 	'' | 0* | *[!0-9]*) num_cpus=1;;
    217       esac
    218     fi
    219     contrib/gcc_build -d ${SOURCE_DIRECTORY} -o ${OBJECT_DIRECTORY} \
    220       -c "--enable-generated-files-in-srcdir --disable-multilib" \
    221       -m "-j$num_cpus" build || \
    222       error "Could not rebuild GCC"
    223   fi
    224 
    225   # Move message catalogs to source directory.
    226   mv ../objdir/gcc/po/*.gmo gcc/po/
    227   [ -f libcpp/po/cpplib.pot ] && mv ../objdir/libcpp/po/*.gmo libcpp/po/
    228 
    229   # Create a "MD5SUMS" file to use for checking the validity of the release.
    230   echo \
    231 "# This file contains the MD5 checksums of the files in the 
    232 # gcc-"${RELEASE}".tar.xz tarball.
    233 #
    234 # Besides verifying that all files in the tarball were correctly expanded,
    235 # it also can be used to determine if any files have changed since the
    236 # tarball was expanded or to verify that a patchfile was correctly applied.
    237 #
    238 # Suggested usage:
    239 # md5sum -c MD5SUMS | grep -v \"OK$\"
    240 #" > MD5SUMS
    241 
    242   find . -type f |
    243   sed -e 's:^\./::' -e '/MD5SUMS/d' |
    244   sort |
    245   xargs md5sum >>MD5SUMS
    246 }
    247 
    248 # Build a single tarfile.  The first argument is the name of the tarfile
    249 # to build, without any suffixes.  They will be added automatically.  The
    250 # rest of the arguments are files or directories to include, and possibly
    251 # other arguments to tar.
    252 
    253 build_tarfile() {
    254   # Get the name of the destination tar file.
    255   TARFILE="$1.tar.xz"
    256   shift
    257 
    258   # Build the tar file itself.
    259   (${TAR} cf - "$@" | ${XZ} > ${TARFILE}) || \
    260     error "Could not build tarfile"
    261   FILE_LIST="${FILE_LIST} ${TARFILE}"
    262 }
    263 
    264 # Build the various tar files for the release.
    265 
    266 build_tarfiles() {
    267   inform "Building tarfiles"
    268 
    269   changedir "${WORKING_DIRECTORY}"
    270 
    271   # The GNU Coding Standards specify that all files should
    272   # world readable.
    273   chmod -R a+r ${SOURCE_DIRECTORY}
    274   # And that all directories have mode 755.
    275   find ${SOURCE_DIRECTORY} -type d -exec chmod 755 {} \;
    276  
    277   # Build one huge tarfile for the entire distribution.
    278   build_tarfile gcc-${RELEASE} `basename ${SOURCE_DIRECTORY}`
    279 }
    280 
    281 # Build .gz files.
    282 build_gzip() {
    283   for f in ${FILE_LIST}; do
    284     target=${f%.xz}.gz
    285     (${XZ} -d -c $f | ${GZIP} > ${target}) || error "Could not create ${target}"
    286   done
    287 }
    288 
    289 # Build diffs against an old release.
    290 build_diffs() {
    291   old_dir=${1%/*}
    292   old_file=${1##*/}
    293   case "$old_file" in
    294     *.tar.xz) old_vers=${old_file%.tar.xz};;
    295     *) old_vers=${old_file%.tar.bz2};;
    296   esac
    297   old_vers=${old_vers#gcc-}
    298   inform "Building diffs against version $old_vers"
    299   for f in gcc; do
    300     if [ -e ${old_dir}/${f}-${old_vers}.tar.xz ]; then
    301       old_tar=${old_dir}/${f}-${old_vers}.tar.xz
    302     else
    303       old_tar=${old_dir}/${f}-${old_vers}.tar.bz2
    304     fi
    305     new_tar=${WORKING_DIRECTORY}/${f}-${RELEASE}.tar.xz
    306     if [ ! -e $old_tar ]; then
    307       inform "$old_tar not found; not generating diff file"
    308     elif [ ! -e $new_tar ]; then
    309       inform "$new_tar not found; not generating diff file"
    310     else
    311       build_diff $old_tar gcc-${old_vers} $new_tar gcc-${RELEASE} \
    312         ${f}-${old_vers}-${RELEASE}.diff.xz
    313     fi
    314   done
    315 }
    316 
    317 # Build an individual diff.
    318 build_diff() {
    319   changedir "${WORKING_DIRECTORY}"
    320   tmpdir=gccdiff.$$
    321   mkdir $tmpdir || error "Could not create directory $tmpdir"
    322   changedir $tmpdir
    323   case "$1" in
    324     *.tar.bz2)
    325       (${BZIP2} -d -c $1 | ${TAR} xf - ) || error "Could not unpack $1 for diffs"
    326       ;;
    327     *.tar.xz)
    328       (${XZ} -d -c $1 | ${TAR} xf - ) || error "Could not unpack $1 for diffs"
    329       ;;
    330   esac
    331   (${XZ} -d -c $3 | ${TAR} xf - ) || error "Could not unpack $3 for diffs"
    332   ${DIFF} $2 $4 > ../${5%.xz}
    333   if [ $? -eq 2 ]; then
    334     error "Trouble making diffs from $1 to $3"
    335   fi
    336   ${XZ} ../${5%.xz} || error "Could not generate ../$5"
    337   changedir ..
    338   rm -rf $tmpdir
    339   FILE_LIST="${FILE_LIST} $5"
    340 }
    341 
    342 # Upload the files to the FTP server.
    343 upload_files() {
    344   inform "Uploading files"
    345 
    346   changedir "${WORKING_DIRECTORY}"
    347 
    348   # Make sure the directory exists on the server.
    349   if [ $LOCAL -eq 0 ]; then
    350     ${SSH} -l ${GCC_USERNAME} ${GCC_HOSTNAME} \
    351       mkdir -p "${FTP_PATH}/diffs"
    352     UPLOAD_PATH="${GCC_USERNAME}@${GCC_HOSTNAME}:${FTP_PATH}"
    353   else
    354     mkdir -p "${FTP_PATH}/diffs" \
    355       || error "Could not create \`${FTP_PATH}'"
    356     UPLOAD_PATH=${FTP_PATH}
    357   fi
    358 
    359   # Then copy files to their respective (sub)directories.
    360   for x in gcc*.gz gcc*.xz; do
    361     if [ -e ${x} ]; then
    362       # Make sure the file will be readable on the server.
    363       chmod a+r ${x}
    364       # Copy it.
    365       case ${x} in
    366         *.diff.*)
    367           SUBDIR="diffs/";
    368           ;;
    369         *)
    370           SUBDIR="";
    371       esac
    372       ${SCP} ${x} ${UPLOAD_PATH}/${SUBDIR} \
    373         || error "Could not upload ${x}"
    374     fi
    375   done
    376 }
    377 
    378 # Print description if snapshot exists.
    379 snapshot_print() {
    380   if [ -e ${RELEASE}/$1 ]; then
    381     hash=`openssl  sha256  ${RELEASE}/$1 | sed -e 's#(.*)##' -e 's# *= *#=#'`
    382     hash2=`openssl sha1 ${RELEASE}/$1 | sed -e 's#(.*)##' -e 's# *= *#=#'`
    383 
    384     printf " %-37s%s\n\n  %s\n  %s\n\n" "$1" "$2" "$hash" "$hash2" \
    385       >> ${SNAPSHOT_README}
    386 
    387      echo "  <tr><td><a href=\"$1\">$1</a></td>" >> ${SNAPSHOT_INDEX}
    388      echo "      <td>$2</td></tr>" >> ${SNAPSHOT_INDEX}
    389   fi
    390 }
    391 
    392 # Announce a snapshot, both on the web and via mail.
    393 announce_snapshot() {
    394   inform "Updating links and READMEs on the FTP server"
    395   
    396   TEXT_DATE=`date --date=$DATE +%B\ %d,\ %Y`
    397   SNAPSHOT_README=${RELEASE}/README
    398   SNAPSHOT_INDEX=${RELEASE}/index.html
    399 
    400   changedir "${SNAPSHOTS_DIR}"
    401   echo \
    402 "Snapshot gcc-"${RELEASE}" is now available on
    403   ftp://gcc.gnu.org/pub/gcc/snapshots/"${RELEASE}"/
    404 and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.
    405 
    406 This snapshot has been generated from the GCC "${BRANCH}" SVN branch
    407 with the following options: "svn://gcc.gnu.org/svn/gcc/${SVNBRANCH} revision ${SVNREV}"
    408 
    409 You'll find:
    410 " > ${SNAPSHOT_README}
    411 
    412   echo \
    413 "<html>
    414 
    415 <head>
    416 <title>GCC "${RELEASE}" Snapshot</title>
    417 </head>
    418 
    419 <body>
    420 <h1>GCC "${RELEASE}" Snapshot</h1>
    421 
    422 <p>The <a href =\"http://gcc.gnu.org/\">GCC Project</a> makes
    423 periodic snapshots of the GCC source tree available to the public
    424 for testing purposes.</p>
    425 	
    426 <p>If you are planning to download and use one of our snapshots, then
    427 we highly recommend you join the GCC developers list.  Details for
    428 how to sign up can be found on the GCC project home page.</p>
    429 
    430 <p>This snapshot has been generated from the GCC "${BRANCH}" SVN branch
    431 with the following options: <code>"svn://gcc.gnu.org/svn/gcc/${SVNBRANCH} revision ${SVNREV}"</code></p>
    432 
    433 <table>" > ${SNAPSHOT_INDEX}
    434        
    435   snapshot_print gcc-${RELEASE}.tar.xz "Complete GCC"
    436 
    437   echo \
    438 "Diffs from "${BRANCH}"-"${LAST_DATE}" are available in the diffs/ subdirectory.
    439 
    440 When a particular snapshot is ready for public consumption the LATEST-"${BRANCH}"
    441 link is updated and a message is sent to the gcc list.  Please do not use
    442 a snapshot before it has been announced that way." >> ${SNAPSHOT_README}
    443 
    444   echo \
    445 "</table>
    446 <p>Diffs from "${BRANCH}"-"${LAST_DATE}" are available in the
    447 <a href=\"diffs/\">diffs/ subdirectory</a>.</p>
    448 
    449 <p>When a particular snapshot is ready for public consumption the LATEST-"${BRANCH}"
    450 link is updated and a message is sent to the gcc list.  Please do not use
    451 a snapshot before it has been announced that way.</p>
    452 
    453 <hr />
    454 
    455 <address>
    456 <a href=\"mailto:gcc (at] gcc.gnu.org\">gcc (at] gcc.gnu.org</a>
    457 <br />
    458 Last modified "${TEXT_DATE}"
    459 </address>
    460 </body>
    461 
    462 </html>" >> ${SNAPSHOT_INDEX}
    463 
    464   rm -f LATEST-${BRANCH}
    465   ln -s ${RELEASE} LATEST-${BRANCH}
    466 
    467   inform "Sending mail"
    468 
    469   export QMAILHOST=gcc.gnu.org
    470   mail -s "gcc-${RELEASE} is now available" gcc@gcc.gnu.org < ${SNAPSHOT_README}
    471 }
    472 
    473 ########################################################################
    474 # Initialization
    475 ########################################################################
    476 
    477 LC_ALL=C
    478 export LC_ALL
    479 
    480 # Today's date.
    481 DATE=`date "+%Y%m%d"`
    482 LONG_DATE=`date "+%Y-%m-%d"`
    483 
    484 SVN=${SVN:-svn}
    485 # The CVS server containing the GCC repository.
    486 SVN_SERVER="gcc.gnu.org"
    487 # The path to the repository on that server.
    488 SVN_REPOSITORY="/svn/gcc"
    489 # The username to use when connecting to the server.
    490 SVN_USERNAME="${USER}"
    491 
    492 # The machine to which files will be uploaded.
    493 GCC_HOSTNAME="gcc.gnu.org"
    494 # The name of the account on the machine to which files are uploaded.
    495 GCC_USERNAME="gccadmin"
    496 # The directory in which the files will be placed (do not use ~user syntax).
    497 FTP_PATH=/var/ftp/pub/gcc
    498 # The directory in which snapshots will be placed.
    499 SNAPSHOTS_DIR=${FTP_PATH}/snapshots
    500 
    501 # The major number for the release.  For release `3.0.2' this would be 
    502 # `3'
    503 RELEASE_MAJOR=""
    504 # The minor number for the release.  For release `3.0.2' this would be
    505 # `0'.
    506 RELEASE_MINOR=""
    507 # The revision number for the release.  For release `3.0.2' this would
    508 # be `2'.
    509 RELEASE_REVISION=""
    510 # The complete name of the release.
    511 RELEASE=""
    512 
    513 # The name of the branch from which the release should be made, in a 
    514 # user-friendly form.
    515 BRANCH=""
    516 
    517 # The name of the branch from which the release should be made, as used
    518 # for our version control system.
    519 SVNBRANCH=""
    520 
    521 # The tag to apply to the sources used for the release.
    522 TAG=""
    523 
    524 # The old tarballs from which to generate diffs.
    525 OLD_TARS=""
    526 
    527 # The directory that will be used to construct the release.  The
    528 # release itself will be placed in a subdirectory of this directory.
    529 DESTINATION=${HOME}
    530 # The subdirectory.
    531 WORKING_DIRECTORY=""
    532 # The directory that will contain the GCC sources.
    533 SOURCE_DIRECTORY=""
    534 
    535 # Non-zero if this is the final release, rather than a prerelease.
    536 FINAL=0
    537 
    538 # Non-zero if we are building a snapshot, and don't build gcc or
    539 # include generated files.
    540 SNAPSHOT=0
    541 
    542 # Non-zero if we are running locally on gcc.gnu.org, and use local CVS
    543 # and copy directly to the FTP directory.
    544 LOCAL=0
    545 
    546 # Major operation modes.
    547 MODE_GZIP=0
    548 MODE_DIFFS=0
    549 MODE_SOURCES=0
    550 MODE_TARFILES=0
    551 MODE_UPLOAD=0
    552 
    553 # List of archive files generated; used to create .gz files from .xz.
    554 FILE_LIST=""
    555 
    556 # Programs we use.
    557 
    558 BZIP2="${BZIP2:-bzip2}"
    559 XZ="${XZ:-xz --best}"
    560 CVS="${CVS:-cvs -f -Q -z9}"
    561 DIFF="${DIFF:-diff -Nrcpad}"
    562 ENV="${ENV:-env}"
    563 GZIP="${GZIP:-gzip --best}"
    564 SCP="${SCP:-scp -p}"
    565 SSH="${SSH:-ssh}"
    566 TAR="${TAR:-tar}"
    567 
    568 ########################################################################
    569 # Command Line Processing
    570 ########################################################################
    571 
    572 # Parse the options.
    573 while getopts "d:fr:u:t:p:s:l" ARG; do
    574     case $ARG in
    575     d)    DESTINATION="${OPTARG}";;
    576     r)    RELEASE="${OPTARG}";;
    577     t)    TAG="${OPTARG}";;
    578     u)    SVN_USERNAME="${OPTARG}";;
    579     f)    FINAL=1;;
    580     s)    SNAPSHOT=1
    581           BRANCH=${OPTARG%:*}
    582           SVNBRANCH=${OPTARG#*:}
    583           ;;
    584     l)    LOCAL=1
    585 	  SCP=cp
    586 	  PATH=~:/usr/local/bin:$PATH;;
    587     p)    OLD_TARS="${OLD_TARS} ${OPTARG}"
    588           if [ ! -f ${OPTARG} ]; then
    589 	    error "-p argument must name a tarball"
    590 	  fi;;
    591     \?)   usage;;
    592     esac
    593 done
    594 shift `expr ${OPTIND} - 1`
    595 
    596 # Handle the major modes.
    597 while [ $# -ne 0 ]; do
    598     case $1 in
    599     diffs)    MODE_DIFFS=1;;
    600     gzip)     MODE_GZIP=1;;
    601     sources)  MODE_SOURCES=1;;
    602     tarfiles) MODE_TARFILES=1;;
    603     upload)   MODE_UPLOAD=1;;
    604     all)      MODE_SOURCES=1; MODE_TARFILES=1; MODE_DIFFS=1; MODE_UPLOAD=1;
    605               if [ $SNAPSHOT -ne 1 ]; then
    606                 # Only for releases and pre-releases.
    607                 MODE_GZIP=1;
    608               fi
    609               ;;
    610     *)        error "Unknown mode $1";;
    611     esac
    612     shift
    613 done
    614 
    615 # Perform consistency checking.
    616 if [ ${LOCAL} -eq 0 ] && [ -z ${SVN_USERNAME} ]; then
    617   error "No username specified"
    618 fi
    619 
    620 if [ ! -d ${DESTINATION} ]; then
    621   error "\`${DESTINATION}' is not a directory"
    622 fi
    623 
    624 if [ $SNAPSHOT -eq 0 ]; then
    625   if [ -z ${RELEASE} ]; then
    626     error "No release number specified"
    627   fi
    628 
    629   # Compute the major and minor release numbers.
    630   RELEASE_MAJOR=`echo $RELEASE | awk --assign FS=. '{ print $1; }'`
    631   RELEASE_MINOR=`echo $RELEASE | awk --assign FS=. '{ print $2; }'`
    632   RELEASE_REVISION=`echo $RELEASE | awk --assign FS=. '{ print $3; }'`
    633 
    634   if [ -z "${RELEASE_MAJOR}" ] || [ -z "${RELEASE_MINOR}" ]; then
    635     error "Release number \`${RELEASE}' is invalid"
    636   fi
    637 
    638   # Compute the full name of the release.
    639   if [ -z "${RELEASE_REVISION}" ]; then
    640     RELEASE="${RELEASE_MAJOR}.${RELEASE_MINOR}"
    641   else
    642     RELEASE="${RELEASE_MAJOR}.${RELEASE_MINOR}.${RELEASE_REVISION}"
    643   fi
    644 
    645   # Compute the name of the branch, which is based solely on the major
    646   # and minor release numbers.
    647   if [ ${RELEASE_MAJOR} -ge 5 ]; then
    648     SVNBRANCH="branches/gcc-${RELEASE_MAJOR}-branch"
    649   else
    650     SVNBRANCH="branches/gcc-${RELEASE_MAJOR}_${RELEASE_MINOR}-branch"
    651   fi
    652 
    653   # If this is not a final release, set various parameters accordingly.
    654   if [ ${FINAL} -ne 1 ]; then
    655     RELEASE="${RELEASE}-RC-${DATE}"
    656     FTP_PATH="${SNAPSHOTS_DIR}/${RELEASE}"
    657   else
    658     FTP_PATH="${FTP_PATH}/releases/gcc-${RELEASE}/"
    659   fi
    660 else
    661   RELEASE=${BRANCH}-${DATE}
    662   FTP_PATH="${FTP_PATH}/snapshots/${RELEASE}"
    663 
    664   # If diffs are requested when building locally on gcc.gnu.org, we (usually)
    665   # know what the last snapshot date was and take the corresponding tarballs,
    666   # unless the user specified tarballs explicitly.
    667   if [ $MODE_DIFFS -ne 0 ] && [ $LOCAL -ne 0 ] && [ -z "${OLD_TARS}" ]; then
    668     LAST_DATE=`cat ~/.snapshot_date-${BRANCH}`
    669     OLD_TARS=${SNAPSHOTS_DIR}/${BRANCH}-${LAST_DATE}/gcc-${BRANCH}-${LAST_DATE}.tar.bz2
    670     if [ ! -e $OLD_TARS ]; then
    671       OLD_TARS=${SNAPSHOTS_DIR}/${BRANCH}-${LAST_DATE}/gcc-${BRANCH}-${LAST_DATE}.tar.xz
    672     fi
    673   fi
    674 fi
    675 
    676 # Compute the name of the WORKING_DIRECTORY and the SOURCE_DIRECTORY.
    677 WORKING_DIRECTORY="${DESTINATION}/gcc-${RELEASE}"
    678 SOURCE_DIRECTORY="${WORKING_DIRECTORY}/gcc-${RELEASE}"
    679 
    680 # Set up SVNROOT.
    681 if [ $LOCAL -eq 0 ]; then
    682     SVNROOT="svn+ssh://${SVN_USERNAME}@${SVN_SERVER}${SVN_REPOSITORY}"
    683 else
    684     SVNROOT="file:///svn/gcc"
    685 fi
    686 export SVNROOT
    687 
    688 ########################################################################
    689 # Main Program
    690 ########################################################################
    691 
    692 # Set the timezone to UTC
    693 TZ="UTC0"
    694 export TZ
    695 
    696 # Build the source directory.
    697 
    698 if [ $MODE_SOURCES -ne 0 ]; then
    699   build_sources
    700 fi
    701 
    702 # Build the tar files.
    703 
    704 if [ $MODE_TARFILES -ne 0 ]; then
    705   build_tarfiles
    706 fi
    707 
    708 # Build diffs
    709 
    710 if [ $MODE_DIFFS -ne 0 ]; then
    711   # Possibly build diffs.
    712   if [ -n "$OLD_TARS" ]; then
    713     for old_tar in $OLD_TARS; do
    714       build_diffs $old_tar
    715     done
    716   fi
    717 fi
    718 
    719 # Build gzip files
    720 if [ $MODE_GZIP -ne 0 ]; then
    721   build_gzip
    722 fi
    723 
    724 # Upload them to the FTP server.
    725 if [ $MODE_UPLOAD -ne 0 ]; then
    726   upload_files
    727 
    728   # For snapshots, make some further updates.
    729   if [ $SNAPSHOT -ne 0 ] && [ $LOCAL -ne 0 ]; then
    730     announce_snapshot
    731 
    732     # Update snapshot date file.
    733     changedir ~
    734     echo $DATE > .snapshot_date-${BRANCH}
    735 
    736     # Remove working directory
    737     rm -rf ${WORKING_DIRECTORY}
    738   fi
    739 fi
    740