#! /bin/sh # # Copyright (C) 2002-2013 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 . # # This file is meant for authors, maintainers, co-maintainers or installers # of packages which are internationalized with the help of GNU gettext. For # further information how to use it consult the GNU gettext manual. progname=$0 package=gettext-tools version=0.18.3 # Set variables # - gettext_dir directory where the sources are stored. prefix="/usr" datarootdir="${prefix}/share" gettext_dir="/usr/share/gettext" # func_tmpdir # creates a temporary directory. # Sets variable # - tmp pathname of freshly created temporary directory func_tmpdir () { # Use the environment variable TMPDIR, falling back to /tmp. This allows # users to specify a different temporary directory, for example, if their # /tmp is filled up or too small. : ${TMPDIR=/tmp} { # Use the mktemp program if available. If not available, hide the error # message. tmp=`(umask 077 && mktemp -d "$TMPDIR/gtXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { # Use a simple mkdir command. It is guaranteed to fail if the directory # already exists. $RANDOM is bash specific and expands to empty in shells # other than bash, ksh and zsh. Its use does not increase security; # rather, it minimizes the probability of failure in a very cluttered /tmp # directory. tmp=$TMPDIR/gt$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$0: cannot create a temporary directory in $TMPDIR" >&2 { (exit 1); exit 1; } } } # Support for relocatability. func_find_curr_installdir () { # Determine curr_installdir, even taking into account symlinks. curr_executable="$0" case "$curr_executable" in */* | *\\*) ;; *) # Need to look in the PATH. save_IFS="$IFS"; IFS="${PATH_SEPARATOR=':'}" for dir in $PATH; do IFS="$save_IFS" test -z "$dir" && dir=. for exec_ext in ''; do if test -f "$dir/$curr_executable$exec_ext"; then curr_executable="$dir/$curr_executable$exec_ext" break 2 fi done done IFS="$save_IFS" ;; esac # Make absolute. case "$curr_executable" in /* | ?:/* | ?:\\*) ;; *) curr_executable=`pwd`/"$curr_executable" ;; esac # Resolve symlinks. sed_dirname='s,/[^/]*$,,' sed_linkdest='s,^.* -> \(.*\),\1,p' while : ; do lsline=`LC_ALL=C ls -l "$curr_executable"` case "$lsline" in *" -> "*) linkdest=`echo "$lsline" | sed -n -e "$sed_linkdest"` case "$linkdest" in /* | ?:/* | ?:\\*) curr_executable="$linkdest" ;; *) curr_executable=`echo "$curr_executable" | sed -e "$sed_dirname"`/"$linkdest" ;; esac ;; *) break ;; esac done curr_installdir=`echo "$curr_executable" | sed -e 's,/[^/]*$,,'` # Canonicalize. curr_installdir=`cd "$curr_installdir" && pwd` } func_find_prefixes () { # Compute the original/current installation prefixes by stripping the # trailing directories off the original/current installation directories. orig_installprefix="$orig_installdir" curr_installprefix="$curr_installdir" while true; do orig_last=`echo "$orig_installprefix" | sed -n -e 's,^.*/\([^/]*\)$,\1,p'` curr_last=`echo "$curr_installprefix" | sed -n -e 's,^.*/\([^/]*\)$,\1,p'` if test -z "$orig_last" || test -z "$curr_last"; then break fi if test "$orig_last" != "$curr_last"; then break fi orig_installprefix=`echo "$orig_installprefix" | sed -e 's,/[^/]*$,,'` curr_installprefix=`echo "$curr_installprefix" | sed -e 's,/[^/]*$,,'` done } if test "no" = yes; then exec_prefix="/usr" bindir="/usr/bin" orig_installdir="$bindir" # see Makefile.am's *_SCRIPTS variables func_find_curr_installdir # determine curr_installdir func_find_prefixes # Relocate the directory variables that we use. gettext_dir=`echo "$gettext_dir/" | sed -e "s%^${orig_installprefix}/%${curr_installprefix}/%" | sed -e 's,/$,,'` fi # func_trace macro # traces an Autoconf macro call and outputs the arguments to stdout. func_trace () { echo '\ dnl ignore M4sugar macros which may abort autom4te m4_undefine([m4_assert]) m4_undefine([m4_fatal]) m4_undefine([m4_warn]) m4_undefine([m4_errprintn]) m4_undefine([m4_exit]) dnl macros which needs to be traced without aclocal.m4 m4_define([AM_GNU_GETTEXT], []) m4_define([AM_GNU_GETTEXT_VERSION], []) ' \ | autom4te --no-cache --language=Autoconf-without-aclocal-m4 \ --trace="$1":\$% - "$2" } # func_usage # outputs to stdout the --help usage message. func_usage () { echo "\ Usage: autopoint [OPTION]... Copies standard gettext infrastructure files into a source package. Options: --help print this help and exit --version print version information and exit -f, --force force overwriting of files that already exist -n, --dry-run print modifications but don't perform them" # echo "\ # -V version copy the infrastructure of the specified gettext version # (dangerous)" echo " Report bugs to ." } # func_version # outputs to stdout the --version message. func_version () { echo "$progname (GNU $package) $version" echo "Uses a versions archive in dirxz format." echo "Copyright (C) 2002-2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law." echo "Written by" "Bruno Haible" } # func_fatal_error message # outputs to stderr a fatal error message, and terminates the program. func_fatal_error () { echo "autopoint: *** $1" 1>&2 echo "autopoint: *** Stop." 1>&2 exit 1 } # Command-line option processing. # Removes the OPTIONS from the arguments. Sets the variables: # - force yes if --force was given, empty otherwise # - ver gettext version if -V was given, empty otherwise # - doit false if --dry-run was given, : otherwise { force= ver= doit=: while test $# -gt 0; do case "$1" in -n | --dry-run | --dry-ru | --dry-r | --dry- | --dry | --dr | --d ) shift doit=false ;; -f | --force | --forc | --for | --fo | --f ) shift force=yes ;; --help | --hel | --he | --h ) func_usage; exit 0 ;; # -V ) # Some people put a space between -V and the version number. # shift # if test $# = 0; then # func_usage 1>&2 # exit 1 # fi # ver=$1; # shift ;; # -V*) # Some people omit the space between -V and the version number. # ver=`echo "X$1" | sed -e 's/^X-V//'` # shift ;; --version | --versio | --versi | --vers | --ver | --ve | --v ) func_version exit 0 ;; -- ) # Stop option prcessing shift; break ;; -* ) echo "autopoint: unknown option $1" 1>&2 echo "Try 'autopoint --help' for more information." 1>&2 exit 1 ;; * ) break ;; esac done } # Command-line argument processing. # Analyzes the remaining arguments. { if test $# -gt 0; then func_usage 1>&2 exit 1 fi } srcdir=`pwd` # The current directory is now $srcdir. # Check integrity of package: A configure.in/ac must be present. Sets variable # - configure_in name of configure.in/ac file. if test -f configure.in; then configure_in=configure.in else if test -f configure.ac; then configure_in=configure.ac else # KDE specific convention: configure.in.in if test -f configure.in.in; then configure_in=configure.in.in else func_fatal_error "Missing configure.in or configure.ac, please cd to your package first." fi fi fi # Check whether the -V option and the version number in configure.in match. # At least one of the two must be given. If both are given, they must agree. xver=`func_trace AM_GNU_GETTEXT_VERSION "$configure_in"` if test -z "$xver" && test -f intl/VERSION; then xver=`cat intl/VERSION | LC_ALL=C sed -n -e 's/^.*gettext-\([-+_.0-9A-Za-z]*\).*$/\1/p'` fi if test -n "$xver"; then if test -n "$ver"; then if test "X$ver" != "X$xver"; then func_fatal_error "Version mismatch: specified -V $ver but the package uses gettext version $xver" fi else ver="$xver" fi else if test -z "$ver"; then func_fatal_error "Missing version: please specify in $configure_in through a line 'AM_GNU_GETTEXT_VERSION(x.yy.zz)' the gettext version the package is using" fi fi # Check whether the version number is supported. case "$ver" in 0.10.35 | 0.10.36 | 0.10.37 | 0.10.38 | 0.10.39 | 0.10.40 | \ 0.11 | 0.11.1 | 0.11.2 | 0.11.3 | 0.11.4 | 0.11.5 | \ 0.12 | 0.12.1 | \ 0.13 | 0.13.1 | \ 0.14 | 0.14.1 | 0.14.2 | 0.14.3 | 0.14.4 | 0.14.5 | 0.14.6 | \ 0.15 | \ 0.16 | 0.16.1 | \ 0.17 | \ 0.18 | 0.18.1 | 0.18.2 | 0.18.3 ) ;; *) func_fatal_error "The AM_GNU_GETTEXT_VERSION declaration in your $configure_in file requires the infrastructure from gettext-$ver but this version is older. Please upgrade to gettext-$ver or newer." ;; esac # Check in which directory config.rpath, mkinstalldirs etc. belong. auxdir=`func_trace AC_CONFIG_AUX_DIR "$configure_in"` if test -n "$auxdir"; then auxdir="$auxdir/" fi # Check in which directory the *.m4 macros belong. macrodirs=`func_trace AC_CONFIG_MACRO_DIR_TRACE "$configure_in"` if test -z "$macrodirs"; then macrodirs=`func_trace AC_CONFIG_MACRO_DIR "$configure_in"` fi for arg in $macrodirs; do m4dir="$arg" break done if test -z "$m4dir" && test -f Makefile.am; then # A package using automake. # Extract the macro directory name from Makefile.am. aclocal_amflags=`grep '^ACLOCAL_AMFLAGS[ ]*=' Makefile.am | sed -e 's/^ACLOCAL_AMFLAGS[ ]*=\(.*\)$/\1/'` m4dir_is_next= for arg in $aclocal_amflags; do if test -n "$m4dir_is_next"; then m4dir="$arg" break else if test "X$arg" = "X-I"; then m4dir_is_next=yes else m4dir_is_next= fi fi done fi # Check whether to omit the intl/ directory. omitintl= xargs=`func_trace AM_GNU_GETTEXT "$configure_in"` for arg in $xargs; do if test 'external' = "$arg"; then omitintl=yes break fi done # Check in which directory or directories the po/* infrastructure belongs. configfiles=`func_trace AC_CONFIG_FILES "$configure_in"` # PO directories have a Makefile.in generated from Makefile.in.in. # Treat a directory as a PO directory if and only if it has a # POTFILES.in file. This allows packages to have multiple PO # directories under different names or in different locations. sed_remove_Makefile_in='s,/Makefile\.in$,,' podirs=`for f in $configfiles; do case "$f" in */Makefile.in) echo $f;; esac; done | sed -e "$sed_remove_Makefile_in"` if test -z "$podirs"; then # If we cannot get the list of PO directories from configure.ac, assume the # common default. podirs="po" fi # Set up a temporary checkout directory. # Set variables # - work_dir directory containing the temporary checkout work_dir=tmpwrk$$ mkdir "$work_dir" || { if test -d "$work_dir"; then func_fatal_error "directory $work_dir already exists" else func_fatal_error "cannot create directory $work_dir" fi } # We support three archive formats. # # Format | Size (KiB) for gettext-0.17 | Extra tools needed | # -------+-----------------------------+--------------------+ # dir | 3000 | -- | # cvs | 356 | cvs | # git | 484 | git | # -------+-----------------------------+--------------------+ case "dirxz" in dir*) # The archive of different versions is very large (unless xz compression is # used), but using it does not require special tools. case "dirxz" in dirgz) gzip -d -c < "$gettext_dir/archive.dir.tar.gz" ;; dirbz2) bzip2 -d -c < "$gettext_dir/archive.dir.tar.bz2" ;; dirxz) xz -d -c < "$gettext_dir/archive.dir.tar.xz" ;; esac \ | (cd "$work_dir" && tar xf - "gettext-$ver") if test `find "$work_dir" -type f -print | wc -l` = 0; then rm -rf "$work_dir" func_fatal_error "infrastructure files for version $ver not found; this is autopoint from GNU $package $version" fi mv "$work_dir/gettext-$ver" "$work_dir/archive" ;; cvs) # We distributed the many different versions of the files in a CVS # repository. This guaranteed a good compression rate: # # Including version size in KB of # "du autopoint-files/archive" # 0.10.35 240 # 0.10.36 428 # 0.10.37 436 # 0.10.38 488 # 0.10.39 500 # 0.10.40 528 # 0.11 720 # 0.11.1 740 # 0.11.2 748 # 0.11.3 804 # 0.11.4 864 # 0.11.5 880 # 0.12 1032 # 0.12.1 1032 # 0.13 1220 # 0.13.1 1236 # 0.14 1296 # 0.14.1 1300 # 0.14.2 1420 # 0.14.3 1428 # 0.14.4 1464 # 0.14.5 1508 # 0.14.6 1580 # 0.15 1760 # 0.16 1808 # 0.16.1 1812 # 0.17 2128 # 0.18 2656 # # The requirement that the user must have the CVS program available is not # a severe restrictions, because most of the people who use autopoint are # users of CVS. # # But the CVS format is now deprecated, because "cvs init" does not work in # all circumstances # (see ) # and we are not allowed to distribute the cvs infrastructure files # ourselves # (see ). # # Check availability of the CVS program. (cvs -v) >/dev/null 2>/dev/null || func_fatal_error "cvs program not found" # Set up a temporary CVS repository. # We need the temporary CVS repository because any checkout needs write # access to the CVSROOT/history file, so it cannot be under $gettext_dir. # We need the temporary checkout directory because when --force was not # given, we need to compare the existing files with the checked out ones. # Set variables # - cvs_dir directory containing the temporary repository cvs_dir=tmpcvs$$ # Use an umask of 077, to avoid attacks that work by overwriting files in # the "$CVSROOT"/CVSROOT directory. (umask 077 && mkdir "$cvs_dir") || { if test -d "$cvs_dir"; then func_fatal_error "directory $cvs_dir already exists" else func_fatal_error "cannot create directory $cvs_dir" fi } CVSROOT="$srcdir/$cvs_dir" unset CVS_CLIENT_LOG unset CVS_CLIENT_PORT unset CVS_IGNORE_REMOTE_ROOT unset CVS_LOCAL_BRANCH_NUM unset CVS_NOBASES unset CVS_PASSFILE unset CVS_PASSWORD unset CVS_PROXY_PORT unset CVS_RCMD_PORT unset CVS_RSH unset CVS_SERVER unset CVS_SERVER_SLEEP CVS_SIGN_COMMITS= export CVS_SIGN_COMMITS unset CVS_SSH unset CVS_VERIFY_CHECKOUTS unset CVS_VERIFY_TEMPLATE unset CVSIGNORE unset CVSREAD unset CVSREADONLYFS unset CVSUMASK unset CVSWRAPPERS # Need to pass -d "$CVSROOT", because there may be a CVS directory in the # current directory. cvs -d "$CVSROOT" init gzip -d -c < "$gettext_dir/archive.cvs.tar.gz" | (cd "$cvs_dir" && tar xf -) cd "$work_dir" cvsver=gettext-`echo "$ver" | sed -e 's/\./_/g'` (cvs -d "$CVSROOT" checkout -r"$cvsver" archive > /dev/null) 2>&1 | grep -v '^cvs checkout: Updating' find archive -name CVS -type d -print | xargs rm -rf cd .. rm -rf "$cvs_dir" # Check that really all CVS directories are gone, otherwise we would overwrite # the contents of the user's CVS directories. if test `find $work_dir/archive -name CVS -type d -print | wc -l` != 0; then rm -rf "$work_dir" func_fatal_error "failed to remove all CVS subdirectories" fi if test `find $work_dir/archive -type f -print | wc -l` = 0; then rm -rf "$work_dir" func_fatal_error "infrastructure files for version $ver not found; this is autopoint from GNU $package $version" fi ;; git) # Check availability of the git program. (git --version) >/dev/null 2>/dev/null || func_fatal_error "git program not found" mkdir "$work_dir/archive" gzip -d -c < "$gettext_dir/archive.git.tar.gz" | (cd "$work_dir/archive" && tar xf -) (cd "$work_dir/archive" && git checkout -q "gettext-$ver") || { rm -rf "$work_dir" func_fatal_error "infrastructure files for version $ver not found; this is autopoint from GNU $package $version" } (cd "$work_dir/archive" && rm -rf .git .gitignore) ;; esac # func_destfile file # determines the destination file, relative to the package's top level # directory, for a given file name, relative to archive. # Sets variables # - destfile relative destination file name, or # empty if the file shall be omitted # - sharedowner yes if the file is not only owned by GNU gettext but may # be installed by automake or other tools, otherwise empty # - allpodirs yes if the file is to be installed in every dir in $podirs func_destfile () { # There are five categories of files: # ABOUT_NLS -> top level directory # config.rpath mkinstalldirs -> $auxdir # m4/* -> $m4dir/ # intl/* -> intl/ # po/* -> sharedowner= allpodirs= case `echo "$1" | sed -e 's,[^/]*$,,'` in "" ) case "$1" in config.rpath ) destfile="$auxdir$1" ;; mkinstalldirs ) destfile="$auxdir$1" sharedowner=yes ;; * ) destfile="$1" ;; esac ;; m4/ ) destfile=`echo "$1" | sed -e "s,^m4/,$m4dir/,"` ;; intl/ ) if test -n "$omitintl"; then destfile=""; else destfile="$1"; fi ;; po/ ) destfile=`echo "$1" | sed -e "s,^po/,,"` allpodirs=yes ;; * ) destfile="$1" ;; esac } # func_compare existingfile gettextfile # compares the existing file and the file from gettext, and decides whether the # existing file should be overwritten with the file from gettext. Returns 0 if # it should be overwritten, or 1 if it should be skipped. sed_extract_serial='s/^#.* serial \([^ ]*\).*/\1/p 1q' func_compare () { if cmp -s "$1" "$2"; then false else case "$2" in *.m4) # For interoperability with gnulib. gnulib often has newer versions of # the *.m4 files than the latest gettext release. Don't overwrite a # newer version from gnulib with an older version from the gettext # release. The version can be retrieved from the first line, which # looks like this: # file.m4 serial NN ... existing_serial=`sed -n -e "$sed_extract_serial" < "$1"` gettext_serial=`sed -n -e "$sed_extract_serial" < "$2"` if test -n "$existing_serial" && test -n "$gettext_serial" \ && test "$existing_serial" -ge "$gettext_serial" 2> /dev/null; then false else true fi ;; *) true ;; esac fi } # If some files have been locally modified and we have not been requested # to overwrite them, then bail out. This is better than leaving a source # package around where half of the files are locally modified and half are # original - too great risk of version mismatch. if test -z "$force"; then mismatch= func_tmpdir mismatchfile="$tmp"/autopoint.diff for file in `find "$work_dir/archive" -type f -print | sed -e "s,^$work_dir/archive/,," | LC_ALL=C sort`; do func_destfile "$file" if test -n "$destfile"; then func_compare_to_destfile () { finaldestfile="$1" if test -f "$finaldestfile"; then if func_compare "$finaldestfile" "$work_dir/archive/$file"; then if test -n "$sharedowner"; then echo "autopoint: warning: File $finaldestfile has been locally modified." 1>&2 else echo "autopoint: File $finaldestfile has been locally modified." 1>&2 mismatch=yes diff -c "$work_dir/archive/$file" "$finaldestfile" | sed -e "1s,$work_dir/archive/,," >> "$mismatchfile" fi fi fi } if test -n "$allpodirs"; then for dir in $podirs; do func_compare_to_destfile "$dir/$destfile" done else func_compare_to_destfile "$destfile" fi fi done if test -n "$mismatch"; then rm -rf "$work_dir" func_fatal_error "Some files have been locally modified. Not overwriting them because --force has not been specified. For your convenience, you find the local modifications in the file '$mismatchfile'." fi rm -rf "$tmp" fi # func_mkdir_for to # ensures the directory that would the given file exists. # 'to' is a relative pathname, relative to the current directory. func_mkdir_for () { base=`echo "$1" | sed -e 's,/[^/]*$,,'` if test "X$base" != "X$1" && test -n "$base"; then func_mkdir_for "$base" # Recompute base. It was clobbered by the recursive call. base=`echo "$1" | sed -e 's,/[^/]*$,,'` test -d "$base" || { echo "Creating directory $base"; mkdir "$base"; } fi } # func_copy from to # copies a file. # 'from' is a relative pathname, relative to the current directory. # 'to' is a relative pathname, relative to the current directory. func_copy () { if $doit; then func_mkdir_for "$2" rm -f "$2" echo "Copying file $2" cp "$1" "$2" else echo "Copy file $2" fi } # func_backup to # makes a backup of a file that is about to be overwritten or replaced. # 'to' is a relative pathname, relative to the current directory. func_backup () { if $doit; then if test -f "$1"; then rm -f "$1~" cp -p "$1" "$1~" fi fi } # Now copy the files. for file in `find "$work_dir/archive" -type f -print | sed -e "s,^$work_dir/archive/,," | LC_ALL=C sort`; do func_destfile "$file" if test -n "$destfile"; then func_copy_to_destfile () { finaldestfile="$1" mustcopy= if test -f "$finaldestfile"; then if func_compare "$finaldestfile" "$work_dir/archive/$file"; then if test -n "$force"; then # Overwrite locally modified file. mustcopy=yes fi # If --force is not specified, don't overwrite locally modified files # for which GNU gettext is a shared owner. fi else mustcopy=yes fi if test -n "$mustcopy"; then func_backup "$finaldestfile" func_copy "$work_dir/archive/$file" "$finaldestfile" fi } if test -n "$allpodirs"; then for dir in $podirs; do func_copy_to_destfile "$dir/$destfile" done else func_copy_to_destfile "$destfile" fi fi done # That's it. rm -rf "$work_dir" exit 0