mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			524 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			524 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| #! @SHELL@
 | |
| # Copyright (C) 2006  Free Software Foundation
 | |
| # Written by Paolo Bonzini.
 | |
| #
 | |
| # 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 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, write to the Free Software Foundation, Inc.,
 | |
| # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | |
| 
 | |
| 
 | |
| # POSIX and NLS nuisances, taken from autoconf.
 | |
| if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
 | |
|   emulate sh
 | |
|   NULLCMD=:
 | |
|   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
 | |
|   # is contrary to our usage.  Disable this feature.
 | |
|   alias -g '${1+"$@"}'='"$@"'
 | |
|   setopt NO_GLOB_SUBST
 | |
| else
 | |
|   case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
 | |
| fi
 | |
| BIN_SH=xpg4; export BIN_SH # for Tru64
 | |
| DUALCASE=1; export DUALCASE # for MKS sh
 | |
| 
 | |
| if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
 | |
| if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
 | |
| if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
 | |
| if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
 | |
| 
 | |
| # Also make sure CDPATH is empty, and IFS is space, tab, \n in that order.
 | |
| # Be careful to avoid that editors munge IFS
 | |
| (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 | |
| IFS=" ""	""
 | |
| "
 | |
| 
 | |
| : ${TMPDIR=/tmp}
 | |
| : ${ZIP="@ZIP@"}
 | |
| : ${UNZIP="@UNZIP@"}
 | |
| progname="$0"
 | |
| 
 | |
| # Emit a usage message and exit with error status 1
 | |
| usage () {
 | |
|   cat >&2 <<EOF
 | |
| Usage: $0 {ctxu}[vfm0Mi@] [jar-file] [manifest-file] {[-C dir] files} ...
 | |
| Options:
 | |
|     -c  create new archive
 | |
|     -t  list table of contents for archive
 | |
|     -x  extract named (or all) files from archive
 | |
|     -u  update existing archive
 | |
|     -v  generate verbose output on standard output
 | |
|     -f  specify archive file name
 | |
|     -m  include manifest information from specified manifest file
 | |
|     -0  store only; use no ZIP compression
 | |
|     -M  do not create a manifest file for the entries
 | |
|     -i  generate index information for the specified jar files
 | |
|     -@  instead of {[-C dir] files} ... accept one or more response files,
 | |
|         each containing one command-line argument
 | |
|     -C  change to the specified directory and include the following file
 | |
| If any file is a directory then it is processed recursively.
 | |
| The manifest file name and the archive file name needs to be specified
 | |
| in the same order the 'm' and 'f' flags are specified.
 | |
| 
 | |
| Example 1: to archive two class files into an archive called classes.jar: 
 | |
|        jar cvf classes.jar Foo.class Bar.class 
 | |
| Example 2: use an existing manifest file 'mymanifest' and archive all the
 | |
|            files in the foo/ directory into 'classes.jar': 
 | |
|        jar cvfm classes.jar mymanifest -C foo/ .
 | |
| 
 | |
| EOF
 | |
|   (exit 1); exit 1
 | |
| }
 | |
| 
 | |
| # Emit an error message and exit with error status 1
 | |
| error () {
 | |
|   echo "$progname: $*" >&2
 | |
|   (exit 1); exit 1
 | |
| }
 | |
| 
 | |
| # Usage: copy SRC DEST
 | |
| # Copy file SRC to directory DEST, which is the staging area of the jar file.
 | |
| # Fail if it is already present or if it is not a regular file.
 | |
| copy () {
 | |
|   if test -f "$1"; then
 | |
|     # A simple optimization.  Optimistically assuming that ln will work
 | |
|     # cuts 60% of the run-time!
 | |
|     if ln "$1" "$2"/"$1" > /dev/null 2>&1; then
 | |
|       return 0
 | |
|     fi
 | |
| 
 | |
|     if test -f "$2"/"$1"; then
 | |
|       error "$1": Duplicate entry.
 | |
|     fi
 | |
|     dir=`dirname "$1"`
 | |
|     $mkdir_p "$2"/"$dir"
 | |
|     ln "$1" "$2"/"$1" > /dev/null 2>&1 || cp "$1" "$2"/"$1"
 | |
|   elif test -e "$1"; then
 | |
|     error "$1": Invalid file type.
 | |
|   else
 | |
|     error "$1": File not found.
 | |
|   fi
 | |
| }
 | |
| 
 | |
| # Make a temporary directory and store its name in the JARTMP variable.
 | |
| make_tmp () {
 | |
|   test -n "$JARTMP" && return
 | |
| 
 | |
|   {
 | |
|     JARTMP=`(umask 077 && mktemp -d "$TMPDIR/jarXXXXXX") 2>/dev/null` &&
 | |
|       test -n "$JARTMP" && test -d "$JARTMP"
 | |
|   } || {
 | |
|     JARTMP=$TMPDIR/jar$$-$RANDOM
 | |
|     (umask 077 && mkdir "$JARTMP")
 | |
|   } || exit $?
 | |
| 
 | |
|   trap 'exit_status=$?
 | |
|         if test -n "$JARTMP"; then rm -rf "$JARTMP"; fi
 | |
|         exit $exit_status' 0
 | |
| }
 | |
| 
 | |
| # Usage: make_manifest destfile kind [source-manifest]
 | |
| # Create a manifest file and store it in destfile.  KIND can be "default",
 | |
| # or "user", in which case SOURCE-MANIFEST must be specified as well.
 | |
| make_manifest () {
 | |
|   dir=`dirname "$1"`
 | |
|   $mkdir_p "$dir"
 | |
|   case $2 in
 | |
|     default)
 | |
|       cat > "$1" <<\EOF
 | |
| Manifest-Version: 1.0
 | |
| Created-By: @VERSION@
 | |
| 
 | |
| EOF
 | |
|       ;;
 | |
|     user)
 | |
|       cp "$3" "$1"
 | |
|       ;;
 | |
|   esac
 | |
| }
 | |
| 
 | |
| # Usage: set_var var [value]
 | |
| # Exit with an error if set_var was already called for the same VAR.  Else
 | |
| # set the variable VAR to the value VALUE (or the empty value if no parameter
 | |
| # is given).
 | |
| set_var () {
 | |
|   if eval test x\$set_$1 = xset; then
 | |
|     error Incompatible or repeated options.
 | |
|   else
 | |
|     eval $1=\$2
 | |
|     eval set_$1=set
 | |
|   fi
 | |
| }
 | |
| 
 | |
| # Process the arguments, including -C options, and copy the whole tree
 | |
| # to $JARTMP/files so that zip can be invoked later from there.
 | |
| make_files () {
 | |
|   change=false
 | |
|   if $process_response_files; then
 | |
|     if test $# = 0; then
 | |
|       while read arg; do
 | |
|         make_files_1 "$arg"
 | |
|       done
 | |
|     else
 | |
|       for infile
 | |
|       do
 | |
|         exec 5<&0
 | |
|         exec 0< $infile
 | |
|         while read arg; do
 | |
|           make_files_1 "$arg"
 | |
|         done
 | |
|         exec 0<&5
 | |
|         exec 5<&-
 | |
|       done
 | |
|     fi
 | |
|   else
 | |
|     for arg
 | |
|     do
 | |
|       make_files_1 "$arg"
 | |
|     done
 | |
|   fi
 | |
|   cd "$old_dir"
 | |
| }
 | |
| 
 | |
| # Usage: make_files_1 ARG
 | |
| # Process one argument, ARG.
 | |
| make_files_1 () {
 | |
|   if $change; then
 | |
|     change=false
 | |
|     if cd "$1"; then
 | |
|       return
 | |
|     else
 | |
|       (exit 1); exit 1
 | |
|     fi
 | |
|   fi
 | |
|   case "$1" in
 | |
|     -C)
 | |
|       change=:
 | |
|       ;;
 | |
|     -C*)
 | |
|       cd `expr "$1" : '-C\(.*\)' `
 | |
|       return
 | |
|       ;;
 | |
|     *)
 | |
|       if test -d "$1"; then
 | |
|         $mkdir_p "$JARTMP"/files/"$1"
 | |
|         find "$1" | while read file; do
 | |
|           if test -d "$file"; then
 | |
|             $mkdir_p "$JARTMP"/files/"$file"
 | |
|           else
 | |
|             copy "$file" "$JARTMP"/files
 | |
|           fi
 | |
|         done
 | |
|       else
 | |
|         copy "$1" "$JARTMP"/files
 | |
|       fi
 | |
|       ;;
 | |
|   esac
 | |
|   cd "$old_dir"
 | |
| }
 | |
| 
 | |
| # Same as "jar tf $1".
 | |
| jar_list () {
 | |
|   $UNZIP -l "$1" | \
 | |
|     sed '1,/^ ----/d;/^ ----/,$d;s/^ *[0-9]*  ..-..-.. ..:..   //'
 | |
| }
 | |
| 
 | |
| # Same as "jar tvf $1".
 | |
| jar_list_verbose () {
 | |
|   $UNZIP -l "$1" | \
 | |
|     @AWK@ 'BEGIN { yes = 0 }
 | |
| 	 /^ ----/ { yes = !yes; next }
 | |
| 	 yes {
 | |
| 	   size=$1
 | |
| 	   split ($2, d, "-")
 | |
| 	   split ($3, t, ":")
 | |
| 	   d[3] += (d[3] < 80) ? 2000 : 1900
 | |
| 	   timestamp=d[3] " " d[1] " " d[2] " " t[1] " " t[2] " 00"
 | |
| 	   gsub (/^ *[0-9]*  ..-..-.. ..:..   /, "")
 | |
| 	   printf "%6d %s %s\n", size, strftime ("%a %b %d %H:%M:%S %Z %Y", mktime (timestamp)), $0
 | |
| 	 }'
 | |
| }
 | |
| 
 | |
| # mkdir -p emulation based on the mkinstalldirs script.
 | |
| func_mkdir_p () {
 | |
|   for file
 | |
|   do
 | |
|     case $file in
 | |
|       /*) pathcomp=/ ;;
 | |
|       *)  pathcomp= ;;
 | |
|     esac
 | |
|     oIFS=$IFS
 | |
|     IFS=/
 | |
|     set fnord $file
 | |
|     shift
 | |
|     IFS=$oIFS
 | |
| 
 | |
|     errstatus=0
 | |
|     for d
 | |
|     do
 | |
|       test "x$d" = x && continue
 | |
|       pathcomp=$pathcomp$d
 | |
|       case $pathcomp in
 | |
|         -*) pathcomp=./$pathcomp ;;
 | |
|       esac
 | |
| 
 | |
|       if test ! -d "$pathcomp"; then
 | |
|         mkdir "$pathcomp" || lasterr=$?
 | |
|         test -d "$pathcomp" || errstatus=$lasterr
 | |
|       fi
 | |
|       pathcomp=$pathcomp/
 | |
|     done
 | |
|   done
 | |
|   return "$errstatus"
 | |
| }
 | |
| 
 | |
| # Detect mkdir -p
 | |
| # On NextStep and OpenStep, the `mkdir' command does not
 | |
| # recognize any option.  It will interpret all options as
 | |
| # directories to create, and then abort because `.' already
 | |
| # exists.
 | |
| if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
 | |
|   mkdir_p='mkdir -p'
 | |
| else
 | |
|   mkdir_p='func_mkdir_p'
 | |
|   test -d ./-p && rmdir ./-p
 | |
|   test -d ./--version && rmdir ./--version
 | |
| fi
 | |
| 
 | |
| # Process the first command line option.
 | |
| case "$1" in
 | |
|   -*) commands=`echo X"$1" | sed 's/^X-//' ` ;;
 | |
|   *) commands="$1"
 | |
| esac
 | |
| shift
 | |
| 
 | |
| # Operation to perform on the JAR file
 | |
| mode=unknown
 | |
| 
 | |
| # First -C option on the command line
 | |
| cur_dir=.
 | |
| 
 | |
| # Base directory for -C options
 | |
| old_dir=`pwd`
 | |
| # JAR file to operate on
 | |
| jarfile=
 | |
| 
 | |
| # default for no {m,M} option, user for "m" option, none for "M" option
 | |
| manifest_kind=default
 | |
| 
 | |
| # "-0" if the "0" option was given
 | |
| store=
 | |
| 
 | |
| # true if the "v" option was given
 | |
| verbose=false
 | |
| 
 | |
| # true if the non-standard "@" option was given
 | |
| process_response_files=false
 | |
| 
 | |
| # An exec command if we need to redirect the zip/unzip commands' output
 | |
| out_redirect=:
 | |
| 
 | |
| while test -n "$commands"; do
 | |
|   # Process a letter at a time
 | |
|   command=`expr "$commands" : '\(.\)'`
 | |
|   commands=`expr "$commands" : '.\(.*\)'`
 | |
|   case "$command" in
 | |
|     c)
 | |
|       set_var mode create
 | |
|       ;;
 | |
|     t)
 | |
|       set_var mode list
 | |
|       ;;
 | |
|     x)
 | |
|       set_var mode extract
 | |
|       ;;
 | |
|     u)
 | |
|       set_var mode update
 | |
|       ;;
 | |
| 
 | |
|     f)
 | |
|       test $# = 0 && usage
 | |
|       # Multiple "f" options are accepted by Sun's JAR tool.
 | |
|       jarfile="$1"
 | |
|       test -z "$jarfile" && usage
 | |
|       shift
 | |
|       ;;
 | |
|     m)
 | |
|       test $# = 0 && usage
 | |
|       # Multiple "m" options are accepted by Sun's JAR tool, but
 | |
|       # M always overrides m.
 | |
|       test "$manifest_kind" = default && manifest_kind=user
 | |
|       manifest_file="$1"
 | |
|       test -z "$manifest_file" && usage
 | |
|       shift
 | |
|       ;;
 | |
|     0)
 | |
|       store=-0
 | |
|       ;;
 | |
|     v)
 | |
|       verbose=:
 | |
|       ;;
 | |
|     i)
 | |
|       # Not yet implemented, and probably never will.
 | |
|       ;;
 | |
|     M)
 | |
|       manifest_kind=none
 | |
|       ;;
 | |
|     C)
 | |
|       test $# = 0 && usage
 | |
|       cur_dir="$1"
 | |
|       shift
 | |
|       ;;
 | |
|     @)
 | |
|       process_response_files=: ;;
 | |
|     *)
 | |
|       usage ;;
 | |
|   esac
 | |
| done
 | |
| 
 | |
| set -e
 | |
| 
 | |
| case "X$jarfile" in
 | |
|   X)
 | |
|     # Work on stdin/stdout.  Messages go to stderr, and if we need an input
 | |
|     # JAR file we save it temporarily in the temporary directory.
 | |
|     make_tmp
 | |
|     $mkdir_p "$JARTMP"/out
 | |
|     jarfile="$JARTMP"/out/tmp-stdin.jar
 | |
|     out_redirect='exec >&2'
 | |
|     case $mode in
 | |
|       update|extract|list)
 | |
|         if $process_response_files && test $# = 0; then
 | |
| 	  error Cannot use stdin for response file.
 | |
| 	fi
 | |
| 	cat > "$JARTMP"/out/tmp-stdin.jar
 | |
| 	;;
 | |
|     esac
 | |
|     ;;
 | |
| 
 | |
|   X*/*)
 | |
|     # Make an absolute path.
 | |
|     dir=`dirname "$jarfile"`
 | |
|     jarfile=`cd $dir && pwd`/`basename "$jarfile"`
 | |
|     ;;
 | |
| 
 | |
|   X*)
 | |
|     # Make an absolute path from a filename in the current directory.
 | |
|     jarfile=`pwd`/`basename "$jarfile"`
 | |
|     ;;
 | |
| esac
 | |
| 
 | |
| # Perform a -C option if given right away.
 | |
| cd "$cur_dir"
 | |
| 
 | |
| case $mode in
 | |
|   unknown)
 | |
|     usage
 | |
|     ;;
 | |
| 
 | |
|   extract)
 | |
|     make_tmp
 | |
| 
 | |
|     # Extract the list of files in the JAR file
 | |
|     jar_list "$jarfile" > "$JARTMP"/list
 | |
| 
 | |
|     # If there are files on the command line, expand directories and skip -C
 | |
|     # command line arguments
 | |
|     for arg
 | |
|     do
 | |
|       if $skip; then
 | |
|         skip=false
 | |
| 	continue
 | |
|       fi
 | |
|       case "$arg" in
 | |
| 	-C) skip=: ;;
 | |
| 	-C*) ;;
 | |
| 	*)
 | |
| 	  escaped=`echo "X$arg" | sed 's/^X//; s/[].[^$\\*]/\\\\&/g' `
 | |
| 	  grep "^$escaped/" "$JARTMP"/list >> "$JARTMP"/chosen || :
 | |
| 	  grep "^$escaped\$" "$JARTMP"/list >> "$JARTMP"/chosen || :
 | |
|       esac
 | |
|     done
 | |
|     test -f "$JARTMP"/chosen || cp "$JARTMP"/list "$JARTMP"/chosen
 | |
| 
 | |
|     # Really execute unzip
 | |
|     if $verbose; then
 | |
|       sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" | \
 | |
| 	sed -ne 's/^   creating/  created/p' -e 's/^  inflating/extracted/p'
 | |
|     else
 | |
|       sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" > /dev/null
 | |
|     fi
 | |
|     ;;
 | |
| 
 | |
|   create)
 | |
|     make_tmp
 | |
|     $mkdir_p "$JARTMP"/out
 | |
|     $mkdir_p "$JARTMP"/files
 | |
| 
 | |
|     # Do not overwrite the JAR file if something goes wrong
 | |
|     tmp_jarfile="$JARTMP"/out/`basename "$jarfile"`
 | |
| 
 | |
|     # Prepare the files in the temporary directory.  This is necessary to
 | |
|     # support -C and still save relative paths in the JAR file.
 | |
|     make_files ${1+"$@"}
 | |
|     if test $manifest_kind != none; then
 | |
|       make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
 | |
|     fi
 | |
| 
 | |
|     # Really execute zip
 | |
|     if $verbose; then
 | |
|       (eval $out_redirect; cd "$JARTMP"/files && $ZIP -rv "$tmp_jarfile" $store .)
 | |
|     else
 | |
|       (cd "$JARTMP/files" && $ZIP -r "$tmp_jarfile" $store . > /dev/null)
 | |
|     fi
 | |
|     test "$jarfile" = "$tmp_jarfile" || mv "$tmp_jarfile" "$jarfile"
 | |
|     ;;
 | |
| 
 | |
|   update)
 | |
|     make_tmp
 | |
|     $mkdir_p "$JARTMP"/files
 | |
|     make_files ${1+"$@"}
 | |
| 
 | |
|     # Same as above, but zip takes care of not overwriting the file
 | |
|     case $manifest_kind in
 | |
|       none)
 | |
| 	$verbose && (eval $out_redirect; echo removing manifest)
 | |
| 	$ZIP -d "$jarfile" META-INF/MANIFEST.MF > /dev/null 2>&1 || :
 | |
| 	;;
 | |
|       *)
 | |
| 	make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
 | |
| 	;;
 | |
|     esac
 | |
|     if $verbose; then
 | |
|       (eval $out_redirect; cd "$JARTMP"/files && $ZIP -ruv "$jarfile" $store .)
 | |
|     else
 | |
|       (cd "$JARTMP"/files && $ZIP -ru "$jarfile" $store . > /dev/null)
 | |
|     fi
 | |
|     ;;
 | |
| 
 | |
|   list)
 | |
|     # Everything's done in the functions
 | |
|     if $verbose; then
 | |
|       jar_list_verbose "$jarfile"
 | |
|     else
 | |
|       jar_list "$jarfile"
 | |
|     fi ;;
 | |
| esac
 | |
| 
 | |
| if test "$out_redirect" != :; then
 | |
|   # Cat back to stdout if necessary
 | |
|   case $mode in
 | |
|     create|update) cat "$JARTMP"/out/tmp-stdin.jar ;;
 | |
|   esac
 | |
| fi
 | |
| exit 0
 |