Daily bump.
[official-gcc.git] / libjava / scripts / jar.in
blob82ea10c2912340c52af92fe823c24ebffe7c0f28
1 #! @SHELL@
2 # Copyright (C) 2006  Free Software Foundation
3 # Written by Paolo Bonzini.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published
7 # by the Free Software Foundation; either version 2 of the License,
8 # or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 # for more details.
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 # POSIX and NLS nuisances, taken from autoconf.
21 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
22   emulate sh
23   NULLCMD=:
24   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
25   # is contrary to our usage.  Disable this feature.
26   alias -g '${1+"$@"}'='"$@"'
27   setopt NO_GLOB_SUBST
28 else
29   case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
31 BIN_SH=xpg4; export BIN_SH # for Tru64
32 DUALCASE=1; export DUALCASE # for MKS sh
34 if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
35 if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
36 if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
37 if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
39 # Also make sure CDPATH is empty, and IFS is space, tab, \n in that order.
40 # Be careful to avoid that editors munge IFS
41 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
42 IFS=" ""        ""
45 : ${TMPDIR=/tmp}
46 : ${ZIP="@ZIP@"}
47 : ${UNZIP="@UNZIP@"}
48 progname="$0"
50 # Emit a usage message and exit with error status 1
51 usage () {
52   cat >&2 <<EOF
53 Usage: $0 {ctxu}[vfm0Mi@] [jar-file] [manifest-file] {[-C dir] files} ...
54 Options:
55     -c  create new archive
56     -t  list table of contents for archive
57     -x  extract named (or all) files from archive
58     -u  update existing archive
59     -v  generate verbose output on standard output
60     -f  specify archive file name
61     -m  include manifest information from specified manifest file
62     -0  store only; use no ZIP compression
63     -M  do not create a manifest file for the entries
64     -i  generate index information for the specified jar files
65     -@  instead of {[-C dir] files} ... accept one or more response files,
66         each containing one command-line argument
67     -C  change to the specified directory and include the following file
68 If any file is a directory then it is processed recursively.
69 The manifest file name and the archive file name needs to be specified
70 in the same order the 'm' and 'f' flags are specified.
72 Example 1: to archive two class files into an archive called classes.jar: 
73        jar cvf classes.jar Foo.class Bar.class 
74 Example 2: use an existing manifest file 'mymanifest' and archive all the
75            files in the foo/ directory into 'classes.jar': 
76        jar cvfm classes.jar mymanifest -C foo/ .
78 EOF
79   (exit 1); exit 1
82 # Emit an error message and exit with error status 1
83 error () {
84   echo "$progname: $*" >&2
85   (exit 1); exit 1
88 # Usage: copy SRC DEST
89 # Copy file SRC to directory DEST, which is the staging area of the jar file.
90 # Fail if it is already present or if it is not a regular file.
91 copy () {
92   if test -f "$1"; then
93     # A simple optimization.  Optimistically assuming that ln will work
94     # cuts 60% of the run-time!
95     if ln "$1" "$2"/"$1" > /dev/null 2>&1; then
96       return 0
97     fi
99     if test -e "$2"/"$1"; then
100       error "$1": Duplicate entry.
101     fi
102     dir=`dirname "$1"`
103     $mkdir_p "$2"/"$dir"
104     ln "$1" "$2"/"$1" > /dev/null 2>&1 || cp "$1" "$2"/"$1"
105   elif test -e "$1"; then
106     error "$1": Invalid file type.
107   else
108     error "$1": File not found.
109   fi
112 # Make a temporary directory and store its name in the JARTMP variable.
113 make_tmp () {
114   test -n "$JARTMP" && return
116   {
117     JARTMP=`(umask 077 && mktemp -d "$TMPDIR/jarXXXXXX") 2>/dev/null` &&
118       test -n "$JARTMP" && test -d "$JARTMP"
119   } || {
120     JARTMP=$TMPDIR/jar$$-$RANDOM
121     (umask 077 && mkdir "$JARTMP")
122   } || exit $?
124   trap 'exit_status=$?
125         if test -n "$JARTMP"; then rm -rf "$JARTMP"; fi
126         exit $exit_status' 0
129 # Usage: make_manifest destfile kind [source-manifest]
130 # Create a manifest file and store it in destfile.  KIND can be "default",
131 # or "user", in which case SOURCE-MANIFEST must be specified as well.
132 make_manifest () {
133   dir=`dirname "$1"`
134   $mkdir_p "$dir"
135   case $2 in
136     default)
137       cat > "$1" <<\EOF
138 Manifest-Version: 1.0
139 Created-By: @VERSION@
142       ;;
143     user)
144       cp "$3" "$1"
145       ;;
146   esac
149 # Usage: set_var var [value]
150 # Exit with an error if set_var was already called for the same VAR.  Else
151 # set the variable VAR to the value VALUE (or the empty value if no parameter
152 # is given).
153 set_var () {
154   if eval test x\$set_$1 = xset; then
155     error Incompatible or repeated options.
156   else
157     eval $1=\$2
158     eval set_$1=set
159   fi
162 # Process the arguments, including -C options, and copy the whole tree
163 # to $JARTMP/files so that zip can be invoked later from there.
164 make_files () {
165   change=false
166   if $process_response_files; then
167     if test $# = 0; then
168       while read arg; do
169         make_files_1 "$arg"
170       done
171     else
172       for infile
173       do
174         exec 5<&0
175         exec 0< $infile
176         while read arg; do
177           make_files_1 "$arg"
178         done
179         exec 0<&5
180         exec 5<&-
181       done
182     fi
183   else
184     for arg
185     do
186       make_files_1 "$arg"
187     done
188   fi
189   cd "$old_dir"
192 # Usage: make_files_1 ARG
193 # Process one argument, ARG.
194 make_files_1 () {
195   if $change; then
196     change=false
197     if cd "$1"; then
198       return
199     else
200       (exit 1); exit 1
201     fi
202   fi
203   case "$1" in
204     -C)
205       change=:
206       ;;
207     -C*)
208       cd `expr "$1" : '-C\(.*\)' `
209       return
210       ;;
211     *)
212       if test -d "$1"; then
213         $mkdir_p "$JARTMP"/files/"$1"
214         find "$1" | while read file; do
215           if test -d "$file"; then
216             $mkdir_p "$JARTMP"/files/"$file"
217           else
218             copy "$file" "$JARTMP"/files
219           fi
220         done
221       else
222         copy "$1" "$JARTMP"/files
223       fi
224       ;;
225   esac
226   cd "$old_dir"
229 # Same as "jar tf $1".
230 jar_list () {
231   $UNZIP -l "$1" | \
232     sed '1,/^ ----/d;/^ ----/,$d;s/^ *[0-9]*  ..-..-.. ..:..   //'
235 # Same as "jar tvf $1".
236 jar_list_verbose () {
237   $UNZIP -l "$1" | \
238     @AWK@ 'BEGIN { yes = 0 }
239          /^ ----/ { yes = !yes; next }
240          yes {
241            size=$1
242            split ($2, d, "-")
243            split ($3, t, ":")
244            d[3] += (d[3] < 80) ? 2000 : 1900
245            timestamp=d[3] " " d[1] " " d[2] " " t[1] " " t[2] " 00"
246            gsub (/^ *[0-9]*  ..-..-.. ..:..   /, "")
247            printf "%6d %s %s\n", size, strftime ("%a %b %d %H:%M:%S %Z %Y", mktime (timestamp)), $0
248          }'
251 # mkdir -p emulation based on the mkinstalldirs script.
252 mkdir_p ()
254   for file
255   do
256     case $file in
257       /*) pathcomp=/ ;;
258       *)  pathcomp= ;;
259     esac
260     oIFS=$IFS
261     IFS=/
262     set fnord $file
263     shift
264     IFS=$oIFS
266     errstatus=0
267     for d
268     do
269       test "x$d" = x && continue
270       pathcomp=$pathcomp$d
271       case $pathcomp in
272         -*) pathcomp=./$pathcomp ;;
273       esac
275       if test ! -d "$pathcomp"; then
276         mkdir "$pathcomp" || lasterr=$?
277         test -d "$pathcomp" || errstatus=$lasterr
278       fi
279       pathcomp=$pathcomp/
280     done
281   done
282   return "$errstatus"
285 # Detect mkdir -p
286 # On NextStep and OpenStep, the `mkdir' command does not
287 # recognize any option.  It will interpret all options as
288 # directories to create, and then abort because `.' already
289 # exists.
290 if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
291   mkdir_p='mkdir -p'
292 else
293   mkdir_p='mkdir_p'
294   test -d ./-p && rmdir ./-p
295   test -d ./--version && rmdir ./--version
298 # Process the first command line option.
299 case "$1" in
300   -*) commands=`echo X"$1" | sed 's/^X-//' ` ;;
301   *) commands="$1"
302 esac
303 shift
305 # Operation to perform on the JAR file
306 mode=unknown
308 # First -C option on the command line
309 cur_dir=.
311 # Base directory for -C options
312 old_dir=`pwd`
313 # JAR file to operate on
314 jarfile=
316 # default for no {m,M} option, user for "m" option, none for "M" option
317 manifest_kind=default
319 # "-0" if the "0" option was given
320 store=
322 # true if the "v" option was given
323 verbose=false
325 # true if the non-standard "@" option was given
326 process_response_files=false
328 # An exec command if we need to redirect the zip/unzip commands' output
329 out_redirect=:
331 while test -n "$commands"; do
332   # Process a letter at a time
333   command=`expr "$commands" : '\(.\)'`
334   commands=`expr "$commands" : '.\(.*\)'`
335   case "$command" in
336     c)
337       set_var mode create
338       ;;
339     t)
340       set_var mode list
341       ;;
342     x)
343       set_var mode extract
344       ;;
345     u)
346       set_var mode update
347       ;;
349     f)
350       test $# = 0 && usage
351       # Multiple "f" options are accepted by Sun's JAR tool.
352       jarfile="$1"
353       test -z "$jarfile" && usage
354       shift
355       ;;
356     m)
357       test $# = 0 && usage
358       # Multiple "m" options are accepted by Sun's JAR tool, but
359       # M always overrides m.
360       test "$manifest_kind" = default && manifest_kind=user
361       manifest_file="$1"
362       test -z "$manifest_file" && usage
363       shift
364       ;;
365     0)
366       store=-0
367       ;;
368     v)
369       verbose=:
370       ;;
371     i)
372       # Not yet implemented, and probably never will.
373       ;;
374     M)
375       manifest_kind=none
376       ;;
377     C)
378       test $# = 0 && usage
379       cur_dir="$1"
380       shift
381       ;;
382     @)
383       process_response_files=: ;;
384     *)
385       usage ;;
386   esac
387 done
389 set -e
391 case "X$jarfile" in
392   X)
393     # Work on stdin/stdout.  Messages go to stderr, and if we need an input
394     # JAR file we save it temporarily in the temporary directory.
395     make_tmp
396     $mkdir_p "$JARTMP"/out
397     jarfile="$JARTMP"/out/tmp-stdin.jar
398     out_redirect='exec >&2'
399     case $mode in
400       update|extract|list)
401         if $process_response_files && test $# = 0; then
402           error Cannot use stdin for response file.
403         fi
404         cat > "$JARTMP"/out/tmp-stdin.jar
405         ;;
406     esac
407     ;;
409   X*/*)
410     # Make an absolute path.
411     dir=`dirname "$jarfile"`
412     jarfile=`cd $dir && pwd`/`basename "$jarfile"`
413     ;;
415   X*)
416     # Make an absolute path from a filename in the current directory.
417     jarfile=`pwd`/`basename "$jarfile"`
418     ;;
419 esac
421 # Perform a -C option if given right away.
422 cd "$cur_dir"
424 case $mode in
425   unknown)
426     usage
427     ;;
429   extract)
430     make_tmp
432     # Extract the list of files in the JAR file
433     jar_list "$jarfile" > "$JARTMP"/list
435     # If there are files on the command line, expand directories and skip -C
436     # command line arguments
437     for arg
438     do
439       if $skip; then
440         skip=false
441         continue
442       fi
443       case "$arg" in
444         -C) skip=: ;;
445         -C*) ;;
446         *)
447           escaped=`echo "X$arg" | sed 's/^X//; s/[].[^$\\*]/\\\\&/g' `
448           grep "^$escaped/" "$JARTMP"/list >> "$JARTMP"/chosen || :
449           grep "^$escaped\$" "$JARTMP"/list >> "$JARTMP"/chosen || :
450       esac
451     done
452     test -f "$JARTMP"/chosen || cp "$JARTMP"/list "$JARTMP"/chosen
454     # Really execute unzip
455     if $verbose; then
456       sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" | \
457         sed -ne 's/^   creating/  created/p' -e 's/^  inflating/extracted/p'
458     else
459       sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" > /dev/null
460     fi
461     ;;
463   create)
464     make_tmp
465     $mkdir_p "$JARTMP"/out
466     $mkdir_p "$JARTMP"/files
468     # Do not overwrite the JAR file if something goes wrong
469     tmp_jarfile="$JARTMP"/out/`basename "$jarfile"`
471     # Prepare the files in the temporary directory.  This is necessary to
472     # support -C and still save relative paths in the JAR file.
473     make_files ${1+"$@"}
474     if test $manifest_kind != none; then
475       make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
476     fi
478     # Really execute zip
479     if $verbose; then
480       (eval $out_redirect; cd "$JARTMP"/files && $ZIP -rv "$tmp_jarfile" $store .)
481     else
482       (cd "$JARTMP/files" && $ZIP -r "$tmp_jarfile" $store . > /dev/null)
483     fi
484     test "$jarfile" = "$tmp_jarfile" || mv "$tmp_jarfile" "$jarfile"
485     ;;
487   update)
488     make_tmp
489     $mkdir_p "$JARTMP"/files
490     make_files ${1+"$@"}
492     # Same as above, but zip takes care of not overwriting the file
493     case $manifest_kind in
494       none)
495         $verbose && (eval $out_redirect; echo removing manifest)
496         $ZIP -d "$jarfile" META-INF/MANIFEST.MF > /dev/null 2>&1 || :
497         ;;
498       *)
499         make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
500         ;;
501     esac
502     if $verbose; then
503       (eval $out_redirect; cd "$JARTMP"/files && $ZIP -ruv "$jarfile" $store .)
504     else
505       (cd "$JARTMP"/files && $ZIP -ru "$jarfile" $store . > /dev/null)
506     fi
507     ;;
509   list)
510     # Everything's done in the functions
511     if $verbose; then
512       jar_list_verbose "$jarfile"
513     else
514       jar_list "$jarfile"
515     fi ;;
516 esac
518 if test "$out_redirect" != :; then
519   # Cat back to stdout if necessary
520   case $mode in
521     create|update) cat "$JARTMP"/out/tmp-stdin.jar ;;
522   esac
524 exit 0