2015-07-06 Marc Glisse <marc.glisse@inria.fr>
[official-gcc.git] / libjava / scripts / jar.in
blobe9cb9f5822e759b19639ba3f03ba27aa0fbba233
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 -f "$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 func_mkdir_p () {
253   for file
254   do
255     case $file in
256       /*) pathcomp=/ ;;
257       *)  pathcomp= ;;
258     esac
259     oIFS=$IFS
260     IFS=/
261     set fnord $file
262     shift
263     IFS=$oIFS
265     errstatus=0
266     for d
267     do
268       test "x$d" = x && continue
269       pathcomp=$pathcomp$d
270       case $pathcomp in
271         -*) pathcomp=./$pathcomp ;;
272       esac
274       if test ! -d "$pathcomp"; then
275         mkdir "$pathcomp" || lasterr=$?
276         test -d "$pathcomp" || errstatus=$lasterr
277       fi
278       pathcomp=$pathcomp/
279     done
280   done
281   return "$errstatus"
284 # Detect mkdir -p
285 # On NextStep and OpenStep, the `mkdir' command does not
286 # recognize any option.  It will interpret all options as
287 # directories to create, and then abort because `.' already
288 # exists.
289 if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
290   mkdir_p='mkdir -p'
291 else
292   mkdir_p='func_mkdir_p'
293   test -d ./-p && rmdir ./-p
294   test -d ./--version && rmdir ./--version
297 # Process the first command line option.
298 case "$1" in
299   -*) commands=`echo X"$1" | sed 's/^X-//' ` ;;
300   *) commands="$1"
301 esac
302 shift
304 # Operation to perform on the JAR file
305 mode=unknown
307 # First -C option on the command line
308 cur_dir=.
310 # Base directory for -C options
311 old_dir=`pwd`
312 # JAR file to operate on
313 jarfile=
315 # default for no {m,M} option, user for "m" option, none for "M" option
316 manifest_kind=default
318 # "-0" if the "0" option was given
319 store=
321 # true if the "v" option was given
322 verbose=false
324 # true if the non-standard "@" option was given
325 process_response_files=false
327 # An exec command if we need to redirect the zip/unzip commands' output
328 out_redirect=:
330 while test -n "$commands"; do
331   # Process a letter at a time
332   command=`expr "$commands" : '\(.\)'`
333   commands=`expr "$commands" : '.\(.*\)'`
334   case "$command" in
335     c)
336       set_var mode create
337       ;;
338     t)
339       set_var mode list
340       ;;
341     x)
342       set_var mode extract
343       ;;
344     u)
345       set_var mode update
346       ;;
348     f)
349       test $# = 0 && usage
350       # Multiple "f" options are accepted by Sun's JAR tool.
351       jarfile="$1"
352       test -z "$jarfile" && usage
353       shift
354       ;;
355     m)
356       test $# = 0 && usage
357       # Multiple "m" options are accepted by Sun's JAR tool, but
358       # M always overrides m.
359       test "$manifest_kind" = default && manifest_kind=user
360       manifest_file="$1"
361       test -z "$manifest_file" && usage
362       shift
363       ;;
364     0)
365       store=-0
366       ;;
367     v)
368       verbose=:
369       ;;
370     i)
371       # Not yet implemented, and probably never will.
372       ;;
373     M)
374       manifest_kind=none
375       ;;
376     C)
377       test $# = 0 && usage
378       cur_dir="$1"
379       shift
380       ;;
381     @)
382       process_response_files=: ;;
383     *)
384       usage ;;
385   esac
386 done
388 set -e
390 case "X$jarfile" in
391   X)
392     # Work on stdin/stdout.  Messages go to stderr, and if we need an input
393     # JAR file we save it temporarily in the temporary directory.
394     make_tmp
395     $mkdir_p "$JARTMP"/out
396     jarfile="$JARTMP"/out/tmp-stdin.jar
397     out_redirect='exec >&2'
398     case $mode in
399       update|extract|list)
400         if $process_response_files && test $# = 0; then
401           error Cannot use stdin for response file.
402         fi
403         cat > "$JARTMP"/out/tmp-stdin.jar
404         ;;
405     esac
406     ;;
408   X*/*)
409     # Make an absolute path.
410     dir=`dirname "$jarfile"`
411     jarfile=`cd $dir && pwd`/`basename "$jarfile"`
412     ;;
414   X*)
415     # Make an absolute path from a filename in the current directory.
416     jarfile=`pwd`/`basename "$jarfile"`
417     ;;
418 esac
420 # Perform a -C option if given right away.
421 cd "$cur_dir"
423 case $mode in
424   unknown)
425     usage
426     ;;
428   extract)
429     make_tmp
431     # Extract the list of files in the JAR file
432     jar_list "$jarfile" > "$JARTMP"/list
434     # If there are files on the command line, expand directories and skip -C
435     # command line arguments
436     for arg
437     do
438       if $skip; then
439         skip=false
440         continue
441       fi
442       case "$arg" in
443         -C) skip=: ;;
444         -C*) ;;
445         *)
446           escaped=`echo "X$arg" | sed 's/^X//; s/[].[^$\\*]/\\\\&/g' `
447           grep "^$escaped/" "$JARTMP"/list >> "$JARTMP"/chosen || :
448           grep "^$escaped\$" "$JARTMP"/list >> "$JARTMP"/chosen || :
449       esac
450     done
451     test -f "$JARTMP"/chosen || cp "$JARTMP"/list "$JARTMP"/chosen
453     # Really execute unzip
454     if $verbose; then
455       sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" | \
456         sed -ne 's/^   creating/  created/p' -e 's/^  inflating/extracted/p'
457     else
458       sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" > /dev/null
459     fi
460     ;;
462   create)
463     make_tmp
464     $mkdir_p "$JARTMP"/out
465     $mkdir_p "$JARTMP"/files
467     # Do not overwrite the JAR file if something goes wrong
468     tmp_jarfile="$JARTMP"/out/`basename "$jarfile"`
470     # Prepare the files in the temporary directory.  This is necessary to
471     # support -C and still save relative paths in the JAR file.
472     make_files ${1+"$@"}
473     if test $manifest_kind != none; then
474       make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
475     fi
477     # Really execute zip
478     if $verbose; then
479       (eval $out_redirect; cd "$JARTMP"/files && $ZIP -rv "$tmp_jarfile" $store .)
480     else
481       (cd "$JARTMP/files" && $ZIP -r "$tmp_jarfile" $store . > /dev/null)
482     fi
483     test "$jarfile" = "$tmp_jarfile" || mv "$tmp_jarfile" "$jarfile"
484     ;;
486   update)
487     make_tmp
488     $mkdir_p "$JARTMP"/files
489     make_files ${1+"$@"}
491     # Same as above, but zip takes care of not overwriting the file
492     case $manifest_kind in
493       none)
494         $verbose && (eval $out_redirect; echo removing manifest)
495         $ZIP -d "$jarfile" META-INF/MANIFEST.MF > /dev/null 2>&1 || :
496         ;;
497       *)
498         make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
499         ;;
500     esac
501     if $verbose; then
502       (eval $out_redirect; cd "$JARTMP"/files && $ZIP -ruv "$jarfile" $store .)
503     else
504       (cd "$JARTMP"/files && $ZIP -ru "$jarfile" $store . > /dev/null)
505     fi
506     ;;
508   list)
509     # Everything's done in the functions
510     if $verbose; then
511       jar_list_verbose "$jarfile"
512     else
513       jar_list "$jarfile"
514     fi ;;
515 esac
517 if test "$out_redirect" != :; then
518   # Cat back to stdout if necessary
519   case $mode in
520     create|update) cat "$JARTMP"/out/tmp-stdin.jar ;;
521   esac
523 exit 0